@adatechnology/game-vfx-three 0.1.3 → 0.2.1
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 +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.global.js +916 -215
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +101 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.global.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../../game-vfx/src/area-cap.ts","../../game-vfx/src/budget.ts","../../game-vfx/src/data/explosion-aliases.json","../../game-vfx/src/data/explosions.json","../../game-vfx/src/catalog.ts","../../game-vfx/src/color.ts","../../game-vfx/src/constants.ts","../../game-vfx/src/pool.ts","../../game-vfx/src/pools/chunks.ts","../../game-vfx/src/vector.ts","../../game-vfx/src/pools/glows.ts","../../game-vfx/src/pools/puffs.ts","../../game-vfx/src/pools/sparks.ts","../../game-vfx/src/spawn.ts","../../game-vfx/src/emitters/fire.ts","../../game-vfx/src/effects/dsl.ts","../../game-vfx/src/effects/steps.ts","../../game-vfx/src/effects/creatures/bloater-cloud.ts","../../game-vfx/src/effects/creatures/blood-hit.ts","../../game-vfx/src/effects/creatures/corpse-decay.ts","../../game-vfx/src/effects/creatures/eyes-in-fog.ts","../../game-vfx/src/effects/creatures/dismember.ts","../../game-vfx/src/effects/creatures/headshot.ts","../../game-vfx/src/effects/creatures/reanimation.ts","../../game-vfx/src/effects/creatures/screamer-shriek.ts","../../game-vfx/src/effects/props.ts","../../game-vfx/src/effects/weapons/impact-by-material.ts","../../game-vfx/src/effects/weapons/penetration.ts","../../game-vfx/src/effects/weapons/casings-and-magazine.ts","../../game-vfx/src/effects/weapons/molotov.ts","../../game-vfx/src/effects/weapons/grenade.ts","../../game-vfx/src/effects/weapons/explosive-barrel.ts","../../game-vfx/src/effects/weapons/muzzle-flash.ts","../../game-vfx/src/effects/destruction/shopfront-glass.ts","../../game-vfx/src/effects/vector-math.ts","../../game-vfx/src/effects/destruction/door-stages.ts","../../game-vfx/src/effects/destruction/building-collapse.ts","../../game-vfx/src/effects/destruction/block-wall.ts","../../game-vfx/src/effects/destruction/spot.ts","../../game-vfx/src/effects/destruction/metal-door.ts","../../game-vfx/src/effects/destruction/iron-railing.ts","../../game-vfx/src/effects/destruction/wooden-fence.ts","../../game-vfx/src/effects/destruction/hit-point-breakage.ts","../../game-vfx/src/effects/destruction/pressure-cylinders.ts","../../game-vfx/src/effects/world/building-fire.ts","../../game-vfx/src/effects/vehicles/scraping-sparks.ts","../../game-vfx/src/effects/vehicles/car.ts","../../game-vfx/src/effects/vehicles/engine-smoke.ts","../../game-vfx/src/effects/vehicles/boom.ts","../../game-vfx/src/effects/vehicles/fuel-leak.ts","../../game-vfx/src/effects/vehicles/car-explosion.ts","../../game-vfx/src/effects/vehicles/windshield.ts","../../game-vfx/src/effects/screen/damage-and-bite.ts","../../game-vfx/src/effects/screen/infection-phases.ts","../../game-vfx/src/effects/screen/panic.ts","../../game-vfx/src/effects/screen/bloater-blindness.ts","../../game-vfx/src/effects/screen/campfire.ts","../../game-vfx/src/effects/screen/cough-and-breath.ts","../../game-vfx/src/effects/events.ts","../../game-vfx/src/effects/catalog.ts","../../game-vfx/src/random.ts","../../game-vfx/src/effects/builders/impact-table.ts","../../game-vfx/src/effects/builders/blood.ts","../../game-vfx/src/effects/behaviors/blocks.ts","../../game-vfx/src/effects/behaviors/car.ts","../../game-vfx/src/effects/behaviors/cracks.ts","../../game-vfx/src/effects/builders/shared.ts","../../game-vfx/src/effects/behaviors/cylinder.ts","../../game-vfx/src/effects/behaviors/plate.ts","../../game-vfx/src/effects/behaviors/walkers.ts","../../game-vfx/src/effects/behaviors.ts","../../game-vfx/src/schedule.ts","../../game-vfx/src/effects/expression.ts","../../game-vfx/src/effects/builders/fire.ts","../../game-vfx/src/effects/builders/weapon.ts","../../game-vfx/src/effects/macros.ts","../../game-vfx/src/effects/instance.ts","../../game-vfx/src/effects/player.ts","../../game-vfx/src/lights.ts","../../game-vfx/src/lod.ts","../../game-vfx/src/marks.ts","../../game-vfx/src/pools/rings.ts","../../game-vfx/src/pools/shocks.ts","../../game-vfx/src/explosion.ts","../../game-vfx/src/pools/chunk-motion.ts","../../game-vfx/src/screen.ts","../../game-vfx/src/sprites/kind-pool.ts","../../game-vfx/src/data/sprite-kinds.json","../../game-vfx/src/sprites/kinds.ts","../../game-vfx/src/sprites/system.ts","../../game-vfx/src/workshop/direction.ts","../../game-vfx/src/workshop/debris.ts","../../game-vfx/src/workshop/decals.ts","../../game-vfx/src/workshop/sprites.ts","../../game-vfx/src/workshop/streaks.ts","../../game-vfx/src/workshop/waves.ts","../../game-vfx/src/workshop/engine.ts","../../game-vfx/src/types.ts","../../game-vfx/src/world.ts","../../game-vfx/src/data/event-effects.json","../../game-vfx/src/effects/event-map.ts","../../game-vfx/src/locales/en.ts","../../game-vfx/src/locales/pt-BR.ts","../../game-vfx/src/locale.ts","../../game-vfx/src/effects/camera.ts","../../game-vfx/src/effects/runner.ts","../../game-vfx/src/ground.ts","../src/shaders/glow.ts","../src/shaders/noise.ts","../src/shaders/puff.ts","../src/shaders/spark.ts","../src/instanced.ts","../src/lights.ts","../src/canvas.ts","../src/marks.ts","../src/screen-overlay.ts","../src/shaders/shock.ts","../src/shocks.ts","../src/shaders/sprite.ts","../src/sprites.ts","../src/shaders/workshop-sprite.ts","../src/workshop-layers.ts","../src/renderer.ts","../src/bench/text.ts","../src/bench/module.ts","../src/ground-patch.ts"],"sourcesContent":["/**\n * @adatechnology/game-vfx-three: the three.js renderer of `@adatechnology/game-vfx`: the Explosion Lab's shaders, debris, shock, lights, marks and\n * screen overlay, plus a deformable ground patch and an `EffectSink` to lend to modules.\n */\nexport { createVfxRenderer, VFX_LAYERS } from './renderer'\nexport { createVfxTestModule } from './bench/module'\nexport type { VfxTestModuleOptions } from './bench/module'\nexport { benchText, benchTexts } from './bench/text'\nexport type { BenchText } from './bench/text'\nexport { createGroundPatch } from './ground-patch'\nexport type { GroundPatch, GroundPatchOptions } from './ground-patch'\nexport { createScreenOverlay } from './screen-overlay'\nexport type { ScreenOverlay } from './screen-overlay'\nexport { createSpriteLayer } from './sprites'\nexport type { SpriteLayer } from './sprites'\nexport { SPRITE_FRAGMENT, SPRITE_VERTEX } from './shaders/sprite'\nexport { createMarkLayer } from './marks'\nexport type { MarkLayer, MarkLayerOptions } from './marks'\nexport { PUFF_FRAGMENT, PUFF_VERTEX } from './shaders/puff'\nexport { SPARK_FRAGMENT, SPARK_VERTEX } from './shaders/spark'\nexport { GLOW_FRAGMENT, GLOW_VERTEX } from './shaders/glow'\nexport { RING_FRAGMENT, RING_VERTEX, SHELL_FRAGMENT, SHELL_VERTEX } from './shaders/shock'\nexport type { CanvasContextLike, CanvasLike, ThreeLib, VfxRenderer, VfxRendererOptions, VfxRendererStats } from './types'\n","import type { AreaCap } from './types'\n\n/** The game's cap (G68194-68202): from the 7th explosion within 40 m in 4 s, the extra ones are made at 0.3. */\nexport const AREA_CAP_GAME: AreaCap = { radius: 40, window: 4, count: 6, excessScale: 0.3 }\n\nexport interface AreaCapTracker {\n /** Registers an explosion at (`x`, `z`) at `time` seconds and answers the scale it gets: 1, or the cap's `excessScale` when `count` or more are already recent in the area. */\n register(time: number, x: number, z: number): number\n clear(): void\n}\n\ninterface Recent {\n time: number\n x: number\n z: number\n}\n\nexport function createAreaCap(cap: AreaCap): AreaCapTracker {\n const recent: Recent[] = []\n const spare: Recent[] = []\n const radiusSquared = cap.radius * cap.radius\n return {\n register(time, x, z) {\n let kept = 0\n for (const entry of recent) {\n if (time - entry.time < cap.window) recent[kept++] = entry\n else spare.push(entry)\n }\n recent.length = kept\n let near = 0\n for (const entry of recent) if ((entry.x - x) ** 2 + (entry.z - z) ** 2 < radiusSquared) near++\n const entry = spare.pop() ?? { time: 0, x: 0, z: 0 }\n entry.time = time\n entry.x = x\n entry.z = z\n recent.push(entry)\n return near >= cap.count ? cap.excessScale : 1\n },\n clear() {\n for (const entry of recent) spare.push(entry)\n recent.length = 0\n },\n }\n}\n","import type { ExplosionDef, VfxProfile, VfxProfileName } from './types'\n\n/**\n * The pool sizes of the three profiles. `high` is the bench and the goldens (the Lab's caps L131/240/295/367 and the Workshop's W221), `medium` the\n * game's default (G67747/67762), `low` close to the game's own budgets (G68074, G68108).\n */\nexport const PROFILES: Readonly<Record<VfxProfileName, VfxProfile>> = {\n high: { puffs: 2600, sparks: 3200, glows: 320, chunks: 300, sprites: { add: 9000, normal: 9000 }, streaks: 3000, debris: 500 },\n medium: { puffs: 1300, sparks: 1600, glows: 160, chunks: 150, sprites: { add: 1500, normal: 600 }, streaks: 1000, debris: 120 },\n low: { puffs: 260, sparks: 800, glows: 80, chunks: 120, sprites: { add: 600, normal: 300 }, streaks: 400, debris: 60 },\n}\n\n/** The Lab's per-event meters (L1043-1044): 400 GPU particles, 40 physics debris, and 4 + 2 lights. */\nexport const EVENT_BUDGET = { particles: 400, debris: 40, blastLights: 4, fireLights: 2 } as const\n\n/** Particles an explosion makes on the GPU, the number of the Lab's effect sheet (L1033): fireballs, smoke, dust, shrapnel, the mushroom and the embers. */\nexport function estimateCost(def: ExplosionDef): number {\n const mushroom = def.mushroom ? def.mushroom.count + def.mushroom.stem : 0\n return def.fireballs + def.smoke.count + def.dust.count + def.shrapnel.count + mushroom + (def.shrapnel.embers ?? 0)\n}\n","{\n \"carl_gustaf_84mm\": \"at4_84mm\",\n \"vog_25\": \"m79_40mm\"\n}\n","{\n \"m67\": {\n \"id\": \"m67\",\n \"lethal\": 5,\n \"injury\": 15,\n \"visualRadius\": 1.3,\n \"fireballs\": 16,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 18,\n \"life\": 5.5\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 30\n },\n \"shrapnel\": {\n \"count\": 150,\n \"kind\": 0,\n \"speed\": 34\n },\n \"chunks\": {\n \"count\": 14,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.25\n },\n \"mark\": {\n \"scorch\": 1.7,\n \"crater\": 0.9,\n \"dent\": 0.25\n },\n \"flash\": {\n \"light\": 45,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.1,\n \"push\": 9,\n \"sources\": [\n \"lab:L796\",\n \"lab:L793\"\n ]\n },\n \"molotov\": {\n \"id\": \"molotov\",\n \"lethal\": 0,\n \"injury\": 4,\n \"visualRadius\": 1.1,\n \"fireballs\": 24,\n \"fuel\": true,\n \"heat\": 0.95,\n \"heatLifeScale\": 1.5,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 3,\n \"life\": 3.5\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 0\n },\n \"shrapnel\": {\n \"count\": 0,\n \"kind\": 0,\n \"speed\": 28\n },\n \"chunks\": {\n \"count\": 0,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.3\n },\n \"mark\": {\n \"scorch\": 2.4\n },\n \"flash\": {\n \"light\": 22,\n \"life\": 1.2,\n \"color\": 16747066,\n \"intensity\": 6\n },\n \"shock\": false,\n \"shake\": 0.25,\n \"push\": 0,\n \"ignite\": 4.2,\n \"sources\": [\n \"lab:L797\",\n \"lab:L793\"\n ]\n },\n \"pipe_bomb\": {\n \"id\": \"pipe_bomb\",\n \"lethal\": 3,\n \"injury\": 10,\n \"visualRadius\": 1,\n \"fireballs\": 8,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 11841704,\n \"count\": 26,\n \"life\": 6,\n \"kind\": 3\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 22\n },\n \"shrapnel\": {\n \"count\": 220,\n \"kind\": 1,\n \"speed\": 30,\n \"width\": 0.03\n },\n \"chunks\": {\n \"count\": 8,\n \"colors\": [\n 5132886,\n 3816768\n ],\n \"plate\": true,\n \"hot\": 0.2\n },\n \"mark\": {\n \"scorch\": 1.3,\n \"crater\": 0.7,\n \"dent\": 0.18\n },\n \"flash\": {\n \"light\": 30,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1,\n \"push\": 7,\n \"sources\": [\n \"lab:L798\",\n \"lab:L793\"\n ]\n },\n \"propane_p13\": {\n \"id\": \"propane_p13\",\n \"lethal\": 5,\n \"injury\": 14,\n \"visualRadius\": 2.2,\n \"fireballs\": 34,\n \"fuel\": true,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 10,\n \"life\": 8\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 26\n },\n \"shrapnel\": {\n \"count\": 70,\n \"kind\": 0,\n \"speed\": 28,\n \"embers\": 30\n },\n \"chunks\": {\n \"count\": 8,\n \"colors\": [\n 3891098,\n 2835824\n ],\n \"plate\": true,\n \"hot\": 0.5\n },\n \"mark\": {\n \"scorch\": 2.6\n },\n \"flash\": {\n \"light\": 70,\n \"life\": 1.1,\n \"color\": 16751168,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.4,\n \"push\": 8,\n \"mushroom\": {\n \"height\": 7,\n \"radius\": 2.6,\n \"count\": 36,\n \"stem\": 16,\n \"life\": 8\n },\n \"residualFires\": [\n {\n \"radius\": 1.4,\n \"life\": 7,\n \"rate\": 20\n }\n ],\n \"ignite\": 5,\n \"hotParts\": true,\n \"sources\": [\n \"lab:L799\",\n \"lab:L793\"\n ]\n },\n \"dynamite\": {\n \"id\": \"dynamite\",\n \"lethal\": 4,\n \"injury\": 12,\n \"visualRadius\": 1.4,\n \"fireballs\": 12,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 8019006,\n \"count\": 24,\n \"life\": 7\n },\n \"dust\": {\n \"color\": 8019006,\n \"count\": 46\n },\n \"shrapnel\": {\n \"count\": 90,\n \"kind\": 0,\n \"speed\": 28\n },\n \"chunks\": {\n \"count\": 26,\n \"colors\": [\n 6965806,\n 8018490,\n 4863526\n ],\n \"hot\": 0.15,\n \"speed\": 1.2\n },\n \"mark\": {\n \"scorch\": 2.4,\n \"crater\": 1.8,\n \"dent\": 0.7\n },\n \"flash\": {\n \"light\": 55,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.5,\n \"push\": 10,\n \"sources\": [\n \"lab:L800\",\n \"lab:L793\"\n ]\n },\n \"c4\": {\n \"id\": \"c4\",\n \"lethal\": 6,\n \"injury\": 18,\n \"visualRadius\": 1.6,\n \"fireballs\": 20,\n \"heat\": 1.25,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 22,\n \"life\": 7\n },\n \"dust\": {\n \"color\": 9407106,\n \"count\": 50\n },\n \"shrapnel\": {\n \"count\": 200,\n \"kind\": 0,\n \"speed\": 42\n },\n \"chunks\": {\n \"count\": 32,\n \"colors\": [\n 9078140,\n 7301730,\n 3881528\n ],\n \"hot\": 0.3,\n \"speed\": 1.4\n },\n \"mark\": {\n \"scorch\": 3,\n \"crater\": 2.3,\n \"dent\": 0.9\n },\n \"flash\": {\n \"light\": 90,\n \"life\": 0.35,\n \"color\": 16773328,\n \"intensity\": 9\n },\n \"shock\": {\n \"duration\": 0.28\n },\n \"shake\": 2.2,\n \"push\": 13,\n \"sources\": [\n \"lab:L801\",\n \"lab:L793\"\n ]\n },\n \"claymore\": {\n \"id\": \"claymore\",\n \"lethal\": 15,\n \"injury\": 50,\n \"visualRadius\": 0.7,\n \"fireballs\": 6,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 8,\n \"life\": 4\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 34\n },\n \"shrapnel\": {\n \"count\": 700,\n \"kind\": 1,\n \"speed\": 55,\n \"width\": 0.025\n },\n \"chunks\": {\n \"count\": 6,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.3\n },\n \"mark\": {\n \"scorch\": 0.9\n },\n \"flash\": {\n \"light\": 28,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1,\n \"push\": 8,\n \"cone\": {\n \"angle\": 0,\n \"half\": 0.5235987755982988,\n \"length\": 50\n },\n \"directionBias\": 2,\n \"sources\": [\n \"lab:L802\",\n \"lab:L793\"\n ]\n },\n \"flashbang\": {\n \"id\": \"flashbang\",\n \"lethal\": 0,\n \"injury\": 10,\n \"visualRadius\": 0.5,\n \"fireballs\": 0,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 11841704,\n \"count\": 10,\n \"life\": 5,\n \"kind\": 3\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 0\n },\n \"shrapnel\": {\n \"count\": 60,\n \"kind\": 2,\n \"speed\": 12\n },\n \"chunks\": {\n \"count\": 0,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.3\n },\n \"mark\": {\n \"scorch\": 0.4\n },\n \"flash\": {\n \"light\": 160,\n \"life\": 0.2,\n \"color\": 16054015,\n \"intensity\": 14,\n \"blinding\": true\n },\n \"shock\": false,\n \"shake\": 0.4,\n \"push\": 0,\n \"sources\": [\n \"lab:L803\",\n \"lab:L793\"\n ]\n },\n \"m79_40mm\": {\n \"id\": \"m79_40mm\",\n \"lethal\": 4,\n \"injury\": 12,\n \"visualRadius\": 1.1,\n \"fireballs\": 14,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 14,\n \"life\": 5\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 24\n },\n \"shrapnel\": {\n \"count\": 130,\n \"kind\": 0,\n \"speed\": 28\n },\n \"chunks\": {\n \"count\": 12,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.3\n },\n \"mark\": {\n \"scorch\": 1.5,\n \"crater\": 0.8,\n \"dent\": 0.22\n },\n \"flash\": {\n \"light\": 40,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1,\n \"push\": 8,\n \"sources\": [\n \"lab:L804\",\n \"lab:L793\"\n ]\n },\n \"m72_66mm\": {\n \"id\": \"m72_66mm\",\n \"lethal\": 5,\n \"injury\": 15,\n \"visualRadius\": 1.5,\n \"fireballs\": 22,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 16,\n \"life\": 6\n },\n \"dust\": {\n \"color\": 9407106,\n \"count\": 30\n },\n \"shrapnel\": {\n \"count\": 180,\n \"kind\": 0,\n \"speed\": 40\n },\n \"chunks\": {\n \"count\": 24,\n \"colors\": [\n 9078140,\n 7301730\n ],\n \"hot\": 0.3\n },\n \"mark\": {\n \"scorch\": 2\n },\n \"flash\": {\n \"light\": 60,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.5,\n \"push\": 11,\n \"directionBias\": 1.4,\n \"sources\": [\n \"lab:L805\",\n \"lab:L793\"\n ]\n },\n \"at4_84mm\": {\n \"id\": \"at4_84mm\",\n \"lethal\": 5,\n \"injury\": 16,\n \"visualRadius\": 1.7,\n \"fireballs\": 26,\n \"heat\": 1.15,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 18,\n \"life\": 6.5\n },\n \"dust\": {\n \"color\": 9407106,\n \"count\": 34\n },\n \"shrapnel\": {\n \"count\": 220,\n \"kind\": 0,\n \"speed\": 46\n },\n \"chunks\": {\n \"count\": 30,\n \"colors\": [\n 9078140,\n 7301730\n ],\n \"hot\": 0.35\n },\n \"mark\": {\n \"scorch\": 2.2,\n \"crater\": 1.4,\n \"dent\": 0.5\n },\n \"flash\": {\n \"light\": 70,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.7,\n \"push\": 12,\n \"directionBias\": 1.6,\n \"sources\": [\n \"lab:L806\",\n \"lab:L793\"\n ]\n },\n \"pg7v\": {\n \"id\": \"pg7v\",\n \"lethal\": 5,\n \"injury\": 16,\n \"visualRadius\": 1.8,\n \"fireballs\": 28,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 18,\n \"life\": 7\n },\n \"dust\": {\n \"color\": 9407106,\n \"count\": 34\n },\n \"shrapnel\": {\n \"count\": 200,\n \"kind\": 0,\n \"speed\": 42,\n \"embers\": 20\n },\n \"chunks\": {\n \"count\": 28,\n \"colors\": [\n 9078140,\n 7301730\n ],\n \"hot\": 0.4\n },\n \"mark\": {\n \"scorch\": 2.2\n },\n \"flash\": {\n \"light\": 70,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.7,\n \"push\": 12,\n \"directionBias\": 1.2,\n \"sources\": [\n \"lab:L807\",\n \"lab:L793\"\n ]\n },\n \"fuel_barrel\": {\n \"id\": \"fuel_barrel\",\n \"lethal\": 4,\n \"injury\": 12,\n \"visualRadius\": 1.9,\n \"fireballs\": 28,\n \"fuel\": true,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 8,\n \"life\": 8\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 22\n },\n \"shrapnel\": {\n \"count\": 60,\n \"kind\": 0,\n \"speed\": 28,\n \"embers\": 24\n },\n \"chunks\": {\n \"count\": 10,\n \"colors\": [\n 10165272,\n 5902864\n ],\n \"plate\": true,\n \"hot\": 0.6\n },\n \"mark\": {\n \"scorch\": 2.4\n },\n \"flash\": {\n \"light\": 60,\n \"life\": 1,\n \"color\": 16748608,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.2,\n \"push\": 8,\n \"mushroom\": {\n \"height\": 6,\n \"radius\": 2.1,\n \"count\": 30,\n \"stem\": 14,\n \"life\": 8\n },\n \"residualFires\": [\n {\n \"dx\": 1.6,\n \"dz\": 0.4,\n \"radius\": 0.9,\n \"life\": 6\n },\n {\n \"dx\": -1.1,\n \"dz\": 1.2,\n \"radius\": 0.7,\n \"life\": 5.5\n },\n {\n \"dx\": -0.4,\n \"dz\": -1.5,\n \"radius\": 0.8,\n \"life\": 6.5\n }\n ],\n \"ignite\": 4,\n \"hotParts\": true,\n \"sources\": [\n \"lab:L808\",\n \"lab:L793\"\n ]\n },\n \"car_fuel_tank\": {\n \"id\": \"car_fuel_tank\",\n \"lethal\": 5,\n \"injury\": 14,\n \"visualRadius\": 2.3,\n \"fireballs\": 36,\n \"fuel\": true,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 12,\n \"life\": 9\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 30\n },\n \"shrapnel\": {\n \"count\": 90,\n \"kind\": 0,\n \"speed\": 28,\n \"embers\": 36\n },\n \"chunks\": {\n \"count\": 14,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"plate\": true,\n \"hot\": 0.5\n },\n \"mark\": {\n \"scorch\": 3.2\n },\n \"flash\": {\n \"light\": 80,\n \"life\": 1.2,\n \"color\": 16748608,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.8,\n \"push\": 9,\n \"mushroom\": {\n \"height\": 7.5,\n \"radius\": 2.8,\n \"count\": 40,\n \"stem\": 16,\n \"life\": 9\n },\n \"ignite\": 5,\n \"hotParts\": true,\n \"sources\": [\n \"lab:L809\",\n \"lab:L793\"\n ]\n },\n \"fuel_pump\": {\n \"id\": \"fuel_pump\",\n \"lethal\": 4,\n \"injury\": 12,\n \"visualRadius\": 1.7,\n \"fireballs\": 24,\n \"fuel\": true,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 6,\n \"life\": 7\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 16\n },\n \"shrapnel\": {\n \"count\": 60,\n \"kind\": 0,\n \"speed\": 28,\n \"embers\": 16\n },\n \"chunks\": {\n \"count\": 12,\n \"colors\": [\n 14209732,\n 2058810,\n 9407106\n ],\n \"plate\": true,\n \"hot\": 0.5\n },\n \"mark\": {\n \"scorch\": 2.4\n },\n \"flash\": {\n \"light\": 55,\n \"life\": 0.9,\n \"color\": 16748608,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.2,\n \"push\": 8,\n \"mushroom\": {\n \"height\": 5,\n \"radius\": 1.8,\n \"count\": 22,\n \"stem\": 10,\n \"life\": 7\n },\n \"residualFires\": [\n {\n \"radius\": 1.1,\n \"life\": 14,\n \"rate\": 22\n }\n ],\n \"ignite\": 4,\n \"hotParts\": true,\n \"sources\": [\n \"lab:L810\",\n \"lab:L793\"\n ]\n },\n \"fuel_station_tank\": {\n \"id\": \"fuel_station_tank\",\n \"lethal\": 12,\n \"injury\": 30,\n \"visualRadius\": 4.5,\n \"fireballs\": 44,\n \"fuel\": true,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 20,\n \"life\": 11\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 46\n },\n \"shrapnel\": {\n \"count\": 160,\n \"kind\": 0,\n \"speed\": 40,\n \"embers\": 60\n },\n \"chunks\": {\n \"count\": 30,\n \"colors\": [\n 9407106,\n 3881528,\n 2058810\n ],\n \"hot\": 0.5\n },\n \"mark\": {\n \"scorch\": 6,\n \"crater\": 4,\n \"dent\": 1.6\n },\n \"flash\": {\n \"light\": 140,\n \"life\": 1.8,\n \"color\": 16748608,\n \"intensity\": 8\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 3,\n \"push\": 14,\n \"mushroom\": {\n \"height\": 16,\n \"radius\": 5.5,\n \"count\": 60,\n \"stem\": 26,\n \"life\": 12,\n \"riseRate\": 0.42\n },\n \"residualFires\": [\n {\n \"radius\": 3.2,\n \"life\": 20,\n \"rate\": 26,\n \"smoke\": 1.4\n },\n {\n \"dx\": 4,\n \"dz\": 3,\n \"radius\": 1.4,\n \"life\": 16\n },\n {\n \"dx\": -4,\n \"dz\": 2,\n \"radius\": 1.2,\n \"life\": 15\n }\n ],\n \"ignite\": 12,\n \"hotParts\": true,\n \"sources\": [\n \"lab:L811\",\n \"lab:L793\"\n ]\n },\n \"generic\": {\n \"id\": \"generic\",\n \"lethal\": 5,\n \"injury\": 15,\n \"visualRadius\": 1.3,\n \"fireballs\": 16,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 18,\n \"life\": 5.5\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 30\n },\n \"shrapnel\": {\n \"count\": 150,\n \"kind\": 0,\n \"speed\": 34\n },\n \"chunks\": {\n \"count\": 14,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.25\n },\n \"mark\": {\n \"scorch\": 1.7,\n \"crater\": 0.9,\n \"dent\": 0.25\n },\n \"flash\": {\n \"light\": 45,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.1,\n \"push\": 9,\n \"sources\": [\n \"lab:L796\",\n \"lab:L793\",\n \"derived: the M67 profile, for a part with no explosive id; the caller scales it by injury / 15\"\n ]\n }\n}\n","import aliasData from './data/explosion-aliases.json'\nimport explosionData from './data/explosions.json'\nimport type { ExplosionDef } from './types'\n\n/**\n * The 16 profiles of the Explosion Lab (`PROF`, L795-812) keyed by the id of the explosive in `game-weapons` (`m67`, `molotov`, `pipe_bomb`,\n * `propane_p13`, `dynamite`, `c4`, `claymore`, `flashbang`, `m79_40mm`, `m72_66mm`, `at4_84mm`, `pg7v`, `fuel_barrel`, `car_fuel_tank`, `fuel_pump`,\n * `fuel_station_tank`), plus `generic` (the M67 for a part with no explosive id: scale it by `injury / 15`). Each one lists the Lab lines it comes from.\n */\nexport const EXPLOSIONS = explosionData as unknown as Readonly<Record<string, ExplosionDef>>\n\n/** Explosives with no profile of their own: the Carl Gustaf blasts like the AT4, the VOG-25 like the M79. */\nexport const EXPLOSION_ALIASES: Readonly<Record<string, string>> = aliasData\n\n/** A copy of a catalogue with some profiles changed (a partial replaces the fields it names) or removed (`null`); a game adds, tunes or drops effects without touching the core. */\nexport function patchExplosions(base: Readonly<Record<string, ExplosionDef>>, changes: Readonly<Record<string, Partial<ExplosionDef> | ExplosionDef | null>>): Record<string, ExplosionDef> {\n const result: Record<string, ExplosionDef> = { ...base }\n for (const [id, change] of Object.entries(changes)) {\n if (change === null) delete result[id]\n else result[id] = { ...(base[id] ?? {}), ...change, id } as ExplosionDef\n }\n return result\n}\n","export type Rgb = readonly [number, number, number]\n\nconst BYTE_MAX = 255\nconst SRGB_LINEAR_SLOPE = 0.0773993808\nconst SRGB_THRESHOLD = 0.04045\n\n/** The channels of `0xRRGGBB` exactly as three.js r128 reads them (no colour-space conversion): the numbers the Lab's shaders and lights were tuned with. */\nexport function hexToRgb(hex: number): Rgb {\n const whole = Math.floor(hex)\n return [((whole >> 16) & BYTE_MAX) / BYTE_MAX, ((whole >> 8) & BYTE_MAX) / BYTE_MAX, (whole & BYTE_MAX) / BYTE_MAX]\n}\n\nexport function srgbChannelToLinear(channel: number): number {\n return channel < SRGB_THRESHOLD ? channel * SRGB_LINEAR_SLOPE : Math.pow(channel * 0.9478672986 + 0.0521327014, 2.4)\n}\n\n/** `new Color(hex).convertSRGBToLinear()` of r128: the smoke, dust and fire colours the puff shader multiplies the light with. Converted once, at spawn. */\nexport function hexToLinearRgb(hex: number): Rgb {\n const [red, green, blue] = hexToRgb(hex)\n return [srgbChannelToLinear(red), srgbChannelToLinear(green), srgbChannelToLinear(blue)]\n}\n\nexport function linearRgbFromRaw(color: Rgb): Rgb {\n return [srgbChannelToLinear(color[0]), srgbChannelToLinear(color[1]), srgbChannelToLinear(color[2])]\n}\n","import { hexToLinearRgb } from './color'\n\n/** The Lab's smoke colours (L211-214), converted to linear once. Colours of an explosion in data are `0xRRGGBB` and go through `hexToLinearRgb` the same way. */\nexport const SMOKE_COLORS = {\n grey: hexToLinearRgb(0x6a655f),\n dark: hexToLinearRgb(0x4a4440),\n black: hexToLinearRgb(0x3a3431),\n brown: hexToLinearRgb(0x7a5c3e),\n dust: hexToLinearRgb(0x7d7368),\n concrete: hexToLinearRgb(0x8f8a82),\n white: hexToLinearRgb(0xb4b0a8),\n blood: hexToLinearRgb(0x5a0b0b),\n bile: hexToLinearRgb(0x7a8a2a),\n gas: hexToLinearRgb(0xe8ecef),\n} as const\n\nexport const DEFAULT_GRAVITY = 9.8\nexport const DEFAULT_WIND = { x: 0.55, y: 0, z: 0.2 } as const\nexport const FRAME_STEP_LIMIT = 0.05\n","/**\n * A pool that keeps its live records in the order they were added, reuses dead records instead of allocating, and compacts in place. When it is full\n * the oldest record goes (the Lab's `P.shift()`); a pool may choose which one instead (the chunks drop a resting one first).\n */\nexport class OrderedPool<T extends object> {\n /** The live records, oldest first. */\n readonly items: T[] = []\n private readonly spare: T[] = []\n\n constructor(\n readonly capacity: number,\n private readonly create: () => T,\n private readonly release?: (item: T) => void,\n ) {}\n\n get count(): number {\n return this.items.length\n }\n\n /** A record to fill in. At capacity the record `victim` picks (default: the oldest) is dropped and reused. */\n acquire(victim?: (items: readonly T[]) => number): T {\n if (this.items.length >= this.capacity) this.removeAt(victim ? victim(this.items) : 0)\n const record = this.spare.pop() ?? this.create()\n this.items.push(record)\n return record\n }\n\n removeAt(index: number): void {\n const record = this.items[index]\n if (record === undefined) return\n for (let shifted = index; shifted < this.items.length - 1; shifted++) this.items[shifted] = this.items[shifted + 1]!\n this.items.length -= 1\n this.release?.(record)\n this.spare.push(record)\n }\n\n /** Keeps the records `keep` accepts, in the same order, without allocating. `context` goes to `keep` so no closure is needed per frame. */\n compact<TContext>(keep: (item: T, context: TContext) => boolean, context: TContext): void {\n let write = 0\n for (let read = 0; read < this.items.length; read++) {\n const record = this.items[read]!\n if (keep(record, context)) {\n this.items[write++] = record\n continue\n }\n this.release?.(record)\n this.spare.push(record)\n }\n this.items.length = write\n }\n\n clear(): void {\n for (const record of this.items) {\n this.release?.(record)\n this.spare.push(record)\n }\n this.items.length = 0\n }\n}\n","import type { Rgb } from '../color'\nimport { OrderedPool } from '../pool'\nimport type { RandomStream } from '../random'\nimport type { Glow } from './glows'\n\n/** Debris with embers (L366-400). The last block is what the renderer reads: the colour already blended towards the glow of a hot piece. */\nexport interface Chunk {\n x: number\n y: number\n z: number\n vx: number\n vy: number\n vz: number\n rx: number\n ry: number\n rz: number\n ax: number\n ay: number\n az: number\n sx: number\n sy: number\n sz: number\n color: Rgb\n plate: boolean\n hot: boolean\n rest: boolean\n blood: boolean\n splat: boolean\n t: number\n trail: number\n glow: Glow | null\n rng: RandomStream\n outColor: [number, number, number]\n}\n\nexport type ChunkInit = Partial<Pick<Chunk, 'x' | 'y' | 'z' | 'vx' | 'vy' | 'vz' | 'sx' | 'sy' | 'sz' | 'color' | 'plate' | 'hot' | 'blood'>>\n\nconst DEFAULT_COLOR: Rgb = [0x55 / 255, 0x55 / 255, 0x55 / 255]\n\n/** A glow that follows a chunk keeps the spot the chunk had when the chunk leaves the pool, as the Lab's does (the object stays where it was). */\nfunction freezeFollowingGlow(chunk: Chunk): void {\n const glow = chunk.glow\n chunk.glow = null\n if (!glow || glow.follow !== chunk) return\n glow.x = chunk.x + glow.fx\n glow.y = chunk.y + glow.fy\n glow.z = chunk.z + glow.fz\n glow.fx = glow.fy = glow.fz = 0\n glow.follow = null\n}\n\nexport function createChunkPool(capacity: number, placeholder: RandomStream): OrderedPool<Chunk> {\n return new OrderedPool<Chunk>(\n capacity,\n () => ({\n x: 0, y: 0, z: 0, vx: 0, vy: 0, vz: 0, rx: 0, ry: 0, rz: 0, ax: 0, ay: 0, az: 0, sx: 0.2, sy: 0.2, sz: 0.2, color: DEFAULT_COLOR, plate: false, hot: false, rest: false,\n blood: false, splat: false, t: 0, trail: 0, glow: null, rng: placeholder, outColor: [0, 0, 0],\n }),\n freezeFollowingGlow,\n )\n}\n\nfunction firstResting(chunks: readonly Chunk[]): number {\n const index = chunks.findIndex((chunk) => chunk.rest)\n return index >= 0 ? index : 0\n}\n\n/** `chunk()` (L368-376). Draws rotation and spin first (six numbers, always), then lets the caller add what it wants; a full pool drops a resting piece, else the oldest. */\nexport function spawnChunk(pool: OrderedPool<Chunk>, random: RandomStream, init: ChunkInit): Chunk {\n const chunk = pool.acquire(firstResting)\n chunk.x = init.x ?? 0\n chunk.y = init.y ?? 0\n chunk.z = init.z ?? 0\n chunk.vx = init.vx ?? 0\n chunk.vy = init.vy ?? 0\n chunk.vz = init.vz ?? 0\n chunk.rx = random.next() * 6\n chunk.ry = random.next() * 6\n chunk.rz = random.next() * 6\n chunk.ax = random.between(-12, 12)\n chunk.ay = random.between(-12, 12)\n chunk.az = random.between(-12, 12)\n chunk.sx = init.sx ?? 0.2\n chunk.sy = init.sy ?? 0.2\n chunk.sz = init.sz ?? 0.2\n chunk.color = init.color ?? DEFAULT_COLOR\n chunk.plate = init.plate ?? false\n chunk.hot = init.hot ?? false\n chunk.rest = false\n chunk.blood = init.blood ?? false\n chunk.splat = false\n chunk.t = 0\n chunk.trail = 0\n chunk.glow = null\n chunk.rng = random\n return chunk\n}\n\nexport const HOT_COLOR: Rgb = [1, 0.42, 0.1]\nexport const HOT_SECONDS = 1.6\nconst HOT_BLEND = 0.85\n\n/** `_hotCol` (L399-400): the colour of a hot piece, blended towards the glow while it is young. */\nexport function colorOfChunk(chunk: Chunk): readonly [number, number, number] {\n if (!chunk.hot || chunk.t >= HOT_SECONDS) {\n chunk.outColor[0] = chunk.color[0]\n chunk.outColor[1] = chunk.color[1]\n chunk.outColor[2] = chunk.color[2]\n return chunk.outColor\n }\n const amount = Math.max(0, 1 - chunk.t / HOT_SECONDS) * HOT_BLEND\n chunk.outColor[0] = chunk.color[0] + (HOT_COLOR[0] - chunk.color[0]) * amount\n chunk.outColor[1] = chunk.color[1] + (HOT_COLOR[1] - chunk.color[1]) * amount\n chunk.outColor[2] = chunk.color[2] + (HOT_COLOR[2] - chunk.color[2]) * amount\n return chunk.outColor\n}\n","import type { MutableVec3 } from './random'\n\n/** Operations on `{ x, y, z }` written the way three.js r128 does them (`normalize` multiplies by the reciprocal), so a port repeats the Lab's numbers bit for bit. */\n\nexport function createVec3(x = 0, y = 0, z = 0): MutableVec3 {\n return { x, y, z }\n}\n\nexport function addScaled(target: MutableVec3, direction: MutableVec3, scale: number): MutableVec3 {\n target.x += direction.x * scale\n target.y += direction.y * scale\n target.z += direction.z * scale\n return target\n}\n\nexport function normalize(target: MutableVec3): MutableVec3 {\n const length = Math.sqrt(target.x * target.x + target.y * target.y + target.z * target.z) || 1\n const inverse = 1 / length\n target.x *= inverse\n target.y *= inverse\n target.z *= inverse\n return target\n}\n\nexport function distanceBetween(ax: number, ay: number, az: number, bx: number, by: number, bz: number): number {\n const dx = ax - bx\n const dy = ay - by\n const dz = az - bz\n return Math.sqrt(dx * dx + dy * dy + dz * dz)\n}\n\nexport function lerp(from: number, to: number, amount: number): number {\n return from + (to - from) * amount\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return value < min ? min : value > max ? max : value\n}\n","import type { Rgb } from '../color'\nimport { lerp } from '../vector'\nimport { OrderedPool } from '../pool'\n\n/** The position a glow follows (a chunk, or anything with `x`, `y`, `z`). */\nexport interface FollowPoint {\n readonly x: number\n readonly y: number\n readonly z: number\n}\n\n/** An additive halo (L294-318). The last block is what the renderer reads after `update`: where it is, how big and how bright. */\nexport interface Glow {\n x: number\n y: number\n z: number\n s: number\n s1: number | null\n i: number\n t: number\n life: number\n color: Rgb\n curve: number\n flick: boolean\n follow: FollowPoint | null\n fx: number\n fy: number\n fz: number\n outX: number\n outY: number\n outZ: number\n outSize: number\n outIntensity: number\n}\n\nexport type GlowInit = Partial<Omit<Glow, 't' | 'outX' | 'outY' | 'outZ' | 'outSize' | 'outIntensity'>>\n\nconst DEFAULT_COLOR: Rgb = [1, 0.6, 0.25]\n\nexport function createGlowPool(capacity: number): OrderedPool<Glow> {\n return new OrderedPool<Glow>(capacity, () => ({\n x: 0, y: 0, z: 0, s: 1, s1: null, i: 1, t: 0, life: 0.3, color: DEFAULT_COLOR, curve: 2, flick: false, follow: null, fx: 0, fy: 0, fz: 0,\n outX: 0, outY: 0, outZ: 0, outSize: 0, outIntensity: 0,\n }))\n}\n\nexport function spawnGlow(pool: OrderedPool<Glow>, init: GlowInit): Glow {\n const glow = pool.acquire()\n glow.x = init.x ?? 0\n glow.y = init.y ?? 0\n glow.z = init.z ?? 0\n glow.s = init.s ?? 1\n glow.s1 = init.s1 ?? null\n glow.i = init.i ?? 1\n glow.t = 0\n glow.life = init.life ?? 0.3\n glow.color = init.color ?? DEFAULT_COLOR\n glow.curve = init.curve ?? 2\n glow.flick = init.flick ?? false\n glow.follow = init.follow ?? null\n glow.fx = init.fx ?? 0\n glow.fy = init.fy ?? 0\n glow.fz = init.fz ?? 0\n return glow\n}\n\nfunction ageOrKeep(glow: Glow, dt: number): boolean {\n glow.t += dt\n return glow.t < glow.life\n}\n\nconst FLICKER_RATE = 40\nconst FLICKER_SPREAD = 9\n\n/** `updateGlows` (L305-318). */\nexport function updateGlows(pool: OrderedPool<Glow>, dt: number): void {\n pool.compact(ageOrKeep, dt)\n for (const glow of pool.items) {\n const age = glow.t / glow.life\n let x = glow.x\n let y = glow.y\n let z = glow.z\n if (glow.follow) {\n x = glow.follow.x + glow.fx\n y = glow.follow.y + glow.fy\n z = glow.follow.z + glow.fz\n }\n glow.outX = x\n glow.outY = y\n glow.outZ = z\n glow.outSize = glow.s1 !== null ? lerp(glow.s, glow.s1, 1 - Math.pow(1 - age, 3)) : glow.s\n const flicker = glow.flick ? 0.75 + 0.25 * Math.sin(glow.t * FLICKER_RATE + glow.s * FLICKER_SPREAD) : 1\n glow.outIntensity = glow.i * Math.pow(1 - age, glow.curve) * flicker\n }\n}\n","import type { Rgb } from '../color'\nimport { SMOKE_COLORS } from '../constants'\nimport { OrderedPool } from '../pool'\nimport type { RandomStream } from '../random'\n\n/** The ring a mushroom cloud's puffs travel on (L722-735). */\nexport interface Ring {\n x: number\n z: number\n y0: number\n rise: number\n rk: number\n R0: number\n R1: number\n r: number\n roll: number\n t: number\n life: number\n}\n\n/**\n * Fire, smoke, dust, blood and gas (L193-238). `kind`: 0 fire that turns into smoke, 1 dust, 2 blood, 3 gas or white powder smoke, 4 bile.\n * The last block is what the renderer reads after `update`.\n */\nexport interface Puff {\n x: number\n y: number\n z: number\n vx: number\n vy: number\n vz: number\n s0: number\n s1: number\n sg: number\n gk: number\n life: number\n t: number\n h0: number\n hl: number\n drag: number\n buoy: number\n grav: number\n kind: number\n seed: number\n wind: number\n color: Rgb\n ring: Ring | null\n ph: number\n th: number\n rng: RandomStream\n age: number\n heat: number\n size: number\n}\n\nexport type PuffInit = Partial<Omit<Puff, 'seed' | 'age' | 'heat' | 'size' | 't' | 'rng'>>\n\nconst FLOOR_FRACTION = 0.4\nconst FLOOR_BOUNCE = -0.2\nconst ARRIVAL_FRAME = 30\nconst ARRIVAL_BASE = 0.3\nconst GROWTH_CAP_SECONDS = 3.5\n\nexport function createPuffPool(capacity: number): OrderedPool<Puff> {\n const placeholder: RandomStream = { next: () => 0, between: (min) => min, direction: (out) => out, state: 0 }\n return new OrderedPool<Puff>(capacity, () => ({\n x: 0, y: 0, z: 0, vx: 0, vy: 0, vz: 0, s0: 0.2, s1: 1, sg: 0.1, gk: 6, life: 3, t: 0, h0: 0, hl: 0.4, drag: 3, buoy: 0.5, grav: 0, kind: 0, seed: 0, wind: 1,\n color: SMOKE_COLORS.grey, ring: null, ph: 0, th: 0, rng: placeholder, age: 0, heat: 0, size: 0,\n }))\n}\n\n/** `puff()` of the Lab: draws `seed` first, always, even when the caller gives one (L196), and drops the oldest puff when the pool is full. */\nexport function spawnPuff(pool: OrderedPool<Puff>, random: RandomStream, init: PuffInit): Puff {\n const puff = pool.acquire()\n puff.x = init.x ?? 0\n puff.y = init.y ?? 0\n puff.z = init.z ?? 0\n puff.vx = init.vx ?? 0\n puff.vy = init.vy ?? 0\n puff.vz = init.vz ?? 0\n puff.s0 = init.s0 ?? 0.2\n puff.s1 = init.s1 ?? 1\n puff.sg = init.sg ?? 0.1\n puff.gk = init.gk ?? 6\n puff.life = init.life ?? 3\n puff.t = 0\n puff.h0 = init.h0 ?? 0\n puff.hl = init.hl ?? 0.4\n puff.drag = init.drag ?? 3\n puff.buoy = init.buoy ?? 0.5\n puff.grav = init.grav ?? 0\n puff.kind = init.kind ?? 0\n puff.seed = random.next()\n puff.wind = init.wind ?? 1\n puff.color = init.color ?? SMOKE_COLORS.grey\n puff.ring = init.ring ?? null\n puff.ph = init.ph ?? 0\n puff.th = init.th ?? 0\n puff.rng = random\n puff.age = 0\n puff.heat = 0\n puff.size = 0\n return puff\n}\n\nfunction ageOrKeep(puff: Puff, dt: number): boolean {\n puff.t += dt\n return puff.t < puff.life\n}\n\nfunction moveOnRing(puff: Puff, ring: Ring, wind: { x: number; z: number }): void {\n const ringTime = ring.t\n const centerY = ring.y0 + ring.rise * (1 - Math.exp(-ringTime * ring.rk))\n const majorRadius = ring.R0 + (ring.R1 - ring.R0) * (1 - Math.exp(-ringTime * 1.6))\n const theta = puff.th + ringTime * ring.roll\n const minorRadius = ring.r * (0.8 + 0.4 * Math.min(1, ringTime))\n const radius = majorRadius + minorRadius * Math.cos(theta)\n puff.x = ring.x + Math.cos(puff.ph) * radius + wind.x * ringTime * 0.6\n puff.z = ring.z + Math.sin(puff.ph) * radius + wind.z * ringTime * 0.6\n puff.y = centerY + minorRadius * Math.sin(theta)\n}\n\nfunction moveFree(puff: Puff, dt: number, age: number, heat: number, wind: { x: number; z: number }): void {\n const damping = Math.exp(-puff.drag * dt)\n puff.vx *= damping\n puff.vy *= damping\n puff.vz *= damping\n puff.vy += (puff.buoy * (heat > 0 ? 1.6 : 1) - puff.grav) * dt\n puff.x += (puff.vx + wind.x * puff.wind * age) * dt\n puff.y += puff.vy * dt\n puff.z += (puff.vz + wind.z * puff.wind * age) * dt\n if (puff.y < puff.s0 * FLOOR_FRACTION) {\n puff.y = puff.s0 * FLOOR_FRACTION\n if (puff.vy < 0) puff.vy *= FLOOR_BOUNCE\n }\n}\n\n/** `updatePuffs` (L205-238): ages, removes what ended, then moves the rest with the wind (or along their mushroom ring) and derives what the shader reads. */\nexport function updatePuffs(pool: OrderedPool<Puff>, dt: number, wind: { x: number; z: number }): void {\n pool.compact(ageOrKeep, dt)\n for (const puff of pool.items) {\n const age = puff.t / puff.life\n const heat = puff.h0 > 0 ? puff.h0 * Math.pow(Math.max(0, 1 - puff.t / puff.hl), 1.25) : 0\n if (puff.ring) moveOnRing(puff, puff.ring, wind)\n else moveFree(puff, dt, age, heat, wind)\n const size = puff.s0 + (puff.s1 - puff.s0) * (1 - Math.exp(-puff.t * puff.gk)) + puff.sg * Math.min(puff.t, GROWTH_CAP_SECONDS)\n puff.size = size * Math.min(1, puff.t * ARRIVAL_FRAME + ARRIVAL_BASE)\n puff.age = age\n puff.heat = heat\n }\n}\n","import { OrderedPool } from '../pool'\n\n/** Shrapnel, sparks and embers, stretched along their velocity by the shader (L239-293). `kind`: 0 hot fragment, 1 steel ball, 2 white spark, 3 glass, 4 slow ember. */\nexport interface Spark {\n x: number\n y: number\n z: number\n vx: number\n vy: number\n vz: number\n t: number\n life: number\n w: number\n st: number\n kind: number\n drag: number\n g: number\n bounce: number\n age: number\n}\n\nexport type SparkInit = Partial<Omit<Spark, 't' | 'age'>>\n\nconst GROUND_LIFT = 0.02\nconst BOUNCE_SLIDE = 0.55\n\nexport function createSparkPool(capacity: number): OrderedPool<Spark> {\n return new OrderedPool<Spark>(capacity, () => ({ x: 0, y: 0, z: 0, vx: 0, vy: 0, vz: 0, t: 0, life: 0.8, w: 0.04, st: 0.035, kind: 0, drag: 0.6, g: 9.8, bounce: 0.35, age: 0 }))\n}\n\nexport function spawnSpark(pool: OrderedPool<Spark>, init: SparkInit): Spark {\n const spark = pool.acquire()\n spark.x = init.x ?? 0\n spark.y = init.y ?? 0\n spark.z = init.z ?? 0\n spark.vx = init.vx ?? 0\n spark.vy = init.vy ?? 0\n spark.vz = init.vz ?? 0\n spark.t = 0\n spark.life = init.life ?? 0.8\n spark.w = init.w ?? 0.04\n spark.st = init.st ?? 0.035\n spark.kind = init.kind ?? 0\n spark.drag = init.drag ?? 0.6\n spark.g = init.g ?? 9.8\n spark.bounce = init.bounce ?? 0.35\n spark.age = 0\n return spark\n}\n\nfunction ageOrKeep(spark: Spark, dt: number): boolean {\n spark.t += dt\n return spark.t < spark.life\n}\n\nexport interface SparkStep {\n readonly dt: number\n readonly groundAt: (x: number, z: number) => number\n}\n\n/** `updateSparks` (L277-293): drag, gravity, a bounce that kills some speed on the ground. */\nexport function updateSparks(pool: OrderedPool<Spark>, step: SparkStep): void {\n pool.compact(ageOrKeep, step.dt)\n for (const spark of pool.items) {\n const damping = Math.exp(-spark.drag * step.dt)\n spark.vx *= damping\n spark.vy *= damping\n spark.vz *= damping\n spark.vy -= spark.g * step.dt\n spark.x += spark.vx * step.dt\n spark.y += spark.vy * step.dt\n spark.z += spark.vz * step.dt\n const floor = step.groundAt(spark.x, spark.z) + GROUND_LIFT\n if (spark.y < floor) {\n spark.y = floor\n if (spark.vy < 0) {\n spark.vy *= -spark.bounce\n spark.vx *= BOUNCE_SLIDE\n spark.vz *= BOUNCE_SLIDE\n }\n }\n spark.age = spark.t / spark.life\n }\n}\n","import type { VfxCore } from './core'\nimport { spawnChunk } from './pools/chunks'\nimport type { Chunk, ChunkInit } from './pools/chunks'\nimport { spawnGlow } from './pools/glows'\nimport type { Glow, GlowInit } from './pools/glows'\nimport { spawnPuff } from './pools/puffs'\nimport type { Puff, PuffInit } from './pools/puffs'\nimport { spawnSpark } from './pools/sparks'\nimport type { Spark, SparkInit } from './pools/sparks'\nimport type { RandomStream } from './random'\n\nconst HOT_GLOW_COLOR = [1, 0.45, 0.12] as const\n\n/** The spawners count what an explosion makes (the Lab's `evCount`) on top of the pools, and a hot chunk carries a halo, as in the Lab (L371-376). */\nexport function addPuff(core: VfxCore, random: RandomStream, init: PuffInit): Puff {\n core.spawned.puffs++\n const puff = spawnPuff(core.puffs, random, init)\n core.trace?.puff?.(puff)\n return puff\n}\n\nexport function addSpark(core: VfxCore, init: SparkInit): Spark {\n core.spawned.sparks++\n const spark = spawnSpark(core.sparks, init)\n core.trace?.spark?.(spark)\n return spark\n}\n\nexport function addGlow(core: VfxCore, init: GlowInit): Glow {\n const glow = spawnGlow(core.glows, init)\n core.trace?.glow?.(glow)\n return glow\n}\n\nexport function addChunk(core: VfxCore, random: RandomStream, init: ChunkInit): Chunk {\n const chunk = spawnChunk(core.chunks, random, init)\n core.spawned.chunks++\n if (chunk.hot && core.layers.shrapnel) {\n chunk.glow = addGlow(core, { follow: chunk, s: 0.35 + chunk.sx, i: 2.2, life: random.between(1, 2.2), color: HOT_GLOW_COLOR, curve: 1.5 })\n }\n core.trace?.chunk?.(chunk)\n return chunk\n}\n","import type { Rgb } from '../color'\nimport { SMOKE_COLORS } from '../constants'\nimport type { VfxCore } from '../core'\nimport { OrderedPool } from '../pool'\nimport type { RandomStream } from '../random'\nimport { addPuff, addSpark } from '../spawn'\nimport type { Follow } from '../types'\nimport { lerp } from '../vector'\n\n/** A lingering fire (L424-442): it grows, gives flames that cool into smoke, and fades out. */\nexport interface Fire {\n x: number\n y: number\n z: number\n r: number\n r0: number\n grow: number\n life: number\n t: number\n rate: number\n acc: number\n smoke: number\n smokeAcc: number\n fade: number\n follow: Follow | null\n fx: number\n fy: number\n fz: number\n color: Rgb\n rng: RandomStream\n handle: number\n}\n\nexport type FireInit = Partial<Pick<Fire, 'x' | 'y' | 'z' | 'r' | 'grow' | 'life' | 'rate' | 'smoke' | 'follow' | 'fx' | 'fy' | 'fz' | 'color'>> & { startRadius?: number }\n\nexport function createFirePool(capacity: number, placeholder: RandomStream): OrderedPool<Fire> {\n return new OrderedPool<Fire>(capacity, () => ({\n x: 0, y: 0, z: 0, r: 0.6, r0: 0.6, grow: 0, life: 6, t: 0, rate: 22, acc: 0, smoke: 0.6, smokeAcc: 0, fade: 1, follow: null, fx: 0, fy: 0, fz: 0, color: SMOKE_COLORS.black,\n rng: placeholder, handle: 0,\n }))\n}\n\nexport function spawnFire(pool: OrderedPool<Fire>, random: RandomStream, init: FireInit, handle: number): Fire {\n const fire = pool.acquire()\n fire.x = init.x ?? 0\n fire.y = init.y ?? 0\n fire.z = init.z ?? 0\n fire.r = init.r ?? 0.6\n fire.r0 = init.startRadius ?? fire.r\n fire.grow = init.grow ?? 0\n fire.life = init.life ?? 6\n fire.t = 0\n fire.rate = init.rate ?? 22\n fire.acc = 0\n fire.smoke = init.smoke ?? 0.6\n fire.smokeAcc = 0\n fire.fade = 1\n fire.follow = init.follow ?? null\n fire.fx = init.fx ?? 0\n fire.fy = init.fy ?? 0\n fire.fz = init.fz ?? 0\n fire.color = init.color ?? SMOKE_COLORS.black\n fire.rng = random\n fire.handle = handle\n return fire\n}\n\nexport function addFire(core: VfxCore, random: RandomStream, init: FireInit, handle: number): Fire {\n const fire = spawnFire(core.fires, random, init, handle)\n core.trace?.fire?.(fire)\n return fire\n}\n\nfunction positionOf(follow: Follow): { x: number; y: number; z: number } {\n return 'position' in follow ? follow.position : follow\n}\n\nfunction emitFlames(core: VfxCore, fire: Fire, radius: number, dt: number): void {\n const random = fire.rng\n fire.acc += dt * fire.rate * (0.5 + radius * 0.9) * fire.fade * core.clock.lod\n while (fire.acc >= 1) {\n fire.acc -= 1\n const angle = random.next() * Math.PI * 2\n const distance = Math.sqrt(random.next()) * radius\n addPuff(core, random, {\n x: fire.x + Math.cos(angle) * distance, y: fire.y + 0.05, z: fire.z + Math.sin(angle) * distance,\n vx: random.between(-0.2, 0.2), vy: random.between(0.6, 1.4), vz: random.between(-0.2, 0.2),\n s0: 0.1, s1: random.between(0.28, 0.46) * (0.8 + Math.min(radius, 3) * 0.22), sg: -0.08,\n life: random.between(0.45, 0.85), h0: random.between(1, 1.25), hl: random.between(0.35, 0.6),\n drag: 1.5, buoy: 3.2, color: fire.color, kind: 0, wind: 0.4,\n })\n }\n}\n\nfunction emitSmoke(core: VfxCore, fire: Fire, radius: number, dt: number): void {\n const random = fire.rng\n fire.smokeAcc += dt * fire.smoke * (1 + radius * 0.8) * fire.fade * core.clock.lod\n while (fire.smokeAcc >= 1 && core.layers.smoke) {\n fire.smokeAcc -= 1\n addPuff(core, random, {\n x: fire.x + random.between(-radius, radius) * 0.5, y: fire.y + 0.6 + radius * 0.3, z: fire.z + random.between(-radius, radius) * 0.5,\n vy: random.between(0.8, 1.5), s0: 0.25, s1: 0.6 + Math.min(radius, 2) * 0.3, sg: 0.3, life: random.between(4, 6.5),\n h0: 0.25, hl: 0.25, drag: 0.6, buoy: 0.55, color: fire.color, kind: 0,\n })\n }\n}\n\nfunction emitEmber(core: VfxCore, fire: Fire, radius: number, dt: number): void {\n const random = fire.rng\n if (!(random.next() < dt * 6 * fire.fade && core.layers.shrapnel)) return\n addSpark(core, {\n x: fire.x + random.between(-radius, radius) * 0.6, y: fire.y + 0.4, z: fire.z + random.between(-radius, radius) * 0.6,\n vx: random.between(-0.4, 0.4), vy: random.between(1.5, 3.2), vz: random.between(-0.4, 0.4),\n life: random.between(0.8, 1.6), w: 0.025, st: 0.02, kind: 4, g: -0.6, drag: 1.2,\n })\n}\n\n/** `updateFires` (L430-442), walking the list backwards like the Lab. */\nexport function updateFires(core: VfxCore, dt: number): void {\n const pool = core.fires\n for (let index = pool.items.length - 1; index >= 0; index--) {\n const fire = pool.items[index]!\n fire.t += dt\n if (fire.follow) {\n const point = positionOf(fire.follow)\n fire.x = point.x + fire.fx\n fire.y = point.y + fire.fy\n fire.z = point.z + fire.fz\n }\n const radius = fire.grow ? lerp(fire.r0, fire.r, Math.min(1, fire.t / fire.grow)) : fire.r\n fire.fade = fire.t < fire.life - 1.5 ? Math.min(1, fire.t * 3) : Math.max(0, (fire.life - fire.t) / 1.5)\n if (fire.t >= fire.life) {\n pool.removeAt(index)\n continue\n }\n if (!core.layers.fire) continue\n emitFlames(core, fire, radius, dt)\n emitSmoke(core, fire, radius, dt)\n emitEmber(core, fire, radius, dt)\n }\n}\n","import type { Expr } from './expression'\n\n/** Constructors for the computed fields of a recipe. They only build data (`{ $, a }`); `expression.ts` runs it. */\nconst call =\n (name: string) =>\n (...args: readonly unknown[]): Expr => ({ $: name, a: args })\n\nexport const rnd = call('rnd')\nexport const rand = call('rand')\nexport const add = call('add')\nexport const concat = call('concat')\nexport const sub = call('sub')\nexport const mul = call('mul')\nexport const div = call('div')\nexport const mod = call('mod')\nexport const neg = call('neg')\nexport const abs = call('abs')\nexport const sqrt = call('sqrt')\nexport const sin = call('sin')\nexport const cos = call('cos')\nexport const atan2 = call('atan2')\nexport const min = call('min')\nexport const max = call('max')\nexport const floor = call('floor')\nexport const ceil = call('ceil')\nexport const round = call('round')\nexport const clamp = call('clamp')\nexport const lerp = call('lerp')\nexport const ease = call('ease')\nexport const lt = call('lt')\nexport const gt = call('gt')\nexport const le = call('le')\nexport const ge = call('ge')\nexport const eq = call('eq')\nexport const ne = call('ne')\nexport const not = call('not')\nexport const and = call('and')\nexport const or = call('or')\nexport const ite = call('ite')\nexport const vadd = call('vadd')\nexport const vsub = call('vsub')\nexport const vscale = call('vscale')\nexport const vnorm = call('vnorm')\nexport const vneg = call('vneg')\nexport const vlerp = call('vlerp')\nexport const vx = call('vx')\nexport const vy = call('vy')\nexport const vz = call('vz')\nexport const vdist = call('vdist')\nexport const vwith = call('with')\nexport const pick = call('at')\nexport const scaled = call('scaled')\nexport const param = (...values: readonly unknown[]): Expr => ({ $: 'param', a: [values] })\n/** Binds `name` to `value` while `body` resolves: the page's `const a = ...` inside a spawn callback. */\nexport const local = (name: string, value: unknown, body: unknown): Expr => ({ $: 'let', a: [name, value, body] })\nexport const query = (behavior: string, name: string, ...args: readonly unknown[]): Expr => ({ $: 'query', a: [behavior, name, ...args] })\nexport const variable = (name: string): Expr => ({ $: 'var', a: [name] })\nexport const cameraForward = call('cameraForward')\nexport const TIME: Expr = { $: 't' }\nexport const PARAM: Expr = { $: 'paramIndex' }\nexport const DELTA: Expr = { $: 'dt' }\nexport const INDEX: Expr = { $: 'index' }\nexport const QUALITY: Expr = { $: 'quality' }\nexport const FRESH: Expr = { $: 'fresh' }\nexport const DIRECTION: Expr = { $: 'direction' }\nexport const NORMAL: Expr = { $: 'normal' }\nexport const CAMERA_POSITION: Expr = { $: 'cameraPosition' }\nexport const UP = [0, 1, 0] as const\n","import type { Computed, EffectStep, ScreenKey } from './types'\n\ntype System = 'add' | 'normal' | 'streak'\n\n/** Constructors for the steps of a recipe (they only build data). */\nexport const burst = (system: System, count: Computed, spawn: Computed): EffectStep => ({ op: 'burst', system, count, spawn })\nexport const spawn = (system: System, options: Computed): EffectStep => ({ op: 'spawn', system, spawn: options })\nexport const emit = (key: string, system: System, rate: Computed, options: Computed): EffectStep => ({ op: 'emit', key, system, rate, spawn: options })\nexport const debris = (options: Computed): EffectStep => ({ op: 'debris', spawn: options })\nexport const decal = (...args: readonly Computed[]): EffectStep => ({ op: 'decal', args })\nexport const ring = (...args: readonly Computed[]): EffectStep => ({ op: 'ring', args })\nexport const flash = (...args: readonly Computed[]): EffectStep => ({ op: 'flash', args })\nexport const lens = (...args: readonly Computed[]): EffectStep => ({ op: 'lens', args })\nexport const screen = (change: { add?: Partial<Record<ScreenKey, Computed>>; set?: Partial<Record<ScreenKey, Computed>>; max?: Partial<Record<ScreenKey, Computed>> }): EffectStep => ({ op: 'screen', ...change })\nexport const fireLight = (slot: 0 | 1, point: Computed, intensity: Computed, time: Computed): EffectStep => ({ op: 'fire_light', slot, point, intensity, time })\nexport const fireLightOff = (slot: 0 | 1): EffectStep => ({ op: 'fire_light_off', slot })\nexport const cue = (name: string, args?: Computed, draws?: number): EffectStep => ({ op: 'cue', cue: name, ...(args !== undefined ? { args } : {}), ...(draws !== undefined ? { draws } : {}) })\nexport const call = (macro: string, ...args: readonly Computed[]): EffectStep => ({ op: 'call', macro, args })\nexport const after = (time: Computed, ...steps: readonly EffectStep[]): EffectStep => ({ op: 'at', time, steps })\nexport const when = (condition: Computed, steps: readonly EffectStep[], otherwise?: readonly EffectStep[]): EffectStep => ({ op: 'when', if: condition, steps, ...(otherwise ? { otherwise } : {}) })\nexport const repeat = (count: Computed, ...steps: readonly EffectStep[]): EffectStep => ({ op: 'repeat', count, steps })\nexport const set = (name: string, value: Computed): EffectStep => ({ op: 'set', name, value })\nexport const behavior = (id: string, action: string, args?: Computed): EffectStep => ({ op: 'behavior', id, action, ...(args !== undefined ? { args } : {}) })\nexport const append = (name: string, value: Computed): EffectStep => ({ op: 'append', name, value })\nexport const camera = (eye: Computed, target: Computed, instant?: boolean): EffectStep => ({ op: 'camera', eye, target, ...(instant ? { instant } : {}) })\nexport const post = (values: Readonly<Record<string, Computed>>): EffectStep => ({ op: 'post', values })\n","import { gt, lt, and, INDEX, ite, mod, scaled, TIME } from '../dsl'\nimport { after, burst, debris, decal, emit, repeat, ring, screen, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst CENTRE: readonly [number, number, number] = [0, 1.1, 0]\nconst UP: readonly [number, number, number] = [0, 1, 0]\n\n/** W501-520: the belly bursts after a second and leaves a green cloud near the ground for eight. */\nexport const BLOATER_CLOUD: EffectDef = {\n id: 'bloater_cloud',\n pageId: 'inchado',\n team: 'creatures',\n budget: { particles: 180 },\n loop: 9,\n view: { eye: [5.5, 3.2, 6], target: [0, 1, 0] },\n timeline: [\n after(\n 1,\n burst('normal', 40, { p: CENTRE, r: 0.4, sp: [1.5, 4], drag: 2.2, life: [4, 6], size: [1, 2.2], grow: 2, c0: 0x6f8a3c, c1: 0x3b4a26, a: 0.32, fi: 0.08, g: 0.05 }),\n burst('normal', 30, { p: CENTRE, dir: UP, cone: 1.3, sp: [2, 4], life: 1.4, size: [0.04, 0.08], c0: 0x4a5a1c, g: 9.8, fi: 0, gnd: 3, ds: [0.1, 0.2] }),\n repeat(scaled(10), debris({ p: CENTRE, dir: UP, cone: 1.2, sp: [2, 5], size: [0.07, 0.05, 0.07], k: [0.6, 1.4], c: ite(mod(INDEX, 2), 0x6b7a52, 0x4a1a12), life: 9 })),\n decal(0, 0, 0, 1.6, 0x6a7a24, { grow: 0.6, life: 60, fluid: 'bile' }),\n ring([0, 0.02, 0], 4, 4, 8, 0x3a5a20, UP, 0.35),\n screen({ add: { shake: 0.15 } }),\n ),\n ],\n tick: [\n when(and(gt(TIME, 1), lt(TIME, 8)), [\n emit('gas', 'normal', 7, { p: [0, 0.4, 0], r: 3.4, flat: true, dir: UP, cone: 1.3, sp: [0.1, 0.35], drag: 0.4, life: [3, 5], size: [1.2, 2.2], grow: 1.5, c0: 0x6f8a3c, c1: 0x3b4a26, a: 0.22, fi: 0.3 }),\n emit('mote', 'add', 10, { p: [0, 0.6, 0], r: 3.6, flat: true, dir: UP, cone: 0.6, sp: [0.05, 0.25], life: [1.5, 2.5], size: [0.04, 0.07], c0: 0x5fe08a, a: 0.7, fi: 0.4 }),\n ]),\n ],\n}\n","import { add, and, gt, lt, mul, param, PARAM, pick, TIME, vnorm } from '../dsl'\nimport { after, call, decal, emit, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst BLOOD = param(0x8a0a0a, 0x5a0c10, 0x3a1c12, 0x1d1914)\nconst BLEED = [1, 0.7, 0.35]\n\n/** W449-473: blood by infection age: a mist at the entry, a jet at the exit, a pool that grows and darkens. */\nexport const BLOOD_HIT: EffectDef = {\n id: 'blood_hit',\n pageId: 'sangue',\n team: 'creatures',\n params: { id: 'age', options: ['fresh', 'recent', 'old', 'decrepit'], default: 0 },\n budget: { particles: 70, decals: 1 },\n loop: 3.2,\n view: { eye: [2.6, 1.9, 3.4], target: [0, 1, -0.6] },\n timeline: [\n after(0.3, call('blood_hit', [0, 1.3, 0.1], vnorm([0.15, 0.1, -1]), PARAM)),\n after(1.5, call('blood_hit', [0.1, 1.05, 0.1], vnorm([-0.2, 0.05, -1]), PARAM, 0.8)),\n when(lt(PARAM, 3), [after(0.7, decal(0, 0, -0.2, add(0.5, mul(0.7, pick(BLEED, PARAM))), BLOOD, { grow: add(2, mul(2, pick(BLEED, PARAM))), dark: 60, dry: 0x3b1d14 }))]),\n ],\n tick: [\n when(and(lt(PARAM, 2), gt(TIME, 0.3)), [\n emit('drip', 'normal', param(7, 3), {\n p: [0.05, 1.15, 0.17], box: [0.08, 0.05, 0], dir: [0, 1, 0], cone: 0.2, sp: [0, 0.2], life: 1.2, size: 0.03, c0: BLOOD, g: 9.8, fi: 0, gnd: 3, ds: [0.04, 0.08],\n }),\n ]),\n ],\n}\n","import { and, gt, lt, TIME } from '../dsl'\nimport { after, decal, emit, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst UP: readonly [number, number, number] = [0, 1, 0]\n\n/** W540-553: fifteen minutes in eight seconds: the pool dries, flies appear from the minute five and the body turns to dust. */\nexport const CORPSE_DECAY: EffectDef = {\n id: 'corpse_decay',\n pageId: 'corpo',\n team: 'creatures',\n budget: { particles: 40 },\n loop: 8.5,\n view: { eye: [2.4, 1.6, 2.6], target: [0, 0.3, -0.6] },\n timeline: [after(0.8, decal(0, 0, -0.9, 1.1, 0x5a0c10, { grow: 1.5, dark: 5, dry: 0x3b1d14 }))],\n tick: [\n when(and(gt(TIME, 2.5), lt(TIME, 7)), [\n emit('fly', 'normal', 6, { p: [0, 0.35, -0.8], r: 0.5, sp: [0.3, 0.8], life: [0.6, 1.2], size: 0.02, c0: 0x050505, a: 1, fi: 0.2 }),\n ]),\n when(and(gt(TIME, 6.8), lt(TIME, 7.6)), [\n emit('dust', 'normal', 40, { p: [0, 0.15, -0.8], box: [0.25, 0.05, 0.8], dir: UP, cone: 0.6, sp: [0.2, 0.6], drag: 1, life: [1, 1.8], size: [0.12, 0.22], grow: 3, c0: 0x2b2722, a: 0.5 }),\n ]),\n ],\n}\n","import { and, INDEX, ite, lt, not, pick, query, QUALITY, rnd, variable } from '../dsl'\nimport { behavior, repeat, set, spawn, when } from '../steps'\nimport type { EffectDef } from '../types'\n\n/** Which of the ten walkers run: the ones with red eyes (W192). */\nconst RUNNERS = [false, true, false, false, false, true, false, false, false, true]\nconst RUN_SPEED = 3.8\nconst WALK_SPEED = 0.7\nconst SPEED = ite(pick(RUNNERS, INDEX), RUN_SPEED, WALK_SPEED)\nconst walkTo = behavior('walkers', 'walk', { index: INDEX, to: [-12, 0, query('walkers', 'z', INDEX)], speed: SPEED })\n\n/** W562-571 (the page's `olhos`): ten zombies walk through fog from the east; the runners leave a short red trail behind their eyes. */\nexport const EYES_IN_FOG: EffectDef = {\n id: 'eyes_in_fog',\n pageId: 'olhos',\n team: 'creatures',\n budget: { particles: 20 },\n loop: 0,\n view: { eye: [-9, 1.7, 2], target: [6, 1.3, 2] },\n setup: [\n repeat(10, set('placeX', rnd(4, 34)), set('placeZ', rnd(-1.5, 5.5)), behavior('walkers', 'place', { index: INDEX, x: variable('placeX'), z: variable('placeZ'), facing: -Math.PI / 2 }), walkTo),\n ],\n timeline: [],\n tick: [\n repeat(\n 10,\n when(lt(query('walkers', 'x', INDEX), -8), [behavior('walkers', 'move_x', { index: INDEX, x: rnd(28, 36) }), walkTo], [when(not(query('walkers', 'is_walking', INDEX)), [walkTo])]),\n when(and(pick(RUNNERS, INDEX), lt(QUALITY, 2)), [\n spawn('streak', { p: query('walkers', 'point', INDEX, [0, 1.74, 0.2]), dir: [1, 0, 0], cone: 0, sp: RUN_SPEED, v: [-RUN_SPEED, 0, 0], life: 0.25, len: 0.06, c0: 0xe5392b, c1: 0x400000, a: 0.8 }),\n ]),\n ),\n ],\n}\n","import { ite, gt, lt, and, mul, sin, sub, vnorm, TIME } from '../dsl'\nimport { after, burst, debris, emit, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst SHOULDER: readonly [number, number, number] = [0.36, 1.46, 0.05]\nconst FRESH_BLOOD = 0x8a0a0a\n\n/** W487-500: the arm leaves as a loose piece and the shoulder spurts in pulses for half a second. */\nexport const DISMEMBER: EffectDef = {\n id: 'dismember',\n pageId: 'membro',\n team: 'creatures',\n budget: { particles: 60, debris: 1, decals: 4 },\n loop: 3.6,\n view: { eye: [3, 1.8, 2.2], target: [0.4, 1.1, 0] },\n timeline: [\n after(\n 0.4,\n debris({ p: SHOULDER, v: [2.2, 2.5, -0.6], sp: 0, size: [0.12, 0.12, 0.66], c: 0x6d7a5a, spin: 9, life: 12, bounce: 0.25 }),\n burst('normal', 12, { p: SHOULDER, r: 0.05, sp: [0.3, 1.2], drag: 3, life: [0.3, 0.6], size: [0.1, 0.16], grow: 3, c0: FRESH_BLOOD, a: 0.6 }),\n ),\n ],\n tick: [\n when(and(gt(TIME, 0.4), lt(TIME, 1.1)), [\n emit('jet', 'normal', mul(90, ite(gt(sin(mul(sub(TIME, 0.4), 28)), 0), 1, 0.2)), { p: SHOULDER, dir: vnorm([1, 0.35, 0.1]), cone: 0.25, sp: [1.5, 3], life: 1.4, size: [0.03, 0.055], c0: FRESH_BLOOD, g: 9.8, fi: 0, gnd: 3, ds: [0.05, 0.12] }),\n ]),\n ],\n}\n","import { ite, mod, INDEX, scaled, vnorm } from '../dsl'\nimport { after, burst, debris, decal, flash, repeat } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst FRESH_BLOOD = 0x8a0a0a\n\n/** W474-486: the head bursts, the eyes go out in the same frame and the body falls. */\nexport const HEADSHOT: EffectDef = {\n id: 'headshot',\n pageId: 'headshot',\n team: 'creatures',\n budget: { particles: 70, debris: 8, decals: 1 },\n loop: 3.2,\n view: { eye: [2.2, 1.8, 3], target: [0, 1.2, -0.5] },\n timeline: [\n after(\n 0.45,\n burst('normal', 20, { p: [0, 1.7, 0], r: 0.1, sp: [0.4, 1.8], drag: 3, life: [0.4, 0.75], size: [0.12, 0.2], grow: 3, c0: FRESH_BLOOD, a: 0.7 }),\n burst('normal', 35, { p: [0, 1.7, 0], dir: vnorm([0, 0.45, -1]), cone: 0.8, sp: [2, 5], life: 1.5, size: [0.035, 0.065], c0: FRESH_BLOOD, g: 9.8, fi: 0, gnd: 3, ds: [0.06, 0.14] }),\n repeat(scaled(8), debris({ p: [0, 1.7, 0], dir: vnorm([0, 0.6, -1]), cone: 0.9, sp: [1.5, 4], size: [0.06, 0.05, 0.06], k: [0.5, 1.2], c: ite(mod(INDEX, 2), 0xd9cfbf, 0x6d7a5a), life: 8 })),\n flash([0, 1.7, 0], 0xff3020, 1.2, 0.08, 4),\n ),\n after(1.4, decal(0, 0, -1.5, 0.9, FRESH_BLOOD, { grow: 2.4, dark: 60, dry: 0x3b1d14 })),\n ],\n}\n","import { and, gt, lt, TIME, vnorm } from '../dsl'\nimport { cue, emit, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst UP: readonly [number, number, number] = [0, 1, 0]\n\n/** W554-561: green motes while the body twitches (two random draws a frame for the arms), the eyes light up and a breath of steam on the first scream. */\nexport const REANIMATION: EffectDef = {\n id: 'reanimation',\n pageId: 'reanima',\n team: 'creatures',\n budget: { particles: 30 },\n loop: 6.5,\n view: { eye: [2.4, 1.4, 2.4], target: [0, 0.6, -0.4] },\n timeline: [],\n tick: [\n when(lt(TIME, 3.4), [\n when(gt(TIME, 1), [cue('zombie_arm_twitch', undefined, 2)]),\n when(gt(TIME, 0.6), [\n emit('mote', 'add', 8, { p: [0, 0.2, -0.8], box: [0.25, 0.05, 0.6], dir: UP, cone: 0.4, sp: [0.2, 0.5], life: [0.6, 1], size: [0.03, 0.05], c0: 0x9fc25a, a: 0.7, fi: 0.3 }),\n ]),\n ]),\n when(and(gt(TIME, 5), lt(TIME, 5.6)), [\n emit('br', 'normal', 20, { p: [0, 1.68, 0.2], dir: vnorm([0, 0.3, 1]), cone: 0.3, sp: [0.6, 1.1], drag: 1.5, life: 1.2, size: [0.05, 0.1], grow: 5, c0: 0xd8dde2, a: 0.2 }),\n ]),\n ],\n}\n","import { add, cos, div, INDEX, local, lt, mul, rand, sin, sub, TIME, variable, vnorm } from '../dsl'\nimport { after, emit, repeat, ring, screen, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst WHITE_RING = 0xe8e2d0\nconst PREPARATION_END = 1.7\nconst SHRIEK_END = 2.6\n\n/** W521-539: a steam of breath while the screamer prepares, then three pressure rings, a ring of dust and a burst of chromatic aberration. */\nexport const SCREAMER_SHRIEK: EffectDef = {\n id: 'screamer_shriek',\n pageId: 'grito',\n team: 'creatures',\n budget: { particles: 150 },\n loop: 5,\n view: { eye: [6, 3, 7], target: [0, 1, -1] },\n timeline: [\n after(\n PREPARATION_END,\n repeat(3, after(add(PREPARATION_END, mul(INDEX, 0.18)), ring([0, 0.03, 0], 0.3, 9, 0.9, WHITE_RING))),\n screen({ add: { chroma: 7, shake: 0.25 } }),\n ),\n ],\n tick: [\n when(lt(TIME, PREPARATION_END), [\n emit('vap', 'normal', 18, { p: [0, 1.68, 0.2], dir: vnorm([0, 0.5, 1]), cone: 0.3, sp: [0.6, 1.2], drag: 1.5, life: [0.8, 1.3], size: [0.05, 0.1], grow: 5, c0: 0xd8dde2, a: 0.2 }),\n ], [\n when(lt(TIME, SHRIEK_END), [\n set('shriekRadius', mul(div(sub(TIME, PREPARATION_END), 0.9), 8)),\n emit(\n 'dust', 'normal', 140,\n local('angle', mul(rand(), 6.283), {\n p: [mul(cos(variable('angle')), variable('shriekRadius')), 0.05, mul(sin(variable('angle')), variable('shriekRadius'))],\n dir: vnorm([cos(variable('angle')), 0.6, sin(variable('angle'))]),\n cone: 0.3, sp: [0.6, 1.6], drag: 2, life: [0.8, 1.4], size: [0.2, 0.35], grow: 3, c0: 0x5d574d, a: 0.35,\n }),\n ),\n ]),\n ]),\n ],\n}\n","import type { Vec3Tuple } from '../workshop/types'\n\n/**\n * A point of a prop's own space in the world, for a prop placed at `translation` and turned by `rotation` (x, y, z radians, applied in the order x, y,\n * z) as three.js composes it: how the page's `carW` and `tbW` find the bumper or a table leg.\n */\nexport function localToWorld(translation: Vec3Tuple, rotation: Vec3Tuple, local: Vec3Tuple): Vec3Tuple {\n const [x, y, z] = local\n const [a, c, e] = [Math.cos(rotation[0]), Math.cos(rotation[1]), Math.cos(rotation[2])]\n const [b, d, f] = [Math.sin(rotation[0]), Math.sin(rotation[1]), Math.sin(rotation[2])]\n const [ae, af, be, bf] = [a * e, a * f, b * e, b * f]\n return [\n c * e * x + -c * f * y + d * z + translation[0],\n (af + be * d) * x + (ae - bf * d) * y + -b * c * z + translation[1],\n (bf - ae * d) * x + (be + af * d) * y + a * c * z + translation[2],\n ]\n}\n","import { add, eq, FRESH, INDEX, ite, PARAM, pick, rnd, variable, vadd } from '../dsl'\nimport { localToWorld } from '../props'\nimport { after, behavior, call, camera, decal, repeat, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst MATERIALS = ['concrete', 'metal', 'wood', 'glass', 'flesh', 'water']\nconst CAR_ORIGIN = [5.6, 0, 0.8] as const\nconst CAR_ROTATION = [0, -0.4, 0] as const\nconst FACING_WALL = [0, 0, 1] as const\nconst UP = [0, 1, 0] as const\nconst GLASS = 3\nconst FLESH = 4\nconst WATER = 5\nconst SHOT_TIMES = [0, 0.55, 1.1]\nconst LAST_SHOT = 2\nconst BUMPER = localToWorld(CAR_ORIGIN, CAR_ROTATION, [0.96, 0.7, 0.4])\nconst CAR_SIDE = [Math.cos(CAR_ROTATION[1]), 0, -Math.sin(CAR_ROTATION[1])] as const\n/** Where each material is hit and the way the surface faces (W752-756). */\nconst POINTS = [[-2, 1.6, -4.45], BUMPER, [2, 1.3, -4.36], [-5, 1.9, -4.45], [0, 1.25, 0.16], [-1.5, 0.012, 2.2]]\nconst NORMALS = [FACING_WALL, CAR_SIDE, FACING_WALL, FACING_WALL, FACING_WALL, UP]\n/** The eye the page glides to for each material on the first run (W773-774); the car's is found from the car. */\nconst EYES = [[-2, 1.6, -1.8], localToWorld(CAR_ORIGIN, CAR_ROTATION, [3, 1.4, 1.5]), [2, 1.3, -1.6], [-5, 1.9, -1.8], [0, 1.2, 2.6], [-1.5, 0.8, 4.6]]\n/** The shop window as the glass texture sees it (`crackAt` takes pixels): 2.6 x 1.8 m on 256 x 180. */\nconst WINDOW = { centreX: -5, centreY: 1.9, width: 2.6, height: 1.8, pixelsX: 256, pixelsY: 180 }\n\nconst scatter = ite(eq(PARAM, WATER), [rnd(-0.6, 0.6), 0, rnd(-0.3, 0.3)], ite(eq(PARAM, FLESH), [rnd(-0.1, 0.1), rnd(-0.15, 0.15), 0], [rnd(-0.4, 0.4), rnd(-0.3, 0.3), 0]))\nconst hitX = { $: 'vx', a: [variable('hit')] }\nconst hitY = { $: 'vy', a: [variable('hit')] }\nconst pixelX = { $: 'mul', a: [{ $: 'add', a: [{ $: 'div', a: [{ $: 'sub', a: [hitX, WINDOW.centreX] }, WINDOW.width] }, 0.5] }, WINDOW.pixelsX] }\nconst pixelY = { $: 'mul', a: [{ $: 'sub', a: [1, { $: 'add', a: [{ $: 'div', a: [{ $: 'sub', a: [hitY, WINDOW.centreY] }, WINDOW.height] }, 0.5] }] }, WINDOW.pixelsY] }\n\n/** W762-775: three hits, 0.55 s apart, on the material the parameter names; the window keeps its cracks and the puddle takes a dark patch. */\nexport const IMPACT_BY_MATERIAL: EffectDef = {\n id: 'impact',\n pageId: 'impacto',\n team: 'weapons',\n params: { id: 'material', options: MATERIALS, default: 0 },\n budget: { particles: 40, decals: 1 },\n loop: 2.6,\n view: { eye: [0, 1.8, 4.5], target: [0, 1.2, -2] },\n props: ['cracks'],\n timeline: [\n when({ $: 'eq', a: [PARAM, WATER] }, [decal(-1.5, 0, 2.2, 3.2, 0x0d1218, { grow: 0, life: 60, ar: 0.55 })]),\n repeat(\n SHOT_TIMES.length,\n after(\n add(0.2, pick(SHOT_TIMES, INDEX)),\n set('hit', vadd(pick(POINTS, PARAM), scatter)),\n call('impact', pick(MATERIALS, PARAM), variable('hit'), pick(NORMALS, PARAM), 1, 0),\n when(eq(PARAM, GLASS), [behavior('cracks', 'crack', { x: pixelX, y: pixelY, big: eq(INDEX, LAST_SHOT) })]),\n ),\n ),\n when(FRESH, [camera(pick(EYES, PARAM), pick(POINTS, PARAM))]),\n ],\n}\n","import { and, DELTA, gt, INDEX, le, lt, mod, mul, add, pick, rnd, sub, TIME, variable } from '../dsl'\nimport { after, append, call, cue, decal, repeat, set, spawn, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst BLOOD = [0x8a0a0a, 0x5a0c10, 0x3a1c12, 0x1d1914]\n/** Where the five bodies stand along the line of the shot (W786). */\nconst BODY_Z = [2.2, 1, -0.2, -1.4, -2.6]\nconst MUZZLE_Z = 8.5\nconst SPEED = 12\nconst WALL_Z = -4.4\nconst FORWARD = [0, 0, -1] as const\nconst bulletAt = [0, 1.45, variable('bulletZ')]\n\n/** W776-785: a tracer of the Barrett crosses five bodies, each bleeding the colour of its age, then hits the wall. */\nexport const PENETRATION: EffectDef = {\n id: 'penetration',\n pageId: 'penetra',\n team: 'weapons',\n budget: { particles: 250 },\n loop: 4.2,\n view: { eye: [4.2, 2.2, 6.5], target: [0, 1.2, -0.5] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n repeat(\n BODY_Z.length,\n set('bodyX', rnd(-0.05, 0.05)),\n set('bodyTurn', rnd(-0.3, 0.3)),\n append('bodiesX', variable('bodyX')),\n cue('zombie_place', { index: INDEX, x: variable('bodyX'), z: pick(BODY_Z, INDEX), turn: variable('bodyTurn') }),\n ),\n ],\n timeline: [set('bulletZ', MUZZLE_Z), set('bulletOn', true), call('muzzle', 'barrett', [0, 1.45, MUZZLE_Z], FORWARD)],\n tick: [\n when(variable('bulletOn'), [\n set('previousZ', variable('bulletZ')),\n set('bulletZ', sub(variable('bulletZ'), mul(SPEED, DELTA))),\n spawn('streak', { p: bulletAt, dir: FORWARD, cone: 0, sp: 12, life: 0.04, len: 0.07, c0: 0xffd090 }),\n spawn('add', { p: bulletAt, size: 0.09, life: 0.05, c0: 0xffc070, fi: 0 }),\n spawn('normal', { p: bulletAt, r: 0.02, sp: [0, 0.05], life: [1.2, 2], size: 0.05, grow: 3, c0: 0xc8ccd2, a: 0.12, fi: 0.1 }),\n repeat(\n BODY_Z.length,\n when(and(gt(variable('previousZ'), pick(BODY_Z, INDEX)), le(variable('bulletZ'), pick(BODY_Z, INDEX))), [\n call('blood_hit', [0, 1.45, sub(pick(BODY_Z, INDEX), 0.1)], [0, 0.05, -1], mod(INDEX, 4), 0.8),\n cue('zombie_fall', { index: INDEX, delay: 0.05, duration: 0.6 }),\n after(\n add(TIME, 0.6),\n decal(pick(variable('bodiesX'), INDEX), 0, sub(pick(BODY_Z, INDEX), 1.2), 0.6, pick(BLOOD, mod(INDEX, 4)), { grow: 2, dark: 60, dry: 0x3b1d14 }),\n ),\n ]),\n ),\n when(lt(variable('bulletZ'), WALL_Z), [set('bulletOn', false), call('impact', 'concrete', [0, 1.45, -4.45], [0, 0, 1], 2.2)]),\n ]),\n ],\n}\n","import { add, gt, INDEX, lt, and, mul, TIME } from '../dsl'\nimport { after, call, cue, debris, emit, repeat, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst TIP = [-0.8, 1.38, 3.4 - 0.78] as const\nconst PORT = [-0.76, 1.4, 3.32] as const\nconst FORWARD = [0, 0, -1] as const\nconst UP = [0, 1, 0] as const\nconst BURST_SHOTS = 12\n\n/** W787-797: twelve rounds of an AK with their brass, the empty magazine falling at 1.8 s and a thread of smoke from the hot barrel. */\nexport const CASINGS_AND_MAGAZINE: EffectDef = {\n id: 'casings_and_magazine',\n pageId: 'capsulas',\n team: 'weapons',\n budget: { particles: 200, debris: 13 },\n loop: 4.6,\n view: { eye: [0.9, 1.3, 4.6], target: [-0.6, 0.6, 3.1] },\n setup: [cue('gun_visible', { visible: true }), cue('zombie_visible', { index: -1, visible: false })],\n timeline: [\n repeat(\n BURST_SHOTS,\n after(add(0.2, mul(INDEX, 0.1)), call('muzzle', 'ak', TIP, FORWARD), call('casing', PORT, ''), cue('gun_recoil', { kick: 0.05 })),\n ),\n after(1.8, debris({ p: [-0.8, 1.15, 3.3], v: [0.1, -0.5, 0.1], sp: 0, size: [0.05, 0.2, 0.09], c: 0x2a2a2a, spin: 3, life: 20, bounce: 0.2 })),\n ],\n tick: [\n when(and(gt(TIME, 1.4), lt(TIME, 3.6)), [\n emit('hot', 'normal', 10, { p: TIP, dir: UP, cone: 0.25, sp: [0.2, 0.5], life: [1.4, 2.2], size: [0.03, 0.06], grow: 5, c0: 0x9a9a96, a: 0.18, g: -0.2, fi: 0.2 }),\n ]),\n ],\n}\n","import { add, and, div, DELTA, FRESH, ge, gt, ite, lerp, lt, max, min, mul, not, scaled, sin, sub, TIME, variable, vadd, vlerp, vwith } from '../dsl'\nimport { call, cue, debris, burst, decal, emit, fireLight, fireLightOff, flash, repeat, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst FROM = [-4, 1.6, 5] as const\nconst TARGET = [0, 0, -0.5] as const\nconst UP = [0, 1, 0] as const\nconst FLIGHT = 1\nconst ARC_HEIGHT = 2.2\nconst GLASS_GREEN = 0x3a6a3a\nconst OBJECT_ID_DRAWS = 12\nconst at = (offset: readonly [number, number, number]) => vadd(TARGET, offset)\n\n/** W798-818 (`lab: 1`): a bottle in an arc with a wick burning, glass and a splash of fire on landing, and a pool of fire that spreads for 6 s. */\nexport const MOLOTOV: EffectDef = {\n id: 'molotov',\n pageId: 'molotov',\n team: 'weapons',\n lab: 'molotov',\n budget: { particles: 300, lights: 1 },\n loop: 9.5,\n view: { eye: [5, 3, 6.5], target: [0, 0.6, -0.5] },\n // three.js draws 12 random numbers (the object ids of the bottle's geometry, material and mesh) the first time the page builds the bottle\n setup: [cue('zombie_visible', { index: -1, visible: false }), when(FRESH, [cue('prop_created', { prop: 'bottle' }, OBJECT_ID_DRAWS)])],\n timeline: [set('landed', false), cue('bottle_visible', { visible: true })],\n tick: [\n when(lt(TIME, FLIGHT), [\n set('bottle', vwith(vlerp(FROM, TARGET, TIME), 1, add(lerp(FROM[1], TARGET[1], TIME), mul(sin(mul(TIME, Math.PI)), ARC_HEIGHT)))),\n cue('bottle_move', { position: variable('bottle'), spin: mul(10, DELTA) }),\n emit('wick', 'add', 40, { p: vadd(variable('bottle'), [0, 0.12, 0]), r: 0.03, sp: [0.1, 0.3], life: [0.15, 0.3], size: [0.08, 0.14], grow: 0.5, c0: 0xffd27a, c1: 0xff5010, fi: 0, g: -1 }),\n emit('wsm', 'normal', 14, { p: variable('bottle'), size: [0.06, 0.1], grow: 4, life: [0.8, 1.2], c0: 0x3a3530, a: 0.3, sp: [0, 0.2] }),\n ], [\n when(not(variable('landed')), [\n set('landed', true),\n cue('bottle_visible', { visible: false }),\n repeat(scaled(12), debris({ p: at([0, 0.1, 0]), dir: UP, cone: 1.3, sp: [1, 3], size: [0.04, 0.01, 0.04], c: GLASS_GREEN, life: 12 })),\n burst('add', 45, { p: at([0, 0.15, 0]), dir: UP, cone: 1.35, sp: [2, 4], drag: 2, life: [0.3, 0.6], size: [0.3, 0.5], c0: 0xffd27a, c1: 0xa02008, fi: 0.05 }),\n flash(at([0, 0.6, 0]), 0xff8a30, 6, 0.3, 12, true),\n decal(TARGET[0], 0, TARGET[2], 4.2, 0x0d0b09, { grow: 0.8, life: 60 }),\n ]),\n ]),\n when(and(gt(TIME, FLIGHT), lt(TIME, 8.2)), [\n set('poolRadius', min(2.2, add(0.5, mul(sub(TIME, 1), 2.1)))),\n set('poolFade', ite(gt(TIME, 7), max(0.1, sub(1, div(sub(TIME, 7), 1.2))), 1)),\n call('fire_emit', 'mol', at([0, 0.05, 0]), variable('poolRadius'), mul(1.6, variable('poolFade')), { smoke: 16 }),\n fireLight(0, at([0, 1, 0]), mul(3.2, variable('poolFade')), TIME),\n ], [\n when(ge(TIME, 8.2), [\n fireLightOff(0),\n emit('emb', 'add', 6, { p: TARGET, r: 2, flat: true, size: [0.04, 0.07], life: [0.6, 1.2], c0: 0xff6a20, a: 0.8, fi: 0.3 }),\n ]),\n ]),\n ],\n}\n","import { add, atan2, DELTA, FRESH, INDEX, lt, mul, neg, not, pick, sub, TIME, variable } from '../dsl'\nimport { call, cue, repeat, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\n/** The five bodies the blast reaches (W826), where they stand and the way each faces (`atan2(-x, -z)`, toward the origin). */\nconst BODIES = [[1.6, 0.8], [-1.8, 1.2], [0.6, -2], [-1, -1.8], [2.4, -1.2]] as const\nconst BODY_X = BODIES.map(([x]) => x)\nconst BODY_Z = BODIES.map(([, z]) => z)\nconst FACING = BODIES.map(([x, z]) => Math.atan2(-x, -z))\nconst FUSE = 1.8\nconst GRAVITY = 9.8\nconst FLOOR = 0.07\nconst BOUNCE = -0.4\nconst SIDE_LOSS = 0.5\n\n/** W819-830 (`lab: 1`): a grenade thrown in an arc, bouncing on the asphalt, then the Workshop's blast and the five bodies turning away to fall. */\nexport const GRENADE: EffectDef = {\n id: 'grenade',\n pageId: 'granada',\n team: 'weapons',\n lab: 'm67',\n budget: { particles: 400, debris: 16, decals: 1 },\n loop: 6.5,\n view: { eye: [7, 3.4, 7.5], target: [0, 0.8, -0.2] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n // three.js draws 12 random numbers (the object ids of the grenade's geometry, material and mesh) the first time the page builds it\n when(FRESH, [cue('prop_created', { prop: 'grenade' }, 12)]),\n repeat(BODIES.length, cue('zombie_place', { index: INDEX, x: pick(BODY_X, INDEX), z: pick(BODY_Z, INDEX), turn: pick(FACING, INDEX) })),\n ],\n timeline: [\n set('px', -4), set('py', 1.4), set('pz', 4.5),\n set('vx', 3.2), set('vy', 2.4), set('vz', -3.6),\n set('boom', false),\n cue('grenade_visible', { visible: true }),\n ],\n tick: [\n when(lt(TIME, FUSE), [\n set('vy', sub(variable('vy'), mul(GRAVITY, DELTA))),\n set('px', add(variable('px'), mul(variable('vx'), DELTA))),\n set('py', add(variable('py'), mul(variable('vy'), DELTA))),\n set('pz', add(variable('pz'), mul(variable('vz'), DELTA))),\n when(lt(variable('py'), FLOOR), [\n set('py', FLOOR),\n set('vy', mul(variable('vy'), BOUNCE)),\n set('vx', mul(variable('vx'), SIDE_LOSS)),\n set('vz', mul(variable('vz'), SIDE_LOSS)),\n ]),\n cue('grenade_move', { position: [variable('px'), variable('py'), variable('pz')] }),\n ], [\n when(not(variable('boom')), [\n set('boom', true),\n cue('grenade_visible', { visible: false }),\n call('explode', [variable('px'), 0, variable('pz')], 1),\n repeat(\n BODIES.length,\n cue('zombie_turn_and_fall', {\n index: INDEX,\n turn: atan2(neg(sub(pick(BODY_X, INDEX), variable('px'))), neg(sub(pick(BODY_Z, INDEX), variable('pz')))),\n delay: 0.02,\n duration: 0.45,\n }),\n ),\n ]),\n ]),\n ],\n}\n","import { add, and, cos, gt, ge, INDEX, ite, lt, mod, mul, rnd, scaled, sin, sub, TIME, variable, vadd, concat } from '../dsl'\nimport { after, append, burst, call, cue, debris, emit, fireLight, fireLightOff, repeat, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst BARREL = [-4.4, 0, 1.4] as const\nconst UP = [0, 1, 0] as const\nconst RED = 0x9b1c18\nconst YELLOW = 0xd8b02a\nconst POOLS = 3\nconst above = (height: number) => vadd(BARREL, [0, height, 0])\n\n/** W831-845 (`lab: 1`): the barrel goes up in a mushroom, its lid and red scraps fly, three pools of petrol burn for 5 s and a black column marks it from afar. */\nexport const EXPLOSIVE_BARREL: EffectDef = {\n id: 'explosive_barrel',\n pageId: 'barril',\n team: 'weapons',\n lab: 'barrel',\n budget: { particles: 450, lights: 1 },\n loop: 9,\n view: { eye: [2.4, 3, 7.5], target: [-4.4, 1.6, 1.4] },\n setup: [cue('zombie_visible', { index: -1, visible: false })],\n timeline: [\n set('pools', []),\n after(\n 0.4,\n cue('barrel_visible', { visible: false }),\n call('explode', BARREL, 1.3, RED),\n burst('add', 30, { p: above(0.8), r: 0.4, dir: UP, cone: 0.25, sp: [3, 5], drag: 1.2, life: [1, 1.6], size: [0.9, 1.4], grow: 1.4, c0: 0xffb050, c1: 0x3a0d05, g: -1, fi: 0.05 }),\n debris({ p: above(1), v: [0.6, 9, 0.3], sp: 0, size: [0.7, 0.05, 0.7], c: RED, spin: 8, life: 12 }),\n repeat(scaled(8), debris({ p: BARREL, dir: UP, cone: 1, sp: [3, 7], size: [0.25, 0.04, 0.18], c: ite(mod(INDEX, 2), RED, YELLOW), life: 12 })),\n repeat(\n POOLS,\n set('poolAngle', add(mul(INDEX, 2.1), rnd(0, 0.6))),\n append('pools', vadd(BARREL, [mul(cos(variable('poolAngle')), 1.4), 0.05, mul(sin(variable('poolAngle')), 1.4)])),\n ),\n ),\n ],\n tick: [\n when(and(variable('pools'), gt(TIME, 0.5), lt(TIME, 6)), [\n set('poolFade', ite(gt(TIME, 5), sub(1, sub(TIME, 5)), 1)),\n repeat(POOLS, call('fire_emit', concat('bp', INDEX), { $: 'at', a: [variable('pools'), INDEX] }, 0.45, mul(0.6, variable('poolFade')), { smoke: 6 })),\n fireLight(0, above(1), mul(2.6, variable('poolFade')), TIME),\n ]),\n when(and(gt(TIME, 0.6), lt(TIME, 8)), [\n emit('col', 'normal', 6, { p: above(1.5), r: 0.6, dir: UP, cone: 0.2, sp: [1.5, 2.5], v: [0.4, 0, 0], drag: 0.05, life: [4, 6], size: [1.2, 1.8], grow: 3, c0: 0x1a1817, c1: 0x0c0d10, a: 0.5, fi: 0.2 }),\n ]),\n when(ge(TIME, 6), [fireLightOff(0)]),\n ],\n}\n","import { add, and, eq, INDEX, ite, mod, mul, ne, param, PARAM, pick, rnd, round, variable } from '../dsl'\nimport { after, call, repeat, set, spawn, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst WEAPONS = ['glock', 'ak', 'r870', 'barrett']\nconst TIP = [-0.8, 1.38, 3.4 - 0.78] as const\nconst PORT = [-0.76, 1.4, 3.32] as const\nconst FORWARD = [0, 0, -1] as const\nconst NORMAL = [0, 0, 1] as const\nconst WALL_Z = -4.45\nconst SHOTS = [[0, 0.45, 0.9], [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6], [0], [0]]\nconst SHOT_TIME = pick(pick(SHOTS, PARAM), INDEX)\nconst AK = 1\nconst SHOTGUN = 2\nconst BARRETT = 3\n\n/** W745-761: core, petals and smoke scaled by weapon (the Barrett also vents sideways and lifts dust), with the shot's casing and hit on the wall. */\nexport const MUZZLE_FLASH: EffectDef = {\n id: 'muzzle_flash',\n pageId: 'muzzle',\n team: 'weapons',\n params: { id: 'weapon', options: ['glock', 'ak', 'r870', 'barrett'], default: 1 },\n budget: { particles: 60, lights: 1 },\n loop: 2.4,\n view: { eye: [1.8, 1.8, 5.2], target: [-0.8, 1.3, 1.4] },\n timeline: [\n repeat(\n param(3, 7, 1, 1),\n after(\n add(0.2, SHOT_TIME),\n call('muzzle', pick(WEAPONS, PARAM), TIP, FORWARD),\n when(ne(PARAM, SHOTGUN), [call('casing', PORT, ite(eq(PARAM, BARRETT), '50', ''))]),\n set('target', [add(-0.8, rnd(-0.4, 0.4)), add(1.4, rnd(-0.3, 0.3)), WALL_Z]),\n when(\n eq(PARAM, SHOTGUN),\n [repeat(8, call('impact', 'concrete', [add(-0.8, rnd(-0.5, 0.5)), add(1.4, rnd(-0.4, 0.4)), WALL_Z], NORMAL, 0.35))],\n [call('impact', 'concrete', variable('target'), NORMAL, ite(eq(PARAM, BARRETT), 2, 1))],\n ),\n when(and(eq(PARAM, AK), eq(mod(round(mul(SHOT_TIME, 10)), 3), 0)), [spawn('streak', { p: TIP, dir: FORWARD, cone: 0, sp: 90, life: 0.09, len: 0.025, c0: 0xffa040, a: 1 })]),\n ),\n ),\n when(eq(PARAM, SHOTGUN), [after(0.75, call('casing', PORT, 'shell'))]),\n ],\n}\n","import { rnd, scaled } from '../dsl'\nimport { after, behavior, burst, call, cue, debris, repeat, screen } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst FACING = [0, 0, 1] as const\n\n/** W846-855 (`vidro`): two cracks open in the shop window, then the whole pane comes down as 60 to 80 shards that stay on the pavement. */\nexport const SHOPFRONT_GLASS: EffectDef = {\n id: 'shopfront_glass',\n pageId: 'vidro',\n team: 'destruction',\n budget: { debris: 80, decals: 1 },\n loop: 5,\n view: { eye: [-2.4, 1.8, 1.2], target: [-5, 1.4, -4] },\n timeline: [\n after(0.3, call('impact', 'glass', [-5.4, 2.2, -4.45], FACING), behavior('cracks', 'crack', { x: 97, y: 59, big: false })),\n after(1, call('impact', 'glass', [-4.5, 1.6, -4.45], FACING), behavior('cracks', 'crack', { x: 177, y: 108, big: true })),\n after(\n 1.8,\n cue('glass_pane_gone'),\n screen({ add: { shake: 0.08 } }),\n repeat(\n scaled(75),\n debris({ p: [-5, 1.9, -4.42], box: [1.25, 0.85, 0.02], v: [rnd(-0.4, 0.4), rnd(-0.5, 0.8), rnd(0.6, 2)], sp: 0, size: [rnd(0.05, 0.18), 0.006, rnd(0.05, 0.18)], c: 0xa8c8d8, spin: 14, life: 30, bounce: 0.15 }),\n ),\n burst('add', 30, { p: [-5, 1.9, -4.3], box: [1.2, 0.8, 0.05], size: [0.02, 0.05], life: [0.2, 0.6], c0: 0xffffff, a: 0.9, fi: 0.3 }),\n burst('normal', 20, { p: [-5, 1.3, -4.2], box: [1.2, 0.5, 0.1], sp: [0.2, 0.6], drag: 2, life: [0.8, 1.4], size: [0.12, 0.2], grow: 3, c0: 0xbfd6e2, a: 0.2 }),\n ),\n ],\n}\n","import type { Vec3Tuple } from '../workshop/types'\n\n/** Vector helpers written as three.js r128 does them, so a recipe's numbers match the page's. */\nexport function normalized(vector: Vec3Tuple): Vec3Tuple {\n const length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]) || 1\n const inverse = 1 / length\n return [vector[0] * inverse, vector[1] * inverse, vector[2] * inverse]\n}\n\nexport function plus(vector: Vec3Tuple, x: number, y: number, z: number): Vec3Tuple {\n return [vector[0] + x, vector[1] + y, vector[2] + z]\n}\n\nexport function scaledBy(vector: Vec3Tuple, factor: number): Vec3Tuple {\n return [vector[0] * factor, vector[1] * factor, vector[2] * factor]\n}\n\nexport function plusScaled(vector: Vec3Tuple, direction: Vec3Tuple, factor: number): Vec3Tuple {\n return [vector[0] + direction[0] * factor, vector[1] + direction[1] * factor, vector[2] + direction[2] * factor]\n}\n\nexport function negated(vector: Vec3Tuple): Vec3Tuple {\n return [-vector[0], -vector[1], -vector[2]]\n}\n","import { add, and, div, DELTA, ge, INDEX, min, mul, not, rnd, scaled, sub, variable } from '../dsl'\nimport { after, behavior, burst, cue, debris, repeat, screen, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef, EffectStep } from '../types'\n\nconst FRAME_DUST = normalized([0, -0.3, 1])\nconst SPLINTER_DIRECTION = normalized([0, 0.3, 1])\nconst FALL_SECONDS = 0.4\n\n/** One blow on the door (`hit`, W779): the frame sheds dust and splinters; a heavy blow sheds twice as much. */\nconst blow = (heavy: boolean): EffectStep[] => [\n cue('door_shake', { strength: 0.25 }),\n burst('normal', heavy ? 24 : 12, { p: [2, 2.3, -4.38], box: [0.6, 0.05, 0.02], dir: FRAME_DUST, cone: 0.6, sp: [0.2, 0.8], drag: 1.5, life: [0.8, 1.4], size: [0.08, 0.16], grow: 3, c0: 0x7a7366, a: 0.45, g: 0.4 }),\n repeat(scaled(heavy ? 5 : 2), debris({ p: [add(2, rnd(-0.5, 0.5)), rnd(0.4, 2), -4.36], dir: SPLINTER_DIRECTION, cone: 0.6, sp: [1, 2.5], size: [0.015, 0.015, 0.1], c: 0x7a5530, life: 12 })),\n]\n\n/** W856-871 (`porta`): blows loosen dust from the frame, a plank cracks at 66 %, falls at 33 % and the door drops at the third stage. */\nexport const DOOR_STAGES: EffectDef = {\n id: 'door_stages',\n pageId: 'porta',\n team: 'destruction',\n budget: { particles: 120, debris: 6 },\n loop: 7.5,\n view: { eye: [4.2, 1.7, 1.4], target: [2, 1.1, -4] },\n setup: [behavior('walkers', 'place', { index: 0, x: 2, z: -5.4, facing: 0 })],\n timeline: [\n after(0.5, ...blow(false)),\n after(1.2, ...blow(false)),\n after(1.9, ...blow(true), cue('door_plank_crack', { stage: 1 })),\n after(2.7, ...blow(false)),\n after(\n 3.3,\n ...blow(true),\n cue('door_plank_fall', { stage: 2 }),\n repeat(3, debris({ p: [add(2, mul(sub(INDEX, 1), 0.4)), 1.1, -4.3], v: [rnd(-0.3, 0.3), 0.5, 1.2], sp: 0, size: [0.38, 0.68, 0.07], c: 0x5a3c22, spin: 4, life: 20, bounce: 0.15 })),\n ),\n after(4.4, set('fall', 0), set('falling', true), cue('door_fall', { stage: 3 })),\n after(4.6, behavior('walkers', 'walk', { index: 0, to: [2, 0, -2.2], speed: 0.9 })),\n ],\n tick: [\n when(variable('falling'), [\n set('fall', add(variable('fall'), DELTA)),\n set('progress', min(1, div(variable('fall'), FALL_SECONDS))),\n when(and(ge(variable('progress'), 1), not(variable('landed'))), [\n set('landed', true),\n screen({ add: { shake: 0.2 } }),\n burst('normal', 45, { p: [2, 0.15, -3.4], box: [0.7, 0.05, 1], dir: [0, 1, 0], cone: 1.4, sp: [0.6, 2], drag: 1.8, life: [1.5, 2.8], size: [0.25, 0.5], grow: 3, c0: 0x6a645a, a: 0.45 }),\n ]),\n ]),\n ],\n}\n","import { abs, add, and, cos, DELTA, gt, local, lt, mul, rand, rnd, scaled, sin, TIME, variable, vnorm } from '../dsl'\nimport { after, cue, debris, emit, repeat, screen, spawn, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst CENTRE = [-1.4, 3.35, -3.75] as const\n\n/** W872-886 (`desaba`): dust trickles from the awning for a second as a warning, then the slab drops in blocks and a cloud rolls along the street. */\nexport const BUILDING_COLLAPSE: EffectDef = {\n id: 'building_collapse',\n pageId: 'desaba',\n team: 'destruction',\n budget: { particles: 350, debris: 26 },\n loop: 8,\n view: { eye: [4, 2.4, 5], target: [-1.4, 1.4, -2.8] },\n setup: [cue('zombie_visible', { index: -1, visible: false })],\n timeline: [\n after(\n 1.5,\n cue('slab_gone'),\n screen({ add: { shake: 0.3 } }),\n repeat(6, debris({ p: CENTRE, box: [2, 0.05, 0.6], v: [rnd(-0.5, 0.5), rnd(-0.5, 0), rnd(0, 0.8)], sp: 0, size: [rnd(0.5, 1.1), 0.25, rnd(0.4, 0.8)], c: 0x6e6a63, spin: 3, life: 30, bounce: 0.1 })),\n repeat(scaled(20), debris({ p: CENTRE, box: [2.1, 0.1, 0.7], v: [rnd(-1, 1), rnd(-1, 1), rnd(0, 1.5)], sp: 0, size: [0.12, 0.1, 0.12], k: [0.5, 1.5], c: 0x5e5a54, life: 30 })),\n ),\n after(\n 2.15,\n screen({ add: { shake: 0.45 } }),\n repeat(\n scaled(70),\n spawn('normal', local('angle', rnd(-0.4, 3.5), {\n p: [add(-1.4, rnd(-2, 2)), 0.2, add(-3.4, rnd(-0.5, 0.5))],\n dir: vnorm([mul(cos(variable('angle')), 0.6), 0.25, abs(sin(variable('angle')))]),\n cone: 0.5, sp: [1, 3.2], drag: 1.1, life: [3, 6], size: [0.7, 1.2], grow: 3, c0: 0x7a7268, c1: 0x4a4640, a: 0.5, fi: 0.12,\n })),\n ),\n ),\n ],\n tick: [\n when(and(gt(TIME, 0.3), lt(TIME, 1.5)), [\n emit('trk', 'normal', 30, { p: [add(-1.4, rnd(-2, 2)), 3.2, -3.05], dir: [0, -1, 0], cone: 0.1, sp: [0.2, 0.5], life: [1, 1.6], size: [0.04, 0.08], grow: 2.5, c0: 0x8a8478, a: 0.5, g: 1 }),\n when(lt(rand(), mul(DELTA, 6)), [debris({ p: [add(-1.4, rnd(-2, 2)), 3.2, -3.05], sp: 0.2, size: [0.04, 0.04, 0.04], c: 0x6e6a63, life: 10 })]),\n ]),\n ],\n}\n","import { add, cos, INDEX, local, mul, rnd, scaled, sin, variable, vnorm } from '../dsl'\nimport { after, behavior, burst, call, cue, debris, repeat, screen, spawn } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\n\nconst FIRING_FROM = [0.6, 1.3, 7] as const\nconst FIRING_DIRECTION = normalized([-2.8, -0.4, -4.4])\nconst WALL_CENTRE = [-2.2, 1, 2.6] as const\n\n/** W1039-1053 (`parede`): a burst of AK fire leaves holes that are stuck to the blocks, then the wall gives way and the holes fall with them. */\nexport const BLOCK_WALL: EffectDef = {\n id: 'block_wall',\n pageId: 'parede',\n team: 'destruction',\n budget: { particles: 300, debris: 16 },\n loop: 8,\n view: { eye: [0.4, 1.7, 6.6], target: [-2.2, 0.9, 2.4] },\n props: ['blocks'],\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('work_light', { intensity: 2.2 })],\n timeline: [\n repeat(\n 14,\n after(\n add(0.3, mul(INDEX, 0.11)),\n call('muzzle', 'ak', FIRING_FROM, FIRING_DIRECTION),\n behavior('blocks', 'hit', { x: rnd(-1.3, 1.3), y: rnd(0.4, 1.9), scale: 1 }),\n ),\n ),\n after(2.2, behavior('blocks', 'hit', { x: -0.2, y: 1.1, scale: 2.2 })),\n after(\n 3,\n screen({ add: { shake: 0.4 } }),\n behavior('blocks', 'collapse', { x: -0.2, y: 1.1 }),\n burst('normal', 30, { p: WALL_CENTRE, box: [1.4, 0.8, 0.2], sp: [0.3, 1.2], drag: 1.5, life: [1.5, 2.6], size: [0.4, 0.7], grow: 3, c0: 0x8a857a, c1: 0x4a4640, a: 0.45 }),\n repeat(scaled(16), debris({ p: WALL_CENTRE, box: [1.3, 0.8, 0.1], sp: [1, 3], size: [0.08, 0.07, 0.08], k: [0.5, 1.5], c: 0x6e6a63, life: 20 })),\n ),\n after(\n 3.6,\n screen({ add: { shake: 0.25 } }),\n repeat(\n scaled(60),\n spawn('normal', local('angle', rnd(0, 6.283), {\n p: [add(-2.2, rnd(-1.4, 1.4)), 0.2, add(2.4, rnd(-0.6, 0.4))],\n dir: vnorm([cos(variable('angle')), 0.3, sin(variable('angle'))]),\n cone: 0.4, sp: [0.8, 2.4], drag: 1.3, life: [2.5, 4.5], size: [0.6, 1], grow: 3, c0: 0x7a7268, c1: 0x4a4640, a: 0.45, fi: 0.12,\n })),\n ),\n ),\n ],\n}\n","import type { Vec3Tuple } from '../../workshop/types'\n\n/** The free spot of the Workshop's set where the wall, door, railing, fence, table and cylinders are put one at a time (W937, `SPOT`). */\nexport const SPOT: Vec3Tuple = [-2.2, 0, 2.6]\nexport const UP: Vec3Tuple = [0, 1, 0]\n","import { add, and, DELTA, div, floor, ge, INDEX, ite, min, mod, mul, not, pick, scaled, variable } from '../dsl'\nimport { after, behavior, burst, call, cue, debris, repeat, screen, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\nimport { SPOT, UP } from './spot'\n\nconst HITS = [[0.4, 1.4], [0.75, 1.0], [0.3, 0.7], [0.6, 1.7], [0.5, 1.2]]\nconst HIT_X = HITS.map(([x]) => x)\nconst HIT_Y = HITS.map(([, y]) => y)\nconst SPARK_DIRECTION = normalized([0, 0.3, 1])\nconst CHIP_DIRECTION = normalized([0, 0.2, 1])\nconst HINGE_DIRECTION = normalized([1, 0.3, 1])\nconst SCRAPE_DIRECTION = normalized([0, 0.4, 1])\nconst FALL_SECONDS = 0.45\nconst SCRAPES = 5\n\n/** W960-985 (`portametal`): each blow dents the plate where it lands and throws sparks, paint chips and rust; the top hinge bursts and the door scrapes down. */\nexport const METAL_DOOR_EFFECT: EffectDef = {\n id: 'metal_door',\n pageId: 'portametal',\n team: 'destruction',\n budget: { particles: 160, debris: 20 },\n loop: 7.5,\n view: { eye: [0.6, 1.6, 6.2], target: [-2.2, 1.1, 2.6] },\n props: ['plate'],\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n cue('work_light', { intensity: 2.2 }),\n behavior('walkers', 'place', { index: 3, x: SPOT[0] + 0.1, z: SPOT[2] - 0.7, facing: 0 }),\n ],\n timeline: [\n repeat(\n HITS.length,\n after(\n add(0.5, mul(INDEX, 0.75)),\n cue('zombie_swing', { index: 3, side: mod(INDEX, 2) }),\n after(\n add(0.5, mul(INDEX, 0.75), 0.15),\n behavior('plate', 'dent', { x: pick(HIT_X, INDEX), y: pick(HIT_Y, INDEX), radius: 0.42, depth: add(0.09, mul(INDEX, 0.025)) }),\n set('spot', [add(SPOT[0] - 0.56, pick(HIT_X, INDEX)), pick(HIT_Y, INDEX), SPOT[2] + 0.06]),\n call('spark_at', variable('spot'), SPARK_DIRECTION, 8),\n repeat(scaled(5), debris({ p: variable('spot'), dir: CHIP_DIRECTION, cone: 0.9, sp: [0.8, 2.2], size: [0.035, 0.004, 0.03], k: [0.6, 1.4], c: ite(mod(INDEX, 2), 0x51625a, 0x8a8f86), life: 20, spin: 16 })),\n call('rust_at', variable('spot'), 6),\n cue('door_dent', { level: min(3, add(1, floor(div(INDEX, 1.7)))) }),\n ),\n ),\n ),\n after(4.4, call('spark_at', [SPOT[0] - 0.6, 2.05, SPOT[2] + 0.05], HINGE_DIRECTION, 30, 1.2), screen({ add: { shake: 0.15 } }), set('fall', 0), set('falling', true), cue('door_hinge_burst')),\n after(5.2, behavior('walkers', 'walk', { index: 3, to: [SPOT[0], 0, SPOT[2] + 2.4], speed: 0.8 })),\n ],\n tick: [\n when(variable('falling'), [\n set('fall', add(variable('fall'), DELTA)),\n set('progress', min(1, div(variable('fall'), FALL_SECONDS))),\n when(and(ge(variable('progress'), 1), not(variable('landed'))), [\n set('landed', true),\n screen({ add: { shake: 0.3 } }),\n repeat(SCRAPES, call('spark_at', [add(SPOT[0] - 0.5, mul(INDEX, 0.27)), 0.03, SPOT[2] + 2.1], SCRAPE_DIRECTION, 8, 1)),\n burst('normal', 40, { p: [SPOT[0], 0.15, SPOT[2] + 1.2], box: [0.6, 0.05, 1], dir: UP, cone: 1.4, sp: [0.6, 2], drag: 1.8, life: [1.4, 2.4], size: [0.25, 0.5], grow: 3, c0: 0x6a645a, a: 0.45 }),\n ]),\n ]),\n ],\n}\n","import { add, and, DELTA, div, ge, gt, INDEX, lt, min, mul, not, pick, rnd, sub, TIME, variable } from '../dsl'\nimport { after, behavior, burst, call, cue, emit, repeat, screen, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\nimport { SPOT, UP } from './spot'\n\n/** Where the four pushing bodies stand, relative to the railing (W987). */\nconst PUSHERS = [[-0.6, 0.45], [0.1, 0.5], [0.6, 0.42], [-0.1, 1]]\nconst BEND_LIMIT = 0.42\nconst BEND_STEP = 0.004\nconst FALL_SECONDS = 0.55\nconst WELD = normalized([0, 0.3, 1])\n\n/** W986-1003 (`grade`): the horde pushes, the bars bend and rust falls in a thread; the weld bursts in sparks twice and the railing topples. */\nexport const IRON_RAILING: EffectDef = {\n id: 'iron_railing',\n pageId: 'grade',\n team: 'destruction',\n budget: { particles: 200 },\n loop: 7.5,\n view: { eye: [1.4, 1.8, 6.4], target: [-2.2, 0.7, 2.4] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n cue('work_light', { intensity: 2.2 }),\n set('bend', 0),\n ...PUSHERS.map(([x, dz], index) => behavior('walkers', 'place', { index, x: SPOT[0] + x!, z: SPOT[2] - dz!, facing: 0 })),\n ],\n timeline: [\n after(1.6, call('spark_at', [SPOT[0], 0.75, SPOT[2] + 0.05], WELD, 20, 1), screen({ add: { shake: 0.08 } }), cue('weld_burst')),\n after(3.2, call('spark_at', [SPOT[0] + 0.02, 1.2, SPOT[2] + 0.1], WELD, 20, 1), screen({ add: { shake: 0.1 } })),\n after(\n 4.3,\n set('fall', 0),\n set('falling', true),\n call('spark_at', [SPOT[0] - 1.5, 0.25, SPOT[2]], normalized([-0.3, 0.5, 1]), 14, 1),\n call('spark_at', [SPOT[0] + 1.5, 0.25, SPOT[2]], normalized([0.3, 0.5, 1]), 14, 1),\n cue('railing_gave_way'),\n ),\n after(\n 4.9,\n repeat(PUSHERS.length, behavior('walkers', 'walk', { index: INDEX, to: [add(SPOT[0], pick(PUSHERS.map(([x]) => x), INDEX)), 0, add(SPOT[2], 2.6, mul(INDEX, 0.3))], speed: 0.7 })),\n ),\n ],\n tick: [\n when(lt(TIME, 4.3), [\n set('target', min(BEND_LIMIT, mul(TIME, 0.1))),\n when(gt(sub(variable('target'), variable('bend')), BEND_STEP), [set('bend', variable('target')), cue('railing_bend', { amount: variable('bend') })]),\n emit('rust', 'normal', 10, { p: [add(SPOT[0], rnd(-0.6, 0.6)), rnd(0.3, 1.2), add(SPOT[2], mul(variable('bend'), 0.8))], sp: [0, 0.2], life: [0.8, 1.2], size: [0.015, 0.03], c0: 0x7a4a2a, a: 0.9, g: 6, fi: 0, gnd: 1 }),\n ]),\n when(variable('falling'), [\n set('fall', add(variable('fall'), DELTA)),\n set('progress', min(1, div(variable('fall'), FALL_SECONDS))),\n when(and(ge(variable('progress'), 1), not(variable('landed'))), [\n set('landed', true),\n screen({ add: { shake: 0.25 } }),\n repeat(4, call('spark_at', [add(SPOT[0] - 1.2, mul(INDEX, 0.8)), 0.04, SPOT[2] + 1.2], normalized([0, 0.5, 1]), 6, 1)),\n burst('normal', 30, { p: [SPOT[0], 0.12, SPOT[2] + 0.8], box: [1.4, 0.05, 0.5], dir: UP, cone: 1.4, sp: [0.5, 1.6], drag: 1.8, life: [1.2, 2.2], size: [0.2, 0.4], grow: 3, c0: 0x6a645a, a: 0.4 }),\n ]),\n ]),\n ],\n}\n","import { add, and, DELTA, div, ge, INDEX, min, mul, not, pick, rnd, scaled, sub, variable, vadd, mod } from '../dsl'\nimport { after, behavior, burst, cue, debris, repeat, screen, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\nimport { SPOT, UP } from './spot'\n\n/** The order the planks break in and where each stands along the fence (W1005-1006). */\nconst ORDER = [3, 4, 8, 5, 9, 2, 7]\nconst PLANK_X = Array.from({ length: 12 }, (_, index) => -1.43 + index * 0.26)\nconst BODIES = [[-0.8, 0.6], [0.5, 0.7], [0, 1.2]]\nconst SPLINTER_DIRECTION = normalized([0, 0.4, 1])\nconst FALL_SECONDS = 0.5\nconst PLANK_HEIGHT = 1.3\n\n/** W1004-1020 (`cerca`): the planks snap one by one at a random height, the stump stays on the rail and the rest flies; the section finally tips over. */\nexport const WOODEN_FENCE: EffectDef = {\n id: 'wooden_fence',\n pageId: 'cerca',\n team: 'destruction',\n budget: { particles: 150, debris: 12 },\n loop: 7.5,\n view: { eye: [1, 1.6, 6], target: [-2.2, 0.7, 2.4] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n cue('work_light', { intensity: 2.2 }),\n ...BODIES.map(([x, dz], index) => behavior('walkers', 'place', { index, x: SPOT[0] + x!, z: SPOT[2] - dz!, facing: 0 })),\n ],\n timeline: [\n repeat(\n ORDER.length,\n after(\n add(0.4, mul(INDEX, 0.5)),\n set('cut', rnd(0.32, 0.6)),\n set('top', sub(PLANK_HEIGHT, variable('cut'))),\n set('break', [add(SPOT[0], pick(PLANK_X, pick(ORDER, INDEX))), variable('cut'), SPOT[2]]),\n cue('zombie_swing', { index: mod(INDEX, 3), side: mod(INDEX, 2) }),\n cue('plank_snap', { plank: pick(ORDER, INDEX), cut: variable('cut') }),\n debris({ p: vadd(variable('break'), [0, div(variable('top'), 2), 0]), v: [rnd(-0.8, 0.8), rnd(1.5, 3), rnd(1.5, 3)], sp: 0, size: [0.17, variable('top'), 0.035], c: 0x8a6a44, spin: 7, life: 20, bounce: 0.2 }),\n repeat(scaled(6), debris({ p: variable('break'), dir: SPLINTER_DIRECTION, cone: 0.9, sp: [1, 3], size: [0.012, 0.012, 0.1], k: [0.6, 1.4], c: 0xb08a5a, life: 20 })),\n burst('normal', 8, { p: variable('break'), dir: [0, 0, 1], cone: 0.8, sp: [0.4, 1.4], drag: 2, life: [0.8, 1.4], size: [0.1, 0.18], grow: 3, c0: 0x7a6048, a: 0.4 }),\n ),\n ),\n after(\n 4.2,\n set('fall', 0),\n set('falling', true),\n repeat(scaled(10), debris({ p: [add(SPOT[0], rnd(-1.4, 1.4)), 1, SPOT[2]], dir: SPLINTER_DIRECTION, cone: 0.9, sp: [1, 3], size: [0.012, 0.012, 0.1], c: 0xb08a5a, life: 20 })),\n cue('fence_rail_cracked'),\n ),\n after(4.8, repeat(BODIES.length, behavior('walkers', 'walk', { index: INDEX, to: [add(SPOT[0], pick(BODIES.map(([x]) => x), INDEX)), 0, SPOT[2] + 2.5], speed: 0.75 }))),\n ],\n tick: [\n when(variable('falling'), [\n set('fall', add(variable('fall'), DELTA)),\n set('progress', min(1, div(variable('fall'), FALL_SECONDS))),\n when(and(ge(variable('progress'), 1), not(variable('landed'))), [\n set('landed', true),\n screen({ add: { shake: 0.2 } }),\n burst('normal', 35, { p: [SPOT[0], 0.12, SPOT[2] + 0.8], box: [1.5, 0.05, 0.5], dir: UP, cone: 1.4, sp: [0.5, 1.6], drag: 1.8, life: [1.2, 2.2], size: [0.25, 0.45], grow: 3, c0: 0x6a5a48, a: 0.4 }),\n ]),\n ]),\n ],\n}\n","import { add, INDEX, mul, rnd, variable, vadd } from '../dsl'\nimport { after, call, cue, debris, burst, repeat, screen, set } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\nimport { SPOT, UP } from './spot'\n\nconst at = (x: number, y: number, z: number): readonly [number, number, number] => [SPOT[0] + x, SPOT[1] + y, SPOT[2] + z]\n/**\n * Where each part of the table is in the world. The page asks its scene graph for it (`tbW`), and the capture does not render, so the table's tilt never\n * reaches the world matrix it reads: the parts are always where the table stands level (W1009, recorded at 2.2 s, 3.8 s and 5.3 s).\n */\nconst FRONT_LEG = at(-0.52, 0.2, 0.32)\nconst TOP_CORNER = at(0.3, 0.78, 0.2)\nconst TOP_PIECE = at(-0.3, 0.78, -0.2)\nconst FAR_CORNER = at(0.3, 0.78, -0.2)\nconst HOLE_OBJECT_ID_DRAWS = 12\nconst HOLES = 9\nconst GLOCK_FROM = [-0.4, 1, 6] as const\nconst SHOTGUN_FROM = [0.2, 1.1, 4.6] as const\nconst toward = (target: readonly [number, number, number], from: readonly [number, number, number]) => normalized([target[0] - from[0], target[1] - from[1], target[2] - from[2]])\n\n/** W1008-1020 (`pontos`): a 9 mm in the leg, a machete on a corner, a bat on the top and a 12-gauge up close: each breaks only the part it hit. */\nexport const HIT_POINT_BREAKAGE: EffectDef = {\n id: 'hit_point_breakage',\n pageId: 'pontos',\n team: 'destruction',\n budget: { particles: 120, debris: 20 },\n loop: 7.5,\n view: { eye: [0.2, 1.6, 5.4], target: [-2.2, 0.6, 2.6] },\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('work_light', { intensity: 2.2 })],\n timeline: [\n after(\n 0.6,\n call('muzzle', 'glock', GLOCK_FROM, toward(FRONT_LEG, GLOCK_FROM)),\n call('chips', FRONT_LEG, normalized([0, 0.2, 1]), 6),\n cue('table_part_detached', { part: 'front_leg' }),\n debris({ p: FRONT_LEG, v: [0.4, 0.6, 1.4], sp: 0, size: [0.07, 0.4, 0.07], c: 0x7a5530, spin: 6, life: 20, bounce: 0.25 }),\n cue('table_tilt'),\n ),\n after(\n 2.2,\n repeat(8, call('chips', vadd(TOP_CORNER, [add(-0.3, mul(INDEX, 0.08)), 0.03, 0]), normalized([0, 0.6, 1]), 1, 0.4)),\n cue('table_part_detached', { part: 'top_corner' }),\n debris({ p: TOP_CORNER, v: [1.2, 1.5, 1], sp: 0, size: [0.6, 0.06, 0.4], c: 0x7a5530, spin: 6, life: 20, bounce: 0.25 }),\n ),\n after(\n 3.8,\n screen({ add: { shake: 0.12 } }),\n call('chips', TOP_PIECE, UP, 10, 1.3),\n cue('table_part_gone', { part: 'top_piece' }),\n repeat(4, debris({ p: [add(TOP_PIECE[0], rnd(-0.2, 0.2)), TOP_PIECE[1], add(TOP_PIECE[2], rnd(-0.1, 0.1))], dir: UP, cone: 1.2, sp: [1, 2.5], size: [rnd(0.15, 0.3), 0.06, rnd(0.12, 0.25)], c: 0x6b4a2a, spin: 8, life: 20, bounce: 0.2 })),\n burst('normal', 20, { p: TOP_PIECE, r: 0.2, sp: [0.3, 1], drag: 2, life: [1, 1.8], size: [0.2, 0.35], grow: 3, c0: 0x7a6048, a: 0.4 }),\n ),\n after(\n 5.3,\n call('muzzle', 'r870', SHOTGUN_FROM, toward(FAR_CORNER, SHOTGUN_FROM)),\n repeat(HOLES, set('holeX', rnd(-0.15, 0.15)), set('holeZ', rnd(-0.1, 0.1)), cue('table_hole', { x: variable('holeX'), z: variable('holeZ') }, HOLE_OBJECT_ID_DRAWS)),\n call('chips', FAR_CORNER, UP, 10, 1),\n ),\n ],\n}\n","import { abs, clamp, DELTA, div, eq, gt, lt, min, mul, not, PARAM, query, sub, TIME, variable, vx, vz } from '../dsl'\nimport { after, behavior, call, cue, emit, set, screen, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\nimport { SPOT, UP } from './spot'\n\nconst OXYGEN = 1\nconst PUNCTURE_AT = 0.6\nconst JET_SECONDS = 3.4\nconst CLOUD_UNTIL = 7\nconst SHOT_FROM = [0.4, 1.2, 6.4] as const\nconst SHOT_DIRECTION = normalized([-0.5, -0.15, -1])\nconst SCRAPE_DIRECTION = normalized([1, 0.4, 0])\nconst jetStrength = variable('jet')\nconst isOxygen = eq(PARAM, OXYGEN)\n\n/** W1021-1038 (`pressao`): a shot into an extinguisher (a white cloud and a spin) or into an oxygen bottle (the valve breaks and it flies off as a rocket). */\nexport const PRESSURE_CYLINDERS: EffectDef = {\n id: 'pressure_cylinders',\n pageId: 'pressao',\n team: 'destruction',\n params: { id: 'cylinder', options: ['extinguisher', 'oxygen'], default: 0 },\n budget: { particles: 250 },\n loop: 7,\n view: { eye: [1.6, 1.5, 6.4], target: [-1.6, 0.4, 2.4] },\n props: ['cylinder'],\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('work_light', { intensity: 2.2 }), behavior('cylinder', 'choose', { oxygen: isOxygen }), cue('cylinder_visible', { oxygen: isOxygen })],\n timeline: [\n after(\n PUNCTURE_AT,\n call('muzzle', 'glock', SHOT_FROM, SHOT_DIRECTION),\n screen({ add: { shake: 0.1 } }),\n behavior('cylinder', 'puncture'),\n when(isOxygen, [call('spark_at', [SPOT[0], 1.3, SPOT[2]], UP, 20, 1.2)]),\n ),\n ],\n tick: [\n when(query('cylinder', 'live'), [\n set('jet', clamp(sub(1, div(sub(TIME, PUNCTURE_AT), JET_SECONDS)), 0, 1)),\n behavior('cylinder', 'step', { dt: DELTA, t: TIME }),\n when(not(isOxygen), [\n when(gt(jetStrength, 0), [\n emit('jet', 'normal', 60, { p: query('cylinder', 'tip'), dir: query('cylinder', 'direction'), cone: 0.3, sp: [3, 6], drag: 2.5, life: [2, 3.5], size: [0.15, 0.3], grow: 6, c0: 0xeeeeea, c1: 0xbfc3c8, a: 0.45, g: -0.05, fi: 0.05 }),\n ]),\n when(lt(TIME, CLOUD_UNTIL), [\n emit('cloud', 'normal', 4, { p: [SPOT[0], 0.6, SPOT[2]], r: 2.5, flat: true, sp: [0.05, 0.2], life: [3, 5], size: [1.5, 2.5], grow: 1.3, c0: 0xe2e2de, a: mul(0.18, min(1, sub(TIME, PUNCTURE_AT))), fi: 0.3 }),\n ]),\n ], [\n when(gt(jetStrength, 0), [\n emit('jet', 'normal', 50, { p: query('cylinder', 'back'), dir: [1, 0, 0], cone: 0.25, sp: [2, 4], drag: 3, life: [0.5, 0.9], size: [0.1, 0.2], grow: 4, c0: 0xdde6ee, a: 0.2 }),\n ]),\n when(gt(abs(query('cylinder', 'speed_x')), 0.5), [\n emit('scr', 'streak', 120, { p: [vx(query('cylinder', 'position')), 0.03, vz(query('cylinder', 'position'))], dir: SCRAPE_DIRECTION, cone: 0.6, sp: [2, 6], v: [mul(query('cylinder', 'speed_x'), 0.5), 0, 0], life: [0.2, 0.45], len: 0.02, c0: 0xfff0c0, c1: 0xff5010, g: 9.8, gnd: 2 }),\n ]),\n ]),\n ]),\n ],\n}\n","import { add, concat, eq, INDEX, pick, TIME, vadd } from '../dsl'\nimport { call, cue, fireLight, repeat, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\n\n/** The two burning windows of the shop front (W73). */\nconst WINDOWS = [[4.6, 5, -4.48], [-1.6, 5, -4.48]]\n\n/** W1054-1068 (`incendio`): fire out of the top of each window, licking up the facade, embers and smoke carried by the wind, and a light that paints the street. */\nexport const BUILDING_FIRE: EffectDef = {\n id: 'building_fire',\n pageId: 'incendio',\n team: 'world',\n budget: { particles: 600, lights: 2 },\n loop: 0,\n view: { eye: [3, 2.4, 6.5], target: [1.5, 4, -4] },\n setup: [cue('zombie_visible', { index: -1, visible: false })],\n timeline: [],\n tick: [\n repeat(\n WINDOWS.length,\n call('fire_emit', concat('w', INDEX), vadd(pick(WINDOWS, INDEX), [0, 0.55, 0.12]), 0.55, 1.1, { dir: normalized([0, 1, 0.35]), wind: [0.9, 0, 0], smoke: 22, smokeAlpha: 0.5 }),\n when(eq(INDEX, 0), [fireLight(0, vadd(pick(WINDOWS, INDEX), [0, 0, 1.4]), 3, add(TIME, INDEX))], [fireLight(1, vadd(pick(WINDOWS, INDEX), [0, 0, 1.4]), 3, add(TIME, INDEX))]),\n ),\n ],\n}\n","import { add, DELTA, lt, mul, rand, rnd, sub, TIME, variable, vx, vz } from '../dsl'\nimport { cue, decal, emit, fireLight, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\n\nconst YAW = -Math.PI / 2\nconst COS = Math.cos(YAW)\nconst SIN = Math.sin(YAW)\nconst START_X = 10\nconst SPEED = 2.4\n/** `carW(0.6, 0.06, 2.15)` for a car turned by `YAW`, as the matrix multiplies it (the y component is replaced by 0.04). */\nconst contactX = (carX: number | object) => add(COS * 0.6, 0 * 0.06, SIN * 2.15, carX)\nconst contactZ = add(-SIN * 0.6, 0 * 0.06, COS * 2.15, 1.5)\nconst BACKWARD = normalized([1, 0.35, 0])\n\n/** W1090-1100 (`faisca`): a bumper dragging on the asphalt throws a river of sparks that bounce and go from white to orange, with a short light and dark scratches. */\nexport const SCRAPING_SPARKS: EffectDef = {\n id: 'scraping_sparks',\n pageId: 'faisca',\n team: 'vehicles',\n budget: { particles: 200, lights: 1 },\n loop: 4.4,\n view: { eye: [2, 1.6, 5.5], target: [3, 0.3, 1.5] },\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('car_pose', { x: START_X, z: 1.5, yaw: YAW })],\n timeline: [],\n tick: [\n set('carX', sub(START_X, mul(TIME, SPEED))),\n set('contact', [contactX(variable('carX')), 0.04, contactZ]),\n cue('car_pose', { x: variable('carX'), z: 1.5, yaw: YAW }),\n emit('sp', 'streak', 200, { p: variable('contact'), dir: BACKWARD, cone: 0.55, sp: [3, 8], v: [-2.4, 0, 0], life: [0.2, 0.5], len: 0.02, c0: 0xfff0c0, c1: 0xff5010, g: 9.8, gnd: 2 }),\n emit('gl', 'add', 40, { p: variable('contact'), r: 0.05, size: [0.08, 0.16], life: 0.05, c0: 0xffd8a0, fi: 0 }),\n when(lt(rand(), mul(DELTA, 14)), [decal(vx(variable('contact')), 0, add(vz(variable('contact')), rnd(-0.05, 0.05)), 0.12, 0x0a0a0a, { grow: 0, life: 60, ar: 0.25 })]),\n fireLight(0, [vx(variable('contact')), 0.34, vz(variable('contact'))], 1.6, mul(TIME, 3)),\n ],\n}\n","import { localToWorld } from '../props'\nimport type { Vec3Tuple } from '../../workshop/types'\nimport { normalized } from '../vector-math'\n\n/** The car of the Workshop's set as the page leaves it between effects (`CAR0`, W104): at (5.6, 0, 0.8), turned -0.4 rad. */\nexport const CAR_ORIGIN: Vec3Tuple = [5.6, 0, 0.8]\nexport const CAR_ROTATION: Vec3Tuple = [0, -0.4, 0]\n/** A point of the car's own space in the world (`carW`). */\nexport const carPoint = (x: number, y: number, z: number): Vec3Tuple => localToWorld(CAR_ORIGIN, CAR_ROTATION, [x, y, z])\nexport const carDirection = (from: Vec3Tuple, to: Vec3Tuple): Vec3Tuple => normalized([to[0] - from[0], to[1] - from[1], to[2] - from[2]])\n","import { DELTA, eq, gt, ite, lt, mul, PARAM, rand, TIME } from '../dsl'\nimport { burst, call, emit, fireLight, fireLightOff, when } from '../steps'\nimport type { EffectDef } from '../types'\nimport { carDirection, carPoint } from './car'\n\nconst HOOD = carPoint(0, 1.02, 1.4)\nconst EXHAUST = carPoint(0.5, 0.3, -2.2)\nconst EXHAUST_DIRECTION = carDirection(EXHAUST, carPoint(0.5, 0.3, -3))\nconst SPARK_FROM = carPoint(0, 0.7, 2.1)\nconst SPARK_DIRECTION = carDirection(SPARK_FROM, carPoint(0, 0.9, 3))\nconst WORN = 1\nconst BAD = 2\nconst CRITICAL = 3\n\n/** W1101-1112 (`motor`): exhaust only at 100, a thread of white steam at 60, steady grey smoke and the odd spark at 30, thick black smoke with fire at 10. */\nexport const ENGINE_SMOKE: EffectDef = {\n id: 'engine_smoke',\n pageId: 'motor',\n team: 'vehicles',\n params: { id: 'condition', options: ['100', '60', '30', '10'], default: 2 },\n budget: { particles: 120, lights: 1 },\n loop: 0,\n view: { eye: [9.5, 2.6, 5.2], target: [5.2, 0.9, 1.5] },\n timeline: [],\n tick: [\n emit('ex', 'normal', ite(eq(PARAM, CRITICAL), 6, 3), { p: EXHAUST, dir: EXHAUST_DIRECTION, cone: 0.3, sp: [0.6, 1.2], drag: 1.2, life: [1, 1.8], size: [0.06, 0.12], grow: 5, c0: ite(gt(PARAM, 1), 0x55524e, 0x9a9a96), a: 0.18, g: -0.2 }),\n when(eq(PARAM, WORN), [\n emit('st', 'normal', 14, { p: HOOD, box: [0.4, 0, 0.3], dir: [0, 1, 0], cone: 0.35, sp: [0.5, 1], drag: 0.8, life: [1.4, 2.4], size: [0.15, 0.25], grow: 4, c0: 0xc8ccd0, a: 0.22, g: -0.3 }),\n ]),\n when(eq(PARAM, BAD), [\n emit('st', 'normal', 22, { p: HOOD, box: [0.4, 0, 0.3], dir: [0, 1, 0], cone: 0.35, sp: [0.6, 1.2], drag: 0.6, life: [2, 3], size: [0.2, 0.35], grow: 4, c0: 0x6a6a68, c1: 0x3a3a3c, a: 0.4, g: -0.35 }),\n when(lt(rand(), mul(DELTA, 0.8)), [burst('streak', 8, { p: SPARK_FROM, dir: SPARK_DIRECTION, cone: 0.6, sp: [2, 4], life: 0.3, len: 0.02, c0: 0xffd080, c1: 0xff4000, g: 9.8 })]),\n ]),\n when(eq(PARAM, CRITICAL), [\n emit('st', 'normal', 34, { p: HOOD, box: [0.5, 0, 0.4], dir: [0, 1, 0], cone: 0.3, sp: [0.8, 1.6], drag: 0.4, life: [2.5, 3.8], size: [0.3, 0.5], grow: 4.5, c0: 0x1c1b1b, c1: 0x0e0e10, a: 0.6, g: -0.4 }),\n call('fire_emit', 'hood', carPoint(0, 0.8, 2.0), 0.3, 0.45, { noSmoke: true }),\n fireLight(0, carPoint(0, 1.2, 2.6), 2.2, TIME),\n ], [fireLightOff(0)]),\n ],\n}\n","import { rnd, scaled, query, vadd } from '../dsl'\nimport { behavior, call, cue, debris, repeat } from '../steps'\nimport type { EffectStep } from '../types'\nimport { carPoint } from './car'\n\nconst UP = [0, 1, 0] as const\n\n/** The velocity the page gives a door: the car's own space pushed outward by `s * 4`, minus the centre, with the height set to 3 (W1124). */\nconst doorVelocity = (side: number): readonly [number, number, number] => {\n const out = carPoint(side * 4, 3, 0.3)\n const centre = carPoint(0, 0, 0.3)\n return [out[0] - centre[0], 3, out[2] - centre[2]]\n}\n\n/** `vehicleBoom` (W1118-1128): the blast at the car, the car jumping, glass in the air, then the bonnet, both doors and a wheel flying off. */\nexport const VEHICLE_BOOM: readonly EffectStep[] = [\n call('explode', vadd(query('car', 'position'), [0, 0.6, 0]), 1.8, 0x2a1a14),\n cue('car_burnt'),\n behavior('car', 'launch', { rise: 4.5, spin: 0.9 }),\n repeat(scaled(30), debris({ p: vadd(query('car', 'position'), [0, 1.3, 0]), dir: UP, cone: 1.3, sp: [2, 6], size: [0.06, 0.006, 0.06], c: 0xa8c8d8, life: 20 })),\n debris({ p: carPoint(0, 1, 1.4), v: [rnd(-1, 1), 9, rnd(-1, 1)], sp: 0, size: [1.6, 0.06, 1.2], c: 0x3a1d18, spin: 6, life: 20, bounce: 0.2 }),\n ...[-1, 1].map((side) => debris({ p: carPoint(side * 0.95, 0.7, 0.3), v: doorVelocity(side), sp: 0, size: [0.06, 0.7, 1.1], c: 0x3a1d18, spin: 5, life: 20, bounce: 0.2 })),\n debris({ p: carPoint(0.95, 0.38, 1.35), v: [3, 4, 2], sp: 0, size: [0.3, 0.76, 0.76], c: 0x111111, spin: 8, life: 20, bounce: 0.4 }),\n]\n","import { add, and, clamp, DELTA, div, ge, gt, lt, mul, query, sub, TIME, variable, vadd, vlerp } from '../dsl'\nimport { after, behavior, burst, call, cue, decal, emit, fireLight, set, when } from '../steps'\nimport type { EffectDef } from '../types'\nimport { VEHICLE_BOOM } from './boom'\nimport { carDirection, carPoint } from './car'\n\nconst TANK = carPoint(-0.6, 0.25, -1.3)\nconst TANK_FLOOR = [TANK[0], 0, TANK[2]] as const\nconst POOL = [TANK_FLOOR[0] - 1.2, 0, TANK_FLOOR[2] - 0.6] as const\nconst BOOM_AT = 7.2\nconst HOLE = carPoint(-0.96, 0.6, -1.2)\n\n/** W1113-1132 (`vazamento`): petrol drips into a pool, a shot into the metal throws a spark, the fire runs along the pool to the tank and the car blows up. */\nexport const FUEL_LEAK: EffectDef = {\n id: 'fuel_leak',\n pageId: 'vazamento',\n team: 'vehicles',\n budget: { particles: 400, lights: 1 },\n loop: 11,\n view: { eye: [10, 2.4, 4.2], target: [5.6, 0.4, 0] },\n setup: [cue('zombie_visible', { index: -1, visible: false })],\n timeline: [\n decal(POOL[0], 0, POOL[2], 2.2, 0x1f2230, { grow: 3, life: 60, ar: 0.6, fluid: 'oil' }),\n after(\n 3.4,\n call('impact', 'metal', HOLE, carDirection(HOLE, carPoint(-2, 0.6, -1.2)), 1.5),\n burst('streak', 14, { p: [POOL[0], 0.05, POOL[2]], cone: 1.4, sp: [1, 3], life: 0.3, len: 0.02, c0: 0xffd080, c1: 0xff4000, g: 9.8 }),\n ),\n after(BOOM_AT, ...VEHICLE_BOOM),\n ],\n tick: [\n when(lt(TIME, BOOM_AT), [\n emit('drip', 'normal', 12, { p: TANK, box: [0.05, 0, 0.05], sp: 0, life: 1, size: 0.03, c0: 0x5a5a7a, a: 0.9, g: 9.8, fi: 0, gnd: 1 }),\n ]),\n when(and(gt(TIME, 3.5), lt(TIME, BOOM_AT)), [\n set('spread', clamp(div(sub(TIME, 3.5), 2.5), 0, 1)),\n set('front', vlerp(POOL, TANK_FLOOR, mul(variable('spread'), 0.8))),\n call('fire_emit', 'vz', variable('front'), add(0.6, mul(variable('spread'), 0.4)), 1.1, { smoke: 14 }),\n call('fire_emit', 'vz2', POOL, 0.7, 0.8, { smoke: 6 }),\n fireLight(0, vadd(variable('front'), [0, 1, 0]), 3, TIME),\n ]),\n when(ge(TIME, BOOM_AT), [\n call('fire_emit', 'wr', vadd(query('car', 'position'), [0, 0.9, 0]), 0.8, 1.4, { smoke: 18, smokeAlpha: 0.55 }),\n fireLight(0, vadd(query('car', 'position'), [0, 1.6, 0]), 3.4, TIME),\n behavior('car', 'step', { dt: DELTA }),\n ]),\n ],\n}\n","import { DELTA, gt, query, TIME, vadd } from '../dsl'\nimport { after, behavior, call, cue, fireLight, when } from '../steps'\nimport type { EffectDef } from '../types'\nimport { VEHICLE_BOOM } from './boom'\n\n/** W1133-1139 (`explosao`, `lab: 1`): a big blast (scale 1.8 of the grenade), the car jumps and lands crooked, bonnet, doors and a wheel fly, and the wreck burns. */\nexport const CAR_EXPLOSION: EffectDef = {\n id: 'car_explosion',\n pageId: 'explosao',\n team: 'vehicles',\n lab: 'car_fuel_tank',\n budget: { particles: 600, debris: 34, lights: 1 },\n loop: 10,\n view: { eye: [12, 4.2, 8], target: [5.6, 1, 0.8] },\n props: ['car'],\n setup: [cue('zombie_visible', { index: -1, visible: false })],\n timeline: [after(0.4, ...VEHICLE_BOOM)],\n tick: [\n when(gt(TIME, 0.5), [\n call('fire_emit', 'wr', vadd(query('car', 'position'), [0, 0.9, 0]), 0.8, 1.4, { smoke: 18, smokeAlpha: 0.55 }),\n fireLight(0, vadd(query('car', 'position'), [0, 1.6, 0]), 3.4, TIME),\n ]),\n behavior('car', 'step', { dt: DELTA }),\n ],\n}\n","import { add, eq, gt, INDEX, mod, mul, or, pick } from '../dsl'\nimport { after, behavior, burst, camera, cue, screen, repeat, when } from '../steps'\nimport type { EffectDef } from '../types'\nimport { carPoint } from './car'\n\nconst HITS = [[90, 40], [170, 60], [120, 75], [60, 50]]\nconst HIT_X = HITS.map(([x]) => x)\nconst HIT_Y = HITS.map(([, y]) => y)\nconst ZOMBIE = carPoint(0, 0, 3.1)\nconst CAR_YAW = -0.4\n\n/** W1140-1152 (`parabrisa`): from inside the car, blows shake the camera and add a star crack; at the second and fourth a smear of blood with a handprint runs down. */\nexport const WINDSHIELD: EffectDef = {\n id: 'windshield',\n pageId: 'parabrisa',\n team: 'vehicles',\n budget: { particles: 6, decals: 1 },\n loop: 5.8,\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n behavior('walkers', 'place', { index: 0, x: ZOMBIE[0], z: ZOMBIE[2], facing: CAR_YAW + Math.PI }),\n camera(carPoint(-0.3, 1.35, -0.2), carPoint(0, 1.2, 2.2), true),\n ],\n timeline: [\n repeat(\n HITS.length,\n after(\n add(0.6, mul(INDEX, 0.85)),\n cue('zombie_swing', { index: 0, side: mod(INDEX, 2) }),\n after(\n add(0.6, mul(INDEX, 0.85), 0.15),\n behavior('cracks', 'crack', { x: pick(HIT_X, INDEX), y: pick(HIT_Y, INDEX), big: gt(INDEX, 1) }),\n when(or(eq(INDEX, 1), eq(INDEX, 3)), [behavior('cracks', 'blood_streaks', { x: pick(HIT_X, INDEX), y: pick(HIT_Y, INDEX) })]),\n screen({ add: { shake: 0.18 } }),\n burst('add', 6, { p: carPoint(-0.1, 1.25, 0.75), box: [0.4, 0.1, 0.05], size: [0.01, 0.03], life: [0.2, 0.5], c0: 0xffffff, a: 0.8, fi: 0.2 }),\n cue('windshield_stage', { stage: add(INDEX, 1) }),\n ),\n ),\n ),\n ],\n}\n","import { add, and, DELTA, gt, lt, mod, mul, rnd, TIME } from '../dsl'\nimport { after, burst, cue, lens, repeat, screen, when } from '../steps'\nimport type { EffectDef, EffectStep } from '../types'\n\nconst FRESH_BLOOD = 0x8a0a0a\nconst BEAT_RATE = 1.9\n\n/** A blow from one side (`swing`, W1178): a red edge on that side, a shake and splashes on the lens, 0.18 s after the swing starts. */\nconst blow = (side: 0 | 1): EffectStep[] => [\n cue('zombie_swing', { index: -1, side }),\n after(\n add(TIME, 0.18),\n screen({ set: side === 0 ? { dirL: 1 } : { dirR: 1 }, add: { shake: 0.3 } }),\n repeat(4, lens(side === 0 ? rnd(0.05, 0.3) : rnd(0.7, 0.95), rnd(0.3, 0.8), rnd(0.02, 0.05), '110,8,8', 0.8)),\n burst('normal', 12, { p: [0, 1.4, 0.9], dir: [0, 0.2, 1], cone: 0.6, sp: [1, 2], life: 1, size: [0.03, 0.05], c0: FRESH_BLOOD, g: 9.8, fi: 0, gnd: 3, ds: [0.05, 0.1] }),\n ),\n]\n\n/** W1169-1185 (`dano`): two blows, from the left and from the right, then the bite: a red flash, the colour drains, the heartbeat pulses and big blood runs down the lens. */\nexport const DAMAGE_AND_BITE: EffectDef = {\n id: 'damage_and_bite',\n pageId: 'dano',\n team: 'screen',\n budget: {},\n loop: 5.6,\n view: { eye: [0, 1.6, 1.7], target: [0, 1.5, 0] },\n timeline: [\n after(0.3, ...blow(0)),\n after(1.6, ...blow(1)),\n after(3, cue('zombie_lunge', { z: 0.45 })),\n after(\n 3.15,\n screen({ set: { red: 1, desat: 0.9 }, add: { shake: 0.6 } }),\n cue('bite', { infection: 1 }),\n repeat(7, lens(rnd(0.2, 0.8), rnd(0.2, 0.7), rnd(0.04, 0.1), '100,6,6', 1)),\n ),\n ],\n tick: [\n when(and(gt(TIME, 3.2), lt(TIME, 5.4)), [when(lt(mod(mul(TIME, BEAT_RATE), 1), mul(DELTA, BEAT_RATE)), [screen({ set: { beat: 1 } })])]),\n ],\n}\n","import { add, CAMERA_POSITION, cameraForward, DELTA, eq, gt, INDEX, lt, max, mod, mul, PARAM, rand, rnd, sin, TIME, variable, vadd } from '../dsl'\nimport { burst, cue, post, repeat, screen, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst MALAISE = 0\nconst FEVER = 1\nconst DELIRIUM = 2\nconst LAST_HOURS = 3\nconst GHOSTS = [[-3, -1.8], [3.5, -2.4], [-6, 1.5]]\n\n/** W1186-1205 (`infeccao`): malaise (washed colour, a breathing vignette), fever (cold edge, waves of blur, a cough that shakes the camera), delirium, the last hours. */\nexport const INFECTION_PHASES: EffectDef = {\n id: 'infection_phases',\n pageId: 'infeccao',\n team: 'screen',\n params: { id: 'phase', options: ['malaise', 'fever', 'delirium', 'last_hours'], default: 1 },\n budget: { particles: 10 },\n loop: 0,\n view: { eye: [2, 1.7, 7], target: [0, 1.2, -1] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n ...GHOSTS.map(([x, z], index) => cue('ghost_place', { index, x, z, turn: rnd(-0.4, 0.4) })),\n ],\n timeline: [set('nextCough', 2)],\n tick: [\n when(eq(PARAM, MALAISE), [post({ desat: 0.25, tunnel: add(0.15, mul(0.12, sin(mul(TIME, 1.2)))), blur: mul(0.3, max(0, sin(mul(TIME, 0.7)))) })]),\n when(eq(PARAM, FEVER), [\n post({ cold: add(0.8, mul(0.15, sin(mul(TIME, 2)))), blur: add(0.6, mul(0.6, sin(mul(TIME, 1.6)))), desat: 0.3 }),\n when(gt(TIME, variable('nextCough')), [\n set('nextCough', add(TIME, rnd(3, 5))),\n screen({ add: { shake: 0.25 } }),\n burst('normal', 10, { p: vadd(CAMERA_POSITION, cameraForward([0, -0.15, -0.6])), dir: cameraForward([0, 0, -1]), cone: 0.4, sp: [0.6, 1.2], drag: 1.5, life: 1.2, size: [0.05, 0.1], grow: 5, c0: 0xdfe6ee, a: 0.2 }),\n ]),\n ]),\n when(eq(PARAM, DELIRIUM), [\n post({ chroma: add(2, mul(3, add(0.5, mul(0.5, sin(mul(TIME, 1.7)))))), hue: mul(22, sin(mul(TIME, 0.6))), tunnel: 0.3, desat: 0.15 }),\n repeat(GHOSTS.length, cue('ghost_visible', { index: INDEX, visible: gt(sin(add(mul(TIME, add(1.3, mul(INDEX, 0.7))), mul(INDEX, 2))), 0.6) })),\n when(lt(rand(), mul(DELTA, 0.3)), [screen({ set: { white: 0.12 } })]),\n ]),\n when(eq(PARAM, LAST_HOURS), [\n post({ desat: 0.85, tintAlpha: 0.22, tintColor: '70,110,40', tunnel: 0.55, blur: 1.2 }),\n when(lt(mod(mul(TIME, 2.2), 1), mul(DELTA, 2.2)), [screen({ set: { beat: 1 }, add: { shake: 0.05 } })]),\n ]),\n ],\n}\n","import { add, CAMERA_POSITION, clamp, DELTA, div, eq, INDEX, ite, lt, min, mod, mul, query, rnd, sub, TIME, variable, vdist } from '../dsl'\nimport { behavior, cue, post, repeat, screen, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst WALKERS = 6\nconst NEAR = 9\nconst RANGE = 7\nconst RESTING_BPM = 70\nconst BPM_RISE = 80\nconst walkerPoint = [query('walkers', 'x', INDEX), 0, query('walkers', 'z', INDEX)]\n\n/** W1206-1217 (`panico`): the aim trembles, the tunnel closes as the nearest zombie arrives and the heartbeat quickens from 70 to 150 bpm. */\nexport const PANIC: EffectDef = {\n id: 'panic',\n pageId: 'panico',\n team: 'screen',\n budget: {},\n loop: 8,\n view: { eye: [0, 1.65, 6], target: [0, 1.3, -2] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n repeat(\n WALKERS,\n set('startX', rnd(-4, 4)),\n set('startZ', sub(rnd(-4, -2), mul(INDEX, 0.6))),\n behavior('walkers', 'place', { index: INDEX, x: variable('startX'), z: variable('startZ'), facing: 0 }),\n behavior('walkers', 'walk', { index: INDEX, to: [rnd(-1.2, 1.2), 0, 5], speed: ite(eq(mod(INDEX, 3), 1), 1.6, 0.7) }),\n ),\n ],\n timeline: [],\n tick: [\n set('nearest', 99),\n repeat(WALKERS, set('nearest', min(variable('nearest'), vdist(walkerPoint, CAMERA_POSITION)))),\n set('fear', clamp(div(sub(NEAR, variable('nearest')), RANGE), 0, 1)),\n set('bpm', add(RESTING_BPM, mul(BPM_RISE, variable('fear')))),\n when(lt(mod(div(mul(TIME, variable('bpm')), 60), 1), div(mul(DELTA, variable('bpm')), 60)), [screen({ set: { beat: add(0.4, mul(0.6, variable('fear'))) } })]),\n post({ tunnel: add(0.1, mul(0.65, variable('fear'))), desat: mul(0.45, variable('fear')) }),\n set('tremor', add(0.012, mul(0.035, variable('fear')))),\n ],\n}\n","import { rnd } from '../dsl'\nimport { after, burst, cue, lens, repeat, screen } from '../steps'\nimport type { EffectDef } from '../types'\n\n/** W1218-1226 (`cegueira`): a green cloud bursts between the bloater and the camera, the screen goes green and blurred and clears in 5 s; two coughs shake the camera. */\nexport const BLOATER_BLINDNESS: EffectDef = {\n id: 'bloater_blindness',\n pageId: 'cegueira',\n team: 'screen',\n budget: { particles: 30 },\n loop: 7.5,\n view: { eye: [0, 1.6, 2.6], target: [0, 1.3, 0] },\n setup: [cue('bloater_pose', { eyes: 0x5fe08a, skin: 0x6b7a52, belly: [1.4, 1.25, 1.6] })],\n timeline: [\n after(\n 0.7,\n cue('zombie_visible', { index: -1, visible: false }),\n screen({ set: { gas: 1 }, add: { shake: 0.3 } }),\n burst('normal', 30, { p: [0, 1.3, 0.8], r: 0.6, sp: [0.5, 2], drag: 2, life: [3, 5], size: [0.8, 1.6], grow: 1.6, c0: 0x6f8a3c, c1: 0x3b4a26, a: 0.3, fi: 0.05 }),\n repeat(8, lens(rnd(0.15, 0.85), rnd(0.15, 0.7), rnd(0.03, 0.08), '110,150,50', 0.9)),\n ),\n after(2, screen({ add: { shake: 0.2 } })),\n after(3.4, screen({ add: { shake: 0.2 } })),\n ],\n}\n","import { TIME } from '../dsl'\nimport { call, cue, fireLight } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst FIRE = [-1.4, 0.1, 3.0] as const\n\n/** W1227-1233 (`fogueira`): a low flame, embers that spiral up, thin smoke and a warm light that trembles and paints the survivor. */\nexport const CAMPFIRE: EffectDef = {\n id: 'campfire',\n pageId: 'fogueira',\n team: 'screen',\n budget: { particles: 120, lights: 1 },\n loop: 0,\n view: { eye: [1.4, 1.6, 6.4], target: [-1.4, 0.6, 3] },\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('survivor_pose', { x: -2.6, z: 3.6, turn: 2.2 })],\n timeline: [],\n tick: [\n call('fire_emit', 'camp', FIRE, 0.25, 0.55, { smoke: 8, smokeColor: 0x4a4642, smokeAlpha: 0.25 }),\n fireLight(0, [FIRE[0], FIRE[1] + 0.8, FIRE[2]], 2.4, TIME),\n ],\n}\n","import { add, gt, TIME, variable } from '../dsl'\nimport { after, burst, cue, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef, EffectStep } from '../types'\n\nconst FACING = 0.5\n/** The survivor's mouth and the way it breathes out, with the survivor at (-1.6, 0, 1.8) turned by `FACING` (W1236-1238). */\nconst MOUTH = [Math.sin(FACING) * 0.2 + -1.6, 1.68, Math.cos(FACING) * 0.2 + 1.8] as const\nconst BREATH = normalized([Math.sin(FACING), -0.15, Math.cos(FACING)])\nconst BREATH_EVERY = 2.4\nconst COUGH_EVERY = 6.5\n\n/** A puff of breath (`puff`, W1239): `strength` scales how many and how fast. */\nconst puff = (strength: number): EffectStep =>\n burst('normal', 8 * strength, { p: MOUTH, dir: BREATH, cone: 0.35, sp: [0.5, 1.1 * strength], drag: 1.6, life: [1.2, 1.8], size: [0.05, 0.09], grow: 6, c0: 0xdfe6ee, a: 0.22, g: -0.1 })\n\n/** W1234-1243 (`tosse`): a short breath every 2.4 s; in a cough, three quick bigger ones and a jolt of the body; the torch shows its beam in the fog. */\nexport const COUGH_AND_BREATH: EffectDef = {\n id: 'cough_and_breath',\n pageId: 'tosse',\n team: 'screen',\n budget: { particles: 40, lights: 1 },\n loop: 0,\n view: { eye: [2.4, 1.8, 6.5], target: [-1.4, 1.3, 1.6] },\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('survivor_pose', { x: -1.6, z: 1.8, turn: FACING }), cue('torch', { on: true })],\n timeline: [set('nextBreath', 0.5), set('nextCough', 3)],\n tick: [\n when(gt(TIME, variable('nextBreath')), [set('nextBreath', add(TIME, BREATH_EVERY)), puff(1)]),\n when(gt(TIME, variable('nextCough')), [\n set('nextCough', add(TIME, COUGH_EVERY)),\n ...[0, 0.25, 0.5].map((delay) => after(add(TIME, delay), puff(1.6), cue('survivor_jolt', { tilt: 0.25 }))),\n ]),\n ],\n}\n","import { cos, local, mul, rnd, scaled, sin, variable, vnorm } from './dsl'\nimport { burst, call, debris, repeat, screen, spawn } from './steps'\nimport type { EffectDef } from './types'\n\nconst FACING = [0, 0, 1] as const\nconst UP = [0, 1, 0] as const\nconst ORIGIN = [0, 0, 0] as const\nconst FORWARD = [0, 0, -1] as const\nconst IMPACT_MATERIALS = ['concrete', 'metal', 'wood', 'glass', 'flesh', 'water'] as const\n\n/** What a hit leaves on one material, the way the Workshop's `impact` helper does (W374-391), played once at the hit. */\nconst impactEffect = (material: (typeof IMPACT_MATERIALS)[number]): EffectDef => ({\n id: `impact_${material}`,\n pageId: `event:impact_${material}`,\n team: 'weapons',\n budget: { particles: 40, decals: 1 },\n loop: 2,\n timeline: [call('impact', material, ORIGIN, FACING, 1, 0)],\n})\n\n/** The flash of one weapon at its muzzle (W417 `muzzle`), played once: the recipe's own per-weapon sizes, petals, light and smoke. */\nconst muzzleEffect = (weapon: 'glock' | 'ak' | 'r870' | 'barrett'): EffectDef => ({\n id: `muzzle_${weapon}`,\n pageId: `event:muzzle_${weapon}`,\n team: 'weapons',\n budget: { particles: 60, lights: 1 },\n loop: 2.4,\n timeline: [call('muzzle', weapon, ORIGIN, FORWARD)],\n})\n\n/** A case thrown out of the port (W430 `casing`): brass, a red shell or a .50 case. */\nconst casingEffect = (id: string, type: '' | 'shell' | '50'): EffectDef => ({\n id,\n pageId: `event:${id}`,\n team: 'weapons',\n budget: { debris: 1 },\n loop: 2,\n timeline: [call('casing', ORIGIN, type)],\n})\n\n/**\n * The effects the destruction events play, as slices of the Workshop's recipes: the same bursts, with the recipe's own numbers, centred on the point the event\n * happens (`data/event-effects.json` says which event plays which). They are not Workshop pages, so they have no golden of their own; each cites the lines it was cut from.\n */\nexport const EVENT_EFFECTS: readonly EffectDef[] = [\n ...IMPACT_MATERIALS.map(impactEffect),\n ...(['glock', 'ak', 'r870', 'barrett'] as const).map(muzzleEffect),\n casingEffect('casing_brass', ''),\n casingEffect('casing_shell', 'shell'),\n casingEffect('casing_50', '50'),\n {\n // door_stages (W856-871): the dust a blow shakes loose from the frame and the splinters.\n id: 'stage_crack',\n pageId: 'event:stage_crack',\n team: 'destruction',\n budget: { particles: 12, debris: 5 },\n loop: 2,\n timeline: [\n burst('normal', 12, { p: ORIGIN, box: [0.6, 0.05, 0.02], dir: [0, -0.287, 0.958], cone: 0.6, sp: [0.2, 0.8], drag: 1.5, life: [0.8, 1.4], size: [0.08, 0.16], grow: 3, c0: 0x7a7366, a: 0.45, g: 0.4 }),\n repeat(scaled(2), debris({ p: [rnd(-0.5, 0.5), rnd(0, 1.6), 0], dir: [0, 0.287, 0.958], cone: 0.6, sp: [1, 2.5], size: [0.015, 0.015, 0.1], c: 0x7a5530, life: 12 })),\n ],\n },\n {\n // block_wall (W872-886, 3.6 s): the ring of dust that rolls out when the wall gives way.\n id: 'breach_dust',\n pageId: 'event:breach_dust',\n team: 'destruction',\n budget: { particles: 90, debris: 16 },\n loop: 5,\n timeline: [\n screen({ add: { shake: 0.25 } }),\n burst('normal', 30, { p: ORIGIN, box: [1.4, 0.8, 0.2], sp: [0.3, 1.2], drag: 1.5, life: [1.5, 2.6], size: [0.4, 0.7], grow: 3, c0: 0x8a857a, c1: 0x4a4640, a: 0.45 }),\n repeat(scaled(16), debris({ p: ORIGIN, box: [1.3, 0.8, 0.1], sp: [1, 3], size: [0.08, 0.07, 0.08], k: [0.5, 1.5], c: 0x6e6a63, life: 20 })),\n repeat(\n scaled(60),\n spawn('normal', local('angle', rnd(0, 6.283), {\n p: [rnd(-1.4, 1.4), 0.2, rnd(-0.6, 0.4)],\n dir: vnorm([cos(variable('angle')), 0.3, sin(variable('angle'))]),\n cone: 0.4, sp: [0.8, 2.4], drag: 1.3, life: [2.5, 4.5], size: [0.6, 1], grow: 3, c0: 0x7a7268, c1: 0x4a4640, a: 0.45, fi: 0.12,\n })),\n ),\n ],\n },\n {\n // building_collapse (W872-886): the slab dropping in blocks and the cloud that rolls along the street.\n id: 'collapse_dust',\n pageId: 'event:collapse_dust',\n team: 'destruction',\n budget: { particles: 350, debris: 26 },\n loop: 8,\n timeline: [\n screen({ add: { shake: 0.45 } }),\n repeat(6, debris({ p: ORIGIN, box: [2, 0.05, 0.6], v: [rnd(-0.5, 0.5), rnd(-0.5, 0), rnd(0, 0.8)], sp: 0, size: [rnd(0.5, 1.1), 0.25, rnd(0.4, 0.8)], c: 0x6e6a63, spin: 3, life: 30, bounce: 0.1 })),\n repeat(scaled(20), debris({ p: ORIGIN, box: [2.1, 0.1, 0.7], v: [rnd(-1, 1), rnd(-1, 1), rnd(0, 1.5)], sp: 0, size: [0.12, 0.1, 0.12], k: [0.5, 1.5], c: 0x5e5a54, life: 30 })),\n repeat(\n scaled(70),\n spawn('normal', local('angle', rnd(-0.4, 3.5), {\n p: [rnd(-2, 2), 0.2, rnd(-0.5, 0.5)],\n dir: vnorm([mul(cos(variable('angle')), 0.6), 0.25, sin(variable('angle'))]),\n cone: 0.5, sp: [1, 3.2], drag: 1.1, life: [3, 6], size: [0.7, 1.2], grow: 3, c0: 0x7a7268, c1: 0x4a4640, a: 0.5, fi: 0.12,\n })),\n ),\n ],\n },\n {\n // shopfront_glass (W846-855): the pane coming down as shards, the flash of the glints and the pale dust.\n id: 'glass_burst',\n pageId: 'event:glass_burst',\n team: 'destruction',\n budget: { debris: 80, particles: 50 },\n loop: 5,\n timeline: [\n screen({ add: { shake: 0.08 } }),\n repeat(\n scaled(75),\n debris({ p: ORIGIN, box: [1.25, 0.85, 0.02], v: [rnd(-0.4, 0.4), rnd(-0.5, 0.8), rnd(0.6, 2)], sp: 0, size: [rnd(0.05, 0.18), 0.006, rnd(0.05, 0.18)], c: 0xa8c8d8, spin: 14, life: 30, bounce: 0.15 }),\n ),\n burst('add', 30, { p: ORIGIN, box: [1.2, 0.8, 0.05], size: [0.02, 0.05], life: [0.2, 0.6], c0: 0xffffff, a: 0.9, fi: 0.3 }),\n burst('normal', 20, { p: [0, -0.6, 0.1], box: [1.2, 0.5, 0.1], sp: [0.2, 0.6], drag: 2, life: [0.8, 1.4], size: [0.12, 0.2], grow: 3, c0: 0xbfd6e2, a: 0.2 }),\n ],\n },\n {\n // The chips macro the page uses on wood (W849) plus rust (`rustAt`), for rebar laid bare in concrete.\n id: 'rebar_expose',\n pageId: 'event:rebar_expose',\n team: 'destruction',\n budget: { particles: 20, debris: 8 },\n loop: 2,\n timeline: [call('chips', ORIGIN, UP, 8, 0.9), call('rust_at', ORIGIN, 6)],\n },\n]\n","import { BLOATER_CLOUD } from './creatures/bloater-cloud'\nimport { BLOOD_HIT } from './creatures/blood-hit'\nimport { CORPSE_DECAY } from './creatures/corpse-decay'\nimport { EYES_IN_FOG } from './creatures/eyes-in-fog'\nimport { DISMEMBER } from './creatures/dismember'\nimport { HEADSHOT } from './creatures/headshot'\nimport { REANIMATION } from './creatures/reanimation'\nimport { SCREAMER_SHRIEK } from './creatures/screamer-shriek'\nimport { IMPACT_BY_MATERIAL } from './weapons/impact-by-material'\nimport { PENETRATION } from './weapons/penetration'\nimport { CASINGS_AND_MAGAZINE } from './weapons/casings-and-magazine'\nimport { MOLOTOV } from './weapons/molotov'\nimport { GRENADE } from './weapons/grenade'\nimport { EXPLOSIVE_BARREL } from './weapons/explosive-barrel'\nimport { MUZZLE_FLASH } from './weapons/muzzle-flash'\nimport { SHOPFRONT_GLASS } from './destruction/shopfront-glass'\nimport { DOOR_STAGES } from './destruction/door-stages'\nimport { BUILDING_COLLAPSE } from './destruction/building-collapse'\nimport { BLOCK_WALL } from './destruction/block-wall'\nimport { METAL_DOOR_EFFECT } from './destruction/metal-door'\nimport { IRON_RAILING } from './destruction/iron-railing'\nimport { WOODEN_FENCE } from './destruction/wooden-fence'\nimport { HIT_POINT_BREAKAGE } from './destruction/hit-point-breakage'\nimport { PRESSURE_CYLINDERS } from './destruction/pressure-cylinders'\nimport { BUILDING_FIRE } from './world/building-fire'\nimport { SCRAPING_SPARKS } from './vehicles/scraping-sparks'\nimport { ENGINE_SMOKE } from './vehicles/engine-smoke'\nimport { FUEL_LEAK } from './vehicles/fuel-leak'\nimport { CAR_EXPLOSION } from './vehicles/car-explosion'\nimport { WINDSHIELD } from './vehicles/windshield'\nimport { DAMAGE_AND_BITE } from './screen/damage-and-bite'\nimport { INFECTION_PHASES } from './screen/infection-phases'\nimport { PANIC } from './screen/panic'\nimport { BLOATER_BLINDNESS } from './screen/bloater-blindness'\nimport { CAMPFIRE } from './screen/campfire'\nimport { COUGH_AND_BREATH } from './screen/cough-and-breath'\nimport { EVENT_EFFECTS } from './events'\nimport type { EffectDef } from './types'\n\nconst ALL_EFFECTS: readonly EffectDef[] = [BLOOD_HIT, HEADSHOT, DISMEMBER, BLOATER_CLOUD, SCREAMER_SHRIEK, CORPSE_DECAY, REANIMATION, EYES_IN_FOG, MUZZLE_FLASH, IMPACT_BY_MATERIAL, PENETRATION, CASINGS_AND_MAGAZINE, MOLOTOV, GRENADE, EXPLOSIVE_BARREL, SHOPFRONT_GLASS, DOOR_STAGES, BUILDING_COLLAPSE, BLOCK_WALL, METAL_DOOR_EFFECT, IRON_RAILING, WOODEN_FENCE, HIT_POINT_BREAKAGE, PRESSURE_CYLINDERS, BUILDING_FIRE, SCRAPING_SPARKS, ENGINE_SMOKE, FUEL_LEAK, CAR_EXPLOSION, WINDSHIELD, DAMAGE_AND_BITE, INFECTION_PHASES, PANIC, BLOATER_BLINDNESS, CAMPFIRE, COUGH_AND_BREATH]\n\n/** Every effect of the Workshop by id. A game adds, changes or removes entries with `patchEffects`. */\nexport const WORKSHOP_EFFECTS: Readonly<Record<string, EffectDef>> = Object.fromEntries(ALL_EFFECTS.map((effect) => [effect.id, effect]))\n\n/** The Workshop's recipes plus the one-shot effects the destruction events play (`event-effects.json`): what a world plays by default. */\nexport const GAME_EFFECTS: Readonly<Record<string, EffectDef>> = { ...WORKSHOP_EFFECTS, ...Object.fromEntries(EVENT_EFFECTS.map((effect) => [effect.id, effect])) }\n\n/** A copy of the recipes with some changed (a partial replaces the fields it names), added or removed (`null`); a game tunes the Workshop's effects without touching the core. */\nexport function patchEffects(base: Readonly<Record<string, EffectDef>>, changes: Readonly<Record<string, Partial<EffectDef> | EffectDef | null>>): Record<string, EffectDef> {\n const result: Record<string, EffectDef> = { ...base }\n for (const [id, change] of Object.entries(changes)) {\n if (change === null) delete result[id]\n else result[id] = { ...(base[id] ?? {}), ...change, id } as EffectDef\n }\n return result\n}\n","const LEHMER_MULTIPLIER = 16807\nconst LEHMER_MODULUS = 2147483647\nconst LCG_MULTIPLIER = 1664525\nconst LCG_INCREMENT = 1013904223\nconst LCG_RANGE = 4294967296\nconst HASH_MIX = 0x9e3779b1\n\nexport interface MutableVec3 {\n x: number\n y: number\n z: number\n}\n\n/** A seeded stream of numbers in [0, 1). The Lab's generator and the Fluid Standard's are both here, behind the same three calls. */\nexport interface RandomStream {\n /** The next number (the Lab's `rnd`). */\n next(): number\n /** The Lab's `rr(min, max)`: one draw, scaled. */\n between(min: number, max: number): number\n /** The Lab's `rdir`: a random unit vector, two draws (`u`, then the angle), written into `out`. */\n direction(out: MutableVec3): MutableVec3\n readonly state: number\n}\n\nfunction normalizeLehmerSeed(seed: number): number {\n const whole = Math.floor(Math.abs(seed)) % (LEHMER_MODULUS - 1)\n return whole === 0 ? 1 : whole\n}\n\n/** Park-Miller 16807 (the Lab's L16-18). A seed in 1..2147483646 is used as is, so a stream replays the page's. */\nexport function lehmer(seed: number): RandomStream {\n let state = normalizeLehmerSeed(seed)\n const next = (): number => {\n state = (state * LEHMER_MULTIPLIER) % LEHMER_MODULUS\n return (state - 1) / (LEHMER_MODULUS - 1)\n }\n return {\n next,\n between: (min, max) => min + (max - min) * next(),\n direction(out) {\n const up = next() * 2 - 1\n const angle = next() * Math.PI * 2\n const ring = Math.sqrt(1 - up * up)\n out.x = ring * Math.cos(angle)\n out.y = up\n out.z = ring * Math.sin(angle)\n return out\n },\n get state() {\n return state\n },\n }\n}\n\n/** The Fluid Standard's generator (F17-18): a 32-bit linear congruential one. */\nexport function lcg(seed: number): RandomStream {\n let state = seed >>> 0\n const next = (): number => {\n state = (Math.imul(state, LCG_MULTIPLIER) + LCG_INCREMENT) >>> 0\n return state / LCG_RANGE\n }\n return {\n next,\n between: (min, max) => min + (max - min) * next(),\n direction(out) {\n const up = next() * 2 - 1\n const angle = next() * Math.PI * 2\n const ring = Math.sqrt(1 - up * up)\n out.x = ring * Math.cos(angle)\n out.y = up\n out.z = ring * Math.sin(angle)\n return out\n },\n get state() {\n return state\n },\n }\n}\n\nfunction mixEventSeed(eventSeed: number): number {\n let mixed = Math.imul((eventSeed | 0) ^ HASH_MIX, 0x85ebca6b)\n mixed ^= mixed >>> 13\n mixed = Math.imul(mixed, 0xc2b2ae35)\n mixed ^= mixed >>> 16\n return (mixed >>> 0) % (LEHMER_MODULUS - 1) + 1\n}\n\n/** The stream of one event: the same event seed draws the same effect on every machine, whatever else is playing (`randomMode: 'per_event'`). */\nexport function streamFor(eventSeed: number): RandomStream {\n return lehmer(mixEventSeed(eventSeed))\n}\n","import type { ImpactMaterial } from './blood'\n\n/** What each material raises when hit: dust colour, chip colour and the number of sparks (W374-381). Zero means none. */\nconst TABLE: Readonly<Record<ImpactMaterial, { readonly dust: number; readonly chip: number; readonly spark: number }>> = {\n concrete: { dust: 0x8a857a, chip: 0x6e6a63, spark: 2 },\n metal: { dust: 0, chip: 0, spark: 18 },\n wood: { dust: 0x6a5038, chip: 0x7a5530, spark: 0 },\n glass: { dust: 0xbfd6e2, chip: 0xa8c8d8, spark: 0 },\n flesh: { dust: 0, chip: 0, spark: 0 },\n water: { dust: 0, chip: 0, spark: 0 },\n}\n\nexport function sparkSpec(material: ImpactMaterial): { readonly dust: number; readonly chip: number; readonly spark: number } {\n return TABLE[material]\n}\n","import type { WorkshopEngine } from '../../workshop/engine'\nimport type { Vec3Tuple } from '../../workshop/types'\nimport { negated, plus, plusScaled } from '../vector-math'\nimport { sparkSpec } from './impact-table'\n\n/** The blood colour of each infection age (W116) and how much each bleeds (W392). */\nexport const BLOOD_COLORS = [0x8a0a0a, 0x5a0c10, 0x3a1c12, 0x1d1914] as const\nconst BLEED_BY_AGE = [1, 0.7, 0.35, 0.1] as const\n\n/** The dust and dry flakes a decrepit body gives instead of blood. */\nfunction drySplash(engine: WorkshopEngine, point: Vec3Tuple, exitDirection: Vec3Tuple, scale: number): void {\n engine.burst('normal', 16 * scale, { p: point, dir: exitDirection, cone: 1, sp: [0.5, 1.6], drag: 2, life: [0.9, 1.6], size: [0.1, 0.2], grow: 4, c0: 0x2e2822, c1: 0x15130f, a: 0.6, g: -0.15 })\n for (let index = 0; index < engine.scaled(5); index++) engine.debrisPiece({ p: point, dir: exitDirection, cone: 1, sp: [0.5, 2], size: [0.03, 0.008, 0.03], c: 0x1c1916, life: 6 })\n engine.decal([point[0], 0, point[2] + exitDirection[2] * 0.6, 0.25, 0x1a1714, { grow: 0.4, ar: 0.7 }])\n}\n\n/** `bloodHit` (W392-398): a mist at the entry, a jet out of the exit and a cloud, by infection age. */\nexport function bloodHit(engine: WorkshopEngine, point: Vec3Tuple, exitDirection: Vec3Tuple, age: number, scale = 1): void {\n if (age === 3) return drySplash(engine, point, exitDirection, scale)\n const amount = BLEED_BY_AGE[age]!\n const color = BLOOD_COLORS[age]!\n engine.burst('normal', 10 * amount * scale, { p: point, dir: negated(exitDirection), cone: 0.9, sp: [0.2, 0.9], drag: 3, life: [0.25, 0.5], size: [0.08, 0.14], grow: 3, c0: color, a: 0.65 })\n engine.burst('normal', 45 * amount * scale, { p: point, dir: exitDirection, cone: 0.45, sp: [2.5, 6], life: [1, 1.6], size: [0.035, 0.07], c0: color, a: 0.95, g: 9.8, fi: 0, gnd: 3, ds: [0.06, 0.16] })\n engine.burst('normal', 14 * amount * scale, { p: point, dir: exitDirection, cone: 0.5, sp: [1, 2.5], drag: 2.5, life: [0.4, 0.8], size: [0.1, 0.18], grow: 3, c0: color, a: 0.45 })\n}\n\nconst MATERIAL_NAMES = ['concrete', 'metal', 'wood', 'glass', 'flesh', 'water'] as const\nexport type ImpactMaterial = (typeof MATERIAL_NAMES)[number]\n\nfunction waterImpact(engine: WorkshopEngine, point: Vec3Tuple, scale: number): void {\n engine.burst('normal', 22 * scale, { p: point, dir: [0, 1, 0], cone: 0.5, sp: [1.5, 3.5], life: [0.4, 0.7], size: [0.03, 0.06], c0: 0xc8d6e6, a: 0.7, g: 9.8, fi: 0, gnd: 1 })\n engine.ring([plus(point, 0, 0.012, 0), 0.02, 0.6, 0.7, 0x8090a8])\n engine.ring([plus(point, 0, 0.013, 0), 0.02, 0.35, 0.5, 0x8090a8])\n}\n\n/** `impact` (W374-391): what a bullet raises on each material. */\nexport function impact(engine: WorkshopEngine, material: ImpactMaterial, point: Vec3Tuple, normal: Vec3Tuple, scale = 1, age = 0): void {\n if (material === 'flesh') return bloodHit(engine, point, negated(normal), age, scale)\n if (material === 'water') return waterImpact(engine, point, scale)\n const spec = sparkSpec(material)\n if (spec.dust) engine.burst('normal', 14 * scale, { p: point, dir: normal, cone: 0.6, sp: [0.6, 2.4], drag: 2.5, life: [0.6, 1.2], size: [0.08, 0.16], grow: 4, c0: spec.dust, c1: 0x3a3936, a: 0.55, g: -0.1 })\n if (spec.chip) {\n const size = material === 'wood' ? ([0.015, 0.015, 0.09] as const) : material === 'glass' ? ([0.03, 0.004, 0.03] as const) : ([0.03, 0.03, 0.03] as const)\n for (let index = 0; index < engine.scaled(material === 'wood' ? 8 : 6) * scale; index++) {\n engine.debrisPiece({ p: point, dir: normal, cone: 0.8, sp: [1.5, 4], size, k: [0.6, 1.4], c: spec.chip, life: 6 })\n }\n }\n if (spec.spark && engine.quality < 2) {\n engine.burst('streak', spec.spark * scale, { p: point, dir: normal, cone: material === 'metal' ? 0.9 : 0.5, sp: [3, 9], life: [0.15, 0.45], len: 0.025, c0: 0xfff0c0, c1: 0xff5a10, g: 9.8, gnd: 2 })\n engine.burst('add', material === 'metal' ? 3 : 1, { p: point, size: [0.12, 0.2], life: 0.06, c0: 0xffe0a0, fi: 0 })\n if (material === 'metal') engine.flash([plusScaled(point, normal, 0.2), 0xffb060, 2, 0.06, 5])\n }\n if (material === 'glass') engine.burst('add', 5, { p: point, r: 0.15, size: [0.02, 0.05], life: [0.2, 0.5], c0: 0xffffff, a: 0.9, fi: 0.3 })\n if (engine.quality < 2) {\n const size = material === 'glass' ? 0.07 : material === 'metal' ? 0.05 : 0.06\n engine.decal([point[0], point[1], point[2], size, material === 'metal' ? 0x2a2522 : 0x0e0d0c, { n: normal, grow: 0, life: 60 }])\n }\n}\n\nexport function impactMaterialAt(index: number): ImpactMaterial {\n return MATERIAL_NAMES[index]!\n}\n","import { impact } from '../builders/blood'\nimport type { Behavior } from '../behavior'\n\nconst COLUMNS = 6\nconst ROWS = 5\nconst ORIGIN = [-2.2, 0, 2.6] as const\nconst BLOCK_SIZE = [0.5, 0.44, 0.25] as const\nconst OBJECT_ID_DRAWS = 4\nconst FLOOR = 0.13\nconst QUARTER_TURN = 1.5708\n\ninterface Motion {\n vx: number\n vy: number\n vz: number\n wx: number\n wy: number\n wz: number\n rest: boolean\n}\n\nexport interface WallBlock {\n readonly home: readonly [number, number]\n x: number\n y: number\n rotation: [number, number, number]\n /** Bullet holes stuck to this block (local to the block). */\n holes: { x: number; y: number; scale: number; chipTurn: number; chipScale: number }[]\n motion: Motion | undefined\n}\n\nconst clamp = (value: number, low: number, high: number): number => (value < low ? low : value > high ? high : value)\n\nfunction createBlocks(): WallBlock[] {\n const blocks: WallBlock[] = []\n for (let row = 0; row < ROWS; row++) {\n for (let column = 0; column < COLUMNS; column++) {\n const home = [(column - 2.5) * BLOCK_SIZE[0] + (row % 2 ? 0.12 : 0), 0.22 + row * BLOCK_SIZE[1]] as const\n blocks.push({ home, x: home[0], y: home[1], rotation: [0, 0, 0], holes: [], motion: undefined })\n }\n }\n return blocks\n}\n\n/**\n * The free-standing wall of 30 blocks of the page (W926-935, W1039-1046): a bullet leaves a hole and a chip stuck to the nearest block (`bwHit`, which\n * also costs the page the ids three.js gives each new mesh), and when it gives way the blocks fall with the velocities the page draws for them and\n * rest on their sides. The holes travel with the blocks, which is the point of the effect.\n */\nexport function createBlocksBehavior(): Behavior {\n let blocks = createBlocks()\n return {\n reset() {\n blocks = createBlocks()\n },\n act(host, action, args) {\n const random = host.engine.random\n if (action === 'hit') {\n const { x, y, scale } = args as { readonly x: number; readonly y: number; readonly scale: number }\n let best: WallBlock | undefined\n let bestDistance = 9\n for (const block of blocks) {\n const distance = Math.hypot(block.x - x, block.y - y)\n if (distance < bestDistance) {\n bestDistance = distance\n best = block\n }\n }\n if (!best) return\n const offsetX = clamp(x - best.x, -0.2, 0.2)\n const offsetY = clamp(y - best.y, -0.17, 0.17)\n for (let draw = 0; draw < OBJECT_ID_DRAWS; draw++) random.next()\n const chipTurn = random.between(0, 6)\n const chipScale = random.between(0.8, 1.3) * scale\n for (let draw = 0; draw < OBJECT_ID_DRAWS; draw++) random.next()\n best.holes.push({ x: offsetX, y: offsetY, scale, chipTurn, chipScale })\n impact(host.engine, 'concrete', [ORIGIN[0] + x, y, ORIGIN[2] + 0.13], [0, 0, 1], 0.8)\n } else if (action === 'collapse') {\n const { x, y } = args as { readonly x: number; readonly y: number }\n for (const block of blocks) {\n const dx = block.x - x\n const dy = block.y - y\n block.motion = {\n vx: dx * random.between(0.8, 2),\n vy: random.between(0.5, 2.5) + dy * 0.5,\n vz: random.between(-2.2, -0.4),\n wx: random.between(-4, 4),\n wy: random.between(-3, 3),\n wz: random.between(-4, 4),\n rest: false,\n }\n }\n }\n },\n query(_host, name) {\n if (name === 'blocks') return blocks\n throw new Error(`blocks: unknown query ${name}`)\n },\n update(_host, dt) {\n for (const block of blocks) {\n const motion = block.motion\n if (!motion || motion.rest) continue\n motion.vy -= 9.8 * dt\n block.x += motion.vx * dt\n block.y += motion.vy * dt\n block.rotation[0] += motion.wx * dt\n block.rotation[1] += motion.wy * dt\n block.rotation[2] += motion.wz * dt\n if (block.y < FLOOR) {\n block.y = FLOOR\n motion.vy *= -0.25\n motion.vx *= 0.5\n motion.vz *= 0.5\n motion.wx *= 0.5\n motion.wy *= 0.5\n motion.wz *= 0.5\n if (Math.abs(motion.vy) < 0.4 && Math.hypot(motion.vx, motion.vz) < 0.3) {\n motion.rest = true\n block.rotation[0] = Math.round(block.rotation[0] / QUARTER_TURN) * QUARTER_TURN\n block.rotation[2] = Math.round(block.rotation[2] / QUARTER_TURN) * QUARTER_TURN\n }\n }\n }\n },\n }\n}\n","import type { Behavior } from '../behavior'\nimport type { Vec3Tuple } from '../../workshop/types'\n\nconst ORIGIN: Vec3Tuple = [5.6, 0, 0.8]\nconst MAX_TILT = 0.25\n\n/**\n * The car of the page after it blew up (`carTick`, W1131): it leaps, spins and lands crooked. Its height is what the burning wreck's fire is emitted\n * from, so the model keeps it; the body is drawn by whoever owns the car.\n */\nexport function createCarBehavior(): Behavior {\n let y = 0\n let rise: number | undefined\n let spin = 0\n let roll = 0\n return {\n reset() {\n y = 0\n rise = undefined\n spin = 0\n roll = 0\n },\n act(_host, action, args) {\n if (action === 'launch') {\n const launch = args as { readonly rise: number; readonly spin: number }\n rise = launch.rise\n spin = launch.spin\n } else if (action === 'step') {\n if (rise === undefined) return\n const dt = (args as { readonly dt: number }).dt\n rise -= 9.8 * dt\n y = Math.max(0, y + rise * dt)\n roll += spin * dt\n spin *= Math.exp(-dt * 2)\n if (y === 0 && rise < 0) {\n rise = undefined\n roll = Math.min(MAX_TILT, Math.max(-MAX_TILT, roll))\n }\n }\n },\n query(_host, name) {\n if (name === 'position') return [ORIGIN[0], y, ORIGIN[2]]\n if (name === 'roll') return roll\n throw new Error(`car: unknown query ${name}`)\n },\n update() {},\n }\n}\n","import type { Behavior } from '../behavior'\n\n/** A smear of blood that runs down the windshield from a hit (`wsMarks`, W1156). */\nexport interface BloodStreak {\n readonly x: number\n readonly y: number\n readonly dx: number\n readonly dy: number\n readonly width: number\n}\n\nexport interface Crack {\n readonly x: number\n readonly y: number\n /** Each ray is a list of `[dx, dy]` segments that start at the impact. */\n readonly rays: readonly (readonly (readonly [number, number])[])[]\n readonly rings: readonly number[]\n}\n\nconst FULL_TURN_ROUNDED = 6.28\nconst SHORT_RAYS = 7\nconst LONG_RAYS = 12\nconst STREAKS_PER_HIT = 5\n\n/** `crackAt` (W62-63): the star of cracks a hit leaves in glass. Its draws depend on the lengths it draws, so the model keeps the same loop. */\nexport function createCracksBehavior(): Behavior {\n let cracks: Crack[] = []\n let streaks: BloodStreak[][] = []\n return {\n reset() {\n cracks = []\n streaks = []\n },\n act(host, action, args) {\n if (action === 'blood_streaks') {\n const { x, y } = args as { readonly x: number; readonly y: number }\n const random = host.engine.random\n const group: BloodStreak[] = []\n for (let index = 0; index < STREAKS_PER_HIT; index++) {\n group.push({ x: x - 18 + index * 8, y: y - 10, dx: random.between(-3, 3), dy: random.between(18, 40), width: random.between(5, 9) })\n }\n streaks.push(group)\n return\n }\n if (action !== 'crack') return\n const { x, y, big } = args as { readonly x: number; readonly y: number; readonly big: boolean }\n const random = host.engine.random\n const count = big ? LONG_RAYS : SHORT_RAYS\n const rays: [number, number][][] = []\n for (let ray = 0; ray < count; ray++) {\n let angle = (ray / count) * FULL_TURN_ROUNDED + random.between(-0.3, 0.3)\n const segments: [number, number][] = []\n let remaining = big ? random.between(40, 110) : random.between(15, 45)\n while (remaining > 0) {\n const length = random.between(6, 14)\n angle += random.between(-0.35, 0.35)\n segments.push([Math.cos(angle) * length, Math.sin(angle) * length])\n remaining -= length\n }\n rays.push(segments)\n }\n cracks.push({ x, y, rays, rings: big ? [12, 26] : [8] })\n },\n query(_host, name) {\n if (name === 'cracks') return cracks\n if (name === 'streaks') return streaks\n throw new Error(`cracks: unknown query ${name}`)\n },\n update() {},\n }\n}\n","import type { WorkshopEngine } from '../../workshop/engine'\nimport type { Vec3Tuple } from '../../workshop/types'\n\n/** Wood chips and a puff of dust (`chips`, W849). */\nexport function chips(engine: WorkshopEngine, point: Vec3Tuple, direction: Vec3Tuple, count: number, spread?: number): void {\n for (let index = 0; index < engine.scaled(count); index++) {\n engine.debrisPiece({ p: point, dir: direction, cone: spread || 0.9, sp: [1, 3], size: [0.012, 0.012, 0.09], k: [0.6, 1.4], c: 0xb08a5a, life: 20 })\n }\n engine.burst('normal', count, { p: point, dir: direction, cone: 0.8, sp: [0.3, 1.2], drag: 2, life: [0.8, 1.4], size: [0.08, 0.15], grow: 3, c0: 0x7a6048, a: 0.4 })\n}\n\n/** Sparks off metal (`sparkAt`, W899). */\nexport function sparkAt(engine: WorkshopEngine, point: Vec3Tuple, direction: Vec3Tuple, count: number, spread?: number): void {\n engine.burst('streak', count, { p: point, dir: direction, cone: spread || 0.8, sp: [2.5, 7], life: [0.2, 0.5], len: 0.025, c0: 0xfff0c0, c1: 0xff5010, g: 9.8, gnd: 2 })\n engine.burst('add', 2, { p: point, size: [0.1, 0.18], life: 0.06, c0: 0xffd8a0, fi: 0 })\n}\n\n/** Rust flakes and a little dust (`rustAt`, W900). */\nexport function rustAt(engine: WorkshopEngine, point: Vec3Tuple, count: number): void {\n engine.burst('normal', count, { p: point, r: 0.1, sp: [0.1, 0.5], life: [1, 1.6], size: [0.02, 0.035], c0: 0x7a4a2a, a: 0.9, g: 6, fi: 0, gnd: 1 })\n engine.burst('normal', Math.ceil(count / 2), { p: point, r: 0.08, sp: [0.2, 0.5], drag: 2, life: [0.8, 1.3], size: [0.08, 0.14], grow: 3, c0: 0x6a4a34, a: 0.3 })\n}\n","import type { Behavior, BehaviorHost } from '../behavior'\nimport { sparkAt } from '../builders/shared'\nimport { normalized } from '../vector-math'\nimport type { Vec3Tuple } from '../../workshop/types'\n\nconst SPOT: Vec3Tuple = [-2.2, 0, 2.6]\nconst WALL_X = -8.2\nconst QUARTER_TURN = Math.PI / 2\n\nconst lerp = (from: number, to: number, amount: number): number => from + (to - from) * amount\nconst clamp = (value: number, low: number, high: number): number => (value < low ? low : value > high ? high : value)\n\n/**\n * The pressure cylinder of the page (W1021-1038): an extinguisher that spins on the floor pushed by its own jet, or an oxygen bottle that becomes a\n * rocket and hits the wall. `step` moves it the way the page's tick does, drawing the sparks of the wall hit; the recipe then asks where the jet comes\n * out (`tip`, `back`, `direction`) to emit it.\n */\nexport function createCylinderBehavior(): Behavior {\n let position: Vec3Tuple = SPOT\n let velocity: Vec3Tuple = [0, 0, 0]\n let rotationZ = 0\n let angle = 0\n let spin = 0\n let live = false\n let oxygen = false\n let direction: Vec3Tuple = [1, 0, 0]\n\n const clear = (): void => {\n position = SPOT\n velocity = [0, 0, 0]\n rotationZ = 0\n angle = 0\n spin = 0\n live = false\n direction = [1, 0, 0]\n }\n\n return {\n reset: clear,\n act(host: BehaviorHost, action: string, args: unknown) {\n if (action === 'choose') {\n clear()\n oxygen = (args as { readonly oxygen: boolean }).oxygen\n } else if (action === 'puncture') {\n live = true\n if (oxygen) velocity = [-5, 0, -0.3]\n else spin = 9\n } else if (action === 'step') {\n if (!live) return\n const { dt, t } = args as { readonly dt: number; readonly t: number }\n const k = clamp(1 - (t - 0.6) / 3.4, 0, 1)\n if (!oxygen) {\n rotationZ = lerp(rotationZ, QUARTER_TURN, dt * 8)\n const y = lerp(position[1], 0.09, dt * 8)\n angle += spin * k * dt\n direction = [Math.cos(angle), 0, -Math.sin(angle)]\n position = [position[0] + direction[0] * (-0.6 * k * dt), y + direction[1] * (-0.6 * k * dt), position[2] + direction[2] * (-0.6 * k * dt)]\n return\n }\n let [vx, vy, vz] = velocity\n if (k > 0) vx -= 4 * k * dt\n const damping = Math.exp(-dt * (k > 0 ? 0.3 : 3))\n vx *= damping\n vy *= damping\n vz *= damping\n velocity = [vx, vy, vz]\n rotationZ = lerp(rotationZ, -QUARTER_TURN, dt * 10)\n position = [position[0] + vx * dt, lerp(position[1], 0.12, dt * 10) + vy * dt, position[2] + vz * dt]\n if (position[0] < WALL_X) {\n position = [WALL_X, position[1], position[2]]\n velocity = [velocity[0] * -0.3, velocity[1], velocity[2]]\n host.engine.screen.shake += 0.08\n sparkAt(host.engine, position, normalized([1, 0.5, 0]), 16, 1)\n }\n }\n },\n query(_host, name) {\n switch (name) {\n case 'live': return live\n case 'oxygen': return oxygen\n case 'position': return position\n case 'direction': return direction\n case 'speed_x': return velocity[0]\n case 'rotation_z': return rotationZ\n case 'tip': return [position[0] + direction[0] * 0.3, 0.1, position[2] + direction[2] * 0.3]\n case 'back': return [position[0] + 1.1, position[1], position[2]]\n default: throw new Error(`cylinder: unknown query ${name}`)\n }\n },\n update() {},\n }\n}\n","import type { Behavior } from '../behavior'\n\n/** The geometry of a box plate as three.js lays out its vertices: `BoxGeometry(width, height, depth, columns, rows, 1)` moved by `(shiftX, shiftY)`. */\nexport interface PlateGeometry {\n readonly width: number\n readonly height: number\n readonly columns: number\n readonly rows: number\n readonly shiftX: number\n readonly shiftY: number\n}\n\n/** The metal door of the page: 1.1 x 2.2 m, 14 x 24 segments, hinged at its left edge (W960). */\nexport const METAL_DOOR: PlateGeometry = { width: 1.1, height: 2.2, columns: 14, rows: 24, shiftX: 0.56, shiftY: 1.1 }\n\n/** Every vertex of the plate seen from the front (x, y), the front and back faces and the four thin edges, each vertex once per face it belongs to. */\nexport function plateVertices(geometry: PlateGeometry): readonly (readonly [number, number])[] {\n const { width, height, columns, rows, shiftX, shiftY } = geometry\n const xs = Array.from({ length: columns + 1 }, (_, column) => (column * width) / columns - width / 2)\n const ys = Array.from({ length: rows + 1 }, (_, row) => (row * height) / rows - height / 2)\n const vertices: [number, number][] = []\n // the sides (px, nx): two vertices, front and back, for each row; then top and bottom (py, ny): the same for each column; then the two big faces\n for (const x of [width / 2, -width / 2]) for (const y of ys) for (let depth = 0; depth < 2; depth++) vertices.push([x, y])\n for (const y of [height / 2, -height / 2]) for (const x of xs) for (let depth = 0; depth < 2; depth++) vertices.push([x, y])\n for (let face = 0; face < 2; face++) for (const y of ys) for (const x of xs) vertices.push([x, y])\n return vertices.map(([x, y]) => [x + shiftX, y + shiftY] as const)\n}\n\ninterface DentArgs {\n readonly x: number\n readonly y: number\n readonly radius: number\n readonly depth: number\n}\n\n/**\n * `dentAt` (W1002): pushes the vertices within `radius` of a hit in and draws one random number for each, so how many it draws depends on how the plate\n * is cut. The model counts them; the deformed mesh belongs to whoever draws the door.\n */\nlet doorVertices: ReturnType<typeof plateVertices> | undefined\n\nexport function createPlateBehavior(geometry: PlateGeometry = METAL_DOOR): Behavior {\n const vertices = geometry === METAL_DOOR ? (doorVertices ??= plateVertices(geometry)) : plateVertices(geometry)\n let dents: { x: number; y: number; radius: number; depth: number; vertices: number }[] = []\n return {\n reset() {\n dents = []\n },\n act(host, action, args) {\n if (action !== 'dent') return\n const { x, y, radius, depth } = args as DentArgs\n let touched = 0\n for (const [vertexX, vertexY] of vertices) {\n if (Math.hypot(vertexX - x, vertexY - y) < radius) {\n host.engine.random.next()\n touched++\n }\n }\n dents.push({ x, y, radius, depth, vertices: touched })\n },\n query(_host, name) {\n if (name === 'dents') return dents\n throw new Error(`plate: unknown query ${name}`)\n },\n update() {},\n }\n}\n","import type { Behavior } from '../behavior'\n\nconst WALKER_COUNT = 10\nconst ARRIVAL_DISTANCE = 0.05\nconst SWAY_AMPLITUDE = 0.04\nconst BOB_AMPLITUDE = 0.04\nconst STRIDE_FACTOR = 4.5\n\n/**\n * The `ph` of each walker, the offset of its sway and stride. The page drew them at load (`Math.random() * 6`) after three.js had drawn a few hundred\n * numbers for object ids, so they cannot be replayed; the three that matter (the runners with red eyes, whose trails start at the eyes) were fitted to\n * the recording until every position matched to four decimals. The others only turn a zombie nobody reads.\n */\nconst PHASES = [0, 0, 3.59629, 0, 0, 0, 2.946505, 0, 0, 0, 2.44693] as const\n\ninterface Walker {\n x: number\n z: number\n facing: number\n bob: number\n sway: number\n walk: { toX: number; toZ: number; speed: number } | undefined\n}\n\nfunction createWalkers(): Walker[] {\n return Array.from({ length: WALKER_COUNT }, () => ({ x: 0, z: 0, facing: 0, bob: 0, sway: 0, walk: undefined }))\n}\n\ninterface PlaceArgs { readonly index: number; readonly x: number; readonly z: number; readonly facing: number }\ninterface WalkArgs { readonly index: number; readonly to: readonly [number, number, number]; readonly speed: number }\ninterface MoveArgs { readonly index: number; readonly x: number }\n\n/**\n * The ten walking zombies of the page (W151, W190-197): they walk to a point at a speed, face where they go, bob with each stride and sway. An effect\n * reads where their eyes are (`point`) to start a trail from them. Phases are the page's, so the sway and bob repeat to the last digit.\n */\nexport function createWalkersBehavior(phases: readonly number[] = PHASES): Behavior {\n let walkers = createWalkers()\n return {\n reset() {\n walkers = createWalkers()\n },\n act(_host, action, args) {\n if (action === 'place') {\n const { index, x, z, facing } = args as PlaceArgs\n Object.assign(walkers[index]!, { x, z, facing })\n } else if (action === 'walk') {\n const { index, to, speed } = args as WalkArgs\n walkers[index]!.walk = { toX: to[0], toZ: to[2], speed }\n } else if (action === 'move_x') {\n const { index, x } = args as MoveArgs\n walkers[index]!.x = x\n }\n },\n query(_host, name, args) {\n const walker = walkers[args[0] as number]!\n if (name === 'x') return walker.x\n if (name === 'z') return walker.z\n if (name === 'is_walking') return walker.walk !== undefined\n if (name !== 'point') throw new Error(`walkers: unknown query ${name}`)\n const [localX, localY, localZ] = args[1] as readonly [number, number, number]\n const swayedX = Math.cos(walker.sway) * localX - Math.sin(walker.sway) * localY\n const swayedY = Math.sin(walker.sway) * localX + Math.cos(walker.sway) * localY + walker.bob\n return [Math.cos(walker.facing) * swayedX + Math.sin(walker.facing) * localZ + walker.x, swayedY, -Math.sin(walker.facing) * swayedX + Math.cos(walker.facing) * localZ + walker.z]\n },\n update(_host, dt, elapsed) {\n walkers.forEach((walker, index) => {\n walker.sway = Math.sin(elapsed * 1.3 + phases[index + 1]!) * SWAY_AMPLITUDE\n const walk = walker.walk\n if (!walk) return\n const dx = walk.toX - walker.x\n const dz = walk.toZ - walker.z\n const distance = Math.hypot(dx, dz)\n if (distance <= ARRIVAL_DISTANCE) {\n walker.walk = undefined\n return\n }\n const step = Math.min(distance, walk.speed * dt)\n walker.x += (dx / distance) * step\n walker.z += (dz / distance) * step\n walker.facing = Math.atan2(dx, dz)\n walker.bob = Math.abs(Math.cos(elapsed * walk.speed * STRIDE_FACTOR + phases[index + 1]!)) * BOB_AMPLITUDE\n })\n },\n}\n}\n","import type { Behavior } from './behavior'\nimport { createBlocksBehavior } from './behaviors/blocks'\nimport { createCarBehavior } from './behaviors/car'\nimport { createCracksBehavior } from './behaviors/cracks'\nimport { createCylinderBehavior } from './behaviors/cylinder'\nimport { createPlateBehavior } from './behaviors/plate'\nimport { createWalkersBehavior } from './behaviors/walkers'\n\n/** How to build each prop the Workshop animates by hand, by id (see `Behavior`). A game adds its own the same way. */\nexport const WORKSHOP_BEHAVIORS: Readonly<Record<string, () => Behavior>> = {\n walkers: () => createWalkersBehavior(),\n cracks: () => createCracksBehavior(),\n blocks: () => createBlocksBehavior(),\n plate: () => createPlateBehavior(),\n cylinder: () => createCylinderBehavior(),\n car: () => createCarBehavior(),\n}\n\n/** A fresh set of the props the Workshop animates by hand, by id; one per runner, since they keep state. */\nexport function createWorkshopBehaviors(factories: Readonly<Record<string, () => Behavior>> = WORKSHOP_BEHAVIORS): Record<string, Behavior> {\n return Object.fromEntries(Object.entries(factories).map(([id, make]) => [id, make()]))\n}\n","export interface Schedule {\n /** Runs `action` once `now` reaches `time`. */\n at(time: number, action: () => void): void\n /** Runs what is due at `now`, from the last one added to the first (the Lab's L1085 and the Workshop's W1280 walk the list backwards, and so does this). */\n update(now: number): void\n clear(): void\n readonly pending: number\n}\n\ninterface Entry {\n time: number\n action: () => void\n}\n\nconst NOOP = (): void => {}\n\nexport function createSchedule(): Schedule {\n const entries: Entry[] = []\n const spare: Entry[] = []\n return {\n at(time, action) {\n const entry = spare.pop() ?? { time: 0, action: NOOP }\n entry.time = time\n entry.action = action\n entries.push(entry)\n },\n update(now) {\n for (let index = entries.length - 1; index >= 0; index--) {\n const entry = entries[index]\n if (!entry || entry.time > now) continue\n const action = entry.action\n entries.splice(index, 1)\n entry.action = NOOP\n spare.push(entry)\n action()\n }\n },\n clear() {\n for (const entry of entries) {\n entry.action = NOOP\n spare.push(entry)\n }\n entries.length = 0\n },\n get pending() {\n return entries.length\n },\n }\n}\n","import type { RandomStream } from '../random'\nimport { normalized } from './vector-math'\n\n/** A value an effect computes: a number, a flag, a name or a vector. */\nexport type EffectValue = number | boolean | string | readonly number[]\n\n/** A computed field of a recipe. Plain data: `{ $: 'add', a: [1, { $: 't' }] }`. Built with the helpers in `dsl.ts`. */\nexport interface Expr {\n readonly $: string\n readonly a?: readonly unknown[]\n}\n\nexport interface ExprContext {\n readonly random: RandomStream\n readonly param: number\n readonly time: number\n readonly dt: number\n readonly index: number\n readonly variables: ReadonlyMap<string, unknown>\n readonly scaled: (count: number) => number\n readonly quality: number\n /** True on the first run after the effect was chosen, false on its repeats (the page's `fresh`). */\n readonly fresh: boolean\n /** Which way the played effect points and which surface it hit, in the world (`play`'s `direction` and `normal`). */\n readonly direction: readonly number[]\n readonly normal: readonly number[]\n readonly query: (behavior: string, name: string, args: readonly unknown[]) => unknown\n readonly camera: { readonly position: readonly number[]; readonly forward: (local: readonly number[]) => readonly number[] }\n}\n\nexport function isExpr(value: unknown): value is Expr {\n return typeof value === 'object' && value !== null && !Array.isArray(value) && '$' in value\n}\n\ntype Vector = readonly number[]\nconst asNumber = (value: unknown): number => value as number\nconst asVector = (value: unknown): Vector => value as Vector\nconst EASE_LIMIT = 1\n\nfunction ease(value: number): number {\n return value < 0 ? 0 : value > EASE_LIMIT ? EASE_LIMIT : value * value * (3 - 2 * value)\n}\n\nfunction reduceVectors(operands: readonly unknown[], combine: (accumulated: number, next: number) => number): Vector {\n const [first, ...rest] = operands.map(asVector)\n return rest.reduce<Vector>((total, next) => [combine(total[0]!, next[0]!), combine(total[1]!, next[1]!), combine(total[2]!, next[2]!)], first!)\n}\n\nfunction evaluateCall(name: string, args: readonly unknown[]): unknown {\n const [first, second, third] = args\n switch (name) {\n case 'concat': return args.map(String).join('')\n case 'add': return args.reduce<number>((total, next) => total + asNumber(next), 0)\n case 'sub': return asNumber(first) - asNumber(second)\n case 'mul': return args.reduce<number>((total, next) => total * asNumber(next), 1)\n case 'div': return asNumber(first) / asNumber(second)\n case 'mod': return asNumber(first) % asNumber(second)\n case 'neg': return -asNumber(first)\n case 'abs': return Math.abs(asNumber(first))\n case 'sqrt': return Math.sqrt(asNumber(first))\n case 'sin': return Math.sin(asNumber(first))\n case 'cos': return Math.cos(asNumber(first))\n case 'atan2': return Math.atan2(asNumber(first), asNumber(second))\n case 'min': return Math.min(...args.map(asNumber))\n case 'max': return Math.max(...args.map(asNumber))\n case 'floor': return Math.floor(asNumber(first))\n case 'ceil': return Math.ceil(asNumber(first))\n case 'round': return Math.round(asNumber(first))\n case 'clamp': return asNumber(first) < asNumber(second) ? asNumber(second) : asNumber(first) > asNumber(third) ? asNumber(third) : asNumber(first)\n case 'lerp': return asNumber(first) + (asNumber(second) - asNumber(first)) * asNumber(third)\n case 'ease': return ease(asNumber(first))\n case 'lt': return asNumber(first) < asNumber(second)\n case 'gt': return asNumber(first) > asNumber(second)\n case 'le': return asNumber(first) <= asNumber(second)\n case 'ge': return asNumber(first) >= asNumber(second)\n case 'eq': return first === second\n case 'ne': return first !== second\n case 'not': return !first\n case 'vadd': return reduceVectors(args, (total, next) => total + next)\n case 'vsub': return reduceVectors(args, (total, next) => total - next)\n case 'vscale': return asVector(first).map((component) => component * asNumber(second))\n case 'vnorm': return normalized(asVector(first) as readonly [number, number, number])\n case 'vneg': return asVector(first).map((component) => -component)\n case 'vlerp': return asVector(first).map((component, axis) => component + (asVector(second)[axis]! - component) * asNumber(third))\n case 'vx': return asVector(first)[0]\n case 'vy': return asVector(first)[1]\n case 'vz': return asVector(first)[2]\n case 'vdist': {\n const dx = asVector(first)[0]! - asVector(second)[0]!\n const dy = asVector(first)[1]! - asVector(second)[1]!\n const dz = asVector(first)[2]! - asVector(second)[2]!\n return Math.sqrt(dx * dx + dy * dy + dz * dz)\n }\n case 'with': return asVector(first).map((component, axis) => (axis === asNumber(second) ? asNumber(third) : component))\n default: throw new Error(`unknown expression: ${name}`)\n }\n}\n\n/** Resolves every `Expr` inside `value` (arrays and plain objects are walked in order, so the draws follow the order the page wrote its fields). */\nexport function resolve(value: unknown, context: ExprContext): unknown {\n if (Array.isArray(value)) return value.map((entry) => resolve(entry, context))\n if (typeof value !== 'object' || value === null) return value\n if (!isExpr(value)) return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, resolve(entry, context)]))\n const args = value.a ?? []\n switch (value.$) {\n case 'rnd': return context.random.between(asNumber(resolve(args[0], context)), asNumber(resolve(args[1], context)))\n case 'rand': return context.random.next()\n case 'param': return (args[0] as readonly unknown[])[context.param]\n case 'paramIndex': return context.param\n case 't': return context.time\n case 'dt': return context.dt\n case 'index': return context.index\n case 'quality': return context.quality\n case 'fresh': return context.fresh\n case 'direction': return context.direction\n case 'normal': return context.normal\n case 'scaled': return context.scaled(asNumber(resolve(args[0], context)))\n case 'var': return context.variables.get(args[0] as string)\n case 'at': return (resolve(args[0], context) as readonly unknown[])[asNumber(resolve(args[1], context))]\n case 'query': return context.query(args[0] as string, args[1] as string, args.slice(2).map((entry) => resolve(entry, context)))\n case 'cameraPosition': return context.camera.position\n case 'cameraForward': return context.camera.forward(asVector(resolve(args[0], context)))\n case 'let': return resolve(args[2], { ...context, variables: new Map([...context.variables, [args[0] as string, resolve(args[1], context)]]) })\n case 'ite': return resolve(resolve(args[0], context) ? args[1] : args[2], context)\n case 'and': return args.reduce<unknown>((result, next) => (result ? resolve(next, context) : result), true)\n case 'or': return args.reduce<unknown>((result, next) => (result ? result : resolve(next, context)), false)\n default: return evaluateCall(value.$, args.map((entry) => resolve(entry, context)))\n }\n}\n","import type { WorkshopEngine } from '../../workshop/engine'\nimport type { SpriteSpawn, Vec3Tuple } from '../../workshop/types'\nimport { normalized, plus } from '../vector-math'\n\nconst UP: Vec3Tuple = [0, 1, 0]\nconst ZERO: Vec3Tuple = [0, 0, 0]\nconst FULL_TURN_DRAWN = 6.283\n\nexport interface FireEmitOptions {\n readonly wind?: Vec3Tuple\n readonly dir?: Vec3Tuple\n readonly smoke?: number\n readonly smokeColor?: number\n readonly smokeAlpha?: number\n readonly noSmoke?: boolean\n}\n\nfunction scaledSizes(range: readonly [number, number], factor: number): readonly [number, number] {\n return [range[0] * Math.sqrt(factor), range[1] * Math.sqrt(factor)]\n}\n\n/** `fireEmit` (W399-405): flames, a hot core, embers and smoke for one frame, from a point and a radius, scaled by `factor`. */\nexport function fireEmit(engine: WorkshopEngine, key: string, dt: number, centre: Vec3Tuple, radius: number, factor: number, options: FireEmitOptions = {}): void {\n const wind = options.wind ?? ZERO\n const sqrtFactor = Math.sqrt(factor)\n engine.emit(`${key}f`, 'add', 90 * factor, dt, () => ({\n p: centre, r: radius, flat: true, dir: options.dir ?? UP, cone: 0.35, sp: [0.4, 1.4], v: wind, life: [0.35, 0.85], size: scaledSizes([0.22, 0.5], factor), grow: 0.35, c0: 0xffd27a, c1: 0x8a1a05, a: 0.85, fi: 0.15, g: -2.2,\n }))\n engine.emit(`${key}c`, 'add', 30 * factor, dt, () => ({\n p: centre, r: radius * 0.6, flat: true, dir: UP, cone: 0.3, sp: [0.3, 0.8], life: [0.2, 0.4], size: scaledSizes([0.25, 0.4], factor), grow: 0.6, c0: 0xfff2c0, c1: 0xff8a20, a: 0.8, fi: 0.1, g: -1,\n }))\n if (engine.quality < 2) {\n engine.emit(`${key}e`, 'streak', 10 * factor, dt, () => {\n const jitter = plus(wind, engine.random.between(-0.4, 0.4), 0, engine.random.between(-0.4, 0.4))\n return { p: centre, box: [radius, 0, radius], dir: UP, cone: 0.5, sp: [1.5, 3.5], v: jitter, life: [0.8, 1.8], len: 0.03, c0: 0xffb050, c1: 0x601000, g: -0.6, drag: 0.4 }\n })\n }\n if (options.noSmoke) return\n engine.emit(`${key}s`, 'normal', (options.smoke || 14) * factor, dt, () => ({\n p: plus(centre, 0, 0.8 * sqrtFactor, 0), r: radius * 0.7, dir: UP, cone: 0.35, sp: [0.6, 1.4], v: wind, drag: 0.15, life: [2.5, 4.5], size: scaledSizes([0.4, 0.8], factor), grow: 4, c0: options.smokeColor || 0x2a2522, c1: 0x121318, a: options.smokeAlpha || 0.42, fi: 0.2, g: -0.25,\n }))\n}\n\nfunction ringOfDust(engine: WorkshopEngine, point: Vec3Tuple, scale: number): void {\n for (let index = 0; index < engine.scaled(44); index++) {\n const angle = engine.random.next() * FULL_TURN_DRAWN\n const spec: SpriteSpawn = {\n p: plus(point, Math.cos(angle) * 0.5, 0.15, Math.sin(angle) * 0.5), dir: [Math.cos(angle), 0.08, Math.sin(angle)], cone: 0.15, sp: [4, 9 * scale], drag: 2.4, life: [1.4, 2.6], size: [0.5, 0.9], grow: 4, c0: 0x5d574d, c1: 0x2a2724, a: 0.5, fi: 0.1,\n }\n engine.spawn('normal', spec)\n }\n}\n\n/** `explode` (W406-416): the Workshop's blast, scaled by `scale`, that the Lab's profiles later replaced. `cameraPosition` turns the second ring to face the viewer. */\nexport function explode(engine: WorkshopEngine, point: Vec3Tuple, scale: number, cameraPosition: Vec3Tuple, chipColor?: number): void {\n engine.flash([plus(point, 0, 1, 0), 0xffa040, 14 * scale, 0.5, 30, 'boom'])\n engine.screen.shake += 0.7 * scale\n engine.screen.white += 0.18 * scale\n engine.burst('add', 55 * scale, { p: point, r: 0.3 * scale, sp: [2, 7 * scale], drag: 4, life: [0.25, 0.6], size: [0.7 * scale, 1.4 * scale], grow: 1.7, c0: 0xfff0b0, c1: 0x9a2a08, fi: 0.04 })\n engine.burst('add', 28 * scale, { p: plus(point, 0, 0.3, 0), r: 0.3, dir: UP, cone: 0.7, sp: [2, 5 * scale], drag: 1.5, life: [0.6, 1.1], size: [0.6 * scale, 1 * scale], grow: 1.3, c0: 0xffc060, c1: 0x5a1205, g: -2, fi: 0.05 })\n engine.ring([plus(point, 0, 0.05, 0), 0.3, 7 * scale, 0.55, 0xffd8a0])\n const toCamera = normalized([cameraPosition[0] - point[0], cameraPosition[1] - point[1], cameraPosition[2] - point[2]])\n engine.ring([plus(point, 0, 1, 0), 0.3, 5 * scale, 0.35, 0xfff0d0, toCamera])\n engine.burst('normal', 32 * scale, { p: plus(point, 0, 0.6, 0), r: 0.8 * scale, dir: UP, cone: 1.1, sp: [1, 3], drag: 1.2, life: [3, 6], size: [1 * scale, 1.8 * scale], grow: 2.6, c0: 0x2b2724, c1: 0x0f1013, a: 0.6, fi: 0.18, g: -0.35 })\n ringOfDust(engine, point, scale)\n if (engine.quality < 2) engine.burst('streak', 44 * scale, { p: point, dir: UP, cone: 1.45, sp: [10, 26], life: [0.3, 0.7], len: 0.03, c0: 0xffc070, c1: 0x802000, g: 9.8, gnd: 2 })\n for (let index = 0; index < engine.scaled(16 * scale); index++) {\n engine.debrisPiece({ p: point, dir: UP, cone: 1.2, sp: [3, 9], size: [0.12, 0.06, 0.1], k: [0.6, 1.6], c: chipColor || 0x2a2622, life: 9 })\n }\n engine.decal([point[0], engine.context.groundAt(point[0], point[2]), point[2], 3 * scale, 0x0a0a0a, { grow: 0.15, life: 60 }])\n}\n","import type { WorkshopEngine } from '../../workshop/engine'\nimport type { Vec3Tuple } from '../../workshop/types'\nimport { normalized, plus, plusScaled, scaledBy } from '../vector-math'\n\nconst FULL_TURN_DRAWN = 6.283\n\nexport const WEAPON_NAMES = ['glock', 'ak', 'r870', 'barrett'] as const\nexport type WeaponName = (typeof WEAPON_NAMES)[number]\n\n/** Per weapon: flash size, petals, light, smoke puffs and length of the petals (W417). */\nconst WEAPON_SIZES: Readonly<Record<WeaponName, readonly [number, number, number, number, number]>> = {\n glock: [0.35, 4, 3, 3, 0.25],\n ak: [0.6, 5, 5, 5, 0.45],\n r870: [0.95, 8, 7, 10, 0.6],\n barrett: [1.45, 6, 11, 14, 0.5],\n}\n\nfunction barrettBrake(engine: WorkshopEngine, tip: Vec3Tuple, direction: Vec3Tuple): void {\n const side = normalized([direction[2], 0, -direction[0]])\n for (const sign of [-1, 1]) {\n const sideways = scaledBy(side, sign)\n for (let index = 0; index < engine.scaled(8); index++) {\n engine.spawn('add', { p: plusScaled(tip, side, sign * 0.06), dir: sideways, cone: 0.25, sp: [2, 5], drag: 6, life: 0.09, size: [0.25, 0.4], c0: 0xffc070, c1: 0xff6010, fi: 0 })\n }\n engine.burst('normal', 10, { p: tip, dir: normalized(plus(sideways, 0, 0.2, 0)), cone: 0.3, sp: [1.5, 3], drag: 2, life: [1.2, 2], size: [0.15, 0.25], grow: 5, c0: 0x8a8a86, a: 0.3, g: -0.2 })\n }\n for (let index = 0; index < engine.scaled(26); index++) {\n const angle = engine.random.next() * FULL_TURN_DRAWN\n engine.spawn('normal', { p: [tip[0] + Math.cos(angle) * 0.3, 0.05, tip[2] + Math.sin(angle) * 0.3], dir: [Math.cos(angle), 0.15, Math.sin(angle)], cone: 0.2, sp: [1.5, 3.5], drag: 2, life: [1, 1.8], size: [0.2, 0.35], grow: 3, c0: 0x5a554b, a: 0.4 })\n }\n}\n\n/** `muzzle` (W417-429): flash core, petals along the barrel and smoke, scaled by weapon; the Barrett also vents sideways and lifts the dust. */\nexport function muzzle(engine: WorkshopEngine, weapon: WeaponName, tip: Vec3Tuple, direction: Vec3Tuple): void {\n const [flashSize, petals, light, smoke, length] = WEAPON_SIZES[weapon]\n engine.burst('add', 3, { p: tip, size: [flashSize * 0.45, flashSize * 0.75], life: 0.055, c0: 0xfff4d0, fi: 0 })\n for (let index = 0; index < engine.scaled(petals * 2); index++) {\n engine.spawn('add', { p: plusScaled(tip, direction, engine.random.between(0, length)), r: 0.03, size: [flashSize * 0.22, flashSize * 0.38], life: 0.06, c0: 0xffb050, c1: 0xff7020, fi: 0 })\n }\n engine.burst('streak', petals, { p: tip, dir: direction, cone: 0.55, sp: [6, 12], life: 0.05, len: 0.025, c0: 0xffd080 })\n if (weapon === 'barrett') barrettBrake(engine, tip, direction)\n engine.burst('normal', smoke, { p: tip, dir: direction, cone: 0.45, sp: [0.4, 1.6], drag: 2.2, life: [1, 2.2], size: [0.06, 0.14], grow: 6, c0: 0x8a8a86, c1: 0x55565a, a: 0.22, g: -0.25, fi: 0.05 })\n engine.flash([tip, 0xffc070, light, 0.05, 10])\n}\n\nexport type CasingType = 'shell' | '50' | ''\n\n/** `casing` (W430): a brass case, or a red shell, thrown out of the port. */\nexport function casing(engine: WorkshopEngine, port: Vec3Tuple, type: CasingType): void {\n const size = type === 'shell' ? ([0.03, 0.03, 0.07] as const) : type === '50' ? ([0.024, 0.024, 0.13] as const) : ([0.014, 0.014, 0.05] as const)\n engine.debrisPiece({ p: port, dir: normalized([0.8, 0.6, 0.2]), cone: 0.3, sp: [1.6, 2.6], size, c: type === 'shell' ? 0xb5281e : 0xc9a24a, spin: 20, bounce: 0.45, life: 20 })\n}\n","import type { WorkshopEngine } from '../workshop/engine'\nimport type { Vec3Tuple } from '../workshop/types'\nimport { bloodHit, impact } from './builders/blood'\nimport type { ImpactMaterial } from './builders/blood'\nimport { explode, fireEmit } from './builders/fire'\nimport type { FireEmitOptions } from './builders/fire'\nimport { chips, rustAt, sparkAt } from './builders/shared'\nimport { casing, muzzle } from './builders/weapon'\nimport type { CasingType, WeaponName } from './builders/weapon'\n\nexport interface MacroContext {\n readonly engine: WorkshopEngine\n readonly cameraPosition: Vec3Tuple\n readonly dt: number\n}\n\ntype MacroArgs = readonly unknown[]\n\n/** The helpers the page's recipes share (`bloodHit`, `impact`, `fireEmit`, `explode`, `muzzle`, `casing`, `chips`, `sparkAt`, `rustAt`), called by name from a step. */\nexport const MACROS: Readonly<Record<string, (context: MacroContext, args: MacroArgs) => void>> = {\n blood_hit: ({ engine }, [point, direction, age, scale]) => bloodHit(engine, point as Vec3Tuple, direction as Vec3Tuple, age as number, scale as number | undefined),\n impact: ({ engine }, [material, point, normal, scale, age]) => impact(engine, material as ImpactMaterial, point as Vec3Tuple, normal as Vec3Tuple, scale as number | undefined, age as number | undefined),\n fire_emit: ({ engine, dt }, [key, centre, radius, factor, options]) => fireEmit(engine, key as string, dt, centre as Vec3Tuple, radius as number, factor as number, options as FireEmitOptions | undefined),\n explode: ({ engine, cameraPosition }, [point, scale, chipColor]) => explode(engine, point as Vec3Tuple, scale as number, cameraPosition, chipColor as number | undefined),\n muzzle: ({ engine }, [weapon, tip, direction]) => muzzle(engine, weapon as WeaponName, tip as Vec3Tuple, direction as Vec3Tuple),\n casing: ({ engine }, [port, type]) => casing(engine, port as Vec3Tuple, type as CasingType),\n chips: ({ engine }, [point, direction, count, spread]) => chips(engine, point as Vec3Tuple, direction as Vec3Tuple, count as number, spread as number | undefined),\n spark_at: ({ engine }, [point, direction, count, spread]) => sparkAt(engine, point as Vec3Tuple, direction as Vec3Tuple, count as number, spread as number | undefined),\n rust_at: ({ engine }, [point, count]) => rustAt(engine, point as Vec3Tuple, count as number),\n}\n","import { createSchedule } from '../schedule'\nimport type { ScreenState } from '../types'\nimport type { Placement, WorkshopEngine } from '../workshop/engine'\nimport type { DebrisSpawn, SpriteSpawn, Vec3Tuple } from '../workshop/types'\nimport type { Behavior, BehaviorHost } from './behavior'\nimport type { ExprContext } from './expression'\nimport { resolve } from './expression'\nimport { MACROS } from './macros'\nimport type { CueRequest, EffectDef, EffectStep, ScreenKey } from './types'\n\nconst DEFAULT_DIRECTION: Vec3Tuple = [0, 0, -1]\nconst DEFAULT_NORMAL: Vec3Tuple = [0, 1, 0]\nconst SCREEN_FIELDS: Readonly<Record<ScreenKey, keyof ScreenState>> = {\n shake: 'shake', white: 'white', red: 'red', dirL: 'directionLeft', dirR: 'directionRight', chroma: 'chroma', desat: 'desat', gas: 'gas', beat: 'beat',\n}\n\n/** What an effect reads off the view: where it is and which way the camera's own axes point. The Workshop's bench also moves it (`camera` steps). */\nexport interface EffectView {\n readonly position: Vec3Tuple\n forward(local: readonly number[]): Vec3Tuple\n goTo?(eye: Vec3Tuple, target: Vec3Tuple): void\n place?(eye: Vec3Tuple, target: Vec3Tuple): void\n}\n\nexport interface InstanceDeps {\n readonly engine: WorkshopEngine\n readonly view: EffectView\n /** The prop models the recipe can call, by id (see `Behavior`). */\n readonly behavior: (id: string) => Behavior\n /** Every behaviour made so far, to age them every frame. */\n readonly behaviors: () => Iterable<Behavior>\n readonly onCue?: (cue: CueRequest) => void\n}\n\n/** Where and how a played effect sits in the world. */\nexport interface InstanceSetup {\n readonly placement?: Placement\n /** Which way the effect points in the world (`direction` in a recipe). */\n readonly direction?: Vec3Tuple\n /** The surface it hit (`normal` in a recipe). */\n readonly normal?: Vec3Tuple\n}\n\n/**\n * One run of one effect (W1259-1295): `begin` runs the recipe's `setup` and `timeline`, `step` runs the timers that came due (from the last added to the\n * first) and the `tick`, once per frame. Step by step it draws random numbers where the page did and in the same order.\n */\nexport class EffectInstance {\n readonly variables = new Map<string, unknown>()\n def: EffectDef | undefined\n param = 0\n /** True until the first run of a chosen effect is over: a repeat of the loop is not fresh (`f.fresh`). */\n fresh = false\n time = 0\n /** Seconds since the effect was chosen: unlike `time`, a restart of the loop does not reset it (`el`). */\n elapsed = 0\n setup: InstanceSetup = {}\n private dt = 0\n private index = 0\n private readonly schedule = createSchedule()\n private readonly host: BehaviorHost\n private readonly context: ExprContext\n\n constructor(private readonly deps: InstanceDeps) {\n const instance = (): EffectInstance => this\n this.host = {\n engine: deps.engine,\n camera: deps.view,\n variables: this.variables,\n get param() { return instance().param },\n get time() { return instance().time },\n after: (seconds, action) => this.schedule.at(seconds, action),\n }\n this.context = {\n get random() { return deps.engine.random },\n get param() { return instance().param },\n get time() { return instance().time },\n get dt() { return instance().dt },\n get index() { return instance().index },\n variables: this.variables,\n scaled: (count) => deps.engine.scaled(count),\n query: (behavior, name, args) => deps.behavior(behavior).query(this.host, name, args),\n get quality() { return deps.engine.quality },\n get fresh() { return instance().fresh },\n get direction() { return instance().setup.direction ?? DEFAULT_DIRECTION },\n get normal() { return instance().setup.normal ?? DEFAULT_NORMAL },\n camera: { get position() { return deps.view.position }, forward: (local) => deps.view.forward(local) },\n }\n }\n\n /** The effect starts (`select` + `startLoop`): the recipe's `setup` and `timeline` run now. */\n begin(def: EffectDef, param: number | undefined, setup: InstanceSetup = {}): void {\n this.def = def\n this.param = param ?? def.params?.default ?? 0\n this.elapsed = 0\n this.fresh = true\n this.setup = setup\n this.restart()\n }\n\n /** The loop starts over (`startLoop`): timers, variables and props go back to the start. */\n restart(): void {\n const def = this.def\n if (!def) return\n this.schedule.clear()\n this.variables.clear()\n for (const behavior of this.deps.behaviors()) behavior.reset(this.host)\n this.time = 0\n this.within(() => {\n this.execute(def.setup ?? [])\n this.execute(def.timeline)\n })\n this.fresh = false\n }\n\n /** The effect's part of one frame: the timers due, then the tick, then the props. The pools are aged by whoever owns the engine. */\n step(dt: number): void {\n const def = this.def\n this.dt = dt\n if (def) {\n this.time += dt\n this.elapsed += dt\n this.within(() => {\n this.schedule.update(this.time)\n this.execute(def.tick ?? [])\n })\n }\n for (const behavior of this.deps.behaviors()) behavior.update(this.host, dt, this.elapsed)\n }\n\n /** True once a looping effect has run its seconds, or a one-shot has nothing left to fire. */\n get finished(): boolean {\n const def = this.def\n if (!def) return true\n if (def.loop && def.loop > 0) return this.time >= def.loop\n return false\n }\n\n /** The recipe's own camera shake on top of the screen's (`panico` trembles the aim). */\n get tremor(): number {\n return (this.variables.get('tremor') as number | undefined) ?? 0\n }\n\n private within(action: () => void): void {\n const engine = this.deps.engine\n const previous = engine.placement\n engine.placement = this.setup.placement\n try {\n action()\n } finally {\n engine.placement = previous\n }\n }\n\n private value(expression: unknown): unknown {\n return resolve(expression, this.context)\n }\n\n execute(steps: readonly EffectStep[]): void {\n for (const step of steps) this.run(step)\n }\n\n private run(step: EffectStep): void {\n const engine = this.deps.engine\n switch (step.op) {\n case 'burst': return engine.burst(step.system, this.value(step.count) as number, this.value(step.spawn) as SpriteSpawn)\n case 'spawn': return engine.spawn(step.system, this.value(step.spawn) as SpriteSpawn)\n case 'emit': return engine.emit(step.key, step.system, this.value(step.rate) as number, this.dt, () => this.value(step.spawn) as SpriteSpawn)\n case 'debris': return engine.debrisPiece(this.value(step.spawn) as DebrisSpawn)\n case 'decal': return engine.decal(this.value(step.args) as Parameters<WorkshopEngine['decal']>[0])\n case 'ring': return engine.ring(this.value(step.args) as Parameters<WorkshopEngine['ring']>[0])\n case 'flash': return engine.flash(this.value(step.args) as Parameters<WorkshopEngine['flash']>[0])\n case 'lens': return engine.lensBlob(...(this.value(step.args) as [number, number, number, string, number]))\n case 'screen': return this.changeScreen(step)\n case 'fire_light': return engine.fireLight(step.slot, this.value(step.point) as Vec3Tuple, this.value(step.intensity) as number, this.value(step.time) as number)\n case 'fire_light_off': engine.lights.fire[step.slot]!.intensity = 0; return\n case 'cue': return this.cue(step)\n case 'call': return MACROS[step.macro]!({ engine, cameraPosition: this.deps.view.position, dt: this.dt }, this.value(step.args) as readonly unknown[])\n case 'at': return this.scheduleSteps(step)\n case 'when': return this.execute(this.value(step.if) ? step.steps : (step.otherwise ?? []))\n case 'repeat': return this.repeat(step)\n case 'set': { this.variables.set(step.name, this.value(step.value)); return }\n case 'append': { this.variables.set(step.name, [...((this.variables.get(step.name) as unknown[] | undefined) ?? []), this.value(step.value)]); return }\n case 'camera': return this.moveView(step)\n case 'post': { Object.assign(engine.post, this.value(step.values)); return }\n case 'behavior': return this.deps.behavior(step.id).act(this.host, step.action, this.value(step.args))\n }\n }\n\n private moveView(step: Extract<EffectStep, { op: 'camera' }>): void {\n const eye = this.value(step.eye) as Vec3Tuple\n const target = this.value(step.target) as Vec3Tuple\n if (step.instant) this.deps.view.place?.(eye, target)\n else this.deps.view.goTo?.(eye, target)\n }\n\n private changeScreen(step: Extract<EffectStep, { op: 'screen' }>): void {\n const screen = this.deps.engine.screen\n for (const [key, expression] of Object.entries(step.add ?? {})) screen[SCREEN_FIELDS[key as ScreenKey]] += this.value(expression) as number\n for (const [key, expression] of Object.entries(step.set ?? {})) screen[SCREEN_FIELDS[key as ScreenKey]] = this.value(expression) as number\n for (const [key, expression] of Object.entries(step.max ?? {})) screen[SCREEN_FIELDS[key as ScreenKey]] = Math.max(screen[SCREEN_FIELDS[key as ScreenKey]], this.value(expression) as number)\n }\n\n private cue(step: Extract<EffectStep, { op: 'cue' }>): void {\n const args = this.value(step.args)\n for (let draw = 0; draw < (step.draws ?? 0); draw++) this.deps.engine.random.next()\n this.deps.onCue?.({ cue: step.cue, args, time: this.time })\n }\n\n private scheduleSteps(step: Extract<EffectStep, { op: 'at' }>): void {\n const captured = this.index\n this.schedule.at(this.value(step.time) as number, () => {\n const previous = this.index\n this.index = captured\n this.execute(step.steps)\n this.index = previous\n })\n }\n\n private repeat(step: Extract<EffectStep, { op: 'repeat' }>): void {\n const previous = this.index\n const count = this.value(step.count) as number\n for (let index = 0; index < count; index++) {\n this.index = index\n this.execute(step.steps)\n }\n this.index = previous\n }\n}\n","import { lehmer } from '../random'\nimport type { RandomStream } from '../random'\nimport type { Follow } from '../types'\nimport type { Placement, WorkshopEngine } from '../workshop/engine'\nimport type { Vec3Tuple } from '../workshop/types'\nimport type { Behavior } from './behavior'\nimport { WORKSHOP_BEHAVIORS } from './behaviors'\nimport { EffectInstance } from './instance'\nimport type { EffectView } from './instance'\nimport type { CueRequest, EffectDef } from './types'\n\nconst ORIGIN: Vec3Tuple = [0, 0, 0]\nconst DEFAULT_HEADING: Vec3Tuple = [0, 0, -1]\nconst DEFAULT_MAX_INSTANCES = 48\n/** A recipe with no end of its own (`loop: 0`: a campfire, a fire in a building) plays this long unless it is stopped. */\nconst ENDLESS_SECONDS = 60\n\nexport interface PlayOptions {\n /** Which way the effect points in the world (the muzzle's barrel, the spray of a jet). */\n readonly direction?: Vec3Tuple\n /** The surface it hit. */\n readonly normal?: Vec3Tuple\n /** Repeats the same visual: a LAN client draws the same numbers from the same seed. */\n readonly seed?: number\n /** The recipe's parameter (age, material, weapon...). */\n readonly param?: number | string\n /** Moves with a thing: the effect sits at its position plus the point it was played at. */\n readonly follow?: Follow\n /** Stops after this many seconds (default: the recipe's loop). */\n readonly seconds?: number\n}\n\nexport interface EffectPlayerOptions {\n readonly engine: WorkshopEngine\n readonly effects: Readonly<Record<string, EffectDef>>\n readonly behaviors?: Readonly<Record<string, () => Behavior>>\n /** Where the viewer is, for the recipes that read it. */\n readonly view: EffectView\n /** A stream for a seed (default `lehmer`). */\n readonly streamFor?: (seed: number) => RandomStream\n readonly maxInstances?: number\n readonly onCue?: (cue: CueRequest) => void\n}\n\nexport interface EffectPlayer {\n /** Plays `id` at `point`; `null` when no recipe has that id or the cap of live effects is reached. Returns a handle for `stop`. */\n play(id: string, point: Vec3Tuple, options?: PlayOptions): number | null\n stop(handle: number): void\n /** Runs the timers and ticks of every live effect (the engine's pools are aged by its owner). */\n update(dt: number): void\n clear(): void\n readonly active: number\n has(id: string): boolean\n ids(): readonly string[]\n}\n\ninterface Playing {\n readonly handle: number\n readonly instance: EffectInstance\n readonly random: RandomStream | undefined\n readonly follow: Follow | undefined\n readonly origin: Vec3Tuple\n readonly anchor: Vec3Tuple\n readonly yaw: number\n readonly seconds: number\n}\n\nconst positionOf = (follow: Follow): Vec3Tuple => {\n const source = 'position' in follow ? follow.position : follow\n return [source.x, source.y, source.z]\n}\n\n/** A parameter given by its option id (`'ak'`, `'concrete'`) as the index of the option; a number is taken as it is. */\nfunction paramIndex(def: EffectDef, param: number | string | undefined): number | undefined {\n if (typeof param !== 'string') return param\n const index = def.params?.options.indexOf(param) ?? -1\n return index >= 0 ? index : undefined\n}\n\n/** The turn about the vertical axis that takes the recipe's `heading` onto `direction` (three.js turns by `x' = cos x + sin z`). */\nfunction yawOf(heading: Vec3Tuple, direction: Vec3Tuple | undefined): number {\n if (!direction || (direction[0] === 0 && direction[2] === 0)) return 0\n return Math.atan2(direction[0], direction[2]) - Math.atan2(heading[0], heading[2])\n}\n\n/**\n * Plays the Workshop's recipes anywhere in the world, many at once, each with its own clock, variables and props, a place and a way it faces. They all\n * spawn into the one engine, so the pools stay shared and bounded. This is what `VfxWorld.play` and the host's `EffectSink` use.\n */\nexport function createEffectPlayer(options: EffectPlayerOptions): EffectPlayer {\n const { engine, view } = options\n const factories = options.behaviors ?? WORKSHOP_BEHAVIORS\n const streamOf = options.streamFor ?? ((seed: number) => lehmer(seed))\n const limit = options.maxInstances ?? DEFAULT_MAX_INSTANCES\n const playing: Playing[] = []\n let next = 0\n\n function makeInstance(): EffectInstance {\n const made = new Map<string, Behavior>()\n return new EffectInstance({\n engine,\n view,\n behavior: (id) => {\n let behavior = made.get(id)\n if (!behavior) {\n const make = factories[id]\n if (!make) throw new Error(`no behaviour ${id}`)\n behavior = make()\n made.set(id, behavior)\n }\n return behavior\n },\n behaviors: () => made.values(),\n ...(options.onCue ? { onCue: options.onCue } : {}),\n })\n }\n\n function placementOf(entry: Playing): Placement {\n const origin = entry.follow ? [entry.origin[0] + positionOf(entry.follow)[0], entry.origin[1] + positionOf(entry.follow)[1], entry.origin[2] + positionOf(entry.follow)[2]] as const : entry.origin\n return { origin, anchor: entry.anchor, yaw: entry.yaw }\n }\n\n /** Runs `action` drawing from the effect's own stream, if it has one. */\n function drawing(entry: Playing, action: () => void): void {\n const context = engine.context\n const shared = context.random\n if (entry.random) context.random = entry.random\n try {\n action()\n } finally {\n context.random = shared\n }\n }\n\n return {\n play(id, point, playOptions = {}) {\n const def = options.effects[id]\n if (!def || playing.length >= limit) return null\n const heading = def.heading ?? DEFAULT_HEADING\n const instance = makeInstance()\n const entry: Playing = {\n handle: ++next,\n instance,\n random: playOptions.seed !== undefined ? streamOf(playOptions.seed) : undefined,\n follow: playOptions.follow,\n origin: point,\n anchor: def.anchor ?? ORIGIN,\n yaw: yawOf(heading, playOptions.direction),\n seconds: playOptions.seconds ?? (def.loop && def.loop > 0 ? def.loop : ENDLESS_SECONDS),\n }\n playing.push(entry)\n drawing(entry, () =>\n instance.begin(def, paramIndex(def, playOptions.param), {\n placement: placementOf(entry),\n ...(playOptions.direction ? { direction: playOptions.direction } : {}),\n ...(playOptions.normal ? { normal: playOptions.normal } : {}),\n }),\n )\n return entry.handle\n },\n stop(handle) {\n const index = playing.findIndex((entry) => entry.handle === handle)\n if (index >= 0) playing.splice(index, 1)\n },\n update(dt) {\n for (let index = playing.length - 1; index >= 0; index--) {\n const entry = playing[index]!\n const instance = entry.instance\n instance.setup = { ...instance.setup, placement: placementOf(entry) }\n drawing(entry, () => instance.step(dt))\n if (instance.time >= entry.seconds) playing.splice(index, 1)\n }\n },\n clear() {\n playing.length = 0\n },\n get active() {\n return playing.length\n },\n has: (id) => id in options.effects,\n ids: () => Object.keys(options.effects),\n }\n}\n","import type { Rgb } from './color'\nimport { hexToRgb, srgbChannelToLinear } from './color'\n\n/** One of the 4 blast lights (L349-365). */\nexport interface BlastLight {\n x: number\n y: number\n z: number\n distance: number\n peak: number\n life: number\n t: number\n color: Rgb\n /** The level before the flash layer is applied. */\n level: number\n intensity: number\n}\n\n/** One of the 2 fire lights: they go to the two largest fires. */\nexport interface FireLight {\n x: number\n y: number\n z: number\n distance: number\n intensity: number\n}\n\n/** The glow the puff shader reads (`uGlowPos`, `uGlowCol`, `uGlowI`): where the brightest light is, in linear colour. */\nexport interface LightGlow {\n x: number\n y: number\n z: number\n color: [number, number, number]\n intensity: number\n}\n\nexport interface LightPool {\n readonly blast: BlastLight[]\n readonly fire: FireLight[]\n readonly glow: LightGlow\n /** Which blast light the next explosion takes (the Lab's `xlIdx`). */\n cursor: number\n}\n\nexport const BLAST_LIGHTS = 4\nexport const FIRE_LIGHTS = 2\nconst DEFAULT_BLAST_COLOR = 0xffa050\nconst FIRE_GLOW_COLOR: Rgb = [1, 0.42, 0.12]\nconst PEAK_HOLD = 0.05\n\nexport function createLightPool(): LightPool {\n return {\n blast: Array.from({ length: BLAST_LIGHTS }, () => ({ x: 0, y: -50, z: 0, distance: 30, peak: 0, life: 1, t: 9, color: hexToRgb(DEFAULT_BLAST_COLOR), level: 0, intensity: 0 })),\n fire: Array.from({ length: FIRE_LIGHTS }, () => ({ x: 0, y: -50, z: 0, distance: 16, intensity: 0 })),\n glow: { x: 0, y: 0, z: 0, color: [1, 0.5, 0.2], intensity: 0 },\n cursor: 0,\n }\n}\n\nexport function resetLightPool(pool: LightPool): void {\n for (const light of pool.blast) {\n light.t = 9\n light.level = 0\n light.intensity = 0\n }\n pool.cursor = 0\n}\n\nexport interface BlastLightSpec {\n readonly x: number\n readonly y: number\n readonly z: number\n readonly peak: number\n readonly distance: number\n readonly life: number\n readonly color: number\n}\n\n/** `boomLight` (L357-358): the next blast light, round robin. */\nexport function lightBlast(pool: LightPool, spec: BlastLightSpec): void {\n const light = pool.blast[pool.cursor++ % pool.blast.length]!\n light.x = spec.x\n light.y = spec.y\n light.z = spec.z\n light.distance = spec.distance\n light.peak = spec.peak\n light.life = spec.life\n light.t = 0\n light.color = hexToRgb(spec.color)\n}\n\nexport interface FireForLight {\n readonly x: number\n readonly y: number\n readonly z: number\n readonly r: number\n readonly fade: number\n}\n\nexport interface LightStep {\n readonly dt: number\n /** 1 while the flash layer is on, 0 while it is off (the Lab multiplies by it). */\n readonly flashLayer: number\n readonly clock: number\n readonly fires: readonly FireForLight[]\n}\n\nfunction largestFire(fires: readonly FireForLight[], skip: FireForLight | null): FireForLight | null {\n let best: FireForLight | null = null\n for (const fire of fires) {\n if (fire === skip) continue\n if (best === null || fire.r > best.r) best = fire\n }\n return best\n}\n\nfunction updateBlastLights(pool: LightPool, step: LightStep): BlastLight | null {\n let brightest: BlastLight | null = null\n for (const light of pool.blast) {\n light.t += step.dt\n const age = light.t / light.life\n const level = age < 1 ? light.peak * (light.t < PEAK_HOLD ? 1 : Math.pow(1 - age, 2.2)) * (0.85 + 0.15 * Math.sin(light.t * 60)) : 0\n light.level = level\n light.intensity = level * step.flashLayer\n if (level > (brightest?.level ?? 0)) brightest = light\n }\n return brightest\n}\n\n/** `updateLights` (L350-364): blast lights fade by their curve, the two fire lights follow the two largest fires, and the glow follows the brightest light. */\nexport function updateLights(pool: LightPool, step: LightStep): void {\n const brightest = updateBlastLights(pool, step)\n const brightness = brightest?.level ?? 0\n const first = largestFire(step.fires, null)\n const second = largestFire(step.fires, first)\n const largest = [first, second]\n for (let index = 0; index < FIRE_LIGHTS; index++) {\n const fire = largest[index]\n const light = pool.fire[index]!\n if (!fire) {\n light.intensity = 0\n continue\n }\n light.x = fire.x\n light.y = fire.y + Math.max(0.8, fire.r * 0.6)\n light.z = fire.z\n light.intensity = (1.4 + fire.r * 0.6) * (0.75 + 0.25 * Math.sin(step.clock * 17 + index * 3) + 0.1 * Math.sin(step.clock * 41)) * fire.fade\n light.distance = 10 + fire.r * 4\n }\n if (brightest && brightness > 0.05) {\n pool.glow.x = brightest.x\n pool.glow.y = brightest.y\n pool.glow.z = brightest.z\n pool.glow.color[0] = srgbChannelToLinear(brightest.color[0])\n pool.glow.color[1] = srgbChannelToLinear(brightest.color[1])\n pool.glow.color[2] = srgbChannelToLinear(brightest.color[2])\n pool.glow.intensity = brightness * 0.06 * step.flashLayer\n } else if (first) {\n pool.glow.x = first.x\n pool.glow.y = first.y + 0.5\n pool.glow.z = first.z\n pool.glow.color[0] = FIRE_GLOW_COLOR[0]\n pool.glow.color[1] = FIRE_GLOW_COLOR[1]\n pool.glow.color[2] = FIRE_GLOW_COLOR[2]\n pool.glow.intensity = (0.35 + first.r * 0.12) * first.fade\n } else pool.glow.intensity = 0\n}\n","import type { LodBands } from './types'\n\n/** The game's bands: distance minus the visual radius, 15 / 40 / 80 m, scales 1 / .5 / .2 / .1 (G68203, the Workshop's quality bands). The default. */\nexport const LOD_GAME: LodBands = { edges: [15, 40, 80], scales: [1, 0.5, 0.2, 0.1], radiusFactor: 1 }\n\n/** The Lab's own bands (L481): distance minus three visual radii, 20 / 45 / 85 m, scales 1 / .5 / .2 / .08. Used on the bench and in the goldens. */\nexport const LOD_LAB: LodBands = { edges: [20, 45, 85], scales: [1, 0.5, 0.2, 0.08], radiusFactor: 3 }\n\n/** The scale of an effect `distance` metres from the camera, for an effect whose fireball has `visualRadius`. */\nexport function lodScale(bands: LodBands, distance: number, visualRadius: number): number {\n const effective = distance - visualRadius * bands.radiusFactor\n if (effective < bands.edges[0]) return bands.scales[0]\n if (effective < bands.edges[1]) return bands.scales[1]\n if (effective < bands.edges[2]) return bands.scales[2]\n return bands.scales[3]\n}\n","import type { GroundField } from './ground'\nimport type { RandomStream } from './random'\n\n/** What an explosion leaves on the ground, as data: the renderer builds the meshes (L443-476). */\nexport interface ScorchMark {\n readonly kind: 'scorch'\n readonly x: number\n readonly z: number\n readonly radius: number\n /** Which of the three scorch textures. */\n readonly variant: number\n readonly lift: number\n readonly rotation: number\n}\n\nexport interface DirtMark {\n readonly kind: 'dirt'\n readonly x: number\n readonly z: number\n readonly radius: number\n readonly lift: number\n readonly rotation: number\n}\n\n/** A piece of broken asphalt on the rim of a crater. */\nexport interface RockMark {\n readonly kind: 'rock'\n readonly x: number\n readonly y: number\n readonly z: number\n readonly scale: readonly [number, number, number]\n readonly rotation: readonly [number, number, number]\n readonly plate: boolean\n readonly color: number\n}\n\nexport interface BloodMark {\n readonly kind: 'blood'\n readonly x: number\n readonly y: number\n readonly z: number\n readonly scaleX: number\n readonly scaleZ: number\n readonly rotation: number\n}\n\nexport type Mark = ScorchMark | DirtMark | RockMark | BloodMark\n\nexport type MarkEvent = { readonly type: 'add'; readonly mark: Mark } | { readonly type: 'clear' }\n\nexport interface MarkStore {\n readonly entries: Mark[]\n /** Goes up on every mark added or cleared. */\n readonly version: number\n readonly bloodCount: number\n /** The counter that lifts each decal a hair higher than the last (the Lab's `decalY`). */\n lift: number\n add(mark: Mark): void\n clear(): void\n /** Tells a renderer the moment a mark is made (the ground it conforms to is the ground of that moment) or taken away. */\n subscribe(listener: (event: MarkEvent) => void): () => void\n}\n\nconst BLOOD_LIMIT = 450\nconst SCORCH_VARIANTS = 3\nconst RIM_COLORS = [0x2b2c2f, 0x3a3836] as const\n\nexport function createMarkStore(): MarkStore {\n const entries: Mark[] = []\n let version = 0\n let bloodCount = 0\n const listeners = new Set<(event: MarkEvent) => void>()\n return {\n entries,\n get version() {\n return version\n },\n get bloodCount() {\n return bloodCount\n },\n lift: 0,\n add(mark) {\n entries.push(mark)\n if (mark.kind === 'blood') bloodCount++\n version++\n for (const listener of listeners) listener({ type: 'add', mark })\n },\n clear() {\n entries.length = 0\n bloodCount = 0\n this.lift = 0\n version++\n for (const listener of listeners) listener({ type: 'clear' })\n },\n subscribe(listener) {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n }\n}\n\nfunction nextLift(store: MarkStore): number {\n return store.lift++ % 20\n}\n\n/** `scorch` (L458): a burn mark; the texture and the turn are drawn in that order. */\nexport function addScorch(store: MarkStore, random: RandomStream, x: number, z: number, radius: number): void {\n const variant = Math.floor(random.next() * SCORCH_VARIANTS)\n const lift = 0.03 + nextLift(store) * 0.001\n const rotation = random.next() * 6\n store.add({ kind: 'scorch', x, z, radius, variant, lift, rotation })\n}\n\nfunction addRimRocks(store: MarkStore, ground: GroundField | undefined, random: RandomStream, x: number, z: number, radius: number): void {\n const count = Math.round(6 + radius * 7)\n for (let index = 0; index < count; index++) {\n const angle = (index / count) * Math.PI * 2 + random.between(-0.15, 0.15)\n const distance = radius * random.between(0.95, 1.3)\n const size = random.between(0.12, 0.26) * Math.min(1.6, 0.6 + radius * 0.4)\n const px = x + Math.cos(angle) * distance\n const pz = z + Math.sin(angle) * distance\n const plate = random.next() < 0.6\n const color = RIM_COLORS[random.next() < 0.5 ? 0 : 1]\n const tiltX = random.between(-0.5, 0.5)\n const tiltZ = random.between(-0.6, 0.2)\n store.add({\n kind: 'rock',\n x: px,\n y: (ground?.heightAt(px, pz) ?? 0) + size * 0.12,\n z: pz,\n scale: [size * 2, size * 0.35, size * 1.4],\n rotation: [tiltX, angle, tiltZ],\n plate,\n color,\n })\n }\n}\n\n/** `crater` (L460-468): digs the ground (always), then, when marks are on, lays the dirt, and broken asphalt around the rim. */\nexport function addCrater(store: MarkStore, ground: GroundField | undefined, random: RandomStream, spec: { x: number; z: number; radius: number; depth: number; marks: boolean }): void {\n ground?.dent(random, spec.x, spec.z, spec.radius, spec.depth)\n if (!spec.marks) return\n const rotation = random.next() * 6\n store.add({ kind: 'dirt', x: spec.x, z: spec.z, radius: spec.radius * 1.02, lift: 0.045, rotation })\n addRimRocks(store, ground, random, spec.x, spec.z, spec.radius)\n}\n\n/** `bloodSplat` (L471-475). */\nexport function addBloodSplat(store: MarkStore, ground: GroundField | undefined, random: RandomStream, spec: { x: number; z: number; radius: number }): void {\n if (store.bloodCount > BLOOD_LIMIT) return\n const y = (ground?.heightAt(spec.x, spec.z) ?? 0) + 0.03 + nextLift(store) * 0.0008\n const scaleX = spec.radius * random.between(1.6, 2.4)\n const scaleZ = spec.radius * random.between(1.2, 2)\n store.add({ kind: 'blood', x: spec.x, y, z: spec.z, scaleX, scaleZ, rotation: random.next() * 6 })\n}\n","import { OrderedPool } from '../pool'\nimport type { Ring } from './puffs'\n\nexport function createRingPool(capacity: number): OrderedPool<Ring> {\n return new OrderedPool<Ring>(capacity, () => ({ x: 0, z: 0, y0: 0, rise: 0, rk: 0, R0: 0, R1: 0, r: 0, roll: 0, t: 0, life: 0 }))\n}\n\nfunction ageOrKeep(ring: Ring, dt: number): boolean {\n ring.t += dt\n return ring.t <= ring.life + 1\n}\n\n/** `updateRings` (L736): a ring is kept one second past the life of its puffs. */\nexport function updateRings(pool: OrderedPool<Ring>, dt: number): void {\n pool.compact(ageOrKeep, dt)\n}\n\nexport function spawnRing(pool: OrderedPool<Ring>, spec: Omit<Ring, 't'>): Ring {\n const ring = pool.acquire()\n ring.x = spec.x\n ring.z = spec.z\n ring.y0 = spec.y0\n ring.rise = spec.rise\n ring.rk = spec.rk\n ring.R0 = spec.R0\n ring.R1 = spec.R1\n ring.r = spec.r\n ring.roll = spec.roll\n ring.t = 0\n ring.life = spec.life\n return ring\n}\n","import { OrderedPool } from '../pool'\nimport type { Puff } from './puffs'\n\n/** A shock wave: an air shell that grows to the lethal radius in 120 ms, and a dust ring on the ground (L319-348). The last block is what the renderer reads. */\nexport interface Shock {\n x: number\n y: number\n z: number\n Rs: number\n Rg: number\n t: number\n dur: number\n shellScale: number\n shellAlpha: number\n ringScale: number\n ringAlpha: number\n}\n\nconst DEFAULT_DURATION = 0.3\nconst SHELL_GROWTH_SECONDS = 0.12\nconst SHELL_FADE_SECONDS = 0.16\nconst PUSH_BAND = 0.8\nconst PUSH_CEILING = 3\nconst PUSH_AGE_LIMIT = 2\n\nexport function createShockPool(capacity: number): OrderedPool<Shock> {\n return new OrderedPool<Shock>(capacity, () => ({ x: 0, y: 0, z: 0, Rs: 0, Rg: 0, t: 0, dur: DEFAULT_DURATION, shellScale: 0, shellAlpha: 0, ringScale: 0, ringAlpha: 0 }))\n}\n\nexport function spawnShock(pool: OrderedPool<Shock>, spec: { x: number; y: number; z: number; shellRadius: number; groundRadius: number; duration: number }): Shock {\n const shock = pool.acquire()\n shock.x = spec.x\n shock.y = spec.y\n shock.z = spec.z\n shock.Rs = spec.shellRadius\n shock.Rg = spec.groundRadius\n shock.t = 0\n shock.dur = spec.duration || DEFAULT_DURATION\n shock.shellScale = 0\n shock.shellAlpha = 0\n shock.ringScale = 0\n shock.ringAlpha = 0\n return shock\n}\n\nfunction pushPuffs(puffs: readonly Puff[], shock: Shock, reach: number, dt: number, age: number): void {\n for (const puff of puffs) {\n if (puff.ring || puff.t > PUSH_AGE_LIMIT) continue\n const dx = puff.x - shock.x\n const dz = puff.z - shock.z\n const distance = Math.hypot(dx, dz) + 0.001\n if (Math.abs(distance - reach) < PUSH_BAND && puff.y < PUSH_CEILING) {\n const strength = 4 * dt * (1 - age)\n puff.vx += (dx / distance) * strength * 6\n puff.vz += (dz / distance) * strength * 6\n }\n }\n}\n\n/** `updateShocks` (L335-348), walking the list backwards like the Lab: the fronts push the smoke and dust they meet. */\nexport function updateShocks(pool: OrderedPool<Shock>, puffs: readonly Puff[], dt: number): void {\n for (let index = pool.items.length - 1; index >= 0; index--) {\n const shock = pool.items[index]!\n shock.t += dt\n const age = shock.t / shock.dur\n const shellEase = 1 - Math.pow(1 - Math.min(1, shock.t / SHELL_GROWTH_SECONDS), 3)\n shock.shellScale = Math.max(0.01, shock.Rs * shellEase)\n shock.shellAlpha = Math.max(0, 1 - shock.t / SHELL_FADE_SECONDS) * 0.9\n const ringEase = 1 - Math.pow(1 - Math.min(1, age), 2.2)\n shock.ringScale = Math.max(0.01, shock.Rg * ringEase)\n shock.ringAlpha = Math.max(0, 1 - age) * 0.85\n pushPuffs(puffs, shock, shock.Rg * ringEase, dt, age)\n if (age >= 1) pool.removeAt(index)\n }\n}\n","import { hexToLinearRgb, hexToRgb } from './color'\nimport { SMOKE_COLORS } from './constants'\nimport type { VfxCore } from './core'\nimport { lightBlast } from './lights'\nimport { lodScale } from './lod'\nimport { addCrater, addScorch } from './marks'\nimport { spawnRing } from './pools/rings'\nimport { spawnShock } from './pools/shocks'\nimport type { RandomStream, MutableVec3 } from './random'\nimport { addFire } from './emitters/fire'\nimport { addChunk, addGlow, addPuff, addSpark } from './spawn'\nimport type { ExplosionDef, MushroomSpec } from './types'\nimport { addScaled, createVec3, distanceBetween, normalize } from './vector'\n\n/** Where and how one explosion goes off. */\nexport interface ExplosionCall {\n readonly x: number\n readonly y: number\n readonly z: number\n /** Where it is aimed (a rocket's direction, a charge's face). */\n readonly direction?: MutableVec3\n /** The stream the whole effect draws from: the world's in `shared` mode, the event's own in `per_event`. */\n readonly random: RandomStream\n readonly handle: number\n}\n\ninterface Context {\n readonly core: VfxCore\n readonly def: ExplosionDef\n readonly call: ExplosionCall\n readonly random: RandomStream\n readonly x: number\n readonly y: number\n readonly z: number\n /** Fireball radius. */\n readonly size: number\n /** LOD scale of this explosion. */\n readonly scale: number\n readonly direction: MutableVec3 | undefined\n readonly smokeColor: readonly [number, number, number]\n /** Where the camera is (for the screen flash), distance to the blast. */\n readonly cameraDistance: number\n}\n\nconst DEFAULT_LIGHT = 40\nconst DEFAULT_LIGHT_LIFE = 0.45\nconst DEFAULT_LIGHT_COLOR = 0xffa050\nconst DEFAULT_FLASH_INTENSITY = 6\nconst DEFAULT_SHOCK_DURATION = 0.32\nconst DEFAULT_CHUNK_COLOR = 0x47423d\nconst ROCK_COLORS = [0x2b2c2f, 0x4a3a2c] as const\nconst SCRATCH = createVec3()\n\nfunction pick<T>(random: RandomStream, items: readonly T[]): T {\n return items[Math.floor(random.next() * items.length)]!\n}\n\nfunction composeFlash(context: Context): void {\n const { core, def, x, y, z, size } = context\n if (!core.layers.flash) return\n const flash = def.flash\n const light = { x, y: y + size * 0.6, z, peak: (flash.light || DEFAULT_LIGHT) * 0.7, distance: (def.injury || 10) * 2.4, life: flash.life || DEFAULT_LIGHT_LIFE, color: flash.color || DEFAULT_LIGHT_COLOR }\n core.trace?.light?.(light)\n lightBlast(core.lights, light)\n core.spawned.lights++\n const blinding = flash.blinding === true\n addGlow(core, { x, y: y + size * 0.4, z, s: size * 1.4, s1: size * 3.2, i: flash.intensity || DEFAULT_FLASH_INTENSITY, life: 0.22, color: [1, 0.92, 0.75], curve: 2.5 })\n if (!blinding) addGlow(core, { x, y: y + size * 0.5, z, s: size * 2.2, s1: size * 3.6, i: 2.2, life: def.fuel ? 1.4 : 0.6, color: [1, 0.45, 0.15], curve: 1.6 })\n if (core.reducedMotion) return\n const distance = context.cameraDistance\n const screen = core.screen\n if (distance < 15) {\n screen.flash = Math.max(screen.flash, (blinding ? 1 : 0.32) * (1 - distance / 15))\n screen.flashDecay = blinding ? 0.55 : 7\n }\n if (blinding && distance < 40) {\n screen.flash = Math.max(screen.flash, 1)\n screen.flashDecay = 0.5\n }\n}\n\nfunction composeFireballs(context: Context): void {\n const { core, def, random, x, y, z, size, scale, direction } = context\n if (!core.layers.fire || !def.fireballs) return\n const count = Math.round(def.fireballs * Math.max(scale, 0.35))\n const fuel = def.fuel === true\n const heat = def.heat ?? 1\n for (let index = 0; index < count; index++) {\n const d = random.direction(SCRATCH)\n d.y = fuel ? Math.abs(d.y) * 0.5 + 0.05 : Math.abs(d.y) * 0.8 + 0.1\n if (direction) normalize(addScaled(d, direction, def.directionBias ?? 1.2))\n const speed = size * random.between(4.5, 7.5) * (fuel ? 0.75 : 1)\n const s1 = size * random.between(0.42, 0.62)\n const sg = size * random.between(0.12, 0.22)\n const life = random.between(def.smoke.life * 0.7, def.smoke.life)\n const h0 = random.between(1.05, 1.35) * heat\n const hl = fuel ? random.between(0.8, 1.4) * (def.heatLifeScale ?? 1) : random.between(0.22, 0.42)\n addPuff(core, random, {\n x: x + d.x * size * 0.15, y: y + size * 0.25 + d.y * size * 0.1, z: z + d.z * size * 0.15,\n vx: d.x * speed, vy: d.y * speed + (fuel ? size * 1.4 : size * 0.6), vz: d.z * speed,\n s0: size * 0.22, s1, sg, gk: 9, life, h0, hl, drag: fuel ? 4.2 : 6.5, buoy: fuel ? 2.2 : 1.2, color: context.smokeColor, kind: 0,\n })\n }\n}\n\nfunction composeSmoke(context: Context): void {\n const { core, def, random, x, y, z, size, scale } = context\n if (!core.layers.smoke || !def.smoke.count) return\n const count = Math.round(def.smoke.count * Math.max(scale, 0.3))\n for (let index = 0; index < count; index++) {\n const d = random.direction(SCRATCH)\n d.y = Math.abs(d.y)\n const vy = size * random.between(0.6, 2.2)\n const s1 = size * random.between(0.55, 0.85)\n const sg = size * random.between(0.18, 0.3)\n const life = random.between(def.smoke.life * 0.7, def.smoke.life * 1.1)\n addPuff(core, random, {\n x: x + d.x * size * 0.6, y: y + size * 0.4 + d.y * size * 0.5, z: z + d.z * size * 0.6,\n vx: d.x * size * 2.4, vy, vz: d.z * size * 2.4, s0: size * 0.25, s1, sg, gk: 4, life, h0: 0.32, hl: 0.25, drag: 3, buoy: 0.45, color: context.smokeColor, kind: def.smoke.kind ?? 0,\n })\n }\n}\n\nfunction composeShock(context: Context): void {\n const { core, def, x, y, z, size, scale } = context\n if (!core.layers.shock || def.shock === false || !(scale > 0.15)) return\n const duration = def.shock ? def.shock.duration : DEFAULT_SHOCK_DURATION\n const spec = { x, y: y + size * 0.3, z, shellRadius: def.lethal * 0.9, groundRadius: def.injury * 0.6, duration }\n core.trace?.shock?.(spec)\n spawnShock(core.shocks, spec)\n}\n\nfunction composeDust(context: Context): void {\n const { core, def, random, x, z, size, scale } = context\n if (!core.layers.smoke || !def.dust.count || !(scale > 0.15)) return\n const count = Math.round(def.dust.count * scale)\n const color = hexToLinearRgb(def.dust.color)\n const cone = def.cone\n for (let index = 0; index < count; index++) {\n let angle = random.next() * Math.PI * 2\n if (cone) angle = coneAngle(context) + random.between(-cone.half, cone.half)\n const speed = random.between(0.6, 1) * def.injury * (cone ? 1.6 : 0.9)\n const vy = random.between(0.2, 1.2)\n const s1 = size * random.between(0.5, 0.8)\n const sg = size * random.between(0.2, 0.35)\n const life = random.between(2.2, 4)\n addPuff(core, random, {\n x: x + Math.cos(angle) * 0.3, y: 0.15, z: z + Math.sin(angle) * 0.3,\n vx: Math.cos(angle) * speed, vy, vz: Math.sin(angle) * speed, s0: size * 0.2, s1, sg, gk: 5, life, drag: 3.6, buoy: 0.2, color, kind: 1,\n })\n }\n}\n\n/** The angle of the cone's axis: the direction it is aimed at, else the one in its profile. */\nfunction coneAngle(context: Context): number {\n const cone = context.def.cone\n if (!cone) return 0\n return context.direction ? Math.atan2(context.direction.z, context.direction.x) : cone.angle\n}\n\nfunction sparkDirection(context: Context): MutableVec3 {\n const { def, random, direction } = context\n const cone = def.cone\n if (cone) {\n const angle = coneAngle(context) + random.between(-cone.half, cone.half)\n SCRATCH.x = Math.cos(angle)\n SCRATCH.y = random.between(-0.05, 0.25)\n SCRATCH.z = Math.sin(angle)\n return SCRATCH\n }\n const d = random.direction(SCRATCH)\n d.y = Math.abs(d.y) * 0.9 + 0.05\n if (direction) normalize(addScaled(d, direction, def.directionBias ?? 1))\n return d\n}\n\nfunction composeEmbers(context: Context): void {\n const { core, def, random, x, y, z, size, scale } = context\n const embers = def.shrapnel.embers\n if (!embers) return\n for (let index = 0; index < embers * scale; index++) {\n const d = random.direction(SCRATCH)\n d.y = Math.abs(d.y)\n const vx = d.x * random.between(2, 6)\n const vy = random.between(3, 8)\n const vz = d.z * random.between(2, 6)\n addSpark(core, { x, y: y + size * 0.5, z, vx, vy, vz, life: random.between(1.2, 2.6), w: 0.04, st: 0.02, kind: 4, drag: 1.6, g: 2.5 })\n }\n}\n\nfunction composeShrapnel(context: Context): void {\n const { core, def, random, x, y, z, size, scale } = context\n if (!core.layers.shrapnel || !def.shrapnel.count) return\n const count = Math.round(def.shrapnel.count * scale)\n for (let index = 0; index < count; index++) {\n const d = sparkDirection(context)\n const speed = def.shrapnel.speed * random.between(0.45, 1)\n addSpark(core, {\n x: x + d.x * 0.1, y: y + size * 0.25, z: z + d.z * 0.1, vx: d.x * speed, vy: d.y * speed, vz: d.z * speed,\n life: random.between(0.35, 1.1), w: def.shrapnel.width ?? 0.035, st: 0.03, kind: def.shrapnel.kind, drag: def.shrapnel.kind === 1 ? 0.15 : 0.9,\n })\n }\n composeEmbers(context)\n}\n\nfunction composeDebris(context: Context): void {\n const { core, def, random, x, y, z, scale, direction } = context\n const chunks = def.chunks\n if (!core.layers.shrapnel || !chunks.count || scale < 0.5) return\n const count = Math.round(chunks.count * (scale >= 1 ? 1 : 0.5))\n for (let index = 0; index < count; index++) {\n const d = random.direction(SCRATCH)\n d.y = Math.abs(d.y) * 0.9 + 0.2\n if (direction) normalize(addScaled(d, direction, 0.8))\n const speed = random.between(4, 11) * (chunks.speed ?? 1)\n const s = random.between(0.07, 0.2) * (chunks.size ?? 1)\n const plate = chunks.plate ? random.next() < 0.6 : random.next() < 0.15\n const sy = plate ? s * 0.3 : s * random.between(0.6, 1)\n const color = hexToRgb(chunks.colors.length > 0 ? pick(random, chunks.colors) : DEFAULT_CHUNK_COLOR)\n const hot = random.next() < chunks.hot\n addChunk(core, random, {\n x: x + d.x * 0.2, y: y + 0.2, z: z + d.z * 0.2, vx: d.x * speed, vy: d.y * speed + 2, vz: d.z * speed,\n sx: plate ? s * 1.6 : s, sy, sz: plate ? s * 1.1 : s, color, plate, hot,\n })\n }\n}\n\nfunction composeRimDebris(context: Context): void {\n const { core, random, x, z } = context\n const radius = context.def.mark.crater ?? 0\n if (!core.layers.shrapnel) return\n const speedScale = context.def.chunks.speed ?? 1\n const count = Math.round(4 + radius * 4)\n for (let index = 0; index < count; index++) {\n const angle = random.next() * Math.PI * 2\n const speed = random.between(3, 8) * speedScale\n const s = random.between(0.12, 0.28)\n const vy = random.between(4, 10)\n const color = hexToRgb(random.next() < 0.6 ? ROCK_COLORS[0] : ROCK_COLORS[1])\n addChunk(core, random, {\n x: x + Math.cos(angle) * 0.3, y: 0.1, z: z + Math.sin(angle) * 0.3, vx: Math.cos(angle) * speed * 0.6, vy, vz: Math.sin(angle) * speed * 0.6,\n sx: s * 1.6, sy: s * 0.35, sz: s * 1.2, color, plate: true,\n })\n }\n}\n\nfunction composeMushroom(context: Context, spec: MushroomSpec): void {\n const { core, random, x, y, z } = context\n core.trace?.mushroom?.(x, y, z, spec)\n const color = spec.color !== undefined ? hexToLinearRgb(spec.color) : SMOKE_COLORS.black\n const ring = spawnRing(core.rings, {\n x, z, y0: y + spec.height * 0.15, rise: spec.height, rk: spec.riseRate ?? 0.55, R0: spec.radius * 0.3, R1: spec.radius, r: spec.radius * 0.42, roll: spec.roll ?? 2.4, life: spec.life || 7,\n })\n const lod = core.clock.lod\n const count = Math.round((spec.count || 40) * Math.max(lod, 0.4))\n for (let index = 0; index < count; index++) {\n const s1 = spec.radius * random.between(0.35, 0.5)\n const life = random.between(ring.life * 0.75, ring.life)\n const h0 = random.between(1, 1.25)\n const hl = random.between(0.9, 1.6)\n const puff = addPuff(core, random, { x, y, z, s0: spec.radius * 0.2, s1, sg: spec.radius * 0.06, gk: 3, life, h0, hl, color, kind: 0 })\n puff.ring = ring\n puff.ph = random.next() * Math.PI * 2\n puff.th = random.next() * Math.PI * 2\n }\n const stemCount = Math.round((spec.stem || 18) * Math.max(lod, 0.4))\n for (let index = 0; index < stemCount; index++) {\n const spread = random.next() * 0.6\n const px = x + random.between(-0.4, 0.4) * spec.radius * 0.2\n const pz = z + random.between(-0.4, 0.4) * spec.radius * 0.2\n const vx = random.between(-0.3, 0.3)\n const vy = spec.height * random.between(0.6, 1.4) * (1 - spread)\n const vz = random.between(-0.3, 0.3)\n const s1 = spec.radius * random.between(0.22, 0.32)\n const life = random.between(3, 5)\n const h0 = random.between(0.9, 1.2)\n const hl = random.between(0.6, 1.1)\n addPuff(core, random, { x: px, y: y + 0.3, z: pz, vx, vy, vz, s0: spec.radius * 0.12, s1, sg: spec.radius * 0.05, gk: 4, life, h0, hl, drag: 1.2, buoy: 0.5, color })\n }\n}\n\nfunction composeAfterEffects(context: Context): void {\n const { core, def, random, x, y, z } = context\n const mark = def.mark\n if (mark.crater && mark.dent && y < 1.2) {\n core.emit({ type: 'crater', x, z, radius: mark.crater, depth: mark.dent })\n core.trace?.crater?.(x, z, mark.crater, mark.dent)\n addCrater(core.marks, core.ground, random, { x, z, radius: mark.crater, depth: mark.dent, marks: core.layers.mark })\n if (core.layers.shrapnel) composeRimDebris(context)\n }\n if (mark.scorch && y < 1.2 && core.layers.mark) {\n core.trace?.scorch?.(x, z, mark.scorch)\n addScorch(core.marks, random, x, z, mark.scorch)\n }\n if (def.mushroom && core.layers.fire) composeMushroom(context, def.mushroom)\n if (def.residualFires && core.layers.fire) {\n for (const fire of def.residualFires) {\n addFire(core, random, {\n x: x + (fire.dx ?? 0), y: 0, z: z + (fire.dz ?? 0), r: fire.radius, life: fire.life, rate: fire.rate, smoke: fire.smoke, startRadius: fire.startRadius, grow: fire.grow,\n color: fire.smokeColor !== undefined ? hexToLinearRgb(fire.smokeColor) : undefined,\n }, context.call.handle)\n }\n }\n}\n\nfunction emitRequests(context: Context): void {\n const { core, def, x, y, z } = context\n const point = [x, y, z] as const\n core.emit({\n type: 'blast_front', explosion: def.id, point, glassRadius: Math.min(def.injury, 20) * 0.85, speed: 340, lethal: def.lethal, injury: def.injury, push: def.push,\n hotParts: def.hotParts === true, blinding: def.flash.blinding === true, cone: def.cone ? { angle: coneAngle(context), half: def.cone.half, length: def.cone.length } : undefined,\n })\n if (def.ignite) core.emit({ type: 'ignite', point, radius: def.ignite })\n}\n\n/**\n * The Lab's layer compositor (`blast`, L642-714), layer by layer in the Lab's order and drawing from the stream in the Lab's order: flash, fireball,\n * its own smoke, shock wave, dust, shrapnel, debris, then marks, mushroom and lingering fires, and last what the host does (glass, characters).\n */\nexport function composeExplosion(core: VfxCore, def: ExplosionDef, call: ExplosionCall): number {\n const cameraDistance = distanceBetween(core.camera.x, core.camera.y, core.camera.z, call.x, call.y, call.z)\n const forced = core.clock.forcedLod\n const bandScale = forced ?? lodScale(core.bands, cameraDistance, def.visualRadius)\n const capScale = core.areaCap ? core.areaCap.register(core.clock.time, call.x, call.z) : 1\n const scale = forced ?? bandScale * capScale\n core.clock.lod = scale\n core.clock.lastBlast = core.clock.time\n core.spawned.puffs = core.spawned.sparks = core.spawned.chunks = core.spawned.lights = 0\n const context: Context = {\n core, def, call, random: call.random, x: call.x, y: call.y, z: call.z, size: def.visualRadius, scale, direction: call.direction,\n smokeColor: hexToLinearRgb(def.smoke.color), cameraDistance,\n }\n composeFlash(context)\n core.screen.shake = Math.max(core.screen.shake, (def.shake || 1) / (1 + cameraDistance * 0.12))\n composeFireballs(context)\n composeSmoke(context)\n composeShock(context)\n composeDust(context)\n composeShrapnel(context)\n composeDebris(context)\n composeAfterEffects(context)\n emitRequests(context)\n return scale\n}\n","import type { VfxCore } from '../core'\nimport type { Chunk } from './chunks'\nimport { addBloodSplat } from '../marks'\nimport { SMOKE_COLORS } from '../constants'\nimport { addPuff, addSpark } from '../spawn'\n\nconst RESTITUTION = -0.32\nconst GROUND_FRICTION = 0.5\nconst REST_SPEED = 0.6\nconst REST_SLIDE = 0.5\nconst TRAIL_SECONDS = 1.8\nconst TRAIL_STEP = 0.025\nconst QUARTER_TURN = Math.PI / 2\n\nfunction bounce(core: VfxCore, chunk: Chunk, floor: number): void {\n chunk.y = floor\n if (chunk.blood && !chunk.splat && core.layers.mark) {\n chunk.splat = true\n addBloodSplat(core.marks, core.ground, chunk.rng, { x: chunk.x, z: chunk.z, radius: chunk.rng.between(0.06, 0.13) })\n }\n chunk.vy *= RESTITUTION\n chunk.vx *= GROUND_FRICTION\n chunk.vz *= GROUND_FRICTION\n chunk.ax *= GROUND_FRICTION\n chunk.ay *= GROUND_FRICTION\n chunk.az *= GROUND_FRICTION\n if (Math.abs(chunk.vy) < REST_SPEED && Math.hypot(chunk.vx, chunk.vz) < REST_SLIDE) {\n chunk.rest = true\n chunk.rx = Math.round(chunk.rx / QUARTER_TURN) * QUARTER_TURN\n chunk.rz = Math.round(chunk.rz / QUARTER_TURN) * QUARTER_TURN\n }\n}\n\nfunction leaveTrail(core: VfxCore, chunk: Chunk, dt: number): void {\n chunk.trail -= dt\n if (chunk.trail > 0) return\n chunk.trail = TRAIL_STEP\n const random = chunk.rng\n addSpark(core, {\n x: chunk.x, y: chunk.y, z: chunk.z, vx: chunk.vx * 0.15, vy: chunk.vy * 0.15, vz: chunk.vz * 0.15,\n life: random.between(0.25, 0.45), w: 0.05 + chunk.sx * 0.2, st: 0.05, kind: 0, g: 0, drag: 1,\n })\n if (random.next() < 0.25) {\n addPuff(core, random, { x: chunk.x, y: chunk.y, z: chunk.z, s0: 0.04, s1: 0.14 + chunk.sx * 0.3, sg: 0.15, life: random.between(1, 1.6), drag: 2, buoy: 0.6, color: SMOKE_COLORS.grey, kind: 0 })\n }\n}\n\n/** `updateChunks` (L383-398): gravity, spin, a bounce that kills speed, a rest pose on a quarter turn, and the ember trail of a hot piece. */\nexport function updateChunks(core: VfxCore, dt: number): void {\n for (const chunk of core.chunks.items) {\n chunk.t += dt\n if (chunk.rest) continue\n chunk.vy -= core.gravity * dt\n chunk.x += chunk.vx * dt\n chunk.y += chunk.vy * dt\n chunk.z += chunk.vz * dt\n chunk.rx += chunk.ax * dt\n chunk.ry += chunk.ay * dt\n chunk.rz += chunk.az * dt\n const floor = chunk.sy * 0.45 + core.groundAt(chunk.x, chunk.z)\n if (chunk.y < floor) bounce(core, chunk, floor)\n if (chunk.hot && chunk.t < TRAIL_SECONDS && core.layers.smoke) leaveTrail(core, chunk, dt)\n }\n}\n","import type { ScreenState } from './types'\n\nconst DECAY = { shake: 5, white: 7, red: 2.2, side: 3, chroma: 3, desat: 0.7, gasSeconds: 5, beat: 6 } as const\nexport const INITIAL_FLASH_DECAY = 6\n\nexport function createScreenState(): ScreenState {\n return { shake: 0, flash: 0, flashDecay: INITIAL_FLASH_DECAY, white: 0, red: 0, directionLeft: 0, directionRight: 0, chroma: 0, desat: 0, gas: 0, beat: 0 }\n}\n\nexport function resetScreenState(state: ScreenState): void {\n Object.assign(state, createScreenState())\n}\n\n/**\n * The decays of the Lab (L1087, L1092: flash by its own rate, shake by 5 per second) and the Workshop (W354-355: white, red, the two sides, chroma,\n * desaturation, gas and the heartbeat), with the same constants.\n */\nexport function updateScreen(state: ScreenState, dt: number): void {\n state.flash *= Math.exp(-state.flashDecay * dt)\n state.shake *= Math.exp(-DECAY.shake * dt)\n state.white *= Math.exp(-DECAY.white * dt)\n state.red *= Math.exp(-DECAY.red * dt)\n state.directionLeft *= Math.exp(-DECAY.side * dt)\n state.directionRight *= Math.exp(-DECAY.side * dt)\n state.chroma *= Math.exp(-DECAY.chroma * dt)\n state.desat *= Math.exp(-DECAY.desat * dt)\n state.gas = Math.max(0, state.gas - dt / DECAY.gasSeconds)\n state.beat *= Math.exp(-DECAY.beat * dt)\n}\n","import type { SpriteKindDef } from './kinds'\n\nconst clamp = (v: number, lo: number, hi: number): number => (v < lo ? lo : v > hi ? hi : v)\nconst lerp = (a: number, b: number, t: number): number => a + (b - a) * t\n\nfunction rgb(hex: number): readonly [number, number, number] {\n return [((hex >> 16) & 255) / 255, ((hex >> 8) & 255) / 255, (hex & 255) / 255]\n}\n\n/** Per-spawn overrides. */\nexport interface SpriteSpawnOptions {\n /** `0xRRGGBB`: replaces the kind's colour ramp. */\n color?: number\n /** Multiplier on the start size. */\n size?: number\n /** Multiplier on the life. */\n life?: number\n /** Multiplier on the peak alpha. */\n alpha?: number\n /** Non-zero: a `land` sprite (a drip) that reaches the ground calls the owner's `onLand` with this tag. */\n tag?: number\n /** Who hears the landing (see `VfxWorld.onLand`). */\n owner?: string\n /** Height the sprite stops or lands at, instead of the ground's under it (a splash on a table top). */\n floor?: number\n /** Multiplier on the kind's upward acceleration (slow steam). */\n rise?: number\n}\n\nexport interface KindPoolHost {\n groundAt(x: number, z: number): number\n gravity: number\n land(owner: string, x: number, y: number, z: number, color: number, tag: number): void\n}\n\n/** The destruction renderer's old generator (mulberry32), so a seed gives the same sprites. */\nexport function spriteRandom(seed: number): () => number {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) >>> 0\n let t = a\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/**\n * One fixed-size ring of sprites of the game's kinds, in typed arrays a renderer draws as points: `position`, `color`, `alpha` and `size` are what it\n * reads, `drawCount` how many records from the start. Additive and normal blending are two instances.\n */\nexport class SpriteKindPool {\n live = 0\n /** Records from the start the renderer draws (the highest live index + 1). */\n drawCount = 0\n readonly position: Float32Array\n readonly color: Float32Array\n readonly alpha: Float32Array\n readonly size: Float32Array\n private next = 0\n private high = 0\n private readonly velocity: Float32Array\n private readonly age: Float32Array\n private readonly life: Float32Array\n private readonly size0: Float32Array\n private readonly alive: Uint8Array\n private readonly kind: Uint8Array\n private readonly seed: Float32Array\n private readonly alphaMul: Float32Array\n private readonly tag: Int32Array\n private readonly owner: Int32Array\n private readonly colorHex: Int32Array\n private readonly rgbStart: Float32Array\n private readonly rgbEnd: Float32Array\n private readonly bounced: Uint8Array\n private readonly floor: Float32Array\n private readonly riseMul: Float32Array\n\n constructor(\n readonly capacity: number,\n private readonly defs: readonly SpriteKindDef[],\n private readonly owners: string[],\n ) {\n const n = Math.max(1, capacity)\n this.position = new Float32Array(n * 3)\n this.color = new Float32Array(n * 3)\n this.alpha = new Float32Array(n)\n this.size = new Float32Array(n)\n this.velocity = new Float32Array(n * 3)\n this.age = new Float32Array(n)\n this.life = new Float32Array(n)\n this.size0 = new Float32Array(n)\n this.alive = new Uint8Array(n)\n this.kind = new Uint8Array(n)\n this.seed = new Float32Array(n)\n this.alphaMul = new Float32Array(n)\n this.tag = new Int32Array(n)\n this.owner = new Int32Array(n)\n this.colorHex = new Int32Array(n)\n this.rgbStart = new Float32Array(n * 3)\n this.rgbEnd = new Float32Array(n * 3)\n this.bounced = new Uint8Array(n)\n this.floor = new Float32Array(n)\n this.riseMul = new Float32Array(n)\n }\n\n spawn(kind: number, p: readonly number[], v: readonly number[], random: () => number, options?: SpriteSpawnOptions): void {\n if (this.capacity <= 0) return\n const def = this.defs[kind]!\n const i = this.next\n this.next = (this.next + 1) % this.capacity\n if (this.alive[i]) this.live--\n this.alive[i] = 1\n this.live++\n if (i + 1 > this.high) this.high = i + 1\n this.kind[i] = kind\n this.position.set(p, i * 3)\n this.velocity.set(v, i * 3)\n this.age[i] = 0\n this.life[i] = lerp(def.life[0], def.life[1], random()) * (options?.life ?? 1)\n this.size0[i] = lerp(def.size[0], def.size[1], random()) * (options?.size ?? 1)\n this.seed[i] = random()\n this.alphaMul[i] = options?.alpha ?? 1\n this.tag[i] = options?.tag ?? 0\n this.owner[i] = options?.owner === undefined ? -1 : this.ownerIndex(options.owner)\n this.colorHex[i] = options?.color ?? -1\n this.rgbStart.set(rgb(options?.color ?? def.c0), i * 3)\n this.rgbEnd.set(rgb(options?.color ?? def.c1), i * 3)\n this.bounced[i] = 0\n this.floor[i] = options?.floor ?? Number.NaN\n this.riseMul[i] = options?.rise ?? 1\n this.size[i] = this.size0[i]!\n this.alpha[i] = 0\n }\n\n private ownerIndex(name: string): number {\n let index = this.owners.indexOf(name)\n if (index < 0) index = this.owners.push(name) - 1\n return index\n }\n\n private kill(i: number): void {\n if (!this.alive[i]) return\n this.alive[i] = 0\n this.live--\n this.alpha[i] = 0\n this.size[i] = 0\n }\n\n clear(): void {\n this.alive.fill(0)\n this.alpha.fill(0)\n this.size.fill(0)\n this.live = 0\n this.high = 0\n this.next = 0\n this.drawCount = 0\n }\n\n /** Shoves the live sprites within `radius` of a point away from it (a blast). */\n push(cx: number, cy: number, cz: number, radius: number, speed: number): void {\n for (let i = 0; i < this.high; i++) {\n if (!this.alive[i]) continue\n const dx = this.position[i * 3]! - cx\n const dy = this.position[i * 3 + 1]! - cy\n const dz = this.position[i * 3 + 2]! - cz\n const d = Math.hypot(dx, dy, dz)\n if (d > radius || d < 1e-4) continue\n const f = (1 - d / radius) * speed\n this.velocity[i * 3]! += (dx / d) * f\n this.velocity[i * 3 + 1]! += (dy / d) * f\n this.velocity[i * 3 + 2]! += (dz / d) * f\n }\n }\n\n update(dt: number, host: KindPoolHost): void {\n let top = 0\n for (let i = 0; i < this.high; i++) {\n if (!this.alive[i]) continue\n const def = this.defs[this.kind[i]!]!\n const age = (this.age[i]! + dt)\n this.age[i] = age\n const life = this.life[i]!\n if (age >= life) {\n this.kill(i)\n continue\n }\n const t = age / life\n const i3 = i * 3\n let vx = this.velocity[i3]!\n let vy = this.velocity[i3 + 1]!\n let vz = this.velocity[i3 + 2]!\n vy += (def.rise * this.riseMul[i]! - def.gravity * host.gravity) * dt\n if (def.flutter) {\n const phase = age * 7 + this.seed[i]! * 40\n vx += Math.sin(phase) * def.flutter * dt\n vz += Math.cos(phase * 1.3) * def.flutter * dt\n }\n if (def.drag > 0) {\n const k = Math.exp(-def.drag * dt)\n vx *= k\n vy *= k\n vz *= k\n }\n const x = this.position[i3]! + vx * dt\n let y = this.position[i3 + 1]! + vy * dt\n const z = this.position[i3 + 2]! + vz * dt\n if (def.ground !== 'none') {\n const own = this.floor[i]!\n const gy = Number.isNaN(own) ? host.groundAt(x, z) + 0.005 : own\n if (y < gy) {\n if (def.ground === 'land') {\n const tag = this.tag[i]!\n const owner = this.owner[i]!\n if (tag !== 0 && owner >= 0) host.land(this.owners[owner]!, x, gy, z, this.colorHex[i]! >= 0 ? this.colorHex[i]! : def.c0, tag)\n this.kill(i)\n continue\n }\n y = gy\n if (def.ground === 'bounce' && !this.bounced[i]) {\n this.bounced[i] = 1\n vy = Math.abs(vy) * 0.35\n vx *= 0.6\n vz *= 0.6\n } else {\n vx = vy = vz = 0\n }\n }\n }\n this.velocity[i3] = vx\n this.velocity[i3 + 1] = vy\n this.velocity[i3 + 2] = vz\n this.position[i3] = x\n this.position[i3 + 1] = y\n this.position[i3 + 2] = z\n this.size[i] = this.size0[i]! * lerp(1, def.grow, t)\n this.color[i3] = lerp(this.rgbStart[i3]!, this.rgbEnd[i3]!, t)\n this.color[i3 + 1] = lerp(this.rgbStart[i3 + 1]!, this.rgbEnd[i3 + 1]!, t)\n this.color[i3 + 2] = lerp(this.rgbStart[i3 + 2]!, this.rgbEnd[i3 + 2]!, t)\n let envelope = t < def.fadeIn ? t / def.fadeIn : 1 - (t - def.fadeIn) / (1 - def.fadeIn)\n if (def.flicker) envelope *= 1 - def.flicker * (0.5 + 0.5 * Math.sin(age * 38 + this.seed[i]! * 50))\n this.alpha[i] = clamp(envelope, 0, 1) * def.alpha * this.alphaMul[i]!\n top = i + 1\n }\n this.high = top\n this.drawCount = top\n }\n}\n\nexport { rgb as hexToUnitRgb }\n","{\n \"fire\": {\n \"id\": \"fire\",\n \"additive\": true,\n \"life\": [\n 0.45,\n 0.9\n ],\n \"size\": [\n 0.1,\n 0.2\n ],\n \"grow\": 0.3,\n \"gravity\": 0,\n \"rise\": 2.4,\n \"drag\": 1.2,\n \"c0\": 16760896,\n \"c1\": 12591104,\n \"alpha\": 0.9,\n \"fadeIn\": 0.12,\n \"cone\": 0.7,\n \"ground\": \"none\",\n \"flicker\": 0.35\n },\n \"smoke\": {\n \"id\": \"smoke\",\n \"additive\": false,\n \"life\": [\n 1.8,\n 3.2\n ],\n \"size\": [\n 0.14,\n 0.24\n ],\n \"grow\": 3.2,\n \"gravity\": 0,\n \"rise\": 0.7,\n \"drag\": 0.8,\n \"c0\": 6710886,\n \"c1\": 10132122,\n \"alpha\": 0.35,\n \"fadeIn\": 0.15,\n \"cone\": 0.6,\n \"ground\": \"none\"\n },\n \"sparks\": {\n \"id\": \"sparks\",\n \"additive\": true,\n \"life\": [\n 0.25,\n 0.6\n ],\n \"size\": [\n 0.018,\n 0.03\n ],\n \"grow\": 0.5,\n \"gravity\": 1,\n \"rise\": 0,\n \"drag\": 0.3,\n \"c0\": 16773792,\n \"c1\": 16738832,\n \"alpha\": 1,\n \"fadeIn\": 0.02,\n \"cone\": 0.55,\n \"ground\": \"bounce\"\n },\n \"dust\": {\n \"id\": \"dust\",\n \"additive\": false,\n \"life\": [\n 1,\n 2\n ],\n \"size\": [\n 0.08,\n 0.14\n ],\n \"grow\": 2.5,\n \"gravity\": 0.05,\n \"rise\": 0,\n \"drag\": 2.5,\n \"c0\": 9274745,\n \"c1\": 9274745,\n \"alpha\": 0.4,\n \"fadeIn\": 0.1,\n \"cone\": 0.4,\n \"ground\": \"none\"\n },\n \"shards\": {\n \"id\": \"shards\",\n \"additive\": true,\n \"life\": [\n 0.8,\n 1.4\n ],\n \"size\": [\n 0.02,\n 0.035\n ],\n \"grow\": 0.8,\n \"gravity\": 1,\n \"rise\": 0,\n \"drag\": 0.2,\n \"c0\": 14677247,\n \"c1\": 10473727,\n \"alpha\": 0.9,\n \"fadeIn\": 0.03,\n \"cone\": 0.5,\n \"ground\": \"bounce\",\n \"flicker\": 0.5\n },\n \"splinters\": {\n \"id\": \"splinters\",\n \"additive\": false,\n \"life\": [\n 0.8,\n 1.5\n ],\n \"size\": [\n 0.02,\n 0.035\n ],\n \"grow\": 1,\n \"gravity\": 1,\n \"rise\": 0,\n \"drag\": 0.3,\n \"c0\": 10516042,\n \"c1\": 8017200,\n \"alpha\": 1,\n \"fadeIn\": 0.02,\n \"cone\": 0.5,\n \"ground\": \"bounce\"\n },\n \"chips\": {\n \"id\": \"chips\",\n \"additive\": false,\n \"life\": [\n 0.8,\n 1.5\n ],\n \"size\": [\n 0.025,\n 0.04\n ],\n \"grow\": 1,\n \"gravity\": 1,\n \"rise\": 0,\n \"drag\": 0.3,\n \"c0\": 9077624,\n \"c1\": 7235679,\n \"alpha\": 1,\n \"fadeIn\": 0.02,\n \"cone\": 0.5,\n \"ground\": \"bounce\"\n },\n \"fibers\": {\n \"id\": \"fibers\",\n \"additive\": false,\n \"life\": [\n 1.5,\n 2.5\n ],\n \"size\": [\n 0.02,\n 0.03\n ],\n \"grow\": 1,\n \"gravity\": 0.15,\n \"rise\": 0,\n \"drag\": 2,\n \"c0\": 12101768,\n \"c1\": 12101768,\n \"alpha\": 0.9,\n \"fadeIn\": 0.05,\n \"cone\": 0.4,\n \"ground\": \"stop\",\n \"flutter\": 2.5\n },\n \"leaves\": {\n \"id\": \"leaves\",\n \"additive\": false,\n \"life\": [\n 1.5,\n 2.8\n ],\n \"size\": [\n 0.03,\n 0.05\n ],\n \"grow\": 1,\n \"gravity\": 0.15,\n \"rise\": 0,\n \"drag\": 2,\n \"c0\": 6003260,\n \"c1\": 4882224,\n \"alpha\": 0.95,\n \"fadeIn\": 0.05,\n \"cone\": 0.4,\n \"ground\": \"stop\",\n \"flutter\": 2.8\n },\n \"drips\": {\n \"id\": \"drips\",\n \"additive\": false,\n \"life\": [\n 2,\n 3\n ],\n \"size\": [\n 0.025,\n 0.035\n ],\n \"grow\": 1,\n \"gravity\": 1,\n \"rise\": 0,\n \"drag\": 0,\n \"c0\": 6974058,\n \"c1\": 6974058,\n \"alpha\": 1,\n \"fadeIn\": 0.01,\n \"cone\": 0.2,\n \"ground\": \"land\"\n },\n \"ash\": {\n \"id\": \"ash\",\n \"additive\": false,\n \"life\": [\n 2,\n 4\n ],\n \"size\": [\n 0.02,\n 0.04\n ],\n \"grow\": 1.2,\n \"gravity\": 0.08,\n \"rise\": 0,\n \"drag\": 1.5,\n \"c0\": 2762275,\n \"c1\": 1710102,\n \"alpha\": 0.8,\n \"fadeIn\": 0.1,\n \"cone\": 0.5,\n \"ground\": \"stop\",\n \"flutter\": 0.6\n },\n \"steam\": {\n \"id\": \"steam\",\n \"additive\": false,\n \"life\": [\n 1,\n 2\n ],\n \"size\": [\n 0.12,\n 0.2\n ],\n \"grow\": 3,\n \"gravity\": 0,\n \"rise\": 0.9,\n \"drag\": 1,\n \"c0\": 16777215,\n \"c1\": 14739694,\n \"alpha\": 0.35,\n \"fadeIn\": 0.15,\n \"cone\": 0.6,\n \"ground\": \"none\"\n },\n \"flash\": {\n \"id\": \"flash\",\n \"additive\": true,\n \"life\": [\n 0.12,\n 0.2\n ],\n \"size\": [\n 1.2,\n 1.8\n ],\n \"grow\": 1.6,\n \"gravity\": 0,\n \"rise\": 0,\n \"drag\": 0,\n \"c0\": 16774080,\n \"c1\": 16748592,\n \"alpha\": 1,\n \"fadeIn\": 0.1,\n \"cone\": 0,\n \"ground\": \"none\"\n },\n \"foam\": {\n \"id\": \"foam\",\n \"additive\": false,\n \"life\": [\n 1,\n 1.8\n ],\n \"size\": [\n 0.06,\n 0.1\n ],\n \"grow\": 1.5,\n \"gravity\": 0.6,\n \"rise\": 0,\n \"drag\": 1.5,\n \"c0\": 16054527,\n \"c1\": 14542576,\n \"alpha\": 0.8,\n \"fadeIn\": 0.05,\n \"cone\": 0.5,\n \"ground\": \"stop\"\n }\n}\n","import kindData from '../data/sprite-kinds.json'\n\n/** The kinds of sprite the game's pools make: debris, sparks, smoke, steam, drips... (the destruction renderer's old `ParticleKind`). */\nexport type SpriteKind =\n | 'fire' | 'smoke' | 'sparks' | 'dust' | 'shards' | 'splinters' | 'chips' | 'fibers' | 'leaves' | 'drips' | 'ash' | 'steam' | 'flash' | 'foam'\n\n/** What happens to a sprite that reaches the ground. */\nexport type SpriteGround = 'none' | 'bounce' | 'stop' | 'land'\n\nexport interface SpriteKindDef {\n readonly id: SpriteKind\n readonly additive: boolean\n /** Life range in seconds. */\n readonly life: readonly [number, number]\n /** Start size range in metres (billboard diameter). */\n readonly size: readonly [number, number]\n /** Size multiplier reached at the end of the life. */\n readonly grow: number\n /** Gravity multiplier (1 = full gravity). */\n readonly gravity: number\n /** Constant upward acceleration in m/s² (heat, steam). */\n readonly rise: number\n /** Velocity damping per second. */\n readonly drag: number\n /** `0xRRGGBB` at the start and at the end of the life. */\n readonly c0: number\n readonly c1: number\n readonly alpha: number\n /** Fraction of the life spent fading in. */\n readonly fadeIn: number\n /** How much of the emission direction follows the surface normal (1) versus a random direction (0). */\n readonly cone: number\n readonly ground: SpriteGround\n readonly flutter?: number\n readonly flicker?: number\n}\n\nexport const SPRITE_KINDS: Readonly<Record<SpriteKind, SpriteKindDef>> = kindData as unknown as Record<SpriteKind, SpriteKindDef>\n\n/** A copy of the kinds with some changed (a partial replaces the fields it names), added or removed (`null`); a game tunes its sprites without touching the core. */\nexport function patchSpriteKinds(\n base: Readonly<Record<string, SpriteKindDef>>,\n changes: Readonly<Record<string, Partial<SpriteKindDef> | SpriteKindDef | null>>,\n): Record<string, SpriteKindDef> {\n const result: Record<string, SpriteKindDef> = { ...base }\n for (const [id, change] of Object.entries(changes)) {\n if (change === null) delete result[id]\n else result[id] = { ...(base[id] ?? {}), ...change, id } as SpriteKindDef\n }\n return result\n}\n","import { SpriteKindPool, spriteRandom } from './kind-pool'\nimport type { SpriteSpawnOptions } from './kind-pool'\nimport { SPRITE_KINDS } from './kinds'\nimport type { SpriteKind, SpriteKindDef } from './kinds'\n\ntype Vec3 = readonly [number, number, number]\n\nexport interface SpriteKindSystemOptions {\n /** Most live sprites at once (additive takes 40 %, normal the rest). */\n readonly capacity: number\n /** Count multiplier for bursts (0.6 on low quality). */\n readonly density: number\n readonly seed: number\n readonly groundAt: (x: number, z: number) => number\n readonly gravity: number\n readonly kinds?: Readonly<Record<string, SpriteKindDef>>\n}\n\nexport type LandListener = (x: number, y: number, z: number, color: number, tag: number) => void\n\n/**\n * The game's sprites of fixed kinds (debris, sparks, smoke, steam, drips...), burst or spawned one by one: two pooled rings, additive and normal, that\n * a renderer draws as points. This is the destruction renderer's old particle system with the maths unchanged and the drawing taken out.\n */\nexport class SpriteKindSystem {\n readonly additive: SpriteKindPool\n readonly normal: SpriteKindPool\n private readonly random: () => number\n private readonly ids: readonly string[]\n private readonly defs: readonly SpriteKindDef[]\n private readonly index = new Map<string, number>()\n private readonly owners: string[] = []\n private readonly listeners = new Map<string, LandListener>()\n\n constructor(private readonly options: SpriteKindSystemOptions) {\n const kinds: Readonly<Record<string, SpriteKindDef>> = options.kinds ?? SPRITE_KINDS\n this.ids = Object.keys(kinds)\n this.defs = this.ids.map((id) => kinds[id]!)\n this.ids.forEach((id, at) => this.index.set(id, at))\n const additiveCapacity = Math.floor(options.capacity * 0.4)\n this.additive = new SpriteKindPool(additiveCapacity, this.defs, this.owners)\n this.normal = new SpriteKindPool(options.capacity - additiveCapacity, this.defs, this.owners)\n this.random = spriteRandom(options.seed)\n }\n\n get capacity(): number {\n return this.additive.capacity + this.normal.capacity\n }\n\n get live(): number {\n return this.additive.live + this.normal.live\n }\n\n /** Hears the landing of the drips of `owner` (the ones spawned with `{ owner, tag }`). Returns the function that stops listening. */\n onLand(owner: string, listener: LandListener): () => void {\n this.listeners.set(owner, listener)\n return () => {\n if (this.listeners.get(owner) === listener) this.listeners.delete(owner)\n }\n }\n\n private kindOf(kind: string): { index: number; def: SpriteKindDef } {\n const index = this.index.get(kind)\n if (index === undefined) throw new Error(`unknown sprite kind ${kind}`)\n return { index, def: this.defs[index]! }\n }\n\n /** One sprite with an explicit velocity. */\n spawn(kind: SpriteKind | string, point: Vec3, velocity: Vec3, options?: SpriteSpawnOptions): void {\n const { index, def } = this.kindOf(kind)\n ;(def.additive ? this.additive : this.normal).spawn(index, point, velocity, this.random, options)\n }\n\n /** `count` sprites leaving `point` around `normal` at about `speed` m/s. */\n burst(kind: SpriteKind | string, point: Vec3, normal: Vec3, count: number, speed = 1, options?: SpriteSpawnOptions): void {\n const { def } = this.kindOf(kind)\n const n = Math.max(0, Math.round(count * this.options.density))\n const rnd = this.random\n const length = Math.hypot(normal[0], normal[1], normal[2]) || 1\n const nx = normal[0] / length\n const ny = normal[1] / length\n const nz = normal[2] / length\n for (let k = 0; k < n; k++) {\n const u = rnd() * 2 - 1\n const phase = rnd() * Math.PI * 2\n const s = Math.sqrt(1 - u * u)\n const rx = s * Math.cos(phase)\n const ry = u\n const rz = s * Math.sin(phase)\n let dx = nx * def.cone + rx * (1 - def.cone)\n let dy = ny * def.cone + ry * (1 - def.cone)\n let dz = nz * def.cone + rz * (1 - def.cone)\n // a little scatter even for a pure cone, and never push into the surface for debris\n dx += rx * 0.35\n dy += ry * 0.35\n dz += rz * 0.35\n const l = Math.hypot(dx, dy, dz) || 1\n const sp = speed * (0.35 + 0.65 * rnd())\n const jitter = 0.01 + (def.size[1] > 0.5 ? 0.15 : 0.02)\n this.spawn(\n def.id,\n [point[0] + (rnd() - 0.5) * jitter, point[1] + (rnd() - 0.5) * jitter, point[2] + (rnd() - 0.5) * jitter],\n [(dx / l) * sp, (dy / l) * sp, (dz / l) * sp],\n options,\n )\n }\n }\n\n /** Blast wave: shoves the live sprites away from a point. */\n push(point: Vec3, radius: number, speed: number): void {\n this.additive.push(point[0], point[1], point[2], radius, speed)\n this.normal.push(point[0], point[1], point[2], radius, speed)\n }\n\n update(dt: number): void {\n const host = {\n groundAt: this.options.groundAt,\n gravity: this.options.gravity,\n land: (owner: string, x: number, y: number, z: number, color: number, tag: number) => this.listeners.get(owner)?.(x, y, z, color, tag),\n }\n if (this.additive.live > 0 || this.additive.drawCount > 0) this.additive.update(dt, host)\n if (this.normal.live > 0 || this.normal.drawCount > 0) this.normal.update(dt, host)\n }\n\n clear(): void {\n this.additive.clear()\n this.normal.clear()\n }\n}\n","import type { RandomStream, MutableVec3 } from '../random'\nimport { addScaled, normalize } from '../vector'\nimport type { SpriteRange, Vec3Tuple } from './types'\n\nconst TWO_PI_ROUNDED = 6.2832\nconst WIDE_CONE = 3.1\nconst UP: Vec3Tuple = [0, 1, 0]\n\nexport function drawRange(random: RandomStream, range: SpriteRange | undefined): number {\n if (Array.isArray(range)) return random.between(range[0], range[1])\n return (range as number | undefined) || 0\n}\n\n/** `randUnit` (W166): the page rounds a turn to 6.2832, so this is not `RandomStream.direction`. */\nexport function randomUnit(random: RandomStream, out: MutableVec3): MutableVec3 {\n const up = random.next() * 2 - 1\n const angle = random.next() * TWO_PI_ROUNDED\n const ring = Math.sqrt(1 - up * up)\n out.x = ring * Math.cos(angle)\n out.y = up\n out.z = ring * Math.sin(angle)\n return out\n}\n\nconst tangentA: MutableVec3 = { x: 0, y: 0, z: 0 }\nconst tangentB: MutableVec3 = { x: 0, y: 0, z: 0 }\nconst axis: MutableVec3 = { x: 0, y: 0, z: 0 }\n\nfunction cross(out: MutableVec3, a: MutableVec3, b: MutableVec3): MutableVec3 {\n const x = a.y * b.z - a.z * b.y\n const y = a.z * b.x - a.x * b.z\n const z = a.x * b.y - a.y * b.x\n out.x = x\n out.y = y\n out.z = z\n return out\n}\n\n/** `coneDir` (W169-171): a direction inside `cone` radians of `direction`, two draws (a full sphere when the cone is wide). */\nexport function coneDirection(random: RandomStream, direction: Vec3Tuple | undefined, cone: number, out: MutableVec3): MutableVec3 {\n if (cone >= WIDE_CONE) return randomUnit(random, out)\n const [dx, dy, dz] = direction ?? UP\n const cosTilt = 1 - random.next() * (1 - Math.cos(cone))\n const sinTilt = Math.sqrt(1 - cosTilt * cosTilt)\n const phase = random.next() * TWO_PI_ROUNDED\n axis.x = dx\n axis.y = dy\n axis.z = dz\n tangentA.x = 1\n tangentA.y = 0\n tangentA.z = 0\n if (Math.abs(dx) > 0.9) {\n tangentA.x = 0\n tangentA.y = 1\n }\n normalize(cross(tangentB, axis, tangentA))\n normalize(cross(tangentA, tangentB, axis))\n out.x = dx * cosTilt\n out.y = dy * cosTilt\n out.z = dz * cosTilt\n addScaled(out, tangentA, sinTilt * Math.cos(phase))\n addScaled(out, tangentB, sinTilt * Math.sin(phase))\n return out\n}\n","import type { MutableVec3 } from '../random'\nimport { coneDirection, drawRange } from './direction'\nimport type { DebrisSpawn, WorkshopContext } from './types'\n\nconst CAPACITY = 500\nconst GRAVITY = 9.8\nconst QUARTER_TURN = 1.5708\nconst FADE_SECONDS = 0.5\nconst DEFAULT_SIZE = [0.05, 0.05, 0.05] as const\nconst DEFAULT_SPIN = 12\nconst DEFAULT_COLOR = 0x888888\nconst DEFAULT_LIFE = 8\nconst DEFAULT_BOUNCE = 0.3\nconst FULL_TURN_DRAWN = 6\n\nexport interface DebrisPiece {\n on: boolean\n x: number\n y: number\n z: number\n vx: number\n vy: number\n vz: number\n sx: number\n sy: number\n sz: number\n rx: number\n ry: number\n rz: number\n ax: number\n ay: number\n az: number\n life: number\n bounce: number\n rest: boolean\n color: number\n}\n\nfunction createPiece(): DebrisPiece {\n return { on: false, x: 0, y: 0, z: 0, vx: 0, vy: 0, vz: 0, sx: 0, sy: 0, sz: 0, rx: 0, ry: 0, rz: 0, ax: 0, ay: 0, az: 0, life: 0, bounce: 0, rest: false, color: DEFAULT_COLOR }\n}\n\n/** The Workshop's physics debris (W248-263): 500 boxes in a ring buffer, the newest overwriting the oldest, that tumble, bounce, settle on a face and shrink away. */\nexport class DebrisPool {\n readonly pieces: DebrisPiece[] = Array.from({ length: CAPACITY }, createPiece)\n count = 0\n private next = 0\n private readonly direction: MutableVec3 = { x: 0, y: 0, z: 0 }\n\n constructor(private readonly context: WorkshopContext) {}\n\n spawn(options: DebrisSpawn): void {\n const random = this.context.random\n const piece = this.pieces[this.next++ % CAPACITY]!\n coneDirection(random, options.dir, options.cone ?? 3.2, this.direction)\n const speed = drawRange(random, options.sp)\n const size = options.size ?? DEFAULT_SIZE\n const scale = options.k ? drawRange(random, options.k) : 1\n const box = options.box\n const spin = options.spin || DEFAULT_SPIN\n piece.on = true\n piece.x = options.p[0] + (box ? random.between(-box[0], box[0]) : 0)\n piece.y = options.p[1] + (box ? random.between(-box[1], box[1]) : 0)\n piece.z = options.p[2] + (box ? random.between(-box[2], box[2]) : 0)\n piece.vx = this.direction.x * speed + (options.v ? options.v[0] : 0)\n piece.vy = this.direction.y * speed + (options.v ? options.v[1] : 0)\n piece.vz = this.direction.z * speed + (options.v ? options.v[2] : 0)\n piece.sx = (size[0] as number) * scale\n piece.sy = (size[1] as number) * scale\n piece.sz = (size[2] as number) * scale\n piece.rx = random.between(0, FULL_TURN_DRAWN)\n piece.ry = random.between(0, FULL_TURN_DRAWN)\n piece.rz = random.between(0, FULL_TURN_DRAWN)\n piece.ax = random.between(-1, 1) * spin\n piece.ay = random.between(-1, 1) * spin\n piece.az = random.between(-1, 1) * spin\n piece.life = options.life || DEFAULT_LIFE\n piece.bounce = options.bounce ?? DEFAULT_BOUNCE\n piece.rest = false\n piece.color = options.c ?? DEFAULT_COLOR\n }\n\n clear(): void {\n for (const piece of this.pieces) piece.on = false\n this.count = 0\n }\n\n update(dt: number): void {\n this.count = 0\n for (const piece of this.pieces) {\n if (!piece.on) continue\n this.count++\n piece.life -= dt\n if (piece.life <= 0) {\n piece.on = false\n continue\n }\n if (!piece.rest) this.move(piece, dt)\n }\n }\n\n /** Scale at the end of its life, 1 until the last half second (the renderer's `sh`). */\n static fade(piece: DebrisPiece): number {\n return Math.min(1, piece.life / FADE_SECONDS)\n }\n\n private move(piece: DebrisPiece, dt: number): void {\n piece.vy -= GRAVITY * dt\n piece.x += piece.vx * dt\n piece.y += piece.vy * dt\n piece.z += piece.vz * dt\n piece.rx += piece.ax * dt\n piece.ry += piece.ay * dt\n piece.rz += piece.az * dt\n const groundHeight = this.context.groundAt(piece.x, piece.z) + Math.min(piece.sx, piece.sy, piece.sz) * 0.5\n if (piece.y >= groundHeight) return\n piece.y = groundHeight\n piece.vy *= -piece.bounce\n piece.vx *= 0.55\n piece.vz *= 0.55\n piece.ax *= 0.5\n piece.ay *= 0.5\n piece.az *= 0.5\n if (Math.abs(piece.vy) < 0.5 && Math.hypot(piece.vx, piece.vz) < 0.3) {\n piece.rest = true\n piece.rx = Math.round(piece.rx / QUARTER_TURN) * QUARTER_TURN\n piece.rz = Math.round(piece.rz / QUARTER_TURN) * QUARTER_TURN\n }\n }\n}\n","import type { DecalOptions, Vec3Tuple, WorkshopContext } from './types'\n\nconst CAPACITY = 400\nconst UP: Vec3Tuple = [0, 1, 0]\nconst DEFAULT_LIFE = 60\nconst DEFAULT_GROW = 1.2\n\n/** The seconds a fluid decal waits and then takes to evaporate away (W276); blood, bile and oil only darken. */\nconst EVAPORATION = { fuel: [6, 5], water: [40, 20] } as const\n\nexport interface Decal {\n on: boolean\n x: number\n y: number\n z: number\n sx: number\n sy: number\n t: number\n life: number\n grow: number\n color: number\n /** Where the surface faces, and the colour a fluid dries to (`-1`: it does not dry). */\n normal: Vec3Tuple\n fluid: DecalOptions['fluid'] | undefined\n dryColor: number\n dryAt: number\n dryTime: number\n}\n\nfunction createDecal(): Decal {\n return { on: false, x: 0, y: 0, z: 0, sx: 0, sy: 0, t: 0, life: 0, grow: 0, color: 0, normal: UP, fluid: undefined, dryColor: -1, dryAt: 0, dryTime: 0 }\n}\n\n/** The Workshop's decals (W265-306): 400 marks on the ground in a ring buffer. Wet ones spread and evaporate (fuel, water), the rest last their life. */\nexport class DecalPool {\n readonly decals: Decal[] = Array.from({ length: CAPACITY }, createDecal)\n count = 0\n private next = 0\n\n constructor(private readonly context: WorkshopContext) {}\n\n add(x: number, y: number, z: number, size: number, color: number, options: DecalOptions = {}): void {\n const random = this.context.random\n const index = this.next++ % CAPACITY\n const decal = this.decals[index]!\n const normal = options.n ?? UP\n random.between(0, 6.28)\n const offset = 0.004 + (index % 40) * 0.0004\n decal.on = true\n decal.x = x + normal[0] * offset\n decal.y = y + normal[1] * offset\n decal.z = z + normal[2] * offset\n decal.sx = size * (options.ar ? 1 : random.between(0.8, 1.2))\n decal.sy = size * (options.ar || random.between(0.65, 1.1))\n decal.t = -(options.delay || 0)\n decal.grow = options.grow ?? DEFAULT_GROW\n decal.life = options.life || DEFAULT_LIFE\n decal.color = color\n decal.normal = normal\n const fluid = options.fluid ?? (options.dark ? 'blood' : undefined)\n decal.fluid = fluid\n decal.dryAt = options.dark && !options.fluid ? 0 : options.dryAt ?? (fluid === 'blood' || fluid === 'bile' ? 40 : 0)\n decal.dryTime = options.dark && !options.fluid ? options.dark : options.dryT ?? (fluid === 'blood' || fluid === 'bile' ? 30 : 0)\n decal.dryColor = options.dry ?? (fluid === 'bile' ? 0x3e4220 : -1)\n }\n\n clear(): void {\n for (const decal of this.decals) decal.on = false\n this.count = 0\n }\n\n update(dt: number): void {\n this.count = 0\n for (const decal of this.decals) {\n if (!decal.on) continue\n this.count++\n decal.t += dt\n if (decal.t < 0) continue\n decal.life -= dt\n if (decal.life <= 0) {\n decal.on = false\n continue\n }\n const evaporation = decal.fluid === 'fuel' || decal.fluid === 'water' ? EVAPORATION[decal.fluid] : undefined\n if (evaporation && (decal.t - evaporation[0]) / evaporation[1] >= 1) decal.on = false\n }\n }\n}\n","import { hexToRgb } from '../color'\nimport { lerp } from '../vector'\nimport type { MutableVec3, RandomStream } from '../random'\nimport { coneDirection, drawRange, randomUnit } from './direction'\nimport type { SpriteSpawn, WorkshopContext } from './types'\n\n/** Colour, size and alpha of a particle at its current age: what the renderer reads (`col`, `siz`, `alp`). */\nconst DEFAULT_FADE_IN = 0.1\nconst FLOATS_PER_VECTOR = 3\nconst BYTE_MAX = 255\n\nexport interface DecalFromSprite {\n (x: number, y: number, z: number, size: number, color: number, options: { readonly grow: number; readonly fluid: 'blood' }): void\n}\n\n/**\n * The Workshop's `PSys` (W179-220): a pool of sprites in typed arrays, as the page keeps them. A dead record is replaced by the last one, so the order\n * in the arrays is the page's, and the golden hashes the arrays as they are. Additive and normal-blend systems are two instances.\n */\nexport class SpritePool {\n count = 0\n readonly position: Float32Array\n readonly velocity: Float32Array\n readonly colorStart: Float32Array\n readonly colorEnd: Float32Array\n readonly life: Float32Array\n readonly maxLife: Float32Array\n readonly startSize: Float32Array\n readonly growth: Float32Array\n readonly startAlpha: Float32Array\n readonly gravity: Float32Array\n readonly drag: Float32Array\n readonly fadeIn: Float32Array\n readonly groundMode: Uint8Array\n readonly decalSize: Float32Array\n /** Written by `update`: what the renderer draws. */\n readonly color: Float32Array\n readonly size: Float32Array\n readonly alpha: Float32Array\n private readonly vectorArrays: readonly Float32Array[]\n private readonly scalarArrays: readonly (Float32Array | Uint8Array)[]\n private readonly direction: MutableVec3 = { x: 0, y: 0, z: 0 }\n private readonly unit: MutableVec3 = { x: 0, y: 0, z: 0 }\n\n constructor(readonly capacity: number, private readonly context: WorkshopContext) {\n const vectorArray = (): Float32Array => new Float32Array(capacity * FLOATS_PER_VECTOR)\n const scalarArray = (): Float32Array => new Float32Array(capacity)\n this.position = vectorArray()\n this.velocity = vectorArray()\n this.colorStart = vectorArray()\n this.colorEnd = vectorArray()\n this.color = vectorArray()\n this.life = scalarArray()\n this.maxLife = scalarArray()\n this.startSize = scalarArray()\n this.growth = scalarArray()\n this.startAlpha = scalarArray()\n this.gravity = scalarArray()\n this.drag = scalarArray()\n this.fadeIn = scalarArray()\n this.decalSize = scalarArray()\n this.size = scalarArray()\n this.alpha = scalarArray()\n this.groundMode = new Uint8Array(capacity)\n this.vectorArrays = [this.position, this.velocity, this.colorStart, this.colorEnd]\n this.scalarArrays = [this.life, this.maxLife, this.startSize, this.growth, this.startAlpha, this.gravity, this.drag, this.fadeIn, this.groundMode, this.decalSize]\n }\n\n spawn(options: SpriteSpawn): void {\n if (this.count >= this.capacity) return\n const random: RandomStream = this.context.random\n const index = this.count++\n const offset = index * FLOATS_PER_VECTOR\n let [x, y, z] = options.p\n if (options.r) {\n randomUnit(random, this.unit)\n const reach = Math.cbrt(random.next()) * options.r\n x += this.unit.x * reach\n y += this.unit.y * reach * (options.flat ? 0 : 1)\n z += this.unit.z * reach\n }\n if (options.box) {\n x += random.between(-options.box[0], options.box[0])\n y += random.between(-options.box[1], options.box[1])\n z += random.between(-options.box[2], options.box[2])\n }\n this.position[offset] = x\n this.position[offset + 1] = y\n this.position[offset + 2] = z\n coneDirection(random, options.dir, options.cone ?? 3.2, this.direction)\n const speed = drawRange(random, options.sp)\n this.velocity[offset] = this.direction.x * speed + (options.v ? options.v[0] : 0)\n this.velocity[offset + 1] = this.direction.y * speed + (options.v ? options.v[1] : 0)\n this.velocity[offset + 2] = this.direction.z * speed + (options.v ? options.v[2] : 0)\n const start = hexToRgb(options.c0 ?? 0xffffff)\n const end = options.c1 != null ? hexToRgb(options.c1) : start\n for (let channel = 0; channel < FLOATS_PER_VECTOR; channel++) {\n this.colorStart[offset + channel] = start[channel]\n this.colorEnd[offset + channel] = end[channel]\n }\n this.life[index] = this.maxLife[index] = drawRange(random, options.life || 1)\n this.startSize[index] = drawRange(random, options.size || 0.1)\n this.growth[index] = options.grow || 1\n this.startAlpha[index] = options.a ?? 1\n this.gravity[index] = options.g || 0\n this.drag[index] = options.drag || 0\n this.fadeIn[index] = options.fi ?? DEFAULT_FADE_IN\n this.groundMode[index] = options.gnd || 0\n this.decalSize[index] = options.ds ? drawRange(random, options.ds) : 0.1\n }\n\n kill(index: number): void {\n const last = --this.count\n if (index === last) return\n for (const array of this.vectorArrays) {\n for (let component = 0; component < FLOATS_PER_VECTOR; component++) array[index * FLOATS_PER_VECTOR + component] = array[last * FLOATS_PER_VECTOR + component]\n }\n for (const array of this.scalarArrays) array[index] = array[last]\n }\n\n clear(): void {\n this.count = 0\n }\n\n update(dt: number, leaveDecal: DecalFromSprite): void {\n const { position, velocity } = this\n for (let index = this.count - 1; index >= 0; index--) {\n this.life[index] -= dt\n if (this.life[index] <= 0) {\n this.kill(index)\n continue\n }\n const offset = index * FLOATS_PER_VECTOR\n const age = 1 - this.life[index] / this.maxLife[index]\n velocity[offset + 1] -= this.gravity[index] * dt\n const factor = Math.max(0, 1 - this.drag[index] * dt)\n velocity[offset] *= factor\n velocity[offset + 1] *= factor\n velocity[offset + 2] *= factor\n position[offset] += velocity[offset] * dt\n position[offset + 1] += velocity[offset + 1] * dt\n position[offset + 2] += velocity[offset + 2] * dt\n const mode = this.groundMode[index]\n if (mode) {\n const groundHeight = this.context.groundAt(position[offset], position[offset + 2])\n if (position[offset + 1] < groundHeight) {\n if (mode === 1) {\n this.kill(index)\n continue\n }\n if (mode === 2) {\n position[offset + 1] = groundHeight + 0.001\n velocity[offset + 1] *= -0.3\n velocity[offset] *= 0.55\n velocity[offset + 2] *= 0.55\n }\n if (mode === 3) {\n if (this.context.quality.level < 2) {\n const red = (this.colorStart[offset] * BYTE_MAX) << 16\n const green = (this.colorStart[offset + 1] * BYTE_MAX) << 8\n leaveDecal(position[offset], groundHeight, position[offset + 2], this.decalSize[index], red | green | (this.colorStart[offset + 2] * BYTE_MAX), { grow: 0.15, fluid: 'blood' })\n }\n this.kill(index)\n continue\n }\n }\n }\n this.size[index] = this.startSize[index] * (1 + (this.growth[index] - 1) * age)\n const fadeIn = this.fadeIn[index]\n this.alpha[index] = this.startAlpha[index] * (fadeIn > 0 && age < fadeIn ? age / fadeIn : 1 - (age - fadeIn) / (1 - fadeIn))\n for (let channel = 0; channel < FLOATS_PER_VECTOR; channel++) this.color[offset + channel] = lerp(this.colorStart[offset + channel], this.colorEnd[offset + channel], age)\n }\n }\n}\n","import { hexToRgb } from '../color'\nimport type { MutableVec3 } from '../random'\nimport { lerp } from '../vector'\nimport { coneDirection, drawRange } from './direction'\nimport type { SpriteSpawn, WorkshopContext } from './types'\n\nconst FLOATS_PER_VECTOR = 3\nconst SEGMENT_FLOATS = 6\nconst TAIL_BRIGHTNESS = 0.15\n\n/** The Workshop's `Streaks` (W223-245): short lines that follow their own velocity (sparks, tracers, rain-like glints). Same swap-with-last pool as `SpritePool`. */\nexport class StreakPool {\n count = 0\n readonly point: Float32Array\n readonly velocity: Float32Array\n readonly colorStart: Float32Array\n readonly colorEnd: Float32Array\n readonly life: Float32Array\n readonly maxLife: Float32Array\n readonly length: Float32Array\n readonly gravity: Float32Array\n readonly drag: Float32Array\n readonly groundMode: Uint8Array\n readonly startAlpha: Float32Array\n /** Two end points and two colours per line: what the renderer draws. */\n readonly segment: Float32Array\n readonly segmentColor: Float32Array\n private readonly vectorArrays: readonly Float32Array[]\n private readonly scalarArrays: readonly (Float32Array | Uint8Array)[]\n private readonly direction: MutableVec3 = { x: 0, y: 0, z: 0 }\n\n constructor(readonly capacity: number, private readonly context: WorkshopContext) {\n const vectorArray = (): Float32Array => new Float32Array(capacity * FLOATS_PER_VECTOR)\n const scalarArray = (): Float32Array => new Float32Array(capacity)\n this.point = vectorArray()\n this.velocity = vectorArray()\n this.colorStart = vectorArray()\n this.colorEnd = vectorArray()\n this.life = scalarArray()\n this.maxLife = scalarArray()\n this.length = scalarArray()\n this.gravity = scalarArray()\n this.drag = scalarArray()\n this.startAlpha = scalarArray()\n this.groundMode = new Uint8Array(capacity)\n this.segment = new Float32Array(capacity * SEGMENT_FLOATS)\n this.segmentColor = new Float32Array(capacity * SEGMENT_FLOATS)\n this.vectorArrays = [this.point, this.velocity, this.colorStart, this.colorEnd]\n this.scalarArrays = [this.life, this.maxLife, this.length, this.gravity, this.drag, this.groundMode, this.startAlpha]\n }\n\n spawn(options: SpriteSpawn): void {\n if (this.count >= this.capacity) return\n const random = this.context.random\n const index = this.count++\n const offset = index * FLOATS_PER_VECTOR\n let [x, y, z] = options.p\n if (options.box) {\n x += random.between(-options.box[0], options.box[0])\n y += random.between(-options.box[1], options.box[1])\n z += random.between(-options.box[2], options.box[2])\n }\n this.point[offset] = x\n this.point[offset + 1] = y\n this.point[offset + 2] = z\n coneDirection(random, options.dir, options.cone ?? 3.2, this.direction)\n const speed = drawRange(random, options.sp)\n this.velocity[offset] = this.direction.x * speed + (options.v ? options.v[0] : 0)\n this.velocity[offset + 1] = this.direction.y * speed + (options.v ? options.v[1] : 0)\n this.velocity[offset + 2] = this.direction.z * speed + (options.v ? options.v[2] : 0)\n const start = hexToRgb(options.c0 ?? 0xffd080)\n const end = options.c1 != null ? hexToRgb(options.c1) : start\n for (let channel = 0; channel < FLOATS_PER_VECTOR; channel++) {\n this.colorStart[offset + channel] = start[channel]\n this.colorEnd[offset + channel] = end[channel]\n }\n this.life[index] = this.maxLife[index] = drawRange(random, options.life || 0.4)\n this.length[index] = options.len || 0.02\n this.gravity[index] = options.g || 0\n this.drag[index] = options.drag || 0\n this.groundMode[index] = options.gnd || 0\n this.startAlpha[index] = options.a ?? 1\n }\n\n kill(index: number): void {\n const last = --this.count\n if (index === last) return\n for (const array of this.vectorArrays) {\n for (let component = 0; component < FLOATS_PER_VECTOR; component++) array[index * FLOATS_PER_VECTOR + component] = array[last * FLOATS_PER_VECTOR + component]\n }\n for (const array of this.scalarArrays) array[index] = array[last]\n }\n\n clear(): void {\n this.count = 0\n }\n\n update(dt: number): void {\n const { point, velocity } = this\n for (let index = this.count - 1; index >= 0; index--) {\n this.life[index] -= dt\n if (this.life[index] <= 0) {\n this.kill(index)\n continue\n }\n const offset = index * FLOATS_PER_VECTOR\n const age = 1 - this.life[index] / this.maxLife[index]\n velocity[offset + 1] -= this.gravity[index] * dt\n const factor = Math.max(0, 1 - this.drag[index] * dt)\n velocity[offset] *= factor\n velocity[offset + 1] *= factor\n velocity[offset + 2] *= factor\n point[offset] += velocity[offset] * dt\n point[offset + 1] += velocity[offset + 1] * dt\n point[offset + 2] += velocity[offset + 2] * dt\n if (this.groundMode[index]) {\n const groundHeight = this.context.groundAt(point[offset], point[offset + 2])\n if (point[offset + 1] < groundHeight) {\n if (this.groundMode[index] === 1) {\n this.kill(index)\n continue\n }\n point[offset + 1] = groundHeight + 0.001\n velocity[offset + 1] *= -0.35\n velocity[offset] *= 0.6\n velocity[offset + 2] *= 0.6\n }\n }\n const length = this.length[index]\n const alpha = this.startAlpha[index] * (1 - age)\n const at = index * SEGMENT_FLOATS\n this.segment[at] = point[offset]\n this.segment[at + 1] = point[offset + 1]\n this.segment[at + 2] = point[offset + 2]\n this.segment[at + 3] = point[offset] - velocity[offset] * length\n this.segment[at + 4] = point[offset + 1] - velocity[offset + 1] * length\n this.segment[at + 5] = point[offset + 2] - velocity[offset + 2] * length\n for (let channel = 0; channel < FLOATS_PER_VECTOR; channel++) {\n const shade = lerp(this.colorStart[offset + channel], this.colorEnd[offset + channel], age) * alpha\n this.segmentColor[at + channel] = shade\n this.segmentColor[at + 3 + channel] = shade * TAIL_BRIGHTNESS\n }\n }\n }\n}\n","import type { Vec3Tuple, WorkshopContext } from './types'\n\nconst RING_CAPACITY = 120\nconst LIGHT_CAPACITY = 4\nconst UP: Vec3Tuple = [0, 1, 0]\nconst DEFAULT_LIGHT_DISTANCE = 14\n\nexport interface WaveRing {\n on: boolean\n point: Vec3Tuple\n from: number\n to: number\n t: number\n duration: number\n color: number\n normal: Vec3Tuple\n hold: number\n}\n\n/** The Workshop's expanding rings on the ground (W308-315): 120 in a ring buffer. A ring with `hold` stays at that brightness until cleared. */\nexport class WaveRingPool {\n readonly rings: WaveRing[] = Array.from({ length: RING_CAPACITY }, () => ({ on: false, point: UP, from: 0, to: 0, t: 0, duration: 1, color: 0, normal: UP, hold: 0 }))\n count = 0\n private next = 0\n\n add(point: Vec3Tuple, from: number, to: number, duration: number, color: number, normal?: Vec3Tuple, hold?: number): void {\n const ring = this.rings[this.next++ % RING_CAPACITY]!\n ring.on = true\n ring.point = [point[0], point[1], point[2]]\n ring.from = from\n ring.to = to\n ring.t = 0\n ring.duration = duration\n ring.color = color\n ring.normal = normal ?? UP\n ring.hold = hold || 0\n }\n\n clear(): void {\n for (const ring of this.rings) ring.on = false\n this.count = 0\n }\n\n update(dt: number): void {\n this.count = 0\n for (const ring of this.rings) {\n if (!ring.on) continue\n this.count++\n ring.t += dt\n if (ring.t / ring.duration >= 1 && !ring.hold) ring.on = false\n }\n }\n}\n\nexport interface FlashLight {\n x: number\n y: number\n z: number\n color: number\n distance: number\n peak: number\n duration: number\n t: number\n intensity: number\n}\n\nexport interface FireLightSlot {\n x: number\n y: number\n z: number\n intensity: number\n}\n\n/** The four short flashes of the Workshop (W333-337), taken in turn, and its two fire lights. */\nexport class FlashLightPool {\n readonly lights: FlashLight[] = Array.from({ length: LIGHT_CAPACITY }, () => ({ x: 0, y: 0, z: 0, color: 0xffc070, distance: DEFAULT_LIGHT_DISTANCE, peak: 0, duration: 1, t: 0, intensity: 0 }))\n readonly fire: FireLightSlot[] = [\n { x: 0, y: 0, z: 0, intensity: 0 },\n { x: 0, y: 0, z: 0, intensity: 0 },\n ]\n private next = 0\n\n constructor(private readonly context: WorkshopContext) {}\n\n get lit(): number {\n return this.lights.filter((light) => light.intensity > 0).length\n }\n\n flash(point: Vec3Tuple, color: number, intensity: number, duration: number, distance?: number, force?: boolean | 'boom'): void {\n const { level } = this.context.quality\n if (level >= 1 && !force) return\n if (level >= 2 && force !== 'boom') return\n const light = this.lights[this.next++ % LIGHT_CAPACITY]!\n light.x = point[0]\n light.y = point[1]\n light.z = point[2]\n light.color = color\n light.distance = distance || DEFAULT_LIGHT_DISTANCE\n light.peak = intensity\n light.duration = duration\n light.t = 0\n light.intensity = intensity\n }\n\n clear(): void {\n for (const light of this.lights) light.intensity = 0\n for (const light of this.fire) light.intensity = 0\n }\n\n update(dt: number): void {\n for (const light of this.lights) {\n if (light.intensity <= 0) continue\n light.t += dt\n const age = light.t / light.duration\n light.intensity = age >= 1 ? 0 : light.peak * (1 - age) * (1 - age)\n }\n }\n}\n","import { PROFILES } from '../budget'\nimport type { RandomStream } from '../random'\nimport { createScreenState, resetScreenState, updateScreen } from '../screen'\nimport type { ScreenState, VfxProfile } from '../types'\nimport { DebrisPool } from './debris'\nimport { DecalPool } from './decals'\nimport { SpritePool } from './sprites'\nimport { StreakPool } from './streaks'\nimport type { DebrisSpawn, DecalOptions, SpriteSpawn, SpriteSystem, Vec3Tuple, WorkshopContext, WorkshopTrace } from './types'\nimport { FlashLightPool, WaveRingPool } from './waves'\n\nconst QUALITY_MULTIPLIERS = [1, 0.5, 0.2] as const\nconst FIRE_FLICKER_SWAY = 0.25\nconst FIRE_FLICKER_JITTER = 0.08\nconst LENS_FADE = 0.16\n\n/** Water or blood on the camera lens: a soft blob that fades and runs down (W351-352). */\nexport interface LensBlob {\n x: number\n y: number\n radius: number\n color: string\n alpha: number\n fall: number\n}\n\n/** The page's `P0` (W347, W1277): what an effect asks of the post-process for this frame only; it is emptied before every frame's tick. */\nexport interface PostProcess {\n desat?: number\n tunnel?: number\n blur?: number\n cold?: number\n chroma?: number\n hue?: number\n red?: number\n tintAlpha?: number\n tintColor?: string\n}\n\n/**\n * Where an effect is put when it is played at a point instead of on the Workshop's set: what the recipe wrote at `anchor` lands at `origin`, turned\n * about the vertical axis by `yaw`. Positions are moved and turned, directions and velocities only turned.\n */\nexport interface Placement {\n readonly origin: Vec3Tuple\n readonly anchor: Vec3Tuple\n readonly yaw: number\n}\n\nexport interface WorkshopOptions {\n readonly random: RandomStream\n readonly profile?: VfxProfile\n readonly groundAt?: (x: number, z: number) => number\n readonly trace?: WorkshopTrace\n}\n\n/** The default ground of the Workshop scene: a raised kerb 12 cm high between z -4.5 and -2.9 (W29). */\nexport function workshopGround(x: number, z: number): number {\n return z < -2.9 && z > -4.5 && Math.abs(x) < 13 ? 0.12 : 0\n}\n\n/**\n * Everything the Workshop's recipes spawn into and the loop that ages it (W168-371, W1285-1287): sprites, streaks, debris, decals, rings, lights, the\n * screen state and the lens blobs, plus the quality level that thins what a recipe asks for and the accumulators that turn a rate into spawns.\n */\nexport class WorkshopEngine {\n readonly context: WorkshopContext\n readonly add: SpritePool\n readonly normal: SpritePool\n readonly streaks: StreakPool\n readonly debris: DebrisPool\n readonly decals: DecalPool\n readonly rings = new WaveRingPool()\n readonly lights: FlashLightPool\n readonly screen: ScreenState = createScreenState()\n readonly lens: LensBlob[] = []\n post: PostProcess = {}\n /** Set by whoever runs an effect for the time it runs; `undefined` leaves every number as the recipe wrote it. */\n placement: Placement | undefined\n private readonly accumulators = new Map<string, number>()\n\n constructor(options: WorkshopOptions) {\n const profile = options.profile ?? PROFILES.high\n this.context = { random: options.random, groundAt: options.groundAt ?? workshopGround, quality: { level: 0, mult: 1 }, trace: options.trace }\n this.add = new SpritePool(profile.sprites.add, this.context)\n this.normal = new SpritePool(profile.sprites.normal, this.context)\n this.streaks = new StreakPool(profile.streaks, this.context)\n this.debris = new DebrisPool(this.context)\n this.decals = new DecalPool(this.context)\n this.lights = new FlashLightPool(this.context)\n }\n\n get random(): RandomStream {\n return this.context.random\n }\n\n get quality(): number {\n return this.context.quality.level\n }\n\n setQuality(level: number): void {\n this.context.quality.level = level\n this.context.quality.mult = QUALITY_MULTIPLIERS[level] ?? 1\n }\n\n /** `n` (W340): a count thinned by the quality level, never to zero when something was asked. */\n scaled(count: number): number {\n return Math.max(count > 0 ? 1 : 0, Math.round(count * this.context.quality.mult))\n }\n\n /** A point of the recipe's space in the world (`undefined` placement: as is). */\n place(point: Vec3Tuple): Vec3Tuple {\n const placement = this.placement\n if (!placement) return point\n const { anchor, origin, yaw } = placement\n const x = point[0] - anchor[0]\n const z = point[2] - anchor[2]\n const cos = Math.cos(yaw)\n const sin = Math.sin(yaw)\n return [origin[0] + cos * x + sin * z, origin[1] + point[1] - anchor[1], origin[2] - sin * x + cos * z]\n }\n\n /** A direction or velocity of the recipe's space in the world. */\n turn(vector: Vec3Tuple): Vec3Tuple {\n const placement = this.placement\n if (!placement) return vector\n const cos = Math.cos(placement.yaw)\n const sin = Math.sin(placement.yaw)\n return [cos * vector[0] + sin * vector[2], vector[1], -sin * vector[0] + cos * vector[2]]\n }\n\n private placed<T extends { readonly p: Vec3Tuple; readonly dir?: Vec3Tuple; readonly v?: Vec3Tuple }>(options: T): T {\n if (!this.placement) return options\n return { ...options, p: this.place(options.p), ...(options.dir ? { dir: this.turn(options.dir) } : {}), ...(options.v ? { v: this.turn(options.v) } : {}) }\n }\n\n spawn(system: SpriteSystem, recipe: SpriteSpawn): void {\n const options = this.placed(recipe)\n this.context.trace?.(system, [options])\n if (system === 'add') this.add.spawn(options)\n else if (system === 'normal') this.normal.spawn(options)\n else this.streaks.spawn(options)\n }\n\n burst(system: SpriteSystem, count: number, options: SpriteSpawn): void {\n const total = this.scaled(count)\n for (let spawned = 0; spawned < total; spawned++) this.spawn(system, options)\n }\n\n /** `emit` (W343-345): `rate` per second, thinned by the quality, carried over between frames under `key`. `options` is read again for every particle. */\n emit(key: string, system: SpriteSystem, rate: number, dt: number, options: () => SpriteSpawn): void {\n let carried = (this.accumulators.get(key) ?? 0) + rate * this.context.quality.mult * dt\n while (carried >= 1) {\n carried -= 1\n this.spawn(system, options())\n }\n this.accumulators.set(key, carried)\n }\n\n debrisPiece(recipe: DebrisSpawn): void {\n const options = this.placed(recipe)\n this.context.trace?.('debris', [options])\n this.debris.spawn(options)\n }\n\n decal(recipe: readonly [number, number, number, number, number, DecalOptions?]): void {\n let args = recipe\n if (this.placement) {\n const [x, y, z] = this.place([recipe[0], recipe[1], recipe[2]])\n const options = recipe[5]\n args = [x, y, z, recipe[3], recipe[4], options?.n ? { ...options, n: this.turn(options.n) } : options]\n }\n this.context.trace?.('decal', args)\n this.decals.add(args[0], args[1], args[2], args[3], args[4], args[5])\n }\n\n ring(recipe: readonly [Vec3Tuple, number, number, number, number, Vec3Tuple?, number?]): void {\n const args = this.placement ? ([this.place(recipe[0]), recipe[1], recipe[2], recipe[3], recipe[4], recipe[5] && this.turn(recipe[5]), recipe[6]] as const) : recipe\n this.context.trace?.('ring', args)\n this.rings.add(args[0], args[1], args[2], args[3], args[4], args[5], args[6])\n }\n\n flash(recipe: readonly [Vec3Tuple, number, number, number, number?, (boolean | 'boom')?]): void {\n const args = this.placement ? ([this.place(recipe[0]), recipe[1], recipe[2], recipe[3], recipe[4], recipe[5]] as const) : recipe\n this.context.trace?.('flash', args)\n this.lights.flash(args[0], args[1], args[2], args[3], args[4], args[5])\n }\n\n /** `fireLight` (W400): sways with the clock and flickers with one draw. */\n fireLight(slot: 0 | 1, recipe: Vec3Tuple, intensity: number, time: number): void {\n const light = this.lights.fire[slot]!\n const point = this.place(recipe)\n light.x = point[0]\n light.y = point[1]\n light.z = point[2]\n light.intensity = intensity * (0.75 + FIRE_FLICKER_SWAY * Math.sin(time * 23) * Math.sin(time * 7.3) + this.random.between(-FIRE_FLICKER_JITTER, FIRE_FLICKER_JITTER))\n }\n\n lensBlob(x: number, y: number, radius: number, color: string, alpha: number): void {\n this.lens.push({ x, y, radius, color, alpha, fall: this.random.between(2, 8) })\n }\n\n /** The order of the page's loop (W1285-1287): the sprites, streaks, debris, decals, rings and lights, then the screen and its lens. */\n update(dt: number): void {\n const leaveDecal = (x: number, y: number, z: number, size: number, color: number, options: DecalOptions): void => {\n this.decal([x, y, z, size, color, options])\n }\n this.add.update(dt, leaveDecal)\n this.normal.update(dt, leaveDecal)\n this.streaks.update(dt)\n this.debris.update(dt)\n this.decals.update(dt)\n this.rings.update(dt)\n this.lights.update(dt)\n updateScreen(this.screen, dt)\n for (let index = this.lens.length - 1; index >= 0; index--) {\n const blob = this.lens[index]!\n blob.alpha -= dt * LENS_FADE\n blob.y += blob.fall * dt\n if (blob.alpha <= 0) this.lens.splice(index, 1)\n }\n }\n\n clear(): void {\n this.add.clear()\n this.normal.clear()\n this.streaks.clear()\n this.debris.clear()\n this.decals.clear()\n this.rings.clear()\n this.lights.clear()\n this.accumulators.clear()\n resetScreenState(this.screen)\n this.lens.length = 0\n this.post = {}\n }\n}\n","import type { Rgb } from './color'\n\nexport type { Rgb }\n\nexport type Vec3Like = readonly [number, number, number]\n\n/** The six layers of an explosion the viewer can turn off one by one (L478): flash and light, fire, shock wave, smoke and dust, shrapnel and debris, marks on the ground. */\nexport type VfxLayer = 'flash' | 'fire' | 'shock' | 'smoke' | 'shrapnel' | 'mark'\n\nexport const VFX_LAYERS: readonly VfxLayer[] = ['flash', 'fire', 'shock', 'smoke', 'shrapnel', 'mark']\n\n/** A chain of things that move: anything with a position, or a position. */\nexport type Follow = { readonly x: number; readonly y: number; readonly z: number } | { readonly position: { readonly x: number; readonly y: number; readonly z: number } }\n\n/** A residual fire left behind by an explosion (L798 `residual`), or started by `world.fire`. */\nexport interface FireSpec {\n /** Offsets from the blast point. */\n readonly dx?: number\n readonly dz?: number\n readonly radius: number\n readonly life: number\n readonly rate?: number\n readonly smoke?: number\n /** Grows from `startRadius` to `radius` over `grow` seconds. */\n readonly startRadius?: number\n readonly grow?: number\n /** `0xRRGGBB` of the smoke the fire gives (default soot black). */\n readonly smokeColor?: number\n}\n\nexport interface MushroomSpec {\n readonly height: number\n readonly radius: number\n readonly count: number\n readonly stem: number\n readonly life: number\n /** How fast the ring climbs towards `height` (the Lab's `rk`, default .55). */\n readonly riseRate?: number\n readonly roll?: number\n readonly color?: number\n}\n\n/** The Lab's explosion profile with English names; every number is the Lab's (`sources` lists the lines they come from). */\nexport interface ExplosionDef {\n readonly id: string\n /** Radius (m) inside which a body is torn apart, and the one inside which it is hurt. */\n readonly lethal: number\n readonly injury: number\n /** Radius of the fireball (`vis`). */\n readonly visualRadius: number\n readonly fireballs: number\n readonly fuel?: boolean\n readonly heat?: number\n readonly heatLifeScale?: number\n readonly smoke: { readonly color: number; readonly count: number; readonly life: number; readonly kind?: 0 | 3 }\n readonly dust: { readonly color: number; readonly count: number }\n readonly shrapnel: { readonly count: number; readonly kind: 0 | 1 | 2 | 3 | 4; readonly speed: number; readonly width?: number; readonly embers?: number }\n readonly chunks: { readonly count: number; readonly colors: readonly number[]; readonly plate?: boolean; readonly hot: number; readonly speed?: number; readonly size?: number }\n readonly mark: { readonly scorch?: number; readonly crater?: number; readonly dent?: number }\n readonly flash: { readonly light: number; readonly life?: number; readonly color?: number; readonly intensity?: number; readonly blinding?: boolean }\n readonly shock?: false | { readonly duration: number }\n readonly shake: number\n readonly push: number\n readonly mushroom?: MushroomSpec\n readonly residualFires?: readonly FireSpec[]\n /** Radius (m) in which characters catch fire. */\n readonly ignite?: number\n /** The pieces that fly are hot (the characters' parts burn). */\n readonly hotParts?: boolean\n readonly cone?: { readonly angle: number; readonly half: number; readonly length: number }\n readonly directionBias?: number\n readonly sources: readonly string[]\n}\n\n/** What a host does with what an effect cannot do by itself (break the windows, hurt the characters, dig the ground). */\nexport type VfxSideRequest =\n | { readonly type: 'crater'; readonly x: number; readonly z: number; readonly radius: number; readonly depth: number }\n | { readonly type: 'ignite'; readonly point: Vec3Like; readonly radius: number }\n | {\n readonly type: 'blast_front'\n readonly explosion: string\n readonly point: Vec3Like\n /** Where the glass breaks, damage and push reach: the Lab's `min(injury, 20) * .85`. */\n readonly glassRadius: number\n /** Metres per second the front travels (the speed of sound): the host delays what it breaks by `distance / speed`. */\n readonly speed: number\n readonly lethal: number\n readonly injury: number\n readonly push: number\n readonly hotParts: boolean\n readonly blinding: boolean\n readonly cone?: { readonly angle: number; readonly half: number; readonly length: number }\n }\n\nexport interface VfxProfile {\n readonly puffs: number\n readonly sparks: number\n readonly glows: number\n readonly chunks: number\n readonly sprites: { readonly add: number; readonly normal: number }\n readonly streaks: number\n readonly debris: number\n}\n\nexport type VfxProfileName = 'low' | 'medium' | 'high'\n\nexport interface LodBands {\n /** Distances (m) at which the scale drops. */\n readonly edges: readonly [number, number, number]\n /** The scale in each of the four bands. */\n readonly scales: readonly [number, number, number, number]\n /** How many visual radii are taken off the distance: a big blast stays detailed farther away. */\n readonly radiusFactor: number\n}\n\nexport interface AreaCap {\n readonly radius: number\n readonly window: number\n readonly count: number\n readonly excessScale: number\n}\n\nexport interface ScreenState {\n /** Camera shake amplitude (the Lab's `shakeAmp`). */\n shake: number\n /** White flash of the Lab, 0..1, and how fast it fades. */\n flash: number\n flashDecay: number\n white: number\n red: number\n directionLeft: number\n directionRight: number\n chroma: number\n desat: number\n gas: number\n beat: number\n}\n\nexport interface VfxStats {\n readonly puffs: number\n readonly sparks: number\n readonly glows: number\n readonly chunks: number\n readonly fires: number\n readonly shocks: number\n readonly rings: number\n /** Blast lights and fire lights that are lit. */\n readonly blastLights: number\n readonly fireLights: number\n /** What the last explosion made: puffs, sparks, chunks, lights. */\n readonly lastBlast: { readonly puffs: number; readonly sparks: number; readonly chunks: number; readonly lights: number }\n /** The scale the last explosion was made at (LOD times the area cap). */\n readonly lod: number\n /** Seconds since the last explosion, or `-1` before the first. */\n readonly blastTime: number\n}\n","import { AREA_CAP_GAME, createAreaCap } from './area-cap'\nimport { PROFILES } from './budget'\nimport { EXPLOSIONS, EXPLOSION_ALIASES } from './catalog'\nimport { hexToLinearRgb } from './color'\nimport { DEFAULT_GRAVITY, DEFAULT_WIND } from './constants'\nimport type { RandomMode, VfxCore } from './core'\nimport { addFire, createFirePool, updateFires } from './emitters/fire'\nimport type { Fire } from './emitters/fire'\nimport { GAME_EFFECTS } from './effects/catalog'\nimport { createEffectPlayer } from './effects/player'\nimport type { EffectPlayer, PlayOptions } from './effects/player'\nimport type { EffectDef } from './effects/types'\nimport { composeExplosion } from './explosion'\nimport type { GroundField } from './ground'\nimport { createLightPool, resetLightPool, updateLights } from './lights'\nimport type { LightPool } from './lights'\nimport { LOD_GAME } from './lod'\nimport { createMarkStore } from './marks'\nimport type { MarkEvent, MarkStore } from './marks'\nimport type { OrderedPool } from './pool'\nimport { updateChunks } from './pools/chunk-motion'\nimport { createChunkPool } from './pools/chunks'\nimport type { Chunk } from './pools/chunks'\nimport { createGlowPool, updateGlows } from './pools/glows'\nimport type { Glow } from './pools/glows'\nimport { createPuffPool, updatePuffs } from './pools/puffs'\nimport type { Puff, Ring } from './pools/puffs'\nimport { createRingPool, updateRings } from './pools/rings'\nimport { createShockPool, updateShocks } from './pools/shocks'\nimport type { Shock } from './pools/shocks'\nimport { createSparkPool, updateSparks } from './pools/sparks'\nimport type { Spark } from './pools/sparks'\nimport { lehmer, streamFor } from './random'\nimport type { MutableVec3, RandomStream } from './random'\nimport { createSchedule } from './schedule'\nimport { createScreenState, resetScreenState, updateScreen } from './screen'\nimport { SpriteKindSystem } from './sprites/system'\nimport type { LandListener } from './sprites/system'\nimport type { SpriteSpawnOptions } from './sprites/kind-pool'\nimport type { SpriteKind, SpriteKindDef } from './sprites/kinds'\nimport type { VfxTrace } from './trace'\nimport { WorkshopEngine } from './workshop/engine'\nimport type { Vec3Tuple } from './workshop/types'\nimport type { AreaCap, ExplosionDef, Follow, LodBands, ScreenState, VfxLayer, VfxProfile, VfxProfileName, VfxSideRequest, VfxStats, Vec3Like } from './types'\nimport { VFX_LAYERS } from './types'\n\nexport interface VfxOptions {\n readonly seed?: number\n /** `per_event` (default): every explosion draws from a stream of its own seed, so a LAN client repeats it from a few bytes. `shared`: one stream for everything, like the Lab page (the goldens). */\n readonly randomMode?: RandomMode\n readonly profile?: VfxProfileName | VfxProfile\n readonly lod?: LodBands\n /** The cap on explosions in one area; `false` turns it off. Default the game's: 6 in 4 s within 40 m, the extra ones at 0.3. */\n readonly areaCap?: AreaCap | false\n /** Height of the ground for what bounces. Default: the `ground` field, else flat at 0. */\n readonly groundAt?: (x: number, z: number) => number\n /** A deformable ground the craters dig into (see `createGroundField`). */\n readonly ground?: GroundField\n readonly wind?: Vec3Like\n readonly gravity?: number\n /** The catalogue by id (default the Lab's 16 and `generic`); build another with `patchExplosions(EXPLOSIONS, ...)`. */\n readonly explosions?: Readonly<Record<string, ExplosionDef>>\n readonly aliases?: Readonly<Record<string, string>>\n /** The Workshop's recipes by id for `play` (default `GAME_EFFECTS`; build another with `patchEffects`). */\n readonly effects?: Readonly<Record<string, EffectDef>>\n /** The sprites of fixed kinds (`burst`, `spawn`): pool size and count multiplier (default 2500 and 1; a `low` profile halves the pool and uses 0.6) and the kinds by id. */\n readonly sprites?: { readonly capacity?: number; readonly density?: number; readonly kinds?: Readonly<Record<string, SpriteKindDef>> }\n readonly reducedMotion?: boolean\n /** Hears everything that spawns, in order (the goldens use it). */\n readonly trace?: VfxTrace\n readonly onRequest?: (request: VfxSideRequest) => void\n}\n\nexport interface ExplosionOptions {\n readonly direction?: Vec3Like\n /** Repeats the same visual: used in `per_event` mode. */\n readonly seed?: number\n /** Multiplies the size of the effect (radius, marks, mushroom, fires). */\n readonly scale?: number\n /** Seconds from now until it goes off (a chain). */\n readonly delay?: number\n}\n\nexport interface FireOptions {\n readonly point: Vec3Like\n readonly radius: number\n readonly life: number\n /** Flames per second per square-ish metre (the Lab's `rate`, default 22) and smoke puffs (default .6). */\n readonly rate?: number\n readonly smoke?: number\n /** Grows from `startRadius` to `radius` over `grow` seconds. */\n readonly startRadius?: number\n readonly grow?: number\n /** `0xRRGGBB` of the smoke (default soot black). */\n readonly smokeColor?: number\n /** Moves with a thing (a burning part): the fire sits at its position plus `offset`. */\n readonly follow?: Follow\n readonly offset?: Vec3Like\n readonly seed?: number\n}\n\n/** The pools as the renderer reads them: live records, oldest first. */\nexport interface VfxPoolsView {\n readonly puffs: OrderedPool<Puff>\n readonly sparks: OrderedPool<Spark>\n readonly glows: OrderedPool<Glow>\n readonly chunks: OrderedPool<Chunk>\n readonly shocks: OrderedPool<Shock>\n readonly rings: OrderedPool<Ring>\n readonly lights: LightPool\n readonly marks: MarkStore\n readonly ground: GroundField | undefined\n}\n\nexport interface VfxWorld {\n /** Sets off an explosion of the catalogue by id (an explosive id or an alias); `null` when the id is unknown. */\n explosion(id: string, point: Vec3Like, options?: ExplosionOptions): number | null\n /** A lingering area fire (a molotov's pool, a burning part). Returns a handle for `stop`. */\n fire(options: FireOptions): number\n /**\n * Plays a recipe of the Workshop (a blood hit, a muzzle flash, a collapse) at `point`, facing `options.direction`, into the world's Workshop pools\n * (`workshop()`); `null` when the id is unknown. Returns a handle for `stop`.\n */\n play(id: string, point: Vec3Like, options?: PlayOptions): number | null\n /** The Workshop's pools (sprites, streaks, debris, decals, rings, lights, screen): what the renderer draws for `play`. Made on first use. */\n workshop(): WorkshopEngine\n /** The Workshop engine if something already made it (`play`, `workshop()`); never creates it. */\n peekWorkshop(): WorkshopEngine | undefined\n /** The ids `play` accepts. */\n effectIds(): readonly string[]\n /** `count` sprites of a kind leaving `point` around `normal` at about `speed` m/s (debris, sparks, smoke, steam, drips...). */\n burst(kind: SpriteKind | string, point: Vec3Like, normal: Vec3Like, count: number, speed?: number, options?: SpriteSpawnOptions): void\n /** One sprite of a kind with an explicit velocity. */\n spawn(kind: SpriteKind | string, point: Vec3Like, velocity: Vec3Like, options?: SpriteSpawnOptions): void\n /** Hears where the sprites of `owner` that land (drips spawned with `{ owner, tag }`) touch the ground. Returns the function that stops listening. */\n onLand(owner: string, listener: LandListener): () => void\n /** The sprite pools as the renderer reads them. */\n sprites(): SpriteKindSystem\n /** Pushes the smoke and dust within `radius` of `point` outwards, as fast as `speed` at the centre. */\n push(point: Vec3Like, radius: number, speed: number): void\n stop(handle: number): void\n setLayer(layer: VfxLayer, on: boolean): void\n layer(layer: VfxLayer): boolean\n setCamera(position: Vec3Like): void\n /** Forces the scale of every explosion from now on (`null`: back to the distance bands and the cap). */\n forceLod(scale: number | null): void\n update(dt: number): void\n screen(): Readonly<ScreenState>\n stats(): VfxStats\n pools(): VfxPoolsView\n /** The live lingering fires, oldest first. */\n fires(): readonly Fire[]\n /** Hears every mark the moment it is made, and when they are cleared. Returns the function that stops listening. */\n onMarks(listener: (event: MarkEvent) => void): () => void\n /** Seconds the world has run since it was created or cleared. */\n time(): number\n /** The state of the shared stream (`randomMode: 'shared'`): what a golden compares after a run. */\n randomState(): number\n /** Takes everything away (pools, marks, ground, timers, lights, screen) and restarts the clock. */\n clear(): void\n /** The catalogue ids `explosion` accepts, aliases included. */\n catalog(): readonly string[]\n}\n\nconst FIRE_CAPACITY = 64\nconst RING_CAPACITY = 16\nconst SHOCK_CAPACITY = 16\nconst AUTO_SEED = 0x2545f491\n\nfunction resolveProfile(profile: VfxOptions['profile']): VfxProfile {\n if (profile === undefined) return PROFILES.medium\n return typeof profile === 'string' ? PROFILES[profile] : profile\n}\n\nfunction scaleDefinition(def: ExplosionDef, factor: number): ExplosionDef {\n if (factor === 1) return def\n const mushroom = def.mushroom && { ...def.mushroom, height: def.mushroom.height * factor, radius: def.mushroom.radius * factor }\n const residual = def.residualFires?.map((fire) => ({ ...fire, radius: fire.radius * factor, dx: (fire.dx ?? 0) * factor, dz: (fire.dz ?? 0) * factor }))\n return {\n ...def,\n lethal: def.lethal * factor,\n injury: def.injury * factor,\n visualRadius: def.visualRadius * factor,\n mark: { scorch: def.mark.scorch && def.mark.scorch * factor, crater: def.mark.crater && def.mark.crater * factor, dent: def.mark.dent && def.mark.dent * factor },\n ...(mushroom ? { mushroom } : {}),\n ...(residual ? { residualFires: residual } : {}),\n }\n}\n\nexport function createVfx(options: VfxOptions = {}): VfxWorld {\n const profile = resolveProfile(options.profile)\n const sharedRandom = lehmer(options.seed ?? 1)\n const explosions = options.explosions ?? EXPLOSIONS\n const aliases = options.aliases ?? EXPLOSION_ALIASES\n const randomMode = options.randomMode ?? 'per_event'\n const wind: MutableVec3 = { x: DEFAULT_WIND.x, y: DEFAULT_WIND.y, z: DEFAULT_WIND.z }\n if (options.wind) [wind.x, wind.y, wind.z] = options.wind\n const camera: MutableVec3 = { x: 0, y: 1.6, z: 0 }\n const layers = Object.fromEntries(VFX_LAYERS.map((layer) => [layer, true])) as Record<VfxLayer, boolean>\n const ground = options.ground\n const groundAt = options.groundAt ?? (ground ? (x: number, z: number) => ground.heightAt(x, z) : () => 0)\n const handles = { next: 0, events: 0 }\n const low = options.profile === 'low'\n const spriteSystem = new SpriteKindSystem({\n capacity: options.sprites?.capacity ?? (low ? 1250 : 2500),\n density: options.sprites?.density ?? (low ? 0.6 : 1),\n seed: 0x9e3779b1 + (options.seed ?? 0),\n groundAt,\n gravity: options.gravity ?? DEFAULT_GRAVITY,\n ...(options.sprites?.kinds ? { kinds: options.sprites.kinds } : {}),\n })\n const core: VfxCore = {\n profile,\n puffs: createPuffPool(profile.puffs),\n sparks: createSparkPool(profile.sparks),\n glows: createGlowPool(profile.glows),\n chunks: createChunkPool(profile.chunks, sharedRandom),\n fires: createFirePool(FIRE_CAPACITY, sharedRandom),\n shocks: createShockPool(SHOCK_CAPACITY),\n rings: createRingPool(RING_CAPACITY),\n lights: createLightPool(),\n marks: createMarkStore(),\n screen: createScreenState(),\n layers,\n schedule: createSchedule(),\n wind,\n camera,\n ground,\n bands: options.lod ?? LOD_GAME,\n areaCap: options.areaCap === false ? undefined : createAreaCap(options.areaCap ?? AREA_CAP_GAME),\n randomMode,\n sharedRandom,\n reducedMotion: options.reducedMotion ?? false,\n gravity: options.gravity ?? DEFAULT_GRAVITY,\n trace: options.trace,\n spawned: { puffs: 0, sparks: 0, chunks: 0, lights: 0 },\n clock: { time: 0, lastBlast: -1, lod: 1, forcedLod: null },\n groundAt,\n emit: (request) => options.onRequest?.(request),\n }\n\n function definitionOf(id: string): ExplosionDef | undefined {\n return explosions[id] ?? explosions[aliases[id] ?? '']\n }\n\n function streamOf(seed: number | undefined): RandomStream {\n if (randomMode === 'shared') return sharedRandom\n handles.events++\n return streamFor(seed ?? Math.imul(handles.events, AUTO_SEED) + (options.seed ?? 0))\n }\n\n function detonate(def: ExplosionDef, point: Vec3Like, call: { direction: MutableVec3 | undefined; random: RandomStream; handle: number }): void {\n composeExplosion(core, def, { x: point[0], y: point[1], z: point[2], direction: call.direction, random: call.random, handle: call.handle })\n }\n\n let engine: WorkshopEngine | undefined\n let player: EffectPlayer | undefined\n const effects = options.effects ?? GAME_EFFECTS\n const view = { get position(): Vec3Tuple { return [camera.x, camera.y, camera.z] }, forward: (local: readonly number[]): Vec3Tuple => [local[0] ?? 0, local[1] ?? 0, local[2] ?? 0] }\n\n function workshop(): WorkshopEngine {\n return (engine ??= new WorkshopEngine({ random: sharedRandom, profile, groundAt }))\n }\n\n function effectPlayer(): EffectPlayer {\n return (player ??= createEffectPlayer({ engine: workshop(), effects, view }))\n }\n\n return {\n play(id, point, playOptions = {}) {\n if (!(id in effects)) return null\n const seed = playOptions.seed ?? (randomMode === 'shared' ? undefined : Math.imul(++handles.events, AUTO_SEED) + (options.seed ?? 0))\n return effectPlayer().play(id, [point[0], point[1], point[2]], { ...playOptions, ...(seed !== undefined ? { seed } : {}) })\n },\n burst: (kind, point, normal, count, speed, spriteOptions) => spriteSystem.burst(kind, point, normal, count, speed, spriteOptions),\n spawn: (kind, point, velocity, spriteOptions) => spriteSystem.spawn(kind, point, velocity, spriteOptions),\n onLand: (owner, listener) => spriteSystem.onLand(owner, listener),\n sprites: () => spriteSystem,\n workshop,\n peekWorkshop: () => engine,\n effectIds: () => Object.keys(effects),\n explosion(id, point, explosionOptions = {}) {\n const base = definitionOf(id)\n if (!base) return null\n const def = scaleDefinition(base, explosionOptions.scale ?? 1)\n const handle = ++handles.next\n const direction = explosionOptions.direction && { x: explosionOptions.direction[0], y: explosionOptions.direction[1], z: explosionOptions.direction[2] }\n const random = streamOf(explosionOptions.seed)\n if (explosionOptions.delay) core.schedule.at(core.clock.time + explosionOptions.delay, () => detonate(def, point, { direction, random, handle }))\n else detonate(def, point, { direction, random, handle })\n return handle\n },\n fire(fireOptions) {\n const handle = ++handles.next\n const { point, offset, seed, radius, smokeColor, ...rest } = fireOptions\n addFire(core, streamOf(seed), {\n ...rest, r: radius, x: point[0], y: point[1], z: point[2], fx: offset?.[0] ?? 0, fy: offset?.[1] ?? 0, fz: offset?.[2] ?? 0,\n ...(smokeColor !== undefined ? { color: hexToLinearRgb(smokeColor) } : {}),\n }, handle)\n return handle\n },\n push(point, radius, speed) {\n spriteSystem.push(point, radius, speed)\n for (const puff of core.puffs.items) {\n const dx = puff.x - point[0]\n const dy = puff.y - point[1]\n const dz = puff.z - point[2]\n const distance = Math.sqrt(dx * dx + dy * dy + dz * dz)\n if (distance >= radius) continue\n const strength = (speed * (1 - distance / radius)) / (distance + 0.001)\n puff.vx += dx * strength\n puff.vy += dy * strength\n puff.vz += dz * strength\n }\n },\n stop(handle) {\n player?.stop(handle)\n const fires = core.fires\n for (let index = fires.items.length - 1; index >= 0; index--) if (fires.items[index]!.handle === handle) fires.removeAt(index)\n },\n setLayer(layer, on) {\n layers[layer] = on\n },\n layer: (layer) => layers[layer],\n setCamera(position) {\n camera.x = position[0]\n camera.y = position[1]\n camera.z = position[2]\n },\n forceLod(scale) {\n core.clock.forcedLod = scale\n },\n update(dt) {\n core.clock.time += dt\n core.schedule.update(core.clock.time)\n updateRings(core.rings, dt)\n updatePuffs(core.puffs, dt, wind)\n updateSparks(core.sparks, { dt, groundAt })\n updateGlows(core.glows, dt)\n updateShocks(core.shocks, core.puffs.items, dt)\n updateChunks(core, dt)\n updateFires(core, dt)\n updateLights(core.lights, { dt, flashLayer: layers.flash ? 1 : 0, clock: core.clock.time, fires: core.fires.items })\n updateScreen(core.screen, dt)\n spriteSystem.update(dt)\n if (engine) {\n engine.post = {}\n player?.update(dt)\n engine.update(dt)\n }\n },\n screen: () => core.screen,\n stats() {\n const lights = core.lights\n return {\n puffs: core.puffs.count,\n sparks: core.sparks.count,\n glows: core.glows.count,\n chunks: core.chunks.count,\n fires: core.fires.count,\n shocks: core.shocks.count,\n rings: core.rings.count,\n blastLights: lights.blast.filter((light) => light.intensity > 0.05).length,\n fireLights: lights.fire.filter((light) => light.intensity > 0.05).length,\n lastBlast: { ...core.spawned },\n lod: core.clock.lod,\n blastTime: core.clock.lastBlast < 0 ? -1 : core.clock.time - core.clock.lastBlast,\n }\n },\n pools: () => ({\n puffs: core.puffs, sparks: core.sparks, glows: core.glows, chunks: core.chunks, shocks: core.shocks, rings: core.rings, lights: core.lights, marks: core.marks, ground,\n }),\n fires: () => core.fires.items,\n onMarks: (listener) => core.marks.subscribe(listener),\n time: () => core.clock.time,\n randomState: () => sharedRandom.state,\n clear() {\n for (const pool of [core.puffs, core.sparks, core.glows, core.chunks, core.fires, core.shocks, core.rings] as OrderedPool<object>[]) pool.clear()\n core.marks.clear()\n core.schedule.clear()\n core.areaCap?.clear()\n ground?.reset()\n resetLightPool(core.lights)\n resetScreenState(core.screen)\n spriteSystem.clear()\n player?.clear()\n engine?.clear()\n core.clock.time = 0\n core.clock.lastBlast = -1\n core.clock.lod = 1\n core.spawned.puffs = core.spawned.sparks = core.spawned.chunks = core.spawned.lights = 0\n },\n catalog: () => [...new Set([...Object.keys(explosions), ...Object.keys(aliases)])],\n }\n}\n","{\n \"spall\": \"impact_{material}\",\n \"stage\": { \"1\": \"stage_crack\", \"2\": \"breach_dust\", \"3\": \"collapse_dust\" },\n \"expose\": \"rebar_expose\",\n \"collapse\": \"collapse_dust\",\n \"explode\": \"explosion\",\n \"fracture\": { \"glass\": \"glass_burst\" }\n}\n","import eventData from '../data/event-effects.json'\n\n/** What a game event looks like to the map: the kind of event and the little that picks its effect. */\nexport interface GameEvent {\n /** `spall`, `stage`, `expose`, `collapse`, `explode`, `fracture`... (strings, so there is no compile dependency on the destruction package). */\n readonly kind: string\n /** The stage of a `stage` event (1, 2 or 3). */\n readonly stage?: number\n /** The material of a `spall` or `fracture` event. */\n readonly material?: string\n}\n\ntype EventMap = Readonly<Record<string, string | Readonly<Record<string, string>>>>\n\nexport const EVENT_EFFECTS_MAP: EventMap = eventData\n\n/**\n * The effect id that plays for an event (`undefined` when the map has none). A string entry may use `{material}`; an object entry is chosen by the event's\n * stage or material. A game passes its own map to add or change entries.\n */\nexport function effectForEvent(event: GameEvent, map: EventMap = EVENT_EFFECTS_MAP): string | undefined {\n const entry = map[event.kind]\n if (entry === undefined) return undefined\n if (typeof entry === 'string') return event.material || !entry.includes('{material}') ? entry.replace('{material}', event.material ?? '') : undefined\n const key = event.stage !== undefined ? String(event.stage) : event.material\n return key === undefined ? undefined : entry[key]\n}\n","import type { EffectTexts } from '../locale'\n\n/** The Workshop's sheet for each effect, in English (the pt-BR texts are the page's own). */\nexport const en: Readonly<Record<string, EffectTexts>> = {\n blood_hit: {\n name: 'Blood by infection age',\n short: 'A mist on the way in, a jet on the way out, a pool that grows. Age changes colour and amount.',\n cost: '≤ 70 part.',\n costNote: '1 pool · 6 splashes',\n paramLabel: 'Age',\n when: 'Every bullet or blow that hits a zombie. The blood value comes from the bestiary age: 1.0 · 0.7 · 0.35 · 0.1.',\n look: 'Fresh sprays bright red and drips. Recent is burgundy. Old is brown and sparse. Decrepit does not bleed: it gives off black dust and dry flakes. The pool grows for 2 to 4 s and darkens in 60 s.',\n budget: 'Up to 70 particles per hit (Fresh), 1 pool and up to 6 splashes on the ground. Drops that land become decals.',\n network: 'Cosmetic. Goes in the impact event with 2 bits of age and the seed.',\n },\n headshot: {\n name: 'Headshot',\n short: 'The head bursts, the eyes go out on the same frame and the body drops.',\n cost: '≤ 70 part.',\n costNote: '8 debris · 1 pool',\n when: 'A head hit that kills (bestiary rule: a head kills at once).',\n look: 'A red mist around the head, a jet of drops backwards, 6 to 8 pieces of bone and skin, a swap to the burst-neck mesh. The eye glow goes out on the same frame, which is the most readable signal from afar.',\n budget: '20 mist + 35 drops + 8 debris + 1 pool. In the horde only the 12 closest get debris.',\n network: 'Cosmetic. The server already sends \"death by head\".',\n },\n dismember: {\n name: 'Dismemberment',\n short: 'The arm comes off whole with physics and the shoulder gushes for half a second.',\n cost: '≤ 60 part.',\n costNote: '1 limb · 4 splashes',\n when: 'Damage to a limb above the threshold (multipliers by region from the bestiary) or an axe blow.',\n look: 'The limb becomes a loose piece with physics and bounces. A short pulsing jet from the shoulder, drops that form a trail to the pool. The zombie staggers but keeps walking.',\n budget: '1 limb with physics (counts toward the cap of 300), a jet of up to 60 drops in 0.7 s.',\n network: 'The server sends which limb came off. The piece is local; each client simulates its own.',\n },\n bloater_cloud: {\n name: 'Bloater cloud',\n short: 'The belly pulses for 0.5 s, bursts and leaves 4 m of gas for 8 s.',\n cost: '≤ 180 part.',\n costNote: 'server entity',\n when: 'Death of the Bloater, by any cause.',\n look: 'A 0.5 s warning with the belly swelling, a burst with pieces and a greenish jet, and a low moss-green cloud that undulates on the ground for 8 s. Loose green glows inside the cloud mark the area.',\n budget: '40 large sprites at the burst and up to 60 alive in the cloud, at half resolution. Fade near the camera so it does not paint the whole screen.',\n network: 'Server entity (radius 4 m, 8 s): blinds for 5 s, doubles the scent trail and makes people cough. The client only draws.',\n },\n screamer_shriek: {\n name: 'Screamer shriek',\n short: 'A 1.5 s wind-up with steam, a wave on the ground and the horde\\'s eyes light up.',\n cost: '≤ 150 part.',\n costNote: '3 rings · aberration',\n when: 'The Screamer spots the player and starts the shriek (1.5 s wind-up, calls everyone within 150 m).',\n look: 'Head back and steam from the mouth during the wind-up. On the shriek, three pressure rings on the ground, dust raised in the radius, a short chromatic aberration on the screen of whoever is near, and the eyes of nearby zombies flare when they hear.',\n budget: '3 rings, up to 150 dust particles. The screen aberration is a 0.4 s post effect.',\n network: 'The server sends \"shriek at X\". The screen effect depends on local distance.',\n },\n eyes_in_fog: {\n name: 'Eyes in the fog',\n short: 'Eye glow that cuts through the fog; runners leave a red trail.',\n cost: '2 sprites/zombie',\n costNote: '0 lights',\n when: 'Always, on every zombie. It is the bestiary reading system: eye colour tells the category.',\n look: 'Two emissive points with bloom that ignore the fog. The body disappears in the mist at 25 m, the eyes stay readable at 60 m. Runners leave a short trail in the eye colour when they run.',\n budget: '2 sprites per zombie in the same instanced batch as the body. Trail only for runners closer than 30 m. No real light.',\n network: 'Nothing goes over the network: it comes from the zombie category.',\n },\n corpse_decay: {\n name: 'Corpse: darken and dissolve',\n short: '15 minutes in 8 seconds: fall, darken, flies and turn to dust.',\n cost: '≤ 40 part.',\n costNote: 'pool of 400 bodies',\n when: 'Zombie death. Bestiary timeline: ragdoll 3 s, frozen mesh, darken, dissolve between 14 and 15 min.',\n look: 'The skin loses colour until almost black, the pool dries to brown, flies appear from minute 5 and in the last minute the body sinks and gives off dark dust.',\n budget: 'Flies: 6 particles per body, only closer than 10 m. Dust: 40 particles once. The body uses the dissolve shader, no extra particle.',\n network: 'The server sends the time of death; each client works out the state.',\n },\n reanimation: {\n name: 'Reanimation',\n short: 'Veins light up, spasms, the eyes switch on and the body gets up.',\n cost: '≤ 30 part.',\n costNote: 'emissive in the shader',\n when: 'End of infection of a player or NPC: reanimates in 2 to 6 min as Fresh (70% Slow, 30% Runner).',\n look: 'Green pulses through the skin (emissive in the shader, not particles), spasms in the arms and head, the eyes light up from the inside out and the body stands. Breath as steam on the first shriek.',\n budget: 'Only animated emissive and 30 particles. It is rare and important, so it may be expensive.',\n network: 'The server sends \"reanimated\". For the friend who sees a teammate get up, it is the strongest moment of co-op.',\n },\n muzzle_flash: {\n name: 'Muzzle flash',\n short: 'Core, petals and smoke scaled by weapon. The Barrett raises dust.',\n cost: '≤ 60 part.',\n costNote: '1 light · 50 ms',\n paramLabel: 'Weapon',\n when: 'Every shot. In first person it uses the weapon model; from afar it is only the core sprite.',\n look: 'Three layers: a white-yellow core of 1 frame, petals along the barrel and grey smoke that stays 1 to 2 s. The 12-gauge has a wide flash and thick smoke. The Barrett vents two side jets through the muzzle brake and raises a ring of dust from the ground. The light illuminates the room for 50 ms (request from the map brief).',\n budget: 'Up to 60 particles and 1 light per shot. An AK burst uses the same light in a loop. A pistol has no light beyond 15 m.',\n network: 'Cosmetic. It comes from the shot event the server already sends (weapon, origin, direction).',\n },\n impact: {\n name: 'Impact by material',\n short: 'Concrete, metal, wood, glass, flesh and water: each with its own response.',\n cost: '≤ 40 part.',\n costNote: '1 hole',\n paramLabel: 'Material',\n when: 'Every bullet that hits something. The material comes from the mesh surface tag.',\n look: 'Concrete: pale dust in a cone and grey chips. Metal: a shower of bouncing sparks, no dust, with a short light. Wood: thin splinters and brown dust. Glass: glint, shards and a crack. Flesh: blood by age. Water: a crown of drops and two rings.',\n budget: '14 dust + 6 chips + up to 18 sparks + 1 hole. At 40 m only the dust remains.',\n network: '12-byte impact event with the material in 4 bits.',\n },\n penetration: {\n name: 'Bullet through the horde',\n short: 'Barrett tracer passing through 5 zombies, in 10x slow motion.',\n cost: '≤ 250 part.',\n costNote: 'aggregate event',\n when: 'Weapon with penetration: the AK goes through 2, the Remington 700 through 3, the Barrett through 6 and cars.',\n look: 'A tracer with a hot-air trail, blood exiting each body in the order the bullet passes (each in the colour of its age), bodies falling one after another and a final impact on the concrete.',\n budget: 'All hits of a shot go in a single aggregate event with the list of points. 5 bodies = 5 exits + 5 pools.',\n network: 'The server sends the shot and the ordered list of hits.',\n },\n casings_and_magazine: {\n name: 'Casings and magazine',\n short: 'Brass that bounces and stays on the ground, an empty magazine falling, smoke from the hot barrel.',\n cost: '200/player',\n costNote: 'physics 1.5 s',\n when: 'Every shot of a semi-automatic weapon, every reload, and the pump of the 12-gauge or the rifle bolt.',\n look: 'The casing leaves the ejection port spinning, bounces on the asphalt two or three times and stays. The empty magazine drops on reload. After a burst, thin smoke rises from the hot barrel for 2 s.',\n budget: 'Physics only for 1.5 s, then it becomes a static instance. Cap of 200 per player, the oldest goes first.',\n network: 'Cosmetic, each client generates its own. Ground position is not synchronised.',\n },\n molotov: {\n name: 'Molotov cocktail',\n short: 'A lit wick in the arc, glass breaking and a pool of fire that spreads.',\n cost: '≤ 300 part.',\n costNote: '2 lights · entity',\n when: 'A molotov hitting the ground or a zombie.',\n look: 'A bottle in an arc with the wick giving off flame and smoke. On impact, green shards and a splash of fire that opens from 0.5 m to 2.2 m in 0.8 s. Low flames, embers, dark smoke and a flickering light for 6 s, then embers and a burn mark.',\n budget: 'Area fire with up to 300 particles and 1 fire light. Burning zombies use a small emitter attached to the body (40 particles) and only the 8 closest.',\n network: 'Fire is a server entity: area, damage per second, time. The client draws from it.',\n },\n grenade: {\n name: 'Fragmentation grenade',\n short: 'A bounce on the asphalt, flash, shock wave, shrapnel and a ring of dust.',\n cost: '≤ 400 part.',\n costNote: 'aggregate event',\n when: 'A grenade exploding (1.8 s fuse after the throw).',\n look: 'The grenade bounces twice. A layered explosion: a white flash that paints the screen, a short fireball, a shock ring on the ground and another facing the camera, bright shrapnel that bounces, a ring of low dust, grey smoke that rises and a burn mark. Zombies in the radius fall outwards.',\n budget: 'Up to 400 particles, 1 strong light of 0.5 s, 16 debris, 1 mark. The 40 zombies hit go in a single aggregate event.',\n network: 'The server sends the explosion and the list of those hit. Visual is local.',\n },\n explosive_barrel: {\n name: 'Explosive barrel',\n short: 'A mushroom of fire, the lid flying, petrol burning on the ground and a column of smoke.',\n cost: '≤ 450 part.',\n costNote: '2 lights · fire entity',\n when: 'A red barrel with damage above the threshold, a shot or fire touching it.',\n look: 'Everything the grenade does, plus: a fireball that rises into a mushroom, the lid and red pieces flying high, three pools of petrol burning for 5 s and a black smoke column that serves as a landmark from afar.',\n budget: 'Peak of 450 particles. The smoke column stays visible beyond 80 m with 6 large sprites.',\n network: 'Explosion + a fire entity in the pools.',\n },\n shopfront_glass: {\n name: 'Shop window bursting',\n short: 'Two cracks, then the whole pane comes down in shards that stay on the pavement.',\n cost: '≤ 80 debris',\n costNote: '1 crack',\n when: 'Glass with accumulated damage (shot, blow, horde pushing). A 20 m noise that draws the horde.',\n look: 'The first blows open star cracks in the glass texture. At the burst the pane vanishes and becomes 60 to 80 shards that fall spinning, glinting in the light, and stay on the pavement. A veil of fine glass dust in front.',\n budget: 'Shards with physics count toward the cap of 300 and become static in 2 s. 3 crack stages in a single mask.',\n network: 'The server sends the glass state (0 to 3). Shards are local.',\n },\n door_stages: {\n name: 'Door giving way in 3 stages',\n short: 'Blows shake dust from the frame, a plank cracks and the door falls.',\n cost: '≤ 120 part.',\n costNote: '3 stages',\n when: 'The horde hitting a door or barricade (the Brute does 3x damage). Stages: 66%, 33%, 0% health.',\n look: 'Each blow shakes the door and loosens dust from the frame and splinters. At stage 2 the middle plank cracks and falls. At 3 the door topples and raises a cloud of low dust, and the zombie comes out of the dark.',\n budget: 'Dust: 12 particles per blow. Fall: 40 of dust and 6 debris. Blows beyond 15 m have no particles, only sound.',\n network: 'The server sends the door health. The visual stage comes from the value.',\n },\n building_collapse: {\n name: 'Collapse',\n short: 'Dust trickling from the awning, blocks falling and a cloud of dust rolling down the street.',\n cost: '≤ 350 part.',\n costNote: '26 debris',\n when: 'A structure that loses its health: explosion, vehicle impact, a big horde pushing (destruction of the map buildings).',\n look: 'Before: fine dust trickling and pebbles falling for 1 s, as a warning. Then: large and small blocks fall, the camera shakes and a cloud of grey-beige dust rolls along the ground and hangs in the air for 5 s, hiding zombies.',\n budget: '26 debris (6 large), 70 dust sprites at half resolution. A rare event, it fits the budget.',\n network: 'The server sends the collapse and the dust area, which blocks zombie sight for 4 s.',\n },\n block_wall: {\n name: 'Wall brought down with holes',\n short: 'A burst leaves holes and chips; the wall falls in blocks and the holes stay on them.',\n cost: '≤ 300 part.',\n costNote: '30 blocks · attached holes',\n when: 'A concrete wall, low wall or barricade that loses health from shots, explosion, the Brute or a car (map and arsenal destruction).',\n look: 'Each bullet opens a dark hole with a chipped rim, giving off dust and pebbles. When the wall gives way it splits into blocks that topple with physics and a cloud of dust rolls along the ground. The bullet holes are attached to the blocks: they stay on the fallen pieces, turned with them, and do not vanish when the wall breaks.',\n budget: 'Holes are decals that are children of the piece (not of the world), up to 12 per block and 128 in total. Blocks count toward the cap of 300 debris and become static at rest. Dust: 60 sprites at half resolution.',\n network: 'The server sends the wall health and the list of holes (2-byte local position per hole). Whoever joins later sees the same holes on the same pieces. The blocks fall using a common seed.',\n },\n metal_door: {\n name: 'Metal door denting',\n short: 'Each blow sinks the plate, flakes the paint and throws sparks; the hinge bursts.',\n cost: '≤ 160 part.',\n costNote: 'deformable mesh',\n when: 'A door, gate or steel plate taking a zombie blow (Brute 3x), a 12-gauge shot or a car hit.',\n look: 'The plate sinks where it is hit (a deformed mesh, not a model swap), with 3 visible levels. Each blow gives off sparks, flakes of green paint and rust dust. When the health runs out the top hinge bursts in sparks, the door topples and scrapes on the ground giving off more sparks.',\n budget: 'Per-vertex deformation only at the moment of the blow (CPU, 400 vertices). Per blow: 8 sparks, 5 flakes, 6 of rust. Fall: 30 sparks and 40 of dust.',\n network: 'The server keeps 3 bits of dent per door zone (9 zones). Whoever joins later sees the same dented door.',\n },\n iron_railing: {\n name: 'Iron railing bending',\n short: 'The horde pushes, the bars bow, the weld pops in a spark and the railing falls.',\n cost: '≤ 200 part.',\n costNote: '3 deformable bars',\n when: 'A railing, iron gate, handrail or chain-link fence with zombies pushing (horde pressure) or a car hitting it.',\n look: 'The bars bow gradually at the point of pressure and the vertical ones tilt with them. Rust falls in a thread during the strain. At two moments the weld pops with a crackle of sparks. At the end the middle post gives and the railing topples, leaving the bent iron on the ground.',\n budget: 'Curvature worked out only when the pressure changes, up to 180 vertices. Rust: 10 per second during the strain. Weld pop: 20 sparks.',\n network: 'The server sends the pressure (0 to 1) and when it gives. The curve comes from the value, the same on all clients.',\n },\n wooden_fence: {\n name: 'Wooden fence breaking',\n short: 'Planks snap one by one, chips and dust, and the section topples as the horde passes.',\n cost: '≤ 150 part.',\n costNote: '12 planks',\n when: 'A fence, yard gate or plank barricade taking a shot, blow or horde pressure.',\n look: 'Each plank snaps at a random point: the stump stays on the rail and the top piece flies off with chips and wood dust. The zombie appears through the gap. At the end the rail cracks and the whole section topples forward.',\n budget: 'Each plank is a piece: breaking swaps it for a stump + a piece with physics. Per break: 6 chips, 8 of dust. Topple: 35 of dust.',\n network: 'The server sends which planks broke (12 bits) and when the section falls.',\n },\n hit_point_breakage: {\n name: 'Breakage by the point hit',\n short: 'A shot to the leg, a machete on the corner, a bat on the top and a 12-gauge up close: each weapon breaks the part it hit.',\n cost: '≤ 120 part.',\n costNote: 'parts with their own health',\n when: 'Any destructible item. The damage goes to the part that was hit, not to the whole item.',\n look: 'A 9 mm shot to the front leg: the lower part of the leg breaks off and the table tips toward that corner. A machete on the corner of the top: the corner comes off whole in a straight cut, with chips in a line. A bat on the other corner: the top cracks and falls apart in pieces with dust. A 12-gauge up close on what is left: 9 grouped holes that stay in the wood.',\n budget: 'Each part has health and material. A common item: 4 to 12 parts. Particles only from the part hit, by its material.',\n network: 'The server sends which part lost health and how much. A loose part simulates on the client; the final position is sent once.',\n },\n pressure_cylinders: {\n name: 'Extinguisher and oxygen cylinder',\n short: 'A shot to the extinguisher makes a white cloud and a spin; on oxygen the valve breaks and the cylinder becomes a rocket.',\n cost: '≤ 250 part.',\n costNote: 'cloud entity',\n paramLabel: 'Cylinder',\n when: 'A shot, a strong blow or fire on an extinguisher, oxygen cylinder or welding cylinder (extinguisher and oxygen_cylinder keys of the map catalogue).',\n look: 'Extinguisher: the hole gives off a jet of white powder, the extinguisher falls, spins on the ground pushed by the jet and fills a 5 m area with a cloud that blocks sight for 6 s. Oxygen: the valve breaks with a crack, the jet becomes propulsion, the cylinder shoots along the ground scraping and throwing sparks, bounces and stops against a wall. With fire nearby, the oxygen blows up like the barrel.',\n budget: 'Jet: 60 particles per second for 3 s. Extinguisher cloud: up to 40 large sprites. Scraping sparks like the car.',\n network: 'The extinguisher cloud is a server entity (blocks zombie and player sight). The cylinder trajectory uses a common seed and the server corrects the final position.',\n },\n building_fire: {\n name: 'Building on fire',\n short: 'Fire coming out of the windows, licking the facade, embers and smoke with the wind.',\n cost: '≤ 600 part.',\n costNote: '2 lights · reference',\n when: 'A building fire (molotov, explosion, vehicle). It lasts minutes and spreads to the neighbour.',\n look: 'Windows lit orange that flicker, tongues of fire coming out of the top of each window and climbing the facade, embers carried by the wind and a thick slanted column of smoke. The light paints the street.',\n budget: 'Up to 600 particles per building and 2 fire lights. Beyond 80 m only the smoke column and the glow of the windows remain, which become a landmark.',\n network: 'A fire entity on the server per building, with a spread state.',\n },\n scraping_sparks: {\n name: 'Scraping sparks',\n short: 'A bumper dragging on the asphalt: a river of bouncing sparks and a mark on the ground.',\n cost: '≤ 200 sparks/s',\n costNote: '1 light',\n when: 'A car part in contact with the ground or a wall (a fallen bumper, a rim without a tyre, a flipped car sliding).',\n look: 'A jet of sparks behind the movement, bouncing on the asphalt and dying from white to orange. A glow and a short light at the contact point. A dark scratched mark on the ground.',\n budget: 'Up to 200 sparks per second, 1 light. Beyond 40 m it is only the glow of the point.',\n network: 'Cosmetic, from the part state and speed that are already replicated.',\n },\n engine_smoke: {\n name: 'Engine smoke',\n short: 'White steam, grey smoke, then black with fire, depending on condition.',\n cost: '≤ 120 part.',\n costNote: 'continuous',\n paramLabel: 'Condition',\n when: 'Whenever the engine is on or hot, from the part condition (0 to 100) in the fleet brief.',\n look: '100: exhaust only. 60: a thread of white steam from the bonnet. 30: steady grey smoke and the odd spark. 10: thick black smoke, flames at the grille and fire light, a warning that it will explode.',\n budget: 'Continuous, so cheap: up to 40 particles per second and 1 light only in the critical state.',\n network: 'Comes from the engine condition, which is already replicated.',\n },\n fuel_leak: {\n name: 'Tank leak and fire',\n short: 'Dripping petrol, a pool, a spark and the fire running to the tank.',\n cost: '≤ 400 part.',\n costNote: 'fire entity',\n when: 'A tank punctured by a shot or a crash. A spark, a shot or nearby fire lights the pool.',\n look: 'Drops of petrol with an oily sheen forming a growing pool. A shot on the metal throws a spark, the fire lights on the pool, runs to the car and, if nobody puts it out, the car explodes.',\n budget: 'Drops: 12 per second. Pool fire like the molotov. The final explosion is the next effect.',\n network: 'The pool and the fire are server entities (they can burn zombies and players).',\n },\n car_explosion: {\n name: 'Car explosion',\n short: 'A fireball, the car jumping, the bonnet and doors flying, the shell burning.',\n cost: '≤ 600 part.',\n costNote: 'rare event',\n when: 'A tank on fire for more than 4 s, or damage above the threshold on a car with fuel.',\n look: 'A large explosion (grenade scale 1.8), the car jumps and lands crooked, the bonnet, doors and a wheel fly off, the glass bursts into shards. The bodywork goes black and the shell burns with black smoke for minutes.',\n budget: 'Peak of 600 particles and 34 debris. It is a rare event and may go over the per-event cap, never the global cap.',\n network: 'Explosion on the server. The car becomes a wreck (another prefab) for everyone.',\n },\n windshield: {\n name: 'Windshield: blood and cracks',\n short: 'View from inside the car: blows, cracks in 4 stages and a bloody hand.',\n cost: '0 particles',\n costNote: '4-stage mask',\n when: 'A zombie hitting the windshield or a side window (fleet brief: the glass takes 8 blows).',\n look: 'Each blow shakes the camera and adds a star crack. Stages 2 and 4 leave a blood stain with a handprint running down. At stage 4 the glass is white with cracks and the next blow breaks it.',\n budget: 'Texture only: a crack mask with 4 stages and a blood decal on the glass. Glass dust: 6 particles per blow.',\n network: 'The server sends the glass health. Blood on the glass is local.',\n },\n damage_and_bite: {\n name: 'Damage and bite',\n short: 'A red edge on the side of the blow, blood on the lens and the pulse of the bite.',\n cost: 'post-process',\n costNote: 'local only',\n when: 'The player takes a blow (with direction) or a bite (100% infection, characters rule).',\n look: 'Blow: a red edge on the side it came from, a short shake and splashes on the lens. Bite: a red flash over the whole screen, the colour drains for 2 s, a heartbeat pulsing in a dark tunnel and big blood on the lens that runs down.',\n budget: 'A post-process effect and one lens layer. No particles in the world besides the normal blood.',\n network: 'Only on the screen of whoever was hit. The others see the blood in the world.',\n },\n infection_phases: {\n name: 'Infection phases',\n short: 'Malaise, fever with a cold edge, delirium with ghosts and the end.',\n cost: 'post-process',\n costNote: 'local only',\n paramLabel: 'Phase',\n when: 'Phases from the characters brief: 2–12 h malaise, 12–30 h fever, 30–48 h delirium, 48 h death.',\n look: 'Malaise: slightly washed colour and a slowly breathing vignette. Fever: a bluish cold edge only for the infected, waves of blur, a cough that shakes the camera. Delirium: colour aberration, an oscillating hue and fake zombies flickering in the fog. 48 h: almost no colour, a green tone, a dark tunnel and a heartbeat.',\n budget: 'Post-process only. The delirium ghosts are 3 zombie instances without collision, only on the infected client.',\n network: 'Never goes over the network. The other player notices only the cough and the breathing (see \"Cough and breath\").',\n },\n panic: {\n name: 'Panic',\n short: 'The aim shakes, the tunnel closes as the horde arrives and the heart speeds up.',\n cost: 'post-process',\n costNote: 'local only',\n when: 'The characters\\' panic meter (rises with visible zombies, runners and a dead companion). Effects above 60 and above 90.',\n look: 'A fine, constant tremor in the camera (the aim shakes), a dark vignette that closes as the nearest zombie arrives and pulses with the heartbeat, which speeds up from 70 to 150 bpm. Colour loses strength.',\n budget: 'Post-process and camera noise only.',\n network: 'Local. Others\\' panic shows in their aim and in the scream (sound).',\n },\n bloater_blindness: {\n name: 'Bloater blindness',\n short: 'Green gas in the face: a blurred screen for 5 s and mucus on the lens.',\n cost: 'post + 30 part.',\n costNote: 'server entity',\n when: 'A player inside the Bloater cloud (radius 4 m) when it spawns.',\n look: 'A green cloud bursts between the zombie and the camera, the screen goes green and blurred and clears in 5 s, with drops of green mucus on the lens that run down. A cough shakes the camera twice.',\n budget: 'Post-process + 30 gas sprites near the camera, with a fade so particles do not cover the whole screen.',\n network: 'The blindness comes from the server entity; the visual is local.',\n },\n campfire: {\n name: 'Campsite fire',\n short: 'A low flame, embers spiralling up and a flickering warm light.',\n cost: '≤ 120 part.',\n costNote: '1 fire light',\n when: 'A campfire lit by the group or by NPCs. It warms, lights and draws zombies from afar (light).',\n look: 'Small low flames, embers that rise turning and fade, thin smoke and a warm light that flickers and paints the survivor.',\n budget: '120 particles and 1 fire light. Several campfires of the camp share the same light if they are closer than 6 m.',\n network: 'A replicated scene object (lit or out). Visual is local.',\n },\n cough_and_breath: {\n name: 'Cough, breath and flashlight',\n short: 'Breath vapour in the cold, the fever cough visible to others and the flashlight beam.',\n cost: '≤ 40 part.',\n costNote: '1 spot with shadow',\n when: 'A cold night: breath always. Infection fever: a cough every few seconds, audible at 10 m.',\n look: 'A short puff of vapour every 2.4 s. On a cough, three quick bigger puffs and the body jolts. The flashlight shows the beam in the fog and is the only light with a shadow.',\n budget: 'Vapour: 8 particles per puff, only closer than 15 m. Flashlight: 1 spot with a shadow per player, only the local player\\'s casts a shadow.',\n network: 'The cough is the social signal of the infection: the server sends the cough event (without saying it is infection) and the others see the vapour and hear it.',\n },\n}\n","import type { EffectTexts } from '../locale'\n\n/** The Workshop's sheet for each effect (W450-1262), as the page wrote it. */\nexport const ptBR: Readonly<Record<string, EffectTexts>> = {\n blood_hit: {\n name: 'Sangue por idade da infecção',\n short: 'Névoa na entrada, jato na saída, poça que cresce. A idade muda cor e quantidade.',\n cost: '≤ 70 part.',\n costNote: '1 poça · 6 respingos',\n paramLabel: 'Idade',\n when: 'Cada acerto de bala ou golpe em zumbi. O valor de sangue vem da idade do bestiário: 1,0 · 0,7 · 0,35 · 0,1.',\n look: 'Fresco espirra vermelho vivo e pinga. Recente sai bordô. Antigo sai marrom e pouco. Decrépito não sangra: solta pó preto e lascas secas. A poça cresce por 2 a 4 s e escurece em 60 s.',\n budget: 'Até 70 partículas por acerto (Fresco), 1 poça e até 6 respingos no chão. Gotas que caem viram decalque.',\n network: 'Cosmético. Vai no evento de impacto com 2 bits de idade e a semente.',\n },\n headshot: {\n name: 'Headshot',\n short: 'A cabeça estoura, os olhos apagam no mesmo quadro e o corpo cai.',\n cost: '≤ 70 part.',\n costNote: '8 detritos · 1 poça',\n when: 'Acerto na cabeça que mata (regra do bestiário: cabeça mata na hora).',\n look: 'Névoa vermelha em volta da cabeça, jato de gotas para trás, 6 a 8 pedaços de osso e pele, troca pela malha de pescoço estourado. O brilho dos olhos apaga no mesmo quadro, que é o sinal mais legível de longe.',\n budget: '20 de névoa + 35 gotas + 8 detritos + 1 poça. Na horda, só os 12 mais próximos ganham detritos.',\n network: 'Cosmético. O servidor já manda “morte por cabeça”.',\n },\n dismember: {\n name: 'Desmembramento',\n short: 'O braço sai inteiro com física e o ombro jorra por meio segundo.',\n cost: '≤ 60 part.',\n costNote: '1 membro · 4 respingos',\n when: 'Dano no membro acima do limite (multiplicadores por região do bestiário) ou golpe de machado.',\n look: 'O membro vira peça solta com física e quica. Jato curto do ombro em pulsos, gotas que formam um rastro até a poça. O zumbi cambaleia mas continua andando.',\n budget: '1 membro com física (conta no teto de 300), jato de até 60 gotas em 0,7 s.',\n network: 'O servidor manda qual membro saiu. A peça é local; cada cliente simula a sua.',\n },\n bloater_cloud: {\n name: 'Nuvem do Inchado',\n short: 'Barriga pulsa por 0,5 s, estoura e deixa 4 m de gás por 8 s.',\n cost: '≤ 180 part.',\n costNote: 'entidade no servidor',\n when: 'Morte do Inchado, por qualquer causa.',\n look: 'Aviso de 0,5 s com a barriga inchando, estouro com pedaços e jato esverdeado, e uma nuvem baixa verde-musgo que ondula no chão por 8 s. Brilhos verdes soltos dentro da nuvem marcam a área.',\n budget: '40 sprites grandes no estouro e até 60 vivos na nuvem, em meia resolução. Fade perto da câmera para não pintar a tela inteira.',\n network: 'Entidade no servidor (raio 4 m, 8 s): cega por 5 s, dobra o rastro de cheiro e faz tossir. O cliente só desenha.',\n },\n screamer_shriek: {\n name: 'Grito do Gritador',\n short: 'Preparo de 1,5 s com vapor, onda no chão e os olhos da horda acendem.',\n cost: '≤ 150 part.',\n costNote: '3 anéis · aberração',\n when: 'O Gritador avista o jogador e começa o grito (preparo de 1,5 s, chama todos num raio de 150 m).',\n look: 'Cabeça para trás e vapor saindo da boca durante o preparo. No grito, três anéis de pressão no chão, poeira levantada no raio, aberração cromática curta na tela de quem está perto e os olhos dos zumbis próximos piscam forte quando escutam.',\n budget: '3 anéis, até 150 partículas de poeira. A aberração na tela é um efeito de pós de 0,4 s.',\n network: 'O servidor manda “grito em X”. O efeito de tela depende da distância local.',\n },\n eyes_in_fog: {\n name: 'Olhos na neblina',\n short: 'Brilho dos olhos que fura a neblina; os corredores deixam rastro vermelho.',\n cost: '2 sprites/zumbi',\n costNote: '0 luzes',\n when: 'Sempre, em todo zumbi. É o sistema de leitura do bestiário: cor do olho diz a categoria.',\n look: 'Dois pontos emissivos com bloom que ignoram a neblina. O corpo some na névoa a 25 m, os olhos continuam legíveis a 60 m. Corredores deixam um rastro curto da cor do olho quando correm.',\n budget: '2 sprites por zumbi no mesmo lote instanciado do corpo. Rastro só para corredores a menos de 30 m. Nenhuma luz real.',\n network: 'Nada vai pela rede: sai da categoria do zumbi.',\n },\n corpse_decay: {\n name: 'Corpo: escurecer e dissolver',\n short: '15 minutos em 8 segundos: queda, escurece, moscas e vira pó.',\n cost: '≤ 40 part.',\n costNote: 'pool de 400 corpos',\n when: 'Morte do zumbi. Linha do tempo do bestiário: ragdoll 3 s, malha congelada, escurece, dissolve entre 14 e 15 min.',\n look: 'A pele perde a cor até ficar quase preta, a poça seca para marrom, aparecem moscas a partir do minuto 5 e no último minuto o corpo afunda e solta pó escuro.',\n budget: 'Moscas: 6 partículas por corpo, só a menos de 10 m. Pó: 40 partículas uma vez. O corpo usa o shader de dissolve, sem partícula extra.',\n network: 'O servidor manda a hora da morte; cada cliente calcula o estado.',\n },\n reanimation: {\n name: 'Reanimação',\n short: 'Veias acendem, espasmos, os olhos ligam e o corpo levanta.',\n cost: '≤ 30 part.',\n costNote: 'emissivo no shader',\n when: 'Fim da infecção de jogador ou NPC: reanima em 2 a 6 min como Fresco (70% Lento, 30% Corredor).',\n look: 'Pulsos verdes pela pele (emissivo no shader, não partícula), espasmos nos braços e na cabeça, os olhos acendem de dentro para fora e o corpo se levanta. Respiração em vapor no primeiro grito.',\n budget: 'Só emissivo animado e 30 partículas. É raro e importante, então pode ser caro.',\n network: 'O servidor manda “reanimou”. Para o amigo que vê o colega levantar, é o momento mais forte do coop.',\n },\n muzzle_flash: {\n name: 'Clarão de disparo',\n short: 'Núcleo, pétalas e fumaça com escala por arma. A Barrett levanta poeira.',\n cost: '≤ 60 part.',\n costNote: '1 luz · 50 ms',\n paramLabel: 'Arma',\n when: 'Cada disparo. Em primeira pessoa usa o modelo da arma; de longe vira só o sprite do núcleo.',\n look: 'Três camadas: núcleo branco-amarelo de 1 quadro, pétalas na direção do cano e fumaça cinza que fica 1 a 2 s. A 12 tem clarão largo e fumaça grossa. A Barrett solta dois jatos laterais pelo freio de boca e levanta um anel de poeira do chão. A luz ilumina o cômodo por 50 ms (pedido do brief do mapa).',\n budget: 'Até 60 partículas e 1 luz por tiro. Rajada de AK usa a mesma luz em loop. Pistola sem luz a mais de 15 m.',\n network: 'Cosmético. Sai do evento de tiro que o servidor já manda (arma, origem, direção).',\n },\n impact: {\n name: 'Impacto por material',\n short: 'Concreto, metal, madeira, vidro, carne e água: cada um com sua resposta.',\n cost: '≤ 40 part.',\n costNote: '1 furo',\n paramLabel: 'Material',\n when: 'Toda bala que acerta algo. O material vem da tag de superfície da malha.',\n look: 'Concreto: pó claro em cone e lascas cinza. Metal: chuva de faíscas que quicam, sem pó, com luz curta. Madeira: lascas finas e pó marrom. Vidro: brilho, cacos e rachadura. Carne: sangue pela idade. Água: coroa de gotas e dois anéis.',\n budget: '14 de pó + 6 lascas + até 18 faíscas + 1 furo. A 40 m sobra só o pó.',\n network: 'Evento de impacto de 12 bytes com material em 4 bits.',\n },\n penetration: {\n name: 'Bala que atravessa a horda',\n short: 'Traçante da Barrett passando por 5 zumbis, em câmera lenta 10×.',\n cost: '≤ 250 part.',\n costNote: 'evento agregado',\n when: 'Arma com penetração: AK atravessa 2, Remington 700 atravessa 3, Barrett atravessa 6 e carros.',\n look: 'Traçante com rastro de ar quente, saída de sangue em cada corpo na ordem em que a bala passa (cada um com a cor da sua idade), corpos caindo um atrás do outro e impacto final no concreto.',\n budget: 'Todos os acertos de um tiro saem num único evento agregado com a lista de pontos. 5 corpos = 5 saídas + 5 poças.',\n network: 'O servidor manda o tiro e a lista ordenada de acertos.',\n },\n casings_and_magazine: {\n name: 'Cápsulas e carregador',\n short: 'Latão que quica e fica no chão, carregador vazio caindo, fumaça do cano quente.',\n cost: '200/jogador',\n costNote: 'física 1,5 s',\n when: 'Cada disparo de arma semiautomática, recarga, e bombeada da 12 ou ferrolho do rifle.',\n look: 'Cápsula sai pela janela de ejeção girando, quica no asfalto duas ou três vezes e fica. O carregador vazio cai na recarga. Depois da rajada, fumaça fina sobe do cano quente por 2 s.',\n budget: 'Física só por 1,5 s, depois vira instância estática. Teto de 200 por jogador, o mais antigo some primeiro.',\n network: 'Cosmético, cada cliente gera as suas. Não sincroniza posição no chão.',\n },\n molotov: {\n name: 'Coquetel molotov',\n short: 'Pavio aceso no arco, vidro quebrando e poça de fogo que espalha.',\n cost: '≤ 300 part.',\n costNote: '2 luzes · entidade',\n when: 'Molotov atingindo o chão ou um zumbi.',\n look: 'Garrafa em arco com pavio soltando chama e fumaça. Ao bater, cacos verdes e um respingo de fogo que abre de 0,5 m para 2,2 m em 0,8 s. Chamas baixas, brasas, fumaça escura e luz tremendo por 6 s, depois brasa e mancha queimada.',\n budget: 'Fogo de área com até 300 partículas e 1 luz de fogo. Zumbis em chamas usam um emissor pequeno preso ao corpo (40 partículas) e só os 8 mais próximos.',\n network: 'Fogo é entidade no servidor: área, dano por segundo, tempo. O cliente desenha a partir dela.',\n },\n grenade: {\n name: 'Granada de fragmentação',\n short: 'Quique no asfalto, clarão, onda de choque, estilhaços e anel de poeira.',\n cost: '≤ 400 part.',\n costNote: 'evento agregado',\n when: 'Granada explodindo (pavio de 1,8 s após o arremesso).',\n look: 'Granada quica duas vezes. Explosão em camadas: clarão branco que pinta a tela, bola de fogo curta, anel de choque no chão e outro de frente para a câmera, estilhaços brilhantes que quicam, anel de poeira rasteira, fumaça cinza que sobe e marca queimada. Zumbis no raio caem para fora.',\n budget: 'Até 400 partículas, 1 luz forte de 0,5 s, 16 detritos, 1 marca. Os 40 zumbis atingidos entram num único evento agregado.',\n network: 'O servidor manda a explosão e a lista de atingidos. Visual local.',\n },\n explosive_barrel: {\n name: 'Barril explosivo',\n short: 'Cogumelo de fogo, tampa voando, gasolina queimando no chão e coluna de fumaça.',\n cost: '≤ 450 part.',\n costNote: '2 luzes · entidade de fogo',\n when: 'Barril vermelho com dano acima do limite, tiro ou fogo encostado.',\n look: 'Tudo da granada, mais: bola de fogo que sobe em cogumelo, tampa e pedaços vermelhos voando alto, três poças de gasolina queimando por 5 s e coluna de fumaça preta que serve de referência de longe.',\n budget: 'Pico de 450 partículas. A coluna de fumaça fica visível além de 80 m com 6 sprites grandes.',\n network: 'Explosão + entidade de fogo nas poças.',\n },\n shopfront_glass: {\n name: 'Vitrine estourando',\n short: 'Duas trincas, depois a placa inteira desce em cacos que ficam na calçada.',\n cost: '≤ 80 detritos',\n costNote: '1 rachadura',\n when: 'Vidro com dano acumulado (tiro, golpe, horda empurrando). Barulho de 20 m que atrai a horda.',\n look: 'Primeiros golpes abrem trincas em estrela na textura do vidro. No estouro a placa some e vira 60 a 80 cacos que caem girando, brilhando na luz, e ficam na calçada. Um véu de pó de vidro fino na frente.',\n budget: 'Cacos com física contam no teto de 300 e viram estáticos em 2 s. 3 estágios de rachadura numa máscara só.',\n network: 'O servidor manda o estado do vidro (0 a 3). Cacos são locais.',\n },\n door_stages: {\n name: 'Porta cedendo em 3 estágios',\n short: 'Pancadas soltam pó do batente, uma tábua racha e a porta cai.',\n cost: '≤ 120 part.',\n costNote: '3 estágios',\n when: 'Horda batendo em porta ou barricada (o Brutamonte faz 3× dano). Estágios: 66%, 33%, 0% de vida.',\n look: 'Cada pancada sacode a porta e solta pó do batente e lascas. No estágio 2 a tábua do meio racha e cai. No 3 a porta tomba e levanta uma nuvem de poeira rasteira, e o zumbi sai do escuro.',\n budget: 'Pó: 12 partículas por pancada. Queda: 40 de poeira e 6 detritos. Pancadas a mais de 15 m sem partícula, só som.',\n network: 'O servidor manda a vida da porta. Estágio visual sai do valor.',\n },\n building_collapse: {\n name: 'Desabamento',\n short: 'Pó escorrendo da marquise, blocos caindo e nuvem de poeira que rola pela rua.',\n cost: '≤ 350 part.',\n costNote: '26 detritos',\n when: 'Estrutura que perde a vida: explosão, veículo batendo, horda grande empurrando (destruição de prédios do mapa).',\n look: 'Antes: pó fino escorrendo e pedrinhas caindo por 1 s, como aviso. Depois: blocos grandes e pequenos caem, a câmera treme e uma nuvem de poeira cinza-bege rola pelo chão e fica no ar por 5 s, escondendo zumbis.',\n budget: '26 detritos (6 grandes), 70 sprites de poeira em meia resolução. É evento raro, cabe no orçamento.',\n network: 'O servidor manda o colapso e a área de poeira, que bloqueia visão de zumbi por 4 s.',\n },\n block_wall: {\n name: 'Parede derrubada com furos',\n short: 'Rajada deixa furos e lascas; a parede cai em blocos e os furos continuam neles.',\n cost: '≤ 300 part.',\n costNote: '30 blocos · furos presos',\n when: 'Parede, mureta ou barricada de concreto que perde a vida por tiros, explosão, Brutamonte ou carro (destruição do mapa e do arsenal).',\n look: 'Cada bala abre um furo escuro com borda lascada, solta pó e pedrinhas. Quando a parede cede, ela se parte em blocos que tombam com física e uma nuvem de poeira rola pelo chão. Os furos de bala estão presos aos blocos: ficam nos pedaços caídos, girados junto com eles, e não somem quando a parede quebra.',\n budget: 'Furos são decalques filhos do pedaço (não do mundo), até 12 por bloco e 128 no total. Blocos contam no teto de 300 detritos e viram estáticos em repouso. Poeira: 60 sprites em meia resolução.',\n network: 'O servidor manda vida da parede e a lista de furos (posição local de 2 bytes por furo). Quem entra depois vê os mesmos furos nos mesmos pedaços. Queda dos blocos usa semente comum.',\n },\n metal_door: {\n name: 'Porta de metal amassando',\n short: 'Cada pancada afunda a chapa, descasca a tinta e solta faísca; a dobradiça arrebenta.',\n cost: '≤ 160 part.',\n costNote: 'malha deformável',\n when: 'Porta, portão ou chapa de aço levando golpe de zumbi (Brutamonte 3×), tiro de 12 ou batida de carro.',\n look: 'A chapa afunda onde apanha (malha deformada, não troca de modelo), com 3 níveis visíveis. Cada pancada solta faísca, lasca de tinta verde e pó de ferrugem. Quando a vida acaba, a dobradiça de cima estoura em faíscas, a porta tomba e raspa no chão soltando mais faísca.',\n budget: 'Deformação por vértice só na hora do golpe (CPU, 400 vértices). Por golpe: 8 faíscas, 5 lascas, 6 de ferrugem. Queda: 30 faíscas e 40 de poeira.',\n network: 'O servidor guarda 3 bits de amassado por zona da porta (9 zonas). Quem entra depois vê a mesma porta amassada.',\n },\n iron_railing: {\n name: 'Grade de ferro entortando',\n short: 'A horda empurra, as barras envergam, a solda estoura em faísca e a grade tomba.',\n cost: '≤ 200 part.',\n costNote: '3 barras deformáveis',\n when: 'Grade, portão de ferro, corrimão ou alambrado com zumbis empurrando (pressão da horda) ou carro batendo.',\n look: 'As barras envergam aos poucos no ponto de pressão e as verticais inclinam junto. Ferrugem cai em fio durante o esforço. Em dois momentos a solda estoura com um estalo de faíscas. No fim o poste do meio cede e a grade tomba, deixando o ferro torto no chão.',\n budget: 'Curvatura calculada só quando a pressão muda, até 180 vértices. Ferrugem: 10 por segundo durante o esforço. Estouro de solda: 20 faíscas.',\n network: 'O servidor manda a pressão (0 a 1) e quando cede. A curva sai do valor, igual em todos os clientes.',\n },\n wooden_fence: {\n name: 'Cerca de madeira quebrando',\n short: 'Tábuas partem uma a uma, lascas e pó, e a seção tomba com a horda passando.',\n cost: '≤ 150 part.',\n costNote: '12 tábuas',\n when: 'Cerca, portão de quintal ou barricada de tábuas recebendo tiro, golpe ou pressão da horda.',\n look: 'Cada tábua parte num ponto aleatório: o toco fica preso no trilho e o pedaço de cima voa com lascas e pó de madeira. O zumbi aparece pelo vão. No fim o trilho racha e a seção inteira tomba para frente.',\n budget: 'Cada tábua é uma peça: quebra troca para toco + pedaço com física. Por quebra: 6 lascas, 8 de pó. Tombo: 35 de poeira.',\n network: 'O servidor manda quais tábuas quebraram (12 bits) e quando a seção cai.',\n },\n hit_point_breakage: {\n name: 'Quebra pelo ponto atingido',\n short: 'Tiro na perna, facão na quina, taco no tampo e 12 de perto: cada arma quebra a parte que pegou.',\n cost: '≤ 120 part.',\n costNote: 'peças com vida própria',\n when: 'Qualquer item destrutível. O dano vai para a peça que foi atingida, não para o item inteiro.',\n look: 'Tiro de 9 mm na perna da frente: a parte de baixo da perna parte e a mesa tomba para aquele canto. Facão na quina do tampo: a quina sai inteira num corte reto, com lascas em linha. Taco no outro canto: o tampo racha e se desfaz em pedaços com pó. 12 de perto no que sobrou: 9 furos agrupados que ficam na madeira.',\n budget: 'Cada peça tem vida e material. Item comum: 4 a 12 peças. Partículas só da peça atingida, pelo material dela.',\n network: 'O servidor manda qual peça perdeu vida e quanto. Peça solta simula no cliente; a posição final é mandada uma vez.',\n },\n pressure_cylinders: {\n name: 'Extintor e cilindro de oxigênio',\n short: 'Tiro no extintor faz nuvem branca e giro; no oxigênio a válvula quebra e o cilindro vira foguete.',\n cost: '≤ 250 part.',\n costNote: 'entidade de nuvem',\n paramLabel: 'Cilindro',\n when: 'Tiro, golpe forte ou fogo em extintor, cilindro de oxigênio ou de solda (chaves extintor e cilindro_oxigenio do catálogo do mapa).',\n look: 'Extintor: o furo solta um jato de pó branco, o extintor cai, gira no chão empurrado pelo jato e enche uma área de 5 m de nuvem que tapa a visão por 6 s. Oxigênio: a válvula quebra com estalo, o jato vira propulsão, o cilindro dispara rente ao chão raspando e soltando faísca, quica e para numa parede. Com fogo por perto, o oxigênio estoura como o barril.',\n budget: 'Jato: 60 partículas por segundo por 3 s. Nuvem do extintor: até 40 sprites grandes. Faísca de raspagem como a do carro.',\n network: 'Nuvem do extintor é entidade no servidor (bloqueia visão de zumbi e de jogador). A trajetória do cilindro usa semente comum e o servidor corrige a posição final.',\n },\n building_fire: {\n name: 'Prédio em chamas',\n short: 'Fogo saindo pelas janelas, lambendo a fachada, brasas e fumaça com vento.',\n cost: '≤ 600 part.',\n costNote: '2 luzes · referência',\n when: 'Incêndio de prédio (molotov, explosão, veículo). Dura minutos e espalha para o vizinho.',\n look: 'Janelas acesas em laranja que tremem, línguas de fogo saindo pela parte de cima de cada janela e subindo pela fachada, brasas levadas pelo vento e uma coluna de fumaça grossa inclinada. A luz pinta a rua.',\n budget: 'Até 600 partículas por prédio e 2 luzes de fogo. Além de 80 m fica só a coluna de fumaça e o brilho das janelas, que viram ponto de referência.',\n network: 'Entidade de fogo no servidor por prédio, com estado de espalhar.',\n },\n scraping_sparks: {\n name: 'Faíscas de raspagem',\n short: 'Para-choque arrastando no asfalto: rio de faíscas que quicam e marca no chão.',\n cost: '≤ 200 faíscas/s',\n costNote: '1 luz',\n when: 'Peça de carro em contato com o chão ou com parede (para-choque caído, roda sem pneu, carro capotado deslizando).',\n look: 'Jato de faíscas para trás do movimento, que quicam no asfalto e apagam do branco para o laranja. Brilho e luz curta no ponto de contato. Marca escura riscada no chão.',\n budget: 'Até 200 faíscas por segundo, 1 luz. A mais de 40 m vira só o brilho do ponto.',\n network: 'Cosmético, a partir do estado da peça e da velocidade que já são replicados.',\n },\n engine_smoke: {\n name: 'Fumaça do motor',\n short: 'Vapor branco, fumaça cinza, depois preta com fogo, conforme a condição.',\n cost: '≤ 120 part.',\n costNote: 'contínuo',\n paramLabel: 'Condição',\n when: 'Sempre que o motor está ligado ou quente, a partir da condição da peça (0 a 100) do brief da frota.',\n look: '100: só escapamento. 60: fio de vapor branco saindo pelo capô. 30: fumaça cinza constante e faísca de vez em quando. 10: fumaça preta grossa, chamas na grade e luz de fogo, aviso de que vai explodir.',\n budget: 'Contínuo, então barato: até 40 partículas por segundo e 1 luz só no estado crítico.',\n network: 'Sai da condição do motor, que já é replicada.',\n },\n fuel_leak: {\n name: 'Vazamento e incêndio do tanque',\n short: 'Gasolina pingando, poça, uma faísca e o fogo correndo até o tanque.',\n cost: '≤ 400 part.',\n costNote: 'entidade de fogo',\n when: 'Tanque furado por tiro ou batida. Faísca, tiro ou fogo próximo acende a poça.',\n look: 'Pingos de gasolina com brilho oleoso formando uma poça que cresce. Um tiro no metal solta faísca, o fogo acende na poça, corre até o carro e, se ninguém apagar, o carro explode.',\n budget: 'Pingos: 12 por segundo. Fogo de poça como o do molotov. A explosão final é o efeito seguinte.',\n network: 'Poça e fogo são entidades no servidor (podem queimar zumbis e jogadores).',\n },\n car_explosion: {\n name: 'Explosão do carro',\n short: 'Bola de fogo, carro pulando, capô e portas voando, carcaça queimando.',\n cost: '≤ 600 part.',\n costNote: 'evento raro',\n when: 'Tanque em chamas por mais de 4 s, ou dano acima do limite em carro com combustível.',\n look: 'Explosão grande (escala 1,8 da granada), o carro pula e cai torto, capô, portas e uma roda saem voando, vidro estoura em cacos. A lataria fica preta e a carcaça queima com fumaça preta por minutos.',\n budget: 'Pico de 600 partículas e 34 detritos. É evento raro e pode passar do teto por evento, nunca do teto global.',\n network: 'Explosão no servidor. O carro vira carcaça (outro prefab) para todos.',\n },\n windshield: {\n name: 'Para-brisa: sangue e rachadura',\n short: 'Visão de dentro do carro: pancadas, trincas em 4 estágios e mão de sangue.',\n cost: '0 partículas',\n costNote: 'máscara 4 estágios',\n when: 'Zumbi batendo no para-brisa ou no vidro lateral (brief da frota: vidro aguenta 8 golpes).',\n look: 'Cada golpe treme a câmera e soma uma trinca em estrela. Estágio 2 e 4 deixam mancha de sangue com marca de mão escorrendo. No estágio 4 o vidro está branco de rachadura e o próximo golpe quebra.',\n budget: 'Só textura: uma máscara de rachadura com 4 estágios e um decal de sangue no vidro. Pó de vidro: 6 partículas por golpe.',\n network: 'O servidor manda a vida do vidro. Sangue no vidro é local.',\n },\n damage_and_bite: {\n name: 'Dano e mordida',\n short: 'Borda vermelha do lado do golpe, sangue na lente e o pulso da mordida.',\n cost: 'pós-processo',\n costNote: 'só local',\n when: 'Jogador recebe golpe (com direção) ou mordida (infecção 100%, regra dos personagens).',\n look: 'Golpe: borda vermelha do lado de onde veio, tremor curto e respingos na lente. Mordida: clarão vermelho na tela inteira, a cor some por 2 s, batimento pulsando no túnel escuro e sangue grande na lente que escorre.',\n budget: 'Efeito de pós-processo e uma camada de lente. Nenhuma partícula no mundo além do sangue normal.',\n network: 'Só na tela de quem levou. Os outros veem o sangue no mundo.',\n },\n infection_phases: {\n name: 'Fases da infecção',\n short: 'Mal-estar, febre com borda fria, delírio com fantasmas e o fim.',\n cost: 'pós-processo',\n costNote: 'só local',\n paramLabel: 'Fase',\n when: 'Fases do brief de personagens: 2–12 h mal-estar, 12–30 h febre, 30–48 h delírio, 48 h morte.',\n look: 'Mal-estar: cor um pouco lavada e vinheta que respira devagar. Febre: borda fria azulada só para o infectado, desfoque em ondas, tosse que treme a câmera. Delírio: aberração de cor, matiz que oscila e zumbis falsos que piscam na neblina. 48 h: quase sem cor, tom verde, túnel escuro e batimento.',\n budget: 'Só pós-processo. Os fantasmas do delírio são 3 instâncias do zumbi sem colisão, só no cliente infectado.',\n network: 'Nunca vai pela rede. O outro jogador percebe só a tosse e a respiração (ver “Tosse e respiração”).',\n },\n panic: {\n name: 'Pânico',\n short: 'A mira treme, o túnel fecha conforme a horda chega e o coração acelera.',\n cost: 'pós-processo',\n costNote: 'só local',\n when: 'Medidor de pânico dos personagens (sobe com zumbis visíveis, corredores e companheiro morto). Efeitos acima de 60 e de 90.',\n look: 'Tremor fino e constante na câmera (a mira treme), vinheta escura que fecha conforme o zumbi mais próximo chega e pulsa com o batimento, que acelera de 70 para 150 bpm. A cor perde força.',\n budget: 'Só pós-processo e ruído de câmera.',\n network: 'Local. O pânico dos outros aparece na mira deles e no grito (som).',\n },\n bloater_blindness: {\n name: 'Cegueira do Inchado',\n short: 'Gás verde na cara: tela turva por 5 s e muco na lente.',\n cost: 'pós + 30 part.',\n costNote: 'entidade do servidor',\n when: 'Jogador dentro da nuvem do Inchado (raio 4 m) quando ela nasce.',\n look: 'Nuvem verde explode entre o zumbi e a câmera, a tela fica verde e desfocada e clareia em 5 s, com gotas de muco verde na lente que escorrem. Tosse treme a câmera duas vezes.',\n budget: 'Pós-processo + 30 sprites de gás perto da câmera, com fade para não cobrir a tela inteira de partícula.',\n network: 'A cegueira vem da entidade no servidor; o visual é local.',\n },\n campfire: {\n name: 'Fogueira do acampamento',\n short: 'Chama baixa, brasas subindo em espiral e luz quente tremendo.',\n cost: '≤ 120 part.',\n costNote: '1 luz de fogo',\n when: 'Fogueira acesa pelo grupo ou por NPCs. Esquenta, ilumina e atrai zumbis de longe (luz).',\n look: 'Chamas pequenas e baixas, brasas que sobem girando e somem, fumaça fina e uma luz quente que treme e pinta o sobrevivente.',\n budget: '120 partículas e 1 luz de fogo. Várias fogueiras do acampamento dividem a mesma luz se estiverem a menos de 6 m.',\n network: 'Objeto de cena replicado (aceso ou apagado). Visual local.',\n },\n cough_and_breath: {\n name: 'Tosse, respiração e lanterna',\n short: 'Vapor da respiração no frio, tosse da febre visível para os outros e feixe da lanterna.',\n cost: '≤ 40 part.',\n costNote: '1 spot com sombra',\n when: 'Noite fria: respiração sempre. Febre da infecção: tosse a cada poucos segundos, audível a 10 m.',\n look: 'Sopro curto de vapor a cada 2,4 s. Na tosse, três sopros rápidos e maiores e o corpo dá um tranco. A lanterna mostra o feixe na neblina e é a única luz com sombra.',\n budget: 'Vapor: 8 partículas por sopro, só a menos de 15 m. Lanterna: 1 spot com sombra por jogador, só a do jogador local projeta sombra.',\n network: 'A tosse é o sinal social da infecção: o servidor manda o evento de tosse (sem dizer que é infecção) e os outros veem o vapor e ouvem.',\n },\n}\n","import { en } from './locales/en'\nimport { ptBR } from './locales/pt-BR'\n\n/** Locales shipped with the package. Unknown locales fall back to `en`. */\nexport type VfxLocale = 'en' | 'pt-BR'\n\n/** The texts of one Workshop effect: its card in the list and its sheet (when, how it looks, what it costs, what goes over the network). */\nexport interface EffectTexts {\n readonly name: string\n readonly short: string\n /** The cost shown on the card, and what comes with it. */\n readonly cost: string\n readonly costNote: string\n /** The label of the effect's parameter, when it has one. */\n readonly paramLabel?: string\n readonly when: string\n readonly look: string\n readonly budget: string\n readonly network: string\n}\n\n/** The words around the sheet (`renderSheet`, W1266). */\nexport interface SheetLabels {\n readonly when: string\n readonly look: string\n readonly budget: string\n readonly network: string\n readonly quality: string\n readonly replay: string\n readonly auto: string\n}\n\nexport interface VfxStrings {\n readonly effects: Readonly<Record<string, EffectTexts>>\n readonly sheet: SheetLabels\n readonly groups: Readonly<Record<string, string>>\n}\n\nexport const locales: Record<VfxLocale, VfxStrings> = {\n en: {\n effects: en,\n sheet: { when: 'When', look: 'Look', budget: 'Budget', network: 'Network', quality: 'Quality', replay: 'Replay', auto: 'Auto replay' },\n groups: { explosions: 'Explosions', creatures: 'Zombies', weapons: 'Weapons and explosives', world: 'Map, weather and destruction', destruction: 'Scenery destruction', vehicles: 'Vehicles', screen: 'Characters and screen effects' },\n },\n 'pt-BR': {\n effects: ptBR,\n sheet: { when: 'Quando', look: 'Visual', budget: 'Orçamento', network: 'Rede', quality: 'Qualidade', replay: 'Repetir', auto: 'Repetição automática' },\n groups: { explosions: 'Explosões', creatures: 'Zumbis', weapons: 'Armas e explosivos', world: 'Mapa, clima e destruição', destruction: 'Destruição de cenário', vehicles: 'Veículos', screen: 'Personagens e efeitos de tela' },\n },\n}\n\nexport const resolveStrings = (locale: string | undefined): VfxStrings => locales[(locale as VfxLocale) ?? 'en'] ?? locales.en\n","import type { Vec3Tuple } from '../workshop/types'\n\nconst ANIMATION_SPEED = 1.4\nconst START_POSITION: Vec3Tuple = [4, 2.4, 7]\nconst START_TARGET: Vec3Tuple = [0, 1, 0]\n\ntype Vector = [number, number, number]\n\nfunction subtract(a: Vec3Tuple, b: Vec3Tuple): Vector {\n return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]\n}\n\nfunction unit(vector: Vector): Vector {\n const length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]) || 1\n const inverse = 1 / length\n return [vector[0] * inverse, vector[1] * inverse, vector[2] * inverse]\n}\n\nfunction crossProduct(a: Vector, b: Vector): Vector {\n return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]\n}\n\nfunction ease(value: number): number {\n return value < 0 ? 0 : value > 1 ? 1 : value * value * (3 - 2 * value)\n}\n\nfunction mix(from: Vec3Tuple, to: Vec3Tuple, amount: number): Vec3Tuple {\n return [from[0] + (to[0] - from[0]) * amount, from[1] + (to[1] - from[1]) * amount, from[2] + (to[2] - from[2]) * amount]\n}\n\n/** Rotates a vector by the quaternion `(x, y, z, w)` as three.js `applyQuaternion` does. */\nfunction rotate(local: readonly number[], x: number, y: number, z: number, w: number): Vec3Tuple {\n const [vx, vy, vz] = local as Vec3Tuple\n const ix = w * vx + y * vz - z * vy\n const iy = w * vy + z * vx - x * vz\n const iz = w * vz + x * vy - y * vx\n const iw = -x * vx - y * vy - z * vz\n return [ix * w + iw * -x + iy * -z - iz * -y, iy * w + iw * -y + iz * -x - ix * -z, iz * w + iw * -z + ix * -y - iy * -x]\n}\n\n/** The quaternion three.js builds from `lookAt(eye, target)` with the y axis up (`setFromRotationMatrix`). */\nfunction lookAtQuaternion(eye: Vec3Tuple, target: Vec3Tuple): readonly [number, number, number, number] {\n const z = unit(subtract(eye, target))\n const x = unit(crossProduct([0, 1, 0], z))\n const y = crossProduct(z, x)\n const [m11, m21, m31, m12, m22, m32, m13, m23, m33] = [x[0], x[1], x[2], y[0], y[1], y[2], z[0], z[1], z[2]]\n const trace = m11 + m22 + m33\n if (trace > 0) {\n const scale = 0.5 / Math.sqrt(trace + 1)\n return [(m32 - m23) * scale, (m13 - m31) * scale, (m21 - m12) * scale, 0.25 / scale]\n }\n if (m11 > m22 && m11 > m33) {\n const scale = 2 * Math.sqrt(1 + m11 - m22 - m33)\n return [0.25 * scale, (m12 + m21) / scale, (m13 + m31) / scale, (m32 - m23) / scale]\n }\n if (m22 > m33) {\n const scale = 2 * Math.sqrt(1 + m22 - m11 - m33)\n return [(m12 + m21) / scale, 0.25 * scale, (m23 + m32) / scale, (m13 - m31) / scale]\n }\n const scale = 2 * Math.sqrt(1 + m33 - m11 - m22)\n return [(m13 + m31) / scale, (m23 + m32) / scale, 0.25 * scale, (m21 - m12) / scale]\n}\n\n/**\n * The Workshop's view (W1259-1262): it glides to each effect's `view` (`camTo`) in about 0.7 s and persists between effects, so an effect that reads the\n * camera (a ring that faces the viewer, a mist at the lens) sees where the previous one left it.\n */\nexport class EffectCamera {\n position: Vec3Tuple = START_POSITION\n target: Vec3Tuple = START_TARGET\n private animation: { from: Vec3Tuple; fromTarget: Vec3Tuple; to: Vec3Tuple; toTarget: Vec3Tuple; progress: number } | undefined\n\n goTo(eye: Vec3Tuple, target: Vec3Tuple): void {\n this.animation = { from: this.position, fromTarget: this.target, to: eye, toTarget: target, progress: 0 }\n }\n\n place(eye: Vec3Tuple, target: Vec3Tuple): void {\n this.position = eye\n this.target = target\n this.animation = undefined\n }\n\n hold(): void {\n this.animation = undefined\n }\n\n update(dt: number): void {\n const animation = this.animation\n if (!animation) return\n animation.progress = Math.min(1, animation.progress + dt * ANIMATION_SPEED)\n const eased = ease(animation.progress)\n this.position = mix(animation.from, animation.to, eased)\n this.target = mix(animation.fromTarget, animation.toTarget, eased)\n if (animation.progress >= 1) this.animation = undefined\n }\n\n /** A direction given in the camera's own axes, in world axes. */\n forward(local: readonly number[]): Vec3Tuple {\n const [x, y, z, w] = lookAtQuaternion(this.position, this.target)\n return rotate(local, x, y, z, w)\n }\n}\n","import type { RandomStream } from '../random'\nimport type { WorkshopEngine } from '../workshop/engine'\nimport type { Vec3Tuple } from '../workshop/types'\nimport type { Behavior } from './behavior'\nimport { EffectCamera } from './camera'\nimport { EffectInstance } from './instance'\nimport type { CueRequest, EffectDef, EffectStep } from './types'\n\nconst SHAKE_SCALE = 0.06\nconst SHAKE_DEPTH = 0.5\n\nexport interface EffectRunnerOptions {\n readonly engine: WorkshopEngine\n readonly effects: Readonly<Record<string, EffectDef>>\n readonly behaviors?: Readonly<Record<string, Behavior>>\n readonly onCue?: (cue: CueRequest) => void\n}\n\n/**\n * The Workshop's one-effect-at-a-time view (W1253-1295): choosing an effect clears the set and runs it; each frame fires the timers due, runs the tick, ages\n * the pools, glides the camera and draws the camera shake. This is what the bench shows and what the golden replays; `createEffectPlayer` plays many at once.\n */\nexport class EffectRunner {\n readonly camera = new EffectCamera()\n readonly instance: EffectInstance\n /** The camera shake of the last frame, three draws per frame as in the page. */\n shake: Vec3Tuple = [0, 0, 0]\n\n constructor(private readonly options: EffectRunnerOptions) {\n const behaviors = options.behaviors ?? {}\n this.instance = new EffectInstance({\n engine: options.engine,\n view: this.camera,\n behavior: (id) => behaviors[id]!,\n behaviors: () => Object.values(behaviors),\n ...(options.onCue ? { onCue: options.onCue } : {}),\n })\n }\n\n get current(): EffectDef | undefined {\n return this.instance.def\n }\n\n get variables(): Map<string, unknown> {\n return this.instance.variables\n }\n\n get param(): number {\n return this.instance.param\n }\n\n get fresh(): boolean {\n return this.instance.fresh\n }\n\n get time(): number {\n return this.instance.time\n }\n\n /** Seconds since the effect was chosen: unlike `time`, a restart of the loop does not reset it (`el`). */\n get elapsed(): number {\n return this.instance.elapsed\n }\n\n get random(): RandomStream {\n return this.options.engine.random\n }\n\n /** `select` + `startLoop` (W1253-1257): clears everything, then runs the effect's setup and timeline. */\n start(id: string, param?: number): boolean {\n const def = this.options.effects[id]\n if (!def) return false\n if (def.view) this.camera.goTo(def.view.eye, def.view.target)\n else this.camera.hold()\n this.options.engine.clear()\n this.instance.begin(def, param)\n return true\n }\n\n /** `startLoop` again: the same effect from its start (the replay button and the end of the loop). */\n restart(): void {\n if (!this.instance.def) return\n this.options.engine.clear()\n this.instance.restart()\n }\n\n /** One frame of the page (W1280-1295). */\n update(dt: number): void {\n const engine = this.options.engine\n engine.post = {}\n this.instance.step(dt)\n engine.update(dt)\n this.camera.update(dt)\n const amplitude = engine.screen.shake * SHAKE_SCALE + this.instance.tremor\n const random = this.random\n this.shake = [random.between(-1, 1) * amplitude, random.between(-1, 1) * amplitude, random.between(-1, 1) * amplitude * SHAKE_DEPTH]\n }\n\n execute(steps: readonly EffectStep[]): void {\n this.instance.execute(steps)\n }\n}\n","import type { RandomStream } from './random'\n\nexport interface GroundFieldOptions {\n /** Side of the deformable patch in metres (the Lab's 60). */\n readonly size?: number\n /** Cells per side (the Lab's 180: 33 cm cells). */\n readonly segments?: number\n}\n\n/** The deformable ground the Lab's craters dig into (L60-83): a height field, in float32 like the page, centred on the origin. */\nexport interface GroundField {\n readonly size: number\n readonly segments: number\n /** Vertices per side. */\n readonly stride: number\n readonly cellSize: number\n /** World coordinate of the first row and column. */\n readonly origin: number\n readonly heights: Float32Array\n /** Goes up on every dent or reset: a renderer redraws its mesh when it changes. */\n readonly version: number\n heightAt(x: number, z: number): number\n /** A bowl with an uneven floor and a raised rim, drawing from `random` like the Lab's `dent`. */\n dent(random: RandomStream, x: number, z: number, radius: number, depth: number): void\n reset(): void\n}\n\nconst DEFAULT_SIZE = 60\nconst DEFAULT_SEGMENTS = 180\nconst MAX_DEPTH = 3\nconst RIM_REACH = 1.45\nconst REACH_FACTOR = 1.5\n\nexport function createGroundField(options: GroundFieldOptions = {}): GroundField {\n const size = options.size ?? DEFAULT_SIZE\n const segments = options.segments ?? DEFAULT_SEGMENTS\n const stride = segments + 1\n const cellSize = size / segments\n const origin = -size / 2\n const heights = new Float32Array(stride * stride)\n let version = 0\n\n function heightAt(x: number, z: number): number {\n const fx = (x - origin) / cellSize\n const fz = (z - origin) / cellSize\n if (fx < 0 || fz < 0 || fx >= segments || fz >= segments) return 0\n const column = fx | 0\n const row = fz | 0\n const tx = fx - column\n const tz = fz - row\n const index = row * stride + column\n return (heights[index]! * (1 - tx) + heights[index + 1]! * tx) * (1 - tz) + (heights[index + stride]! * (1 - tx) + heights[index + stride + 1]! * tx) * tz\n }\n\n function dent(random: RandomStream, x: number, z: number, radius: number, depth: number): void {\n const reach = radius * REACH_FACTOR\n const column0 = Math.max(0, Math.floor((x - reach - origin) / cellSize))\n const column1 = Math.min(segments, Math.ceil((x + reach - origin) / cellSize))\n const row0 = Math.max(0, Math.floor((z - reach - origin) / cellSize))\n const row1 = Math.min(segments, Math.ceil((z + reach - origin) / cellSize))\n const phaseA = random.next() * 6\n const phaseB = random.next() * 6\n for (let row = row0; row <= row1; row++) {\n for (let column = column0; column <= column1; column++) {\n const px = origin + column * cellSize\n const pz = origin + row * cellSize\n const distance = Math.hypot(px - x, pz - z)\n const angle = Math.atan2(pz - z, px - x)\n const q = distance / (radius * (1 + 0.13 * Math.sin(angle * 5 + phaseA) + 0.07 * Math.sin(angle * 11 + phaseB)))\n let change = 0\n if (q < 1) change = -depth * (1 - q * q) * (0.85 + random.next() * 0.3)\n else if (q < RIM_REACH) {\n const k = (q - 1) / 0.45\n change = depth * 0.3 * Math.sin(k * Math.PI) * (1 - k * 0.3) * (0.6 + random.next() * 0.8)\n }\n if (!change) continue\n const index = row * stride + column\n heights[index] = Math.max(-MAX_DEPTH, heights[index]! + change)\n }\n }\n version++\n }\n\n function reset(): void {\n heights.fill(0)\n version++\n }\n\n return {\n size,\n segments,\n stride,\n cellSize,\n origin,\n heights,\n get version() {\n return version\n },\n heightAt,\n dent,\n reset,\n }\n}\n","/** The additive halo (Lab L297-304), verbatim except for the r160 colour-space chunk. */\nexport const GLOW_VERTEX = `attribute vec4 aP;attribute vec4 aC;varying vec2 vU;varying vec4 vC;\nvoid main(){vec3 R=vec3(viewMatrix[0][0],viewMatrix[1][0],viewMatrix[2][0]);vec3 Up=vec3(viewMatrix[0][1],viewMatrix[1][1],viewMatrix[2][1]);\nvec3 wp=aP.xyz+(R*position.x+Up*position.y)*aP.w;vU=position.xy;vC=aC;gl_Position=projectionMatrix*viewMatrix*vec4(wp,1.);}`\n\nexport const GLOW_FRAGMENT = `varying vec2 vU;varying vec4 vC;void main(){float r=dot(vU,vU);if(r>1.)discard;float f=exp(-r*4.2)-.015;gl_FragColor=vec4(vC.rgb*vC.a*max(f,0.),1.);\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}`\n","/** The value noise the puff shader builds its dissolve from (Lab L116-122), verbatim. */\nexport const GL_NOISE = `\nfloat h3(vec3 p){p=fract(p*.3183099+.1);p*=17.0;return fract(p.x*p.y*p.z*(p.x+p.y+p.z));}\nfloat vn(vec3 x){vec3 i=floor(x),f=fract(x);f=f*f*(3.-2.*f);\n return mix(mix(mix(h3(i),h3(i+vec3(1,0,0)),f.x),mix(h3(i+vec3(0,1,0)),h3(i+vec3(1,1,0)),f.x),f.y),\n mix(mix(h3(i+vec3(0,0,1)),h3(i+vec3(1,0,1)),f.x),mix(h3(i+vec3(0,1,1)),h3(i+vec3(1,1,1)),f.x),f.y),f.z);}\n`\n","import { GL_NOISE } from './noise'\n\n/**\n * The puff shader of the Lab (L130-192), verbatim: a faceted icosahedron per puff, a five-band posterised heat ramp, a noise dissolve and banded light.\n * The only change is the r160 colour-space chunk: `encodings_fragment` (r128) is `colorspace_fragment` now.\n */\nexport const PUFF_VERTEX = `${GL_NOISE}\nattribute vec4 aP;attribute vec4 aD;attribute vec3 aC;\nvarying vec3 vWP;varying vec3 vL;varying vec4 vD;varying vec3 vC;\nvoid main(){\n vec3 p=position;\n float s=aD.z;\n float n=vn(p*1.6+vec3(s*11.0,s*7.0,s*3.0));\n p*=0.78+0.5*n;\n float a=s*6.2831;float c=cos(a),si=sin(a);p.xz=mat2(c,-si,si,c)*p.xz;\n vL=p;\n vec3 wp=aP.xyz+p*aP.w;\n vWP=wp;vD=aD;vC=aC;\n gl_Position=projectionMatrix*viewMatrix*vec4(wp,1.0);\n}`\n\nexport const PUFF_FRAGMENT = `${GL_NOISE}\nuniform vec3 uLight;uniform vec3 uSky;uniform vec3 uGround;uniform vec3 uGlowPos;uniform vec3 uGlowCol;uniform float uGlowI;\nvarying vec3 vWP;varying vec3 vL;varying vec4 vD;varying vec3 vC;\nvec3 L(vec3 c){return pow(c,vec3(2.2));}\nvec3 ramp(float h){\n vec3 c0=L(vec3(.36,.07,.03)),c1=L(vec3(.76,.21,.1)),c2=L(vec3(1.,.54,.16)),c3=L(vec3(1.,.83,.42)),c4=L(vec3(1.,.96,.84));\n if(h<.25)return mix(c0,c1,h/.25);\n if(h<.5)return mix(c1,c2,(h-.25)/.25);\n if(h<.8)return mix(c2,c3,(h-.5)/.3);\n return mix(c3,c4,clamp((h-.8)/.4,0.,1.));\n}\nvoid main(){\n vec3 N=normalize(cross(dFdx(vWP),dFdy(vWP)));\n float age=vD.x,heat=vD.y,kind=vD.w;\n float n=vn(vL*2.4+vD.z*13.0);\n float diss=smoothstep(.5,1.,age);\n if(n<diss*1.08-.04)discard;\n float lam=max(dot(N,uLight),0.);\n float band=lam>.55?1.:lam>.15?.68:.42;\n vec3 col=vC*(vec3(.5,.56,.7)*band*1.05+vec3(.2,.19,.18)+uGround*(.4-.4*N.y));\n vec3 tg=uGlowPos-vWP;float dg=length(tg)+.001;\n float gi=uGlowI/(1.+dg*dg*.05)*(.3+.7*max(dot(N,tg/dg),0.));\n col+=uGlowCol*gi*vC*1.6;\n float h=heat*(.72+.56*n)+heat*(-N.y)*.18;\n if(h>.05){\n float hq=floor(h*5.+.5)/5.;\n vec3 fc=ramp(clamp(hq,0.,1.2))*(1.1+3.1*hq);\n col=mix(col,fc,smoothstep(.04,.2,h));\n }\n if(kind>2.5&&kind<3.5){col+=vec3(.02,.025,.03);}\n gl_FragColor=vec4(col,1.);\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}`\n","/** The streak shader of shrapnel, sparks and embers (Lab L255-275), verbatim except for the r160 colour-space chunk. */\nexport const SPARK_VERTEX = `\nattribute vec3 aPos;attribute vec3 aVel;attribute vec4 aE;varying vec2 vU;varying vec4 vE;\nvoid main(){\n float sp=length(aVel)+1e-4;vec3 d=aVel/sp;\n vec3 tc=normalize(cameraPosition-aPos);\n vec3 sd=normalize(cross(d,tc)+vec3(1e-5));\n float len=max(aE.y*2.5,min(sp*aE.z,2.2));\n vec3 wp=aPos+sd*position.x*aE.y-d*position.y*len;\n vU=position.xy;vE=aE;\n gl_Position=projectionMatrix*viewMatrix*vec4(wp,1.);\n}`\n\nexport const SPARK_FRAGMENT = `\nvarying vec2 vU;varying vec4 vE;\nvoid main(){\n float age=vE.x,k=vE.w;\n float w=1.-abs(vU.x)*2.;w=w*w;\n float tail=1.-vU.y;\n vec3 c;\n if(k<.5){c=mix(vec3(4.,3.3,2.2),vec3(2.4,.7,.12),smoothstep(0.,.55,age));c=mix(c,vec3(.5,.06,.02),smoothstep(.55,1.,age));}\n else if(k<1.5){c=mix(vec3(1.6,1.6,1.6),vec3(.35,.35,.36),smoothstep(0.,.4,age));}\n else if(k<2.5){c=mix(vec3(5.,5.,6.),vec3(1.,1.3,2.),smoothstep(0.,.5,age));}\n else if(k<3.5){c=vec3(.9,1.2,1.4)*(1.-age);}\n else {c=mix(vec3(3.2,1.4,.3),vec3(1.2,.25,.05),age);}\n float a=w*(.35+.65*tail)*(1.-smoothstep(.75,1.,age));\n gl_FragColor=vec4(c*a,1.);\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}`\n","import type * as THREE_NS from 'three'\nimport type { Chunk, Glow, OrderedPool, Puff, Spark } from '@adatechnology/game-vfx'\nimport { GLOW_FRAGMENT, GLOW_VERTEX } from './shaders/glow'\nimport { PUFF_FRAGMENT, PUFF_VERTEX } from './shaders/puff'\nimport { SPARK_FRAGMENT, SPARK_VERTEX } from './shaders/spark'\nimport type { ThreeLib } from './types'\n\nexport interface DrawnLayer {\n readonly mesh: THREE_NS.Mesh\n /** Copies the pool into the instance buffers and answers how many are drawn. */\n sync(): number\n dispose(): void\n}\n\ntype Attribute = THREE_NS.InstancedBufferAttribute\n\nfunction dynamic(THREE: ThreeLib, array: Float32Array, size: number): Attribute {\n return new THREE.InstancedBufferAttribute(array, size).setUsage(THREE.DynamicDrawUsage)\n}\n\nexport interface PuffUniforms {\n uLight: { value: THREE_NS.Vector3 }\n uSky: { value: THREE_NS.Vector3 }\n uGround: { value: THREE_NS.Vector3 }\n uGlowPos: { value: THREE_NS.Vector3 }\n uGlowCol: { value: THREE_NS.Vector3 }\n uGlowI: { value: number }\n uTime: { value: number }\n}\n\nexport function createPuffLayer(THREE: ThreeLib, pool: OrderedPool<Puff>, uniforms: PuffUniforms): DrawnLayer {\n const capacity = pool.capacity\n const geometry = new THREE.InstancedBufferGeometry()\n geometry.setAttribute('position', new THREE.IcosahedronGeometry(1, 1).getAttribute('position'))\n const a = new Float32Array(capacity * 4)\n const d = new Float32Array(capacity * 4)\n const c = new Float32Array(capacity * 3)\n const attributes = [dynamic(THREE, a, 4), dynamic(THREE, d, 4), dynamic(THREE, c, 3)] as const\n geometry.setAttribute('aP', attributes[0])\n geometry.setAttribute('aD', attributes[1])\n geometry.setAttribute('aC', attributes[2])\n geometry.instanceCount = 0\n const material = new THREE.ShaderMaterial({ uniforms: uniforms as never, vertexShader: PUFF_VERTEX, fragmentShader: PUFF_FRAGMENT })\n const mesh = new THREE.Mesh(geometry, material)\n mesh.name = 'vfx-puffs'\n mesh.frustumCulled = false\n return {\n mesh,\n sync() {\n let n = 0\n for (const p of pool.items) {\n a[n * 4] = p.x\n a[n * 4 + 1] = p.y\n a[n * 4 + 2] = p.z\n a[n * 4 + 3] = p.size\n d[n * 4] = p.age\n d[n * 4 + 1] = p.heat\n d[n * 4 + 2] = p.seed\n d[n * 4 + 3] = p.kind\n c[n * 3] = p.color[0]\n c[n * 3 + 1] = p.color[1]\n c[n * 3 + 2] = p.color[2]\n n++\n }\n geometry.instanceCount = n\n for (const attribute of attributes) attribute.needsUpdate = true\n return n\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\nexport function createSparkLayer(THREE: ThreeLib, pool: OrderedPool<Spark>): DrawnLayer {\n const capacity = pool.capacity\n const geometry = new THREE.InstancedBufferGeometry()\n geometry.setAttribute('position', new THREE.Float32BufferAttribute([-0.5, 0, 0, 0.5, 0, 0, 0.5, 1, 0, -0.5, 1, 0], 3))\n geometry.setIndex([0, 1, 2, 0, 2, 3])\n const position = new Float32Array(capacity * 3)\n const velocity = new Float32Array(capacity * 3)\n const extra = new Float32Array(capacity * 4)\n const attributes = [dynamic(THREE, position, 3), dynamic(THREE, velocity, 3), dynamic(THREE, extra, 4)] as const\n geometry.setAttribute('aPos', attributes[0])\n geometry.setAttribute('aVel', attributes[1])\n geometry.setAttribute('aE', attributes[2])\n geometry.instanceCount = 0\n const material = new THREE.ShaderMaterial({ transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, vertexShader: SPARK_VERTEX, fragmentShader: SPARK_FRAGMENT })\n const mesh = new THREE.Mesh(geometry, material)\n mesh.name = 'vfx-sparks'\n mesh.frustumCulled = false\n mesh.renderOrder = 5\n return {\n mesh,\n sync() {\n let n = 0\n for (const s of pool.items) {\n position[n * 3] = s.x\n position[n * 3 + 1] = s.y\n position[n * 3 + 2] = s.z\n velocity[n * 3] = s.vx\n velocity[n * 3 + 1] = s.vy\n velocity[n * 3 + 2] = s.vz\n extra[n * 4] = s.age\n extra[n * 4 + 1] = s.w\n extra[n * 4 + 2] = s.st\n extra[n * 4 + 3] = s.kind\n n++\n }\n geometry.instanceCount = n\n for (const attribute of attributes) attribute.needsUpdate = true\n return n\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\nexport function createGlowLayer(THREE: ThreeLib, pool: OrderedPool<Glow>): DrawnLayer {\n const capacity = pool.capacity\n const geometry = new THREE.InstancedBufferGeometry()\n geometry.setAttribute('position', new THREE.Float32BufferAttribute([-1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0], 3))\n geometry.setIndex([0, 1, 2, 0, 2, 3])\n const where = new Float32Array(capacity * 4)\n const color = new Float32Array(capacity * 4)\n const attributes = [dynamic(THREE, where, 4), dynamic(THREE, color, 4)] as const\n geometry.setAttribute('aP', attributes[0])\n geometry.setAttribute('aC', attributes[1])\n geometry.instanceCount = 0\n const material = new THREE.ShaderMaterial({ transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, vertexShader: GLOW_VERTEX, fragmentShader: GLOW_FRAGMENT })\n const mesh = new THREE.Mesh(geometry, material)\n mesh.name = 'vfx-glows'\n mesh.frustumCulled = false\n mesh.renderOrder = 6\n return {\n mesh,\n sync() {\n let n = 0\n for (const g of pool.items) {\n where[n * 4] = g.outX\n where[n * 4 + 1] = g.outY\n where[n * 4 + 2] = g.outZ\n where[n * 4 + 3] = g.outSize\n color[n * 4] = g.color[0]\n color[n * 4 + 1] = g.color[1]\n color[n * 4 + 2] = g.color[2]\n color[n * 4 + 3] = g.outIntensity\n n++\n }\n geometry.instanceCount = n\n for (const attribute of attributes) attribute.needsUpdate = true\n return n\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\nexport interface ChunkLayer {\n readonly rocks: THREE_NS.InstancedMesh\n readonly plates: THREE_NS.InstancedMesh\n sync(): number\n dispose(): void\n}\n\nexport function createChunkLayer(THREE: ThreeLib, pool: OrderedPool<Chunk>, shapes: { rock: THREE_NS.BufferGeometry; plate: THREE_NS.BufferGeometry }, colorOf: (chunk: Chunk) => readonly [number, number, number]): ChunkLayer {\n const capacity = pool.capacity\n const rockMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0.85, flatShading: true })\n const plateMaterial = rockMaterial.clone()\n const make = (geometry: THREE_NS.BufferGeometry, material: THREE_NS.Material): THREE_NS.InstancedMesh => {\n const mesh = new THREE.InstancedMesh(geometry, material, capacity)\n mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)\n mesh.castShadow = true\n mesh.receiveShadow = true\n mesh.frustumCulled = false\n mesh.count = 0\n mesh.setColorAt(0, new THREE.Color(1, 1, 1))\n return mesh\n }\n const rocks = make(shapes.rock, rockMaterial)\n const plates = make(shapes.plate, plateMaterial)\n const matrix = new THREE.Matrix4()\n const quaternion = new THREE.Quaternion()\n const euler = new THREE.Euler()\n const position = new THREE.Vector3()\n const scale = new THREE.Vector3()\n return {\n rocks,\n plates,\n sync() {\n let rockCount = 0\n let plateCount = 0\n for (const chunk of pool.items) {\n euler.set(chunk.rx, chunk.ry, chunk.rz)\n quaternion.setFromEuler(euler)\n matrix.compose(position.set(chunk.x, chunk.y, chunk.z), quaternion, scale.set(chunk.sx, chunk.sy, chunk.sz))\n const mesh = chunk.plate ? plates : rocks\n const index = chunk.plate ? plateCount++ : rockCount++\n mesh.setMatrixAt(index, matrix)\n const color = colorOf(chunk)\n const colors = mesh.instanceColor!.array as Float32Array\n colors[index * 3] = color[0]\n colors[index * 3 + 1] = color[1]\n colors[index * 3 + 2] = color[2]\n }\n rocks.count = rockCount\n plates.count = plateCount\n for (const mesh of [rocks, plates]) {\n mesh.instanceMatrix.needsUpdate = true\n mesh.instanceColor!.needsUpdate = true\n }\n return rockCount + plateCount\n },\n dispose() {\n rockMaterial.dispose()\n plateMaterial.dispose()\n rocks.dispose()\n plates.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { LightPool } from '@adatechnology/game-vfx'\nimport type { ThreeLib } from './types'\n\nexport interface LightLayer {\n readonly group: THREE_NS.Group\n /** Moves and lights the 4 blast lights and 2 fire lights from the pool; answers how many are lit. */\n sync(): number\n dispose(): void\n}\n\n/** The Lab's light pool as real point lights (L349-365). Colours are the raw numbers the Lab used, not converted from sRGB. */\nexport function createLightLayer(THREE: ThreeLib, pool: LightPool, scale: number): LightLayer {\n const group = new THREE.Group()\n const blast = pool.blast.map(() => {\n const light = new THREE.PointLight(0xffa050, 0, 30, 2)\n light.position.set(0, -50, 0)\n group.add(light)\n return light\n })\n const fire = pool.fire.map(() => {\n const light = new THREE.PointLight(0xff7a2a, 0, 16, 2)\n light.position.set(0, -50, 0)\n group.add(light)\n return light\n })\n return {\n group,\n sync() {\n let lit = 0\n pool.blast.forEach((entry, index) => {\n const light = blast[index]!\n light.position.set(entry.x, entry.y, entry.z)\n light.distance = entry.distance\n light.color.setRGB(entry.color[0], entry.color[1], entry.color[2], THREE.LinearSRGBColorSpace)\n light.intensity = entry.intensity * scale\n if (entry.intensity > 0.05) lit++\n })\n pool.fire.forEach((entry, index) => {\n const light = fire[index]!\n light.position.set(entry.x, entry.y, entry.z)\n light.distance = entry.distance\n light.intensity = entry.intensity * scale\n if (entry.intensity > 0.05) lit++\n })\n return lit\n },\n dispose() {\n for (const light of [...blast, ...fire]) light.dispose()\n },\n }\n}\n","import { lehmer } from '@adatechnology/game-vfx'\nimport type { RandomStream } from '@adatechnology/game-vfx'\nimport type { CanvasContextLike, CanvasLike, ThreeLib } from './types'\nimport type * as THREE_NS from 'three'\n\nconst SCORCH_SEED = 5\nconst TEXTURE_SIZE = 256\nconst FULL_TURN = Math.PI * 2\n\n/** Where a texture draws its randomness: the Lab seeded the page with 5 before it made the marks, so the textures do not touch the effect's own stream. */\nexport function createTextureStream(): RandomStream {\n return lehmer(SCORCH_SEED)\n}\n\n/** Without a DOM (a server, a test in Node) there is nothing to draw on: the textures stay blank and the marks still lay down their geometry. */\nfunction blankCanvas(): CanvasLike {\n return { width: 0, height: 0, getContext: () => null }\n}\n\nfunction defaultCanvas(): CanvasLike {\n if (typeof document === 'undefined') return blankCanvas()\n return document.createElement('canvas') as unknown as CanvasLike\n}\n\nfunction paint(createCanvas: () => CanvasLike, draw: (context: CanvasContextLike, size: number) => void): CanvasLike {\n const canvas = createCanvas()\n canvas.width = TEXTURE_SIZE\n canvas.height = TEXTURE_SIZE\n const context = canvas.getContext('2d')\n if (context) draw(context, TEXTURE_SIZE)\n return canvas\n}\n\nfunction drawScorch(context: CanvasContextLike, size: number, random: RandomStream): void {\n context.clearRect(0, 0, size, size)\n const center = size / 2\n for (let ray = 0; ray < 60; ray++) {\n const angle = random.next() * FULL_TURN\n const length = center * (0.55 + random.next() * 0.42)\n context.strokeStyle = `rgba(8,6,5,${0.25 + random.next() * 0.35})`\n context.lineWidth = 2 + random.next() * 6\n context.beginPath()\n context.moveTo(center, center)\n context.lineTo(center + Math.cos(angle) * length, center + Math.sin(angle) * length)\n context.stroke()\n }\n const gradient = context.createRadialGradient(center, center, 0, center, center, center * 0.72)\n gradient.addColorStop(0, 'rgba(4,3,3,.96)')\n gradient.addColorStop(0.55, 'rgba(10,8,7,.85)')\n gradient.addColorStop(1, 'rgba(14,11,9,0)')\n context.fillStyle = gradient\n context.fillRect(0, 0, size, size)\n for (let spot = 0; spot < 26; spot++) {\n context.fillStyle = `rgba(60,40,28,${0.15 + random.next() * 0.2})`\n context.beginPath()\n context.arc(center + random.between(-0.4, 0.4) * center, center + random.between(-0.4, 0.4) * center, 2 + random.next() * 7, 0, 7)\n context.fill()\n }\n}\n\nfunction drawDirt(context: CanvasContextLike, size: number, random: RandomStream): void {\n const center = size / 2\n context.clearRect(0, 0, size, size)\n const gradient = context.createRadialGradient(center, center, 0, center, center, center)\n gradient.addColorStop(0, 'rgba(92,72,52,1)')\n gradient.addColorStop(0.6, 'rgba(118,92,64,1)')\n gradient.addColorStop(0.82, 'rgba(80,64,50,.8)')\n gradient.addColorStop(1, 'rgba(40,36,34,0)')\n context.fillStyle = gradient\n context.fillRect(0, 0, size, size)\n for (let speck = 0; speck < 420; speck++) {\n const angle = random.next() * FULL_TURN\n const distance = Math.sqrt(random.next()) * center * 0.8\n context.fillStyle = random.next() < 0.5 ? 'rgba(40,30,22,.5)' : 'rgba(160,132,96,.5)'\n context.beginPath()\n context.arc(center + Math.cos(angle) * distance, center + Math.sin(angle) * distance, 1 + random.next() * 3.5, 0, 7)\n context.fill()\n }\n}\n\nexport interface MarkTextures {\n readonly scorch: readonly THREE_NS.CanvasTexture[]\n readonly dirt: THREE_NS.CanvasTexture\n}\n\n/** The three scorch textures and the dirt one (L443-457), drawn once from a stream seeded like the page's. */\nexport function createMarkTextures(THREE: ThreeLib, createCanvas: (() => CanvasLike) | undefined): MarkTextures {\n const make = createCanvas ?? defaultCanvas\n const random = createTextureStream()\n const texture = (canvas: CanvasLike): THREE_NS.CanvasTexture => {\n const result = new THREE.CanvasTexture(canvas as unknown as HTMLCanvasElement)\n result.colorSpace = THREE.SRGBColorSpace\n result.anisotropy = 4\n return result\n }\n const scorch = [0, 1, 2].map(() => texture(paint(make, (context, size) => drawScorch(context, size, random))))\n const dirt = texture(paint(make, (context, size) => drawDirt(context, size, random)))\n return { scorch, dirt }\n}\n","import type * as THREE_NS from 'three'\nimport type { BloodMark, DirtMark, GroundField, Mark, MarkEvent, RockMark, ScorchMark } from '@adatechnology/game-vfx'\nimport { createMarkTextures } from './canvas'\nimport type { MarkTextures } from './canvas'\nimport type { CanvasLike, ThreeLib } from './types'\n\nconst MAX_CONFORM_STEPS = 48\nconst MIN_CONFORM_STEPS = 16\nconst BLOOD_GROW_RATE = 1.2\n\ninterface BloodDrawn {\n readonly mesh: THREE_NS.Mesh\n readonly scaleX: number\n readonly scaleZ: number\n age: number\n}\n\nexport interface MarkLayer {\n readonly group: THREE_NS.Group\n /** The shared rock and plate shapes, so the debris and the rim rocks use the same geometry. */\n handle(event: MarkEvent): void\n update(dt: number): void\n /** The meshes in the group right now. */\n count(): number\n dispose(): void\n}\n\nexport interface MarkLayerOptions {\n readonly ground: GroundField | undefined\n readonly createCanvas: (() => CanvasLike) | undefined\n readonly rockGeometry: THREE_NS.BufferGeometry\n readonly plateGeometry: THREE_NS.BufferGeometry\n}\n\n/**\n * The scorch, dirt, rim rocks and blood of the Lab as meshes (L443-476). A scorch or dirt mesh follows the ground as it was the moment the mark was\n * made (`conform`), so the renderer builds it from the mark event, not later.\n */\nexport function createMarkLayer(THREE: ThreeLib, options: MarkLayerOptions): MarkLayer {\n const group = new THREE.Group()\n const textures: MarkTextures = createMarkTextures(THREE, options.createCanvas)\n const owned: { dispose(): void }[] = [...textures.scorch, textures.dirt]\n const scorchMaterials = textures.scorch.map((map) => {\n const material = new THREE.MeshStandardMaterial({ map, transparent: true, depthWrite: false, roughness: 1, polygonOffset: true, polygonOffsetFactor: -2, polygonOffsetUnits: -2 })\n owned.push(material)\n return material\n })\n const dirtMaterial = new THREE.MeshStandardMaterial({\n map: textures.dirt, transparent: true, depthWrite: false, roughness: 1, flatShading: true, polygonOffset: true, polygonOffsetFactor: -1, polygonOffsetUnits: -1,\n })\n owned.push(dirtMaterial)\n const bloodMaterial = new THREE.MeshStandardMaterial({ color: 0x5c0a0a, roughness: 0.15, metalness: 0.1, polygonOffset: true, polygonOffsetFactor: -3, polygonOffsetUnits: -3 })\n const bloodGeometry = new THREE.CircleGeometry(0.5, 9).rotateX(-Math.PI / 2)\n owned.push(bloodMaterial, bloodGeometry)\n const rockMaterials = new Map<number, THREE_NS.MeshStandardMaterial>()\n const blood: BloodDrawn[] = []\n let meshCount = 0\n\n function rockMaterial(color: number): THREE_NS.MeshStandardMaterial {\n let material = rockMaterials.get(color)\n if (!material) {\n material = new THREE.MeshStandardMaterial({ color, roughness: 0.9, metalness: 0, flatShading: true })\n rockMaterials.set(color, material)\n owned.push(material)\n }\n return material\n }\n\n function conform(mark: ScorchMark | DirtMark, material: THREE_NS.Material): THREE_NS.Mesh {\n const radius = mark.radius\n const steps = Math.max(MIN_CONFORM_STEPS, Math.min(MAX_CONFORM_STEPS, Math.round(radius * 8)))\n const geometry = new THREE.PlaneGeometry(2, 2, steps, steps).rotateX(-Math.PI / 2)\n const position = geometry.attributes.position!\n const cos = Math.cos(mark.rotation)\n const sin = Math.sin(mark.rotation)\n for (let index = 0; index < position.count; index++) {\n const localX = position.getX(index) * radius\n const localZ = position.getZ(index) * radius\n const worldX = mark.x + localX * cos - localZ * sin\n const worldZ = mark.z + localX * sin + localZ * cos\n position.setXYZ(index, worldX, (options.ground?.heightAt(worldX, worldZ) ?? 0) + mark.lift, worldZ)\n }\n geometry.computeVertexNormals()\n const mesh = new THREE.Mesh(geometry, material as THREE_NS.MeshStandardMaterial)\n mesh.receiveShadow = true\n return mesh\n }\n\n function addRock(mark: RockMark): THREE_NS.Mesh {\n const mesh = new THREE.Mesh(mark.plate ? options.plateGeometry : options.rockGeometry, rockMaterial(mark.color))\n mesh.position.set(mark.x, mark.y, mark.z)\n mesh.scale.set(mark.scale[0], mark.scale[1], mark.scale[2])\n mesh.rotation.set(mark.rotation[0], mark.rotation[1], mark.rotation[2])\n mesh.castShadow = true\n mesh.receiveShadow = true\n return mesh\n }\n\n function addBlood(mark: BloodMark): THREE_NS.Mesh {\n const mesh = new THREE.Mesh(bloodGeometry, bloodMaterial)\n mesh.position.set(mark.x, mark.y, mark.z)\n mesh.scale.set(mark.scaleX, 1, mark.scaleZ)\n mesh.rotation.y = mark.rotation\n mesh.receiveShadow = true\n mesh.scale.multiplyScalar(0.05)\n blood.push({ mesh, scaleX: mark.scaleX, scaleZ: mark.scaleZ, age: 0 })\n return mesh\n }\n\n function build(mark: Mark): THREE_NS.Mesh {\n if (mark.kind === 'scorch') return conform(mark, scorchMaterials[mark.variant]!)\n if (mark.kind === 'dirt') return conform(mark, dirtMaterial)\n if (mark.kind === 'rock') return addRock(mark)\n return addBlood(mark)\n }\n\n function clearMeshes(): void {\n for (const child of [...group.children]) {\n group.remove(child)\n const geometry = (child as THREE_NS.Mesh).geometry\n if (geometry !== options.rockGeometry && geometry !== options.plateGeometry && geometry !== bloodGeometry) geometry.dispose()\n }\n blood.length = 0\n meshCount = 0\n }\n\n return {\n group,\n handle(event) {\n if (event.type === 'clear') {\n clearMeshes()\n return\n }\n group.add(build(event.mark))\n meshCount++\n },\n update(dt) {\n for (const drawn of blood) {\n if (drawn.age > 1) continue\n drawn.age += dt * BLOOD_GROW_RATE\n const ease = 1 - Math.pow(1 - Math.min(1, drawn.age), 2.5)\n drawn.mesh.scale.set(drawn.scaleX * Math.max(0.05, ease), 1, drawn.scaleZ * Math.max(0.05, ease))\n }\n },\n count: () => meshCount,\n dispose() {\n clearMeshes()\n for (const item of owned) item.dispose()\n },\n }\n}\n","import type { ScreenState } from '@adatechnology/game-vfx'\n\nexport interface ScreenOverlay {\n update(state: Readonly<ScreenState>): void\n dispose(): void\n}\n\nconst clamp = (value: number, min: number, max: number): number => (value < min ? min : value > max ? max : value)\n\nfunction layer(container: HTMLElement, name: string, blend?: string): HTMLDivElement {\n const element = container.ownerDocument.createElement('div')\n element.dataset.vfxOverlay = name\n Object.assign(element.style, { position: 'absolute', inset: '0', pointerEvents: 'none', opacity: '0' })\n if (blend) element.style.mixBlendMode = blend\n container.appendChild(element)\n return element\n}\n\n/**\n * The screen effects as overlays inside the host's container: the Lab's white flash (L1087, `mix-blend-mode: screen`) and the Workshop's white,\n * red edge, the two sides and the gas tint (W356-366), with the same colours. Nothing is drawn while the state is at rest.\n */\nexport function createScreenOverlay(container: HTMLElement): ScreenOverlay {\n const flash = layer(container, 'flash', 'screen')\n flash.style.background = '#fff'\n const white = layer(container, 'white')\n const red = layer(container, 'red')\n const sides = layer(container, 'sides')\n const gas = layer(container, 'gas')\n const elements = [flash, white, red, sides, gas]\n return {\n update(state) {\n flash.style.opacity = clamp(state.flash, 0, 1).toFixed(3)\n white.style.opacity = '1'\n white.style.background = `rgba(235,240,255,${clamp(state.white, 0, 1).toFixed(2)})`\n red.style.opacity = '1'\n red.style.background = `radial-gradient(ellipse at center, transparent 40%, rgba(170,16,12,${(clamp(state.red, 0, 1) * 0.85).toFixed(2)}) 100%)`\n sides.style.opacity = '1'\n sides.style.background = `linear-gradient(90deg, rgba(190,20,14,${(state.directionLeft * 0.8).toFixed(2)}) 0%, transparent 35%, transparent 65%, rgba(190,20,14,${(state.directionRight * 0.8).toFixed(2)}) 100%)`\n gas.style.opacity = '1'\n gas.style.background = state.gas > 0.01 ? `rgba(90,130,40,${(state.gas * 0.55).toFixed(2)})` : 'transparent'\n },\n dispose() {\n for (const element of elements) element.remove()\n },\n }\n}\n","/** The shock shell (fresnel edge, Lab L322-325) and the dust ring on the ground (L326-333), verbatim except for the r160 colour-space chunk. */\nexport const SHELL_VERTEX = `varying vec3 vN;varying vec3 vV;void main(){vec4 wp=modelMatrix*vec4(position,1.);vN=normalize(mat3(modelMatrix)*normal);vV=normalize(cameraPosition-wp.xyz);gl_Position=projectionMatrix*viewMatrix*wp;}`\n\nexport const SHELL_FRAGMENT = `uniform float uA;varying vec3 vN;varying vec3 vV;void main(){float f=1.-abs(dot(vN,vV));f=pow(f,5.);gl_FragColor=vec4(vec3(1.,.93,.82)*f*uA*.45,1.);\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}`\n\nexport const RING_VERTEX = `varying vec2 vU;void main(){vU=position.xz;gl_Position=projectionMatrix*viewMatrix*modelMatrix*vec4(position,1.);}`\n\nexport const RING_FRAGMENT = `uniform float uA;uniform float uW;uniform vec3 uC;varying vec2 vU;\n float h(vec2 p){return fract(sin(dot(p,vec2(12.9898,78.233)))*43758.5453);}\n void main(){float r=length(vU);float b=smoothstep(1.,1.-uW,r)*smoothstep(1.-uW*3.5,1.-uW,r);float a=atan(vU.y,vU.x);float n=.7+.3*h(vec2(floor(a*14.),1.));gl_FragColor=vec4(uC,b*uA*n);\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}`\n","import type * as THREE_NS from 'three'\nimport type { OrderedPool, Shock } from '@adatechnology/game-vfx'\nimport { RING_FRAGMENT, RING_VERTEX, SHELL_FRAGMENT, SHELL_VERTEX } from './shaders/shock'\nimport type { ThreeLib } from './types'\n\ninterface Pair {\n readonly shell: THREE_NS.Mesh\n readonly ring: THREE_NS.Mesh\n readonly shellAlpha: { value: number }\n readonly ringAlpha: { value: number }\n}\n\nconst RING_HEIGHT = 0.05\n\nexport interface ShockLayer {\n readonly group: THREE_NS.Group\n sync(): number\n dispose(): void\n}\n\n/** The shock shell and ground ring of each live shock (L319-348): one pair of meshes per slot, shown while the slot has a shock. */\nexport function createShockLayer(THREE: ThreeLib, pool: OrderedPool<Shock>): ShockLayer {\n const group = new THREE.Group()\n const shellGeometry = new THREE.SphereGeometry(1, 28, 18)\n const ringGeometry = new THREE.PlaneGeometry(2, 2).rotateX(-Math.PI / 2)\n const pairs: Pair[] = []\n\n function makePair(): Pair {\n const shellAlpha = { value: 0 }\n const ringAlpha = { value: 0 }\n const shellMaterial = new THREE.ShaderMaterial({ transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, uniforms: { uA: shellAlpha }, vertexShader: SHELL_VERTEX, fragmentShader: SHELL_FRAGMENT })\n const ringMaterial = new THREE.ShaderMaterial({\n transparent: true, depthWrite: false, uniforms: { uA: ringAlpha, uW: { value: 0.12 }, uC: { value: new THREE.Color(0.55, 0.5, 0.44) } }, vertexShader: RING_VERTEX, fragmentShader: RING_FRAGMENT,\n })\n const shell = new THREE.Mesh(shellGeometry, shellMaterial)\n shell.renderOrder = 4\n const ring = new THREE.Mesh(ringGeometry, ringMaterial)\n ring.renderOrder = 3\n group.add(shell, ring)\n return { shell, ring, shellAlpha, ringAlpha }\n }\n\n return {\n group,\n sync() {\n const shocks = pool.items\n for (let index = 0; index < shocks.length; index++) {\n const pair = (pairs[index] ??= makePair())\n const shock = shocks[index]!\n pair.shell.visible = pair.ring.visible = true\n pair.shell.position.set(shock.x, shock.y, shock.z)\n pair.shell.scale.setScalar(shock.shellScale)\n pair.shellAlpha.value = shock.shellAlpha\n pair.ring.position.set(shock.x, RING_HEIGHT, shock.z)\n pair.ring.scale.setScalar(shock.ringScale)\n pair.ringAlpha.value = shock.ringAlpha\n }\n for (let index = shocks.length; index < pairs.length; index++) pairs[index]!.shell.visible = pairs[index]!.ring.visible = false\n return shocks.length\n },\n dispose() {\n for (const pair of pairs) {\n ;(pair.shell.material as THREE_NS.Material).dispose()\n ;(pair.ring.material as THREE_NS.Material).dispose()\n }\n shellGeometry.dispose()\n ringGeometry.dispose()\n },\n }\n}\n","/** The soft round point sprite of the game's sprite kinds (moved verbatim from the destruction renderer's particles). */\nexport const SPRITE_VERTEX = `\nuniform float uScale;\nattribute float size;\nattribute float alpha;\nattribute vec3 pcolor;\nvarying float vAlpha;\nvarying vec3 vColor;\nvoid main() {\n vAlpha = alpha;\n vColor = pcolor;\n vec4 mv = modelViewMatrix * vec4(position, 1.0);\n gl_PointSize = min(size * uScale / max(0.1, -mv.z), 256.0);\n gl_Position = projectionMatrix * mv;\n}`\n\nexport const SPRITE_FRAGMENT = `\nvarying float vAlpha;\nvarying vec3 vColor;\nvoid main() {\n float d = length(gl_PointCoord - vec2(0.5)) * 2.0;\n float a = (1.0 - smoothstep(0.35, 1.0, d)) * vAlpha;\n if (a < 0.004) discard;\n gl_FragColor = vec4(vColor, a);\n}`\n","import type * as THREE_NS from 'three'\nimport type { SpriteKindPool, SpriteKindSystem } from '@adatechnology/game-vfx'\nimport { SPRITE_FRAGMENT, SPRITE_VERTEX } from './shaders/sprite'\nimport type { ThreeLib } from './types'\n\nexport interface SpriteLayer {\n readonly additive: THREE_NS.Points\n readonly normal: THREE_NS.Points\n /** Tells the GPU what changed and answers how many sprites are drawn. */\n sync(): number\n dispose(): void\n}\n\ninterface Drawn {\n readonly points: THREE_NS.Points\n sync(): number\n dispose(): void\n}\n\nfunction drawPool(THREE: ThreeLib, pool: SpriteKindPool, additive: boolean, pointScale: number): Drawn {\n const geometry = new THREE.BufferGeometry()\n const attributes: [string, Float32Array, number][] = [['position', pool.position, 3], ['pcolor', pool.color, 3], ['alpha', pool.alpha, 1], ['size', pool.size, 1]]\n const buffers = attributes.map(([name, array, size]) => {\n const attribute = new THREE.BufferAttribute(array, size).setUsage(THREE.DynamicDrawUsage)\n geometry.setAttribute(name, attribute)\n return attribute\n })\n geometry.setDrawRange(0, 0)\n const material = new THREE.ShaderMaterial({\n uniforms: { uScale: { value: pointScale } },\n vertexShader: SPRITE_VERTEX,\n fragmentShader: SPRITE_FRAGMENT,\n transparent: true,\n depthWrite: false,\n blending: additive ? THREE.AdditiveBlending : THREE.NormalBlending,\n })\n const points = new THREE.Points(geometry, material)\n points.frustumCulled = false\n points.name = additive ? 'vfx-sprites-additive' : 'vfx-sprites'\n points.renderOrder = additive ? 11 : 10\n return {\n points,\n sync() {\n geometry.setDrawRange(0, pool.drawCount)\n for (const buffer of buffers) buffer.needsUpdate = true\n return pool.drawCount\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\n/** Draws the game's sprite kinds (debris, sparks, smoke, steam, drips...) as two soft point layers, additive and normal. */\nexport function createSpriteLayer(THREE: ThreeLib, system: SpriteKindSystem, pointScale: number): SpriteLayer {\n const additive = drawPool(THREE, system.additive, true, pointScale)\n const normal = drawPool(THREE, system.normal, false, pointScale)\n return {\n additive: additive.points,\n normal: normal.points,\n sync: () => additive.sync() + normal.sync(),\n dispose() {\n additive.dispose()\n normal.dispose()\n },\n }\n}\n","/** The Workshop's soft point sprite (W168-171): the size is in metres, clamped to 1..512 px; `uSoft` is 1 for the soft (normal blend) pool. */\nexport const WORKSHOP_SPRITE_VERTEX = `attribute float size;attribute float alpha;attribute vec3 pcol;varying vec3 vC;varying float vA;uniform float uScale;\nvoid main(){vC=pcol;vA=alpha;vec4 mv=modelViewMatrix*vec4(position,1.);gl_PointSize=clamp(size*uScale/-mv.z,1.,512.);gl_Position=projectionMatrix*mv;}`\n\nexport const WORKSHOP_SPRITE_FRAGMENT = `uniform float uSoft;varying vec3 vC;varying float vA;\nvoid main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a=mix(smoothstep(1.,.78,r),pow(1.-r,1.5),uSoft);gl_FragColor=vec4(vC,vA*a);}`\n","import type * as THREE_NS from 'three'\nimport type { Decal, WorkshopEngine } from '@adatechnology/game-vfx'\nimport { WORKSHOP_SPRITE_FRAGMENT, WORKSHOP_SPRITE_VERTEX } from './shaders/workshop-sprite'\nimport type { ThreeLib } from './types'\n\nconst DEBRIS_CAPACITY = 500\nconst DECAL_CAPACITY = 400\nconst RING_CAPACITY = 120\nconst RIPPLE_SEGMENTS = 12\nconst FADE_SECONDS = 0.5\nconst FIRE_LIGHT_COLOR = 0xff7a2a\nconst FIRE_LIGHT_DISTANCE = 14\nconst GLOSS_DRIED_AT = 0.85\nconst BROWN = 0x2a1610\nconst GROUND_COLOR = 0x888888\nconst FUEL_DRIED = 0x888888\n\nexport interface WorkshopLayers {\n readonly group: THREE_NS.Group\n /** Copies the pools into the draw buffers; answers how many draw calls have something to draw. */\n sync(): number\n dispose(): void\n}\n\ninterface Drawn {\n readonly object: THREE_NS.Object3D\n sync(): boolean\n dispose(): void\n}\n\nconst clamp = (v: number, lo: number, hi: number): number => (v < lo ? lo : v > hi ? hi : v)\n\nfunction spriteLayer(THREE: ThreeLib, pool: WorkshopEngine['add'], additive: boolean, soft: number, scale: number): Drawn {\n const geometry = new THREE.BufferGeometry()\n const arrays: [string, Float32Array, number][] = [['position', pool.position, 3], ['pcol', pool.color, 3], ['size', pool.size, 1], ['alpha', pool.alpha, 1]]\n const buffers = arrays.map(([name, array, size]) => {\n const attribute = new THREE.BufferAttribute(array, size).setUsage(THREE.DynamicDrawUsage)\n geometry.setAttribute(name, attribute)\n return attribute\n })\n geometry.setDrawRange(0, 0)\n const material = new THREE.ShaderMaterial({\n uniforms: { uScale: { value: scale }, uSoft: { value: soft } },\n vertexShader: WORKSHOP_SPRITE_VERTEX,\n fragmentShader: WORKSHOP_SPRITE_FRAGMENT,\n transparent: true,\n depthWrite: false,\n blending: additive ? THREE.AdditiveBlending : THREE.NormalBlending,\n })\n const points = new THREE.Points(geometry, material)\n points.frustumCulled = false\n points.renderOrder = additive ? 3 : 2\n points.name = additive ? 'workshop-add' : 'workshop-normal'\n return {\n object: points,\n sync() {\n geometry.setDrawRange(0, pool.count)\n for (const buffer of buffers) buffer.needsUpdate = true\n return pool.count > 0\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\nfunction streakLayer(THREE: ThreeLib, pool: WorkshopEngine['streaks']): Drawn {\n const geometry = new THREE.BufferGeometry()\n const position = new THREE.BufferAttribute(pool.segment, 3).setUsage(THREE.DynamicDrawUsage)\n const color = new THREE.BufferAttribute(pool.segmentColor, 3).setUsage(THREE.DynamicDrawUsage)\n geometry.setAttribute('position', position)\n geometry.setAttribute('color', color)\n geometry.setDrawRange(0, 0)\n const material = new THREE.LineBasicMaterial({ vertexColors: true, transparent: true, blending: THREE.AdditiveBlending, depthWrite: false })\n const lines = new THREE.LineSegments(geometry, material)\n lines.frustumCulled = false\n lines.renderOrder = 4\n lines.name = 'workshop-streaks'\n return {\n object: lines,\n sync() {\n geometry.setDrawRange(0, pool.count * 2)\n position.needsUpdate = color.needsUpdate = true\n return pool.count > 0\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\nfunction debrisLayer(THREE: ThreeLib, pool: WorkshopEngine['debris']): Drawn {\n const geometry = new THREE.BoxGeometry(1, 1, 1)\n const material = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0.45, metalness: 0.25, flatShading: true })\n const mesh = new THREE.InstancedMesh(geometry, material, DEBRIS_CAPACITY)\n mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)\n mesh.frustumCulled = false\n mesh.name = 'workshop-debris'\n const euler = new THREE.Euler()\n const quaternion = new THREE.Quaternion()\n const position = new THREE.Vector3()\n const scale = new THREE.Vector3()\n const matrix = new THREE.Matrix4()\n const colour = new THREE.Color()\n const hidden = new THREE.Matrix4().makeScale(0, 0, 0)\n for (let index = 0; index < DEBRIS_CAPACITY; index++) mesh.setMatrixAt(index, hidden)\n mesh.setColorAt(0, colour.setHex(0xffffff))\n return {\n object: mesh,\n sync() {\n let drawn = false\n for (let index = 0; index < DEBRIS_CAPACITY; index++) {\n const piece = pool.pieces[index]!\n if (!piece.on) {\n mesh.setMatrixAt(index, hidden)\n continue\n }\n drawn = true\n const shrink = Math.min(1, piece.life / FADE_SECONDS)\n euler.set(piece.rx, piece.ry, piece.rz)\n quaternion.setFromEuler(euler)\n matrix.compose(position.set(piece.x, piece.y, piece.z), quaternion, scale.set(piece.sx * shrink, piece.sy * shrink, piece.sz * shrink))\n mesh.setMatrixAt(index, matrix)\n mesh.setColorAt(index, colour.setHex(piece.color))\n }\n mesh.instanceMatrix.needsUpdate = true\n if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true\n return drawn\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\n/** A decal's current look from its fields (W276-306): it grows, a wet one creeps, dries towards its dry colour or evaporates. */\nfunction decalLook(decal: Decal, colour: THREE_NS.Color, dryColour: THREE_NS.Color, brown: THREE_NS.Color, ground: THREE_NS.Color, index: number): { sx: number; sy: number; dried: boolean } | null {\n const grown = decal.grow > 0 ? 1 - Math.pow(1 - Math.min(1, decal.t / decal.grow), 2.4) : 1\n let sx = decal.sx * grown\n let sy = decal.sy * grown\n colour.setHex(decal.color)\n let dried = false\n const fluid = decal.fluid\n if (fluid) {\n const creep = fluid === 'oil' ? 0.5 : fluid === 'fuel' ? 0.7 : fluid === 'bile' ? 0.25 : fluid === 'water' ? 0.2 : 0.3\n const age = decal.t\n if (decal.dryTime > 0) {\n const k = clamp((age - decal.dryAt) / decal.dryTime, 0, 1)\n if (decal.dryColor >= 0) dryColour.setHex(decal.dryColor)\n else dryColour.copy(colour).multiplyScalar(0.45).lerp(brown, 0.45)\n dried = k > GLOSS_DRIED_AT\n const spread = dried ? 1 + creep : 1 + creep * (1 - Math.exp(-age / 6))\n sx *= dried ? spread : spread * (1 + 0.04 * Math.sin(age * 1.9 + index))\n sy *= dried ? spread : spread * (1 + 0.04 * Math.cos(age * 1.5 + index * 0.7))\n colour.lerp(dryColour, k)\n } else {\n const spread = 1 + creep * (1 - Math.exp(-age / 6))\n sx *= spread * (1 + 0.04 * Math.sin(age * 1.9 + index))\n sy *= spread * (1 + 0.04 * Math.cos(age * 1.5 + index * 0.7))\n if (fluid === 'fuel' || fluid === 'water') {\n const [wait, span] = fluid === 'fuel' ? [6, 5] : [40, 20]\n const gone = clamp((age - wait) / span, 0, 1)\n sx *= 1 - gone * 0.85\n sy *= 1 - gone * 0.85\n colour.lerp(ground.setHex(fluid === 'fuel' ? FUEL_DRIED : GROUND_COLOR), gone * 0.8)\n if (gone >= 1) return null\n }\n }\n }\n return { sx, sy, dried }\n}\n\nfunction decalLayer(THREE: ThreeLib, pool: WorkshopEngine['decals']): Drawn {\n const geometry = new THREE.CircleGeometry(0.5, RIPPLE_SEGMENTS)\n const positions = geometry.getAttribute('position')\n // a blob, not a disc: each rim vertex is pulled in by a fixed amount between .72 and 1.12\n for (let index = 1; index < positions.count; index++) {\n const k = 0.72 + (((index * 2654435761) >>> 0) / 4294967296) * 0.4\n positions.setXY(index, positions.getX(index) * k, positions.getY(index) * k)\n }\n const wet = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0.1, metalness: 0.3, polygonOffset: true, polygonOffsetFactor: -4, polygonOffsetUnits: -4 })\n const dry = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 1, metalness: 0, flatShading: true, polygonOffset: true, polygonOffsetFactor: -4, polygonOffsetUnits: -4 })\n const wetMesh = new THREE.InstancedMesh(geometry, wet, DECAL_CAPACITY)\n const dryMesh = new THREE.InstancedMesh(geometry, dry, DECAL_CAPACITY)\n const group = new THREE.Group()\n group.name = 'workshop-decals'\n for (const mesh of [wetMesh, dryMesh]) {\n mesh.frustumCulled = false\n mesh.renderOrder = 1\n mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)\n group.add(mesh)\n }\n const hidden = new THREE.Matrix4().makeScale(0, 0, 0)\n const colour = new THREE.Color()\n const dryColour = new THREE.Color()\n const brown = new THREE.Color(BROWN)\n const ground = new THREE.Color()\n const normal = new THREE.Vector3()\n const forward = new THREE.Vector3(0, 0, 1)\n const turn = new THREE.Quaternion()\n const quaternion = new THREE.Quaternion()\n const position = new THREE.Vector3()\n const scale = new THREE.Vector3()\n const matrix = new THREE.Matrix4()\n wetMesh.setColorAt(0, colour.setHex(0))\n dryMesh.setColorAt(0, colour.setHex(0))\n for (let index = 0; index < DECAL_CAPACITY; index++) {\n wetMesh.setMatrixAt(index, hidden)\n dryMesh.setMatrixAt(index, hidden)\n }\n return {\n object: group,\n sync() {\n let drawn = false\n for (let index = 0; index < DECAL_CAPACITY; index++) {\n const decal = pool.decals[index]!\n wetMesh.setMatrixAt(index, hidden)\n dryMesh.setMatrixAt(index, hidden)\n if (!decal.on || decal.t < 0) continue\n const look = decalLook(decal, colour, dryColour, brown, ground, index)\n if (!look) continue\n drawn = true\n normal.set(decal.normal[0], decal.normal[1], decal.normal[2])\n quaternion.setFromUnitVectors(forward, normal)\n quaternion.multiply(turn.setFromAxisAngle(forward, index * 2.399963))\n const offset = 0.004 + (index % 40) * 0.0004\n matrix.compose(position.set(decal.x + normal.x * offset, decal.y + normal.y * offset, decal.z + normal.z * offset), quaternion, scale.set(look.sx, look.sy, 1))\n const mesh = look.dried ? dryMesh : wetMesh\n mesh.setMatrixAt(index, matrix)\n mesh.setColorAt(index, colour)\n }\n for (const mesh of [wetMesh, dryMesh]) {\n mesh.instanceMatrix.needsUpdate = true\n if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true\n }\n return drawn\n },\n dispose() {\n geometry.dispose()\n wet.dispose()\n dry.dispose()\n },\n }\n}\n\nfunction ringLayer(THREE: ThreeLib, pool: WorkshopEngine['rings']): Drawn {\n const geometry = new THREE.RingGeometry(0.86, 1, 40)\n const material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true, blending: THREE.AdditiveBlending, depthWrite: false, side: THREE.DoubleSide })\n const mesh = new THREE.InstancedMesh(geometry, material, RING_CAPACITY)\n mesh.frustumCulled = false\n mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)\n mesh.name = 'workshop-rings'\n const hidden = new THREE.Matrix4().makeScale(0, 0, 0)\n const colour = new THREE.Color()\n const normal = new THREE.Vector3()\n const forward = new THREE.Vector3(0, 0, 1)\n const quaternion = new THREE.Quaternion()\n const position = new THREE.Vector3()\n const scale = new THREE.Vector3()\n const matrix = new THREE.Matrix4()\n mesh.setColorAt(0, colour.setHex(0))\n for (let index = 0; index < RING_CAPACITY; index++) mesh.setMatrixAt(index, hidden)\n return {\n object: mesh,\n sync() {\n let drawn = false\n for (let index = 0; index < RING_CAPACITY; index++) {\n const ring = pool.rings[index]!\n if (!ring.on) {\n mesh.setMatrixAt(index, hidden)\n continue\n }\n drawn = true\n const k = Math.min(1, ring.t / ring.duration)\n const radius = ring.from + (ring.to - ring.from) * (1 - Math.pow(1 - k, 2))\n quaternion.setFromUnitVectors(forward, normal.set(ring.normal[0], ring.normal[1], ring.normal[2]))\n matrix.compose(position.set(ring.point[0], ring.point[1], ring.point[2]), quaternion, scale.set(radius, radius, 1))\n mesh.setMatrixAt(index, matrix)\n mesh.setColorAt(index, colour.setHex(ring.color).multiplyScalar(ring.hold ? ring.hold : 1 - k))\n }\n mesh.instanceMatrix.needsUpdate = true\n if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true\n return drawn\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\n/**\n * Draws the pools of the world's Workshop engine (what `world.play` fills): the two sprite systems, the streaks, the physics debris, the decals, the\n * expanding rings and the flash and fire lights, with the page's shaders and materials.\n */\nexport function createWorkshopLayers(THREE: ThreeLib, engine: WorkshopEngine, pointScale: number, lightScale: number): WorkshopLayers {\n const group = new THREE.Group()\n group.name = 'workshop'\n const layers: Drawn[] = [\n spriteLayer(THREE, engine.add, true, 1, pointScale),\n spriteLayer(THREE, engine.normal, false, 0.55, pointScale),\n streakLayer(THREE, engine.streaks),\n debrisLayer(THREE, engine.debris),\n decalLayer(THREE, engine.decals),\n ringLayer(THREE, engine.rings),\n ]\n for (const layer of layers) group.add(layer.object)\n const flashLights = engine.lights.lights.map(() => new THREE.PointLight(0xffc070, 0, 14))\n const fireLights = engine.lights.fire.map(() => new THREE.PointLight(FIRE_LIGHT_COLOR, 0, FIRE_LIGHT_DISTANCE))\n for (const light of [...flashLights, ...fireLights]) group.add(light)\n return {\n group,\n sync() {\n let drawCalls = 0\n for (const layer of layers) if (layer.sync()) drawCalls++\n engine.lights.lights.forEach((source, index) => {\n const light = flashLights[index]!\n light.position.set(source.x, source.y, source.z)\n light.color.setHex(source.color)\n light.distance = source.distance\n light.intensity = source.intensity * lightScale\n })\n engine.lights.fire.forEach((source, index) => {\n const light = fireLights[index]!\n light.position.set(source.x, source.y, source.z)\n light.intensity = source.intensity * lightScale\n })\n return drawCalls\n },\n dispose() {\n for (const layer of layers) layer.dispose()\n group.clear()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { ControlValue } from '@adatechnology/game-contracts'\nimport { colorOfChunk, createVfx, hexToLinearRgb } from '@adatechnology/game-vfx'\nimport type { ScreenState, VfxWorld, WorkshopEngine } from '@adatechnology/game-vfx'\nimport { createChunkLayer, createGlowLayer, createPuffLayer, createSparkLayer } from './instanced'\nimport type { PuffUniforms } from './instanced'\nimport { createLightLayer } from './lights'\nimport { createMarkLayer } from './marks'\nimport { createScreenOverlay } from './screen-overlay'\nimport { createShockLayer } from './shocks'\nimport { createSpriteLayer } from './sprites'\nimport type { ThreeLib, VfxRenderer, VfxRendererOptions } from './types'\nimport { createWorkshopLayers } from './workshop-layers'\nimport type { WorkshopLayers } from './workshop-layers'\n\nconst LAB_LIGHT_DIRECTION = [-14, 26, 12] as const\nconst SKY_COLOR = 0x6f7c92\nconst GROUND_COLOR = 0x2a241f\nconst LOD_BANDS: Readonly<Record<string, number | null>> = { auto: null, near: 1, middle: 0.5, far: 0.2 }\n/** The quality names the bench offers, as the Workshop's levels (0 keeps every particle). */\nconst QUALITY_LEVELS: Readonly<Record<string, number>> = { high: 0, medium: 1, low: 2 }\n/** `configure({ layer_<id>: false })` hides a layer of the renderer: `puffs`, `sparks`, `glows`, `debris`, `shock`, `sprites`. */\nexport const VFX_LAYERS = ['puffs', 'sparks', 'glows', 'debris', 'shock', 'sprites'] as const\nconst LAYER_PREFIX = 'layer_'\nconst SHAKE_REACH = 0.18\nconst SHAKE_FLOOR = 0.001\n\nfunction isWorld(value: unknown): value is VfxWorld {\n return typeof value === 'object' && value !== null && 'explosion' in value && typeof (value as VfxWorld).explosion === 'function'\n}\n\n/** The overlay shows the Lab's screen and the Workshop's together: the stronger of each field. */\nfunction mergeScreens(lab: ScreenState, workshop: ScreenState | undefined): ScreenState {\n if (!workshop) return lab\n const merged = { ...lab }\n for (const key of Object.keys(lab) as (keyof ScreenState)[]) merged[key] = Math.max(lab[key], workshop[key])\n return merged\n}\n\nfunction prefersReducedMotion(): boolean {\n return typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches\n}\n\n/** Draws a `VfxWorld`: the Lab's shaders, debris, shock, lights, marks and the screen overlay, and plays effects asked of it by id (`EffectSink`). */\nexport function createVfxRenderer(THREE: ThreeLib, options: VfxRendererOptions): VfxRenderer {\n const reducedMotion = options.reducedMotion ?? prefersReducedMotion()\n const requested = options.vfx\n const world = isWorld(requested) ? requested : createVfx({ profile: options.quality ?? 'medium', reducedMotion, ...requested })\n const pools = world.pools()\n const root = new THREE.Group()\n options.scene.add(root)\n\n const direction = new THREE.Vector3(...(options.lightDirection ?? LAB_LIGHT_DIRECTION)).normalize()\n const sky = hexToLinearRgb(SKY_COLOR)\n const ground = hexToLinearRgb(GROUND_COLOR)\n const uniforms: PuffUniforms = {\n uLight: { value: direction },\n uSky: { value: new THREE.Vector3(sky[0] * 0.55, sky[1] * 0.55, sky[2] * 0.55) },\n uGround: { value: new THREE.Vector3(ground[0] * 0.6, ground[1] * 0.6, ground[2] * 0.6) },\n uGlowPos: { value: new THREE.Vector3() },\n uGlowCol: { value: new THREE.Vector3(1, 0.5, 0.2) },\n uGlowI: { value: 0 },\n uTime: { value: 0 },\n }\n const puffs = createPuffLayer(THREE, pools.puffs, uniforms)\n const sparks = createSparkLayer(THREE, pools.sparks)\n const glows = createGlowLayer(THREE, pools.glows)\n const rockGeometry = new THREE.DodecahedronGeometry(0.5, 0)\n const plateGeometry = new THREE.BoxGeometry(1, 1, 1)\n const chunks = createChunkLayer(THREE, pools.chunks, { rock: rockGeometry, plate: plateGeometry }, colorOfChunk)\n const shocks = createShockLayer(THREE, pools.shocks)\n const sprites = createSpriteLayer(THREE, world.sprites(), options.pointScale ?? 700)\n const lights = createLightLayer(THREE, pools.lights, options.lightScale ?? Math.PI)\n const marks = createMarkLayer(THREE, { ground: pools.ground, createCanvas: options.createCanvas, rockGeometry, plateGeometry })\n root.add(puffs.mesh, sparks.mesh, glows.mesh, chunks.rocks, chunks.plates, shocks.group, lights.group, sprites.additive, sprites.normal, marks.group)\n const stopMarks = world.onMarks((event) => marks.handle(event))\n const overlay = options.overlay ? createScreenOverlay(options.overlay) : undefined\n let drawCalls = 0\n let workshopLayers: WorkshopLayers | undefined\n let workshopEngine: WorkshopEngine | undefined\n const layerOn = new Map<string, boolean>()\n const layerObjects = (): Record<string, THREE_NS.Object3D[]> => ({\n puffs: [puffs.mesh],\n sparks: [sparks.mesh],\n glows: [glows.mesh],\n debris: [chunks.rocks, chunks.plates],\n shock: [shocks.group],\n sprites: [sprites.additive, sprites.normal, ...(workshopLayers ? [workshopLayers.group] : [])],\n })\n const applyLayers = (): void => {\n for (const [id, objects] of Object.entries(layerObjects())) for (const object of objects) object.visible = layerOn.get(id) !== false\n }\n const screenNow = (): ScreenState => mergeScreens(world.screen(), world.peekWorkshop()?.screen)\n let clock = 0\n const lastDrawn = { puffs: 0, sparks: 0, glows: 0, chunks: 0, shocks: 0, sprites: 0 }\n\n function followCamera(): void {\n const position = options.camera.position\n world.setCamera([position.x, position.y, position.z])\n }\n\n function syncAll(): void {\n lastDrawn.puffs = puffs.sync()\n lastDrawn.sparks = sparks.sync()\n lastDrawn.glows = glows.sync()\n lastDrawn.chunks = chunks.sync()\n lastDrawn.shocks = shocks.sync()\n lastDrawn.sprites = sprites.sync()\n lights.sync()\n const engine = world.peekWorkshop()\n if (engine && engine !== workshopEngine) {\n workshopLayers?.dispose()\n if (workshopLayers) root.remove(workshopLayers.group)\n workshopEngine = engine\n workshopLayers = createWorkshopLayers(THREE, engine, options.pointScale ?? 700, 1)\n root.add(workshopLayers.group)\n applyLayers()\n }\n const workshopCalls = workshopLayers?.sync() ?? 0\n const glow = pools.lights.glow\n uniforms.uGlowPos.value.set(glow.x, glow.y, glow.z)\n uniforms.uGlowCol.value.set(glow.color[0], glow.color[1], glow.color[2])\n uniforms.uGlowI.value = glow.intensity\n drawCalls = Number(lastDrawn.puffs > 0) + Number(lastDrawn.sparks > 0) + Number(lastDrawn.glows > 0) + Number(chunks.rocks.count > 0) + Number(chunks.plates.count > 0) + Number(sprites.additive.geometry.drawRange.count > 0) + Number(sprites.normal.geometry.drawRange.count > 0) + lastDrawn.shocks * 2 + marks.count() + workshopCalls\n }\n\n return {\n world,\n play(request) {\n followCamera()\n const explosion = world.explosion(request.effect, request.point, {\n ...(request.direction ? { direction: request.direction } : {}),\n ...(request.seed !== undefined ? { seed: request.seed } : {}),\n ...(request.scale !== undefined ? { scale: request.scale } : {}),\n })\n if (explosion !== null) return explosion\n return world.play(request.effect, request.point, {\n ...(request.direction ? { direction: request.direction } : {}),\n ...(request.normal ? { normal: request.normal } : {}),\n ...(request.seed !== undefined ? { seed: request.seed } : {}),\n ...(request.param !== undefined ? { param: request.param } : {}),\n })\n },\n stop: (handle) => world.stop(handle),\n configure(settings: Readonly<Record<string, ControlValue>>) {\n const band = settings.lod_band\n if (typeof band === 'string' && band in LOD_BANDS) world.forceLod(LOD_BANDS[band] ?? null)\n const quality = settings.quality\n if (typeof quality === 'string' && quality in QUALITY_LEVELS) world.workshop().setQuality(QUALITY_LEVELS[quality] ?? 0)\n let layersChanged = false\n for (const [key, value] of Object.entries(settings)) {\n if (!key.startsWith(LAYER_PREFIX) || typeof value !== 'boolean') continue\n layerOn.set(key.slice(LAYER_PREFIX.length), value)\n layersChanged = true\n }\n if (layersChanged) applyLayers()\n },\n catalog: () => [...world.catalog(), ...world.effectIds()],\n update(dt) {\n clock += dt\n uniforms.uTime.value = clock\n followCamera()\n world.update(dt)\n marks.update(dt)\n syncAll()\n overlay?.update(screenNow())\n },\n applyCamera() {\n const shake = screenNow().shake\n if (reducedMotion || !(shake > SHAKE_FLOOR)) return () => {}\n const camera = options.camera as THREE_NS.Camera\n const base = camera.position.clone()\n const reach = shake * SHAKE_REACH\n camera.position.x += Math.sin(clock * 71) * reach\n camera.position.y += Math.sin(clock * 53 + 1) * reach * 0.7\n camera.position.z += Math.sin(clock * 67 + 2) * reach\n return () => camera.position.copy(base)\n },\n stats() {\n const { lastBlast, ...counters } = world.stats()\n return { ...counters, last_puffs: lastBlast.puffs, last_sparks: lastBlast.sparks, last_chunks: lastBlast.chunks, last_lights: lastBlast.lights, drawCalls }\n },\n screen: screenNow,\n dispose() {\n stopMarks()\n overlay?.dispose()\n workshopLayers?.dispose()\n for (const layer of [puffs, sparks, glows, chunks, shocks, lights, marks, sprites]) layer.dispose()\n rockGeometry.dispose()\n plateGeometry.dispose()\n options.scene.remove(root)\n },\n }\n}\n","/** The words of the effects bench, per locale (the effects' own texts live in `@adatechnology/game-vfx`). */\nexport interface BenchText {\n readonly module: string\n readonly controls: Readonly<Record<'effect' | 'variant' | 'replay' | 'auto_repeat' | 'distance' | 'lod_band' | 'quality', string>>\n readonly lod: Readonly<Record<'auto' | 'near' | 'middle' | 'far', string>>\n readonly quality: Readonly<Record<'high' | 'medium' | 'low', string>>\n readonly layers: Readonly<Record<'puffs' | 'sparks' | 'glows' | 'debris' | 'shock' | 'sprites', string>>\n readonly metrics: Readonly<Record<'puffs' | 'sparks' | 'debris' | 'lights' | 'budget_particles' | 'lod' | 'phase' | 'blast_time', string>>\n readonly sheet: Readonly<Record<'explosion' | 'lethal' | 'injury' | 'radius' | 'fireballs' | 'particles' | 'scale', string>>\n readonly none: string\n}\n\nexport const benchTexts: Readonly<Record<string, BenchText>> = {\n en: {\n module: 'Effects',\n controls: { effect: 'Effect', variant: 'Variant', replay: 'Replay', auto_repeat: 'Auto replay', distance: 'Distance', lod_band: 'LOD band', quality: 'Quality' },\n lod: { auto: 'Auto', near: 'Near', middle: 'Middle', far: 'Far' },\n quality: { high: 'High', medium: 'Medium', low: 'Low' },\n layers: { puffs: 'Smoke and fire', sparks: 'Sparks', glows: 'Glows', debris: 'Debris', shock: 'Shock wave', sprites: 'Droplets and recipes' },\n metrics: { puffs: 'Puffs', sparks: 'Sparks', debris: 'Debris', lights: 'Lights', budget_particles: 'Particles of the effect', lod: 'LOD scale', phase: 'Time since replay', blast_time: 'Time since the blast' },\n sheet: { explosion: 'Explosion', lethal: 'Lethal radius', injury: 'Injury radius', radius: 'Fireball', fireballs: 'Fireballs', particles: 'Particles', scale: 'Scale' },\n none: 'None',\n },\n 'pt-BR': {\n module: 'Efeitos',\n controls: { effect: 'Efeito', variant: 'Variante', replay: 'Repetir', auto_repeat: 'Repetição automática', distance: 'Distância', lod_band: 'Faixa de LOD', quality: 'Qualidade' },\n lod: { auto: 'Automático', near: 'Perto', middle: 'Meio', far: 'Longe' },\n quality: { high: 'Alta', medium: 'Média', low: 'Baixa' },\n layers: { puffs: 'Fumaça e fogo', sparks: 'Faíscas', glows: 'Brilhos', debris: 'Destroços', shock: 'Onda de choque', sprites: 'Gotas e receitas' },\n metrics: { puffs: 'Nuvens', sparks: 'Faíscas', debris: 'Destroços', lights: 'Luzes', budget_particles: 'Partículas do efeito', lod: 'Escala de LOD', phase: 'Tempo desde a repetição', blast_time: 'Tempo desde a explosão' },\n sheet: { explosion: 'Explosão', lethal: 'Raio letal', injury: 'Raio de ferimento', radius: 'Bola de fogo', fireballs: 'Bolas de fogo', particles: 'Partículas', scale: 'Escala' },\n none: 'Nenhuma',\n },\n}\n\nexport const benchText = (locale: string): BenchText => benchTexts[locale] ?? benchTexts.en!\n","import type * as THREE_NS from \"three\";\nimport type {\n BenchChange,\n BenchSheet,\n ChoiceOption,\n EffectHandle,\n EffectSink,\n ModuleControl,\n ModuleHost,\n ModuleLayer,\n ModuleMetric,\n TestableModule,\n} from \"@adatechnology/game-contracts\";\nimport {\n EVENT_BUDGET,\n EXPLOSIONS,\n GAME_EFFECTS,\n estimateCost,\n resolveStrings,\n} from \"@adatechnology/game-vfx\";\nimport type { EffectDef, ExplosionDef } from \"@adatechnology/game-vfx\";\nimport { createVfxRenderer, VFX_LAYERS } from \"../renderer\";\nimport type { ThreeLib, VfxRenderer } from \"../types\";\nimport { benchText } from \"./text\";\n\nexport interface VfxTestModuleOptions {\n readonly locale?: string;\n /** The recipes the bench lists (default `GAME_EFFECTS`) and the explosions (default `EXPLOSIONS`). */\n readonly effects?: Readonly<Record<string, EffectDef>>;\n readonly explosions?: Readonly<Record<string, ExplosionDef>>;\n /** Seconds between two replays while `auto_repeat` is on. */\n readonly repeatSeconds?: number;\n}\n\nconst DEFAULT_EFFECT = \"m67\";\n/** The profile the Lab falls back to for an unknown explosive: not something to pick. */\nconst FALLBACK_EXPLOSION = \"generic\";\nconst NO_VARIANT = \"none\";\nconst BLAST_POINT: readonly [number, number, number] = [0, 0.1, 0];\nconst DEFAULT_DISTANCE = 14;\nconst DEFAULT_REPEAT_SECONDS = 4;\nconst LIGHT_BUDGET = EVENT_BUDGET.blastLights + EVENT_BUDGET.fireLights;\nconst SEGMENT_COLORS = [\"#ffb347\", \"#ff7a2a\", \"#8a8f98\", \"#5c6370\"] as const;\n\nconst TEAMS = [\n \"creatures\",\n \"weapons\",\n \"destruction\",\n \"world\",\n \"vehicles\",\n \"screen\",\n] as const;\nconst LAYER_ID = \"show_\";\n\nconst humanize = (id: string): string => id.replace(/_/g, \" \");\n\n/** Where the bench stands for a distance (m): a three-quarter view that keeps the blast in frame. */\nconst eyeFor = (distance: number): [number, number, number] => [\n distance * 0.6,\n distance * 0.35 + 1.4,\n distance * 0.8,\n];\n\n/** The tick marks and segments of a sheet's timeline: an explosion's flash, fireball and smoke, or a recipe's time. */\nfunction timelineOf(\n explosion: ExplosionDef | undefined,\n recipe: EffectDef | undefined,\n metric: string,\n): NonNullable<BenchSheet[\"timeline\"]> {\n if (explosion) {\n const flash = explosion.flash.life ?? 0.2;\n const smoke = Math.max(explosion.smoke.life, 1);\n return {\n segments: [\n { name: \"flash\", start: 0, end: flash, color: SEGMENT_COLORS[0] },\n {\n name: \"fireball\",\n start: 0,\n end: Math.min(smoke, 2.4),\n color: SEGMENT_COLORS[1],\n },\n { name: \"smoke\", start: 0.4, end: smoke, color: SEGMENT_COLORS[2] },\n ],\n ticks: Array.from({ length: Math.ceil(smoke) }, (_, index) => index + 1),\n metric,\n };\n }\n const span = recipe?.loop && recipe.loop > 0 ? recipe.loop : 4;\n return {\n segments: [\n { name: recipe?.id ?? \"\", start: 0, end: span, color: SEGMENT_COLORS[1] },\n ],\n ticks: Array.from({ length: Math.floor(span) }, (_, index) => index + 1),\n metric,\n };\n}\n\n/**\n * The effects bench: pick an explosion or a recipe (listed by team), its variant, the distance, the quality and the layers, replay it or let it repeat,\n * and watch the particle and light counters against the budget. It plays through `host.effects` (the room's world) and, in a host without one, draws\n * into a renderer of its own.\n */\nexport function createVfxTestModule(\n options: VfxTestModuleOptions = {},\n): TestableModule {\n const locale = options.locale ?? \"en\";\n const recipes = options.effects ?? GAME_EFFECTS;\n const explosions = options.explosions ?? EXPLOSIONS;\n const text = benchText(locale);\n const strings = resolveStrings(locale);\n\n const effectOptions = (): ChoiceOption[] => [\n ...Object.keys(explosions)\n .filter((id) => id !== FALLBACK_EXPLOSION)\n .map((id) => ({\n id,\n name: humanize(id),\n group: strings.groups.explosions ?? text.sheet.explosion,\n })),\n // an id the explosions already use is the explosion's: the sink tries the explosions first, so the recipe of the same name could not be reached\n ...TEAMS.flatMap((team) =>\n Object.values(recipes)\n .filter((def) => def.team === team && !(def.id in explosions))\n .map((def) => ({\n id: def.id,\n name: strings.effects[def.id]?.name ?? humanize(def.id),\n group: strings.groups[def.team] ?? def.team,\n })),\n ),\n ];\n\n const sheetFor = (id: string): BenchSheet => {\n const explosion = explosions[id];\n if (explosion) {\n return {\n kicker: strings.groups.explosions ?? text.sheet.explosion,\n title: humanize(id),\n facts: [\n { label: text.sheet.lethal, value: `${explosion.lethal} m` },\n { label: text.sheet.injury, value: `${explosion.injury} m` },\n { label: text.sheet.radius, value: `${explosion.visualRadius} m` },\n { label: text.sheet.fireballs, value: String(explosion.fireballs) },\n {\n label: text.sheet.particles,\n value: `${estimateCost(explosion)} / ${EVENT_BUDGET.particles}`,\n },\n ],\n timeline: timelineOf(explosion, undefined, \"blast_time\"),\n };\n }\n const recipe = recipes[id];\n const words = strings.effects[id];\n const labels = strings.sheet;\n return {\n kicker: recipe ? (strings.groups[recipe.team] ?? recipe.team) : undefined,\n title: words?.name ?? humanize(id),\n ...(words ? { body: words.short } : {}),\n facts: words\n ? [{ label: labels.budget, value: `${words.cost} · ${words.costNote}` }]\n : [],\n steps: words\n ? [\n { at: labels.when, text: words.when },\n { at: labels.look, text: words.look },\n { at: labels.budget, text: words.budget },\n { at: labels.network, text: words.network },\n ]\n : [],\n timeline: timelineOf(undefined, recipe, \"phase\"),\n };\n };\n\n const controls = (): ModuleControl[] => [\n {\n kind: \"choice\",\n id: \"effect\",\n name: text.controls.effect,\n options: effectOptions(),\n default:\n DEFAULT_EFFECT in explosions ? DEFAULT_EFFECT : effectOptions()[0]!.id,\n },\n {\n kind: \"choice\",\n id: \"variant\",\n name: text.controls.variant,\n options: [{ id: NO_VARIANT, name: text.none }],\n default: NO_VARIANT,\n hidden: true,\n },\n { kind: \"action\", id: \"replay\", name: text.controls.replay },\n {\n kind: \"boolean\",\n id: \"auto_repeat\",\n name: text.controls.auto_repeat,\n default: false,\n },\n {\n kind: \"number\",\n id: \"distance\",\n name: text.controls.distance,\n min: 4,\n max: 120,\n step: 1,\n unit: \"m\",\n default: DEFAULT_DISTANCE,\n },\n {\n kind: \"choice\",\n id: \"lod_band\",\n name: text.controls.lod_band,\n options: ([\"auto\", \"near\", \"middle\", \"far\"] as const).map((id) => ({\n id,\n name: text.lod[id],\n })),\n default: \"auto\",\n },\n {\n kind: \"choice\",\n id: \"quality\",\n name: text.controls.quality,\n options: ([\"high\", \"medium\", \"low\"] as const).map((id) => ({\n id,\n name: text.quality[id],\n })),\n default: \"high\",\n },\n ];\n\n const layers = (): ModuleLayer[] =>\n VFX_LAYERS.map((id) => ({ id: `${LAYER_ID}${id}`, name: text.layers[id] }));\n\n /** The live counters: shared by `metrics` and filled by `attach` (a module without a host reads zeros). */\n let read: () => {\n stats: Readonly<Record<string, number>>;\n phase: number;\n budget: number;\n } = () => ({ stats: {}, phase: 0, budget: 0 });\n\n const metrics = (): ModuleMetric[] => [\n {\n id: \"puffs\",\n name: text.metrics.puffs,\n digits: 0,\n read: () => read().stats.puffs ?? 0,\n },\n {\n id: \"sparks\",\n name: text.metrics.sparks,\n digits: 0,\n read: () => read().stats.sparks ?? 0,\n },\n {\n id: \"debris\",\n name: text.metrics.debris,\n digits: 0,\n max: EVENT_BUDGET.debris,\n read: () => read().stats.chunks ?? 0,\n },\n {\n id: \"lights\",\n name: text.metrics.lights,\n digits: 0,\n max: LIGHT_BUDGET,\n read: () =>\n (read().stats.blastLights ?? 0) + (read().stats.fireLights ?? 0),\n },\n {\n id: \"budget_particles\",\n name: text.metrics.budget_particles,\n digits: 0,\n max: EVENT_BUDGET.particles,\n read: () => read().budget,\n },\n {\n id: \"lod\",\n name: text.metrics.lod,\n digits: 2,\n read: () => read().stats.lod ?? 1,\n },\n {\n id: \"phase\",\n name: text.metrics.phase,\n unit: \"s\",\n digits: 2,\n read: () => read().phase,\n },\n {\n id: \"blast_time\",\n name: text.metrics.blast_time,\n unit: \"s\",\n digits: 2,\n read: () => Math.max(0, read().stats.blastTime ?? 0),\n },\n ];\n\n return {\n id: \"vfx\",\n name: text.module,\n group: \"effects\",\n items: () => [],\n controls,\n layers,\n metrics,\n attach(host: ModuleHost) {\n const bench = host.bench;\n let own: VfxRenderer | undefined;\n let sink: EffectSink | undefined = host.effects;\n if (!sink) {\n own = createVfxRenderer(host.THREE as ThreeLib, {\n scene: host.scene as THREE_NS.Scene,\n camera: host.camera as THREE_NS.PerspectiveCamera,\n });\n sink = own;\n }\n const effects = sink;\n let effect = \"m67\";\n let variant = NO_VARIANT;\n let distance = DEFAULT_DISTANCE;\n let auto = false;\n let phase = 0;\n let handle: EffectHandle | null = null;\n let sinceRepeat = 0;\n\n read = () => {\n const def = explosions[effect];\n const recipe = recipes[effect];\n const budget = def\n ? estimateCost(def)\n : (recipe?.budget.particles ?? 0);\n return { stats: effects.stats?.() ?? {}, phase, budget };\n };\n\n function replay(): void {\n if (handle !== null) effects.stop(handle);\n phase = 0;\n sinceRepeat = 0;\n handle = effects.play({\n effect,\n point: [BLAST_POINT[0], BLAST_POINT[1], BLAST_POINT[2]],\n direction: [1, 0.2, 0.4],\n normal: [0, 1, 0],\n ...(variant !== NO_VARIANT &&\n recipes[effect]?.params?.options.includes(variant)\n ? { param: variant }\n : {}),\n });\n }\n\n function choose(id: string): void {\n effect = id;\n const params = recipes[id]?.params;\n variant = params\n ? (params.options[params.default] ?? params.options[0] ?? NO_VARIANT)\n : NO_VARIANT;\n bench?.patch(\n \"variant\",\n params\n ? {\n hidden: false,\n options: params.options.map((option) => ({\n id: option,\n name: option,\n })),\n value: variant,\n }\n : {\n hidden: true,\n options: [{ id: NO_VARIANT, name: text.none }],\n value: NO_VARIANT,\n },\n );\n bench?.sheet?.(sheetFor(id));\n replay();\n }\n\n function look(): void {\n const eye = eyeFor(distance);\n bench?.look(eye, [0, 1.2, 0]);\n }\n\n const apply = (change: BenchChange): void => {\n if (change.kind === \"layer\")\n effects.configure?.({\n [`layer_${change.id.slice(LAYER_ID.length)}`]: change.on,\n });\n else if (change.kind === \"action\") {\n if (change.id === \"replay\") replay();\n } else if (change.id === \"effect\" && typeof change.value === \"string\")\n choose(change.value);\n else if (change.id === \"variant\" && typeof change.value === \"string\") {\n variant = change.value;\n if (recipes[effect]?.params) replay();\n } else if (change.id === \"auto_repeat\") auto = change.value === true;\n else if (change.id === \"distance\" && typeof change.value === \"number\") {\n distance = change.value;\n look();\n } else if (change.id === \"lod_band\" || change.id === \"quality\")\n effects.configure?.({ [change.id]: change.value });\n };\n const offChange = bench?.onChange(apply);\n const offFrame = host.onFrame((dt) => {\n phase += dt;\n sinceRepeat += dt;\n own?.update(dt);\n if (\n auto &&\n sinceRepeat >= (options.repeatSeconds ?? DEFAULT_REPEAT_SECONDS)\n )\n replay();\n });\n return () => {\n offChange?.();\n offFrame();\n if (handle !== null) effects.stop(handle);\n bench?.sheet?.(null);\n own?.dispose();\n read = () => ({ stats: {}, phase: 0, budget: 0 });\n };\n },\n };\n}\n","import type * as THREE_NS from 'three'\nimport type { GroundField } from '@adatechnology/game-vfx'\nimport type { ThreeLib } from './types'\n\nexport interface GroundPatchOptions {\n /** The height field the craters dig; the mesh follows it. */\n readonly field: GroundField\n /** What the patch is made of (default a plain flat-shaded grey standard material). */\n readonly material?: THREE_NS.Material\n /** Texture coordinates repeat every this many metres (the Lab's 17). */\n readonly textureMetres?: number\n}\n\nexport interface GroundPatch {\n readonly mesh: THREE_NS.Mesh\n /** Redraws the vertices when the field changed since the last call. Returns whether it did. */\n sync(): boolean\n dispose(): void\n}\n\nconst DEFAULT_TEXTURE_METRES = 17\n\n/** The Lab's 60 m deformable patch with 33 cm cells (L60-83), as a mesh that follows a `GroundField`. */\nexport function createGroundPatch(THREE: ThreeLib, options: GroundPatchOptions): GroundPatch {\n const field = options.field\n const metres = options.textureMetres ?? DEFAULT_TEXTURE_METRES\n const geometry = new THREE.PlaneGeometry(field.size, field.size, field.segments, field.segments).rotateX(-Math.PI / 2)\n const position = geometry.attributes.position!\n const uv = geometry.attributes.uv!\n for (let index = 0; index < position.count; index++) uv.setXY(index, position.getX(index) / metres, position.getZ(index) / metres)\n const material = options.material ?? new THREE.MeshStandardMaterial({ color: 0x2b2c2f, roughness: 0.93, flatShading: true })\n const mesh = new THREE.Mesh(geometry, material)\n mesh.receiveShadow = true\n let version = -1\n\n function sync(): boolean {\n if (field.version === version) return false\n version = field.version\n for (let index = 0; index < position.count; index++) position.setY(index, field.heights[index]!)\n position.needsUpdate = true\n geometry.computeBoundingSphere()\n return true\n }\n\n return {\n mesh,\n sync,\n dispose() {\n geometry.dispose()\n if (!options.material) material.dispose()\n },\n }\n}\n"],"mappings":"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;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;QACP,OAAS;MACX;MACA,MAAQ;QACN,QAAU;QACV,QAAU;QACV,MAAQ;MACV;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,SAAW;QACT;QACA;MACF;IACF;IACA,IAAM;MACJ,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;QACP,OAAS;MACX;MACA,MAAQ;QACN,QAAU;QACV,QAAU;QACV,MAAQ;MACV;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,SAAW;QACT;QACA;MACF;IACF;IACA,UAAY;MACV,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,MAAQ;QACN,OAAS;QACT,MAAQ;QACR,QAAU;MACZ;MACA,eAAiB;MACjB,SAAW;QACT;QACA;MACF;IACF;IACA,WAAa;MACX,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;QACR,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;QACb,UAAY;MACd;MACA,OAAS;MACT,OAAS;MACT,MAAQ;MACR,SAAW;QACT;QACA;MACF;IACF;IACA,UAAY;MACV,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;QACV,QAAU;QACV,MAAQ;MACV;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,SAAW;QACT;QACA;MACF;IACF;IACA,UAAY;MACV,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,eAAiB;MACjB,SAAW;QACT;QACA;MACF;IACF;IACA,UAAY;MACV,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;QACV,QAAU;QACV,MAAQ;MACV;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,eAAiB;MACjB,SAAW;QACT;QACA;MACF;IACF;IACA,MAAQ;MACN,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,QAAU;MACZ;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,eAAiB;MACjB,SAAW;QACT;QACA;MACF;IACF;IACA,aAAe;MACb,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,QAAU;MACZ;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,UAAY;QACV,QAAU;QACV,QAAU;QACV,OAAS;QACT,MAAQ;QACR,MAAQ;MACV;MACA,eAAiB;QACf;UACE,IAAM;UACN,IAAM;UACN,QAAU;UACV,MAAQ;QACV;QACA;UACE,IAAM;UACN,IAAM;UACN,QAAU;UACV,MAAQ;QACV;QACA;UACE,IAAM;UACN,IAAM;UACN,QAAU;UACV,MAAQ;QACV;MACF;MACA,QAAU;MACV,UAAY;MACZ,SAAW;QACT;QACA;MACF;IACF;IACA,eAAiB;MACf,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,QAAU;MACZ;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,OAAS;QACT,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,UAAY;QACV,QAAU;QACV,QAAU;QACV,OAAS;QACT,MAAQ;QACR,MAAQ;MACV;MACA,QAAU;MACV,UAAY;MACZ,SAAW;QACT;QACA;MACF;IACF;IACA,WAAa;MACX,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,QAAU;MACZ;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,OAAS;QACT,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,UAAY;QACV,QAAU;QACV,QAAU;QACV,OAAS;QACT,MAAQ;QACR,MAAQ;MACV;MACA,eAAiB;QACf;UACE,QAAU;UACV,MAAQ;UACR,MAAQ;QACV;MACF;MACA,QAAU;MACV,UAAY;MACZ,SAAW;QACT;QACA;MACF;IACF;IACA,mBAAqB;MACnB,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,QAAU;MACZ;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;QACV,QAAU;QACV,MAAQ;MACV;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,UAAY;QACV,QAAU;QACV,QAAU;QACV,OAAS;QACT,MAAQ;QACR,MAAQ;QACR,UAAY;MACd;MACA,eAAiB;QACf;UACE,QAAU;UACV,MAAQ;UACR,MAAQ;UACR,OAAS;QACX;QACA;UACE,IAAM;UACN,IAAM;UACN,QAAU;UACV,MAAQ;QACV;QACA;UACE,IAAM;UACN,IAAM;UACN,QAAU;UACV,MAAQ;QACV;MACF;MACA,QAAU;MACV,UAAY;MACZ,SAAW;QACT;QACA;MACF;IACF;IACA,SAAW;MACT,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;QACV,QAAU;QACV,MAAQ;MACV;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,SAAW;QACT;QACA;QACA;MACF;IACF;EACF;ACv8BO,MAAM,aAAa;AAGnB,MAAM,oBAAsD;ACVnE,MAAM,WAAW;AACjB,MAAM,oBAAoB;AAC1B,MAAM,iBAAiB;AAGhB,WAAS,SAAS,KAAkB;AACzC,UAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,WAAO,EAAG,SAAS,KAAM,YAAY,WAAY,SAAS,IAAK,YAAY,WAAW,QAAQ,YAAY,QAAQ;EACpH;AAEO,WAAS,oBAAoB,SAAyB;AAC3D,WAAO,UAAU,iBAAiB,UAAU,oBAAoB,KAAK,IAAI,UAAU,eAAe,cAAc,GAAG;EACrH;AAGO,WAAS,eAAe,KAAkB;AAC/C,UAAM,CAAC,KAAK,OAAO,IAAI,IAAI,SAAS,GAAG;AACvC,WAAO,CAAC,oBAAoB,GAAG,GAAG,oBAAoB,KAAK,GAAG,oBAAoB,IAAI,CAAC;EACzF;ACjBO,MAAM,eAAe;IAC1B,MAAM,eAAe,OAAQ;IAC7B,MAAM,eAAe,OAAQ;IAC7B,OAAO,eAAe,OAAQ;IAC9B,OAAO,eAAe,OAAQ;IAC9B,MAAM,eAAe,OAAQ;IAC7B,UAAU,eAAe,OAAQ;IACjC,OAAO,eAAe,QAAQ;IAC9B,OAAO,eAAe,OAAQ;IAC9B,MAAM,eAAe,OAAQ;IAC7B,KAAK,eAAe,QAAQ;EAC9B;AAEO,MAAM,kBAAkB;AACxB,MAAM,eAAe,EAAE,GAAG,MAAM,GAAG,GAAG,GAAG,IAAI;ACb7C,MAAM,cAAN,MAAoC;IAKzC,YACW,UACQ,QACA,SACjB;AAHS,oBAAA,MAAA,YAAA,QAAA;AACQ,oBAAA,MAAA,UAAA,MAAA;AACA,oBAAA,MAAA,WAAA,OAAA;AANnB,oBAAA,MAAS,SAAa,CAAC,CAAA;AACvB,oBAAA,MAAiB,SAAa,CAAC,CAAA;IAM5B;IAEH,IAAI,QAAgB;AAClB,aAAO,KAAK,MAAM;IACpB;;IAGA,QAAQ,QAA6C;AACnD,UAAI,KAAK,MAAM,UAAU,KAAK,SAAU,MAAK,SAAS,SAAS,OAAO,KAAK,KAAK,IAAI,CAAC;AACrF,YAAM,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO;AAC/C,WAAK,MAAM,KAAK,MAAM;AACtB,aAAO;IACT;IAEA,SAAS,OAAqB;AAC5B,YAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,UAAI,WAAW,OAAW;AAC1B,eAAS,UAAU,OAAO,UAAU,KAAK,MAAM,SAAS,GAAG,UAAW,MAAK,MAAM,OAAO,IAAI,KAAK,MAAM,UAAU,CAAC;AAClH,WAAK,MAAM,UAAU;AACrB,WAAK,UAAU,MAAM;AACrB,WAAK,MAAM,KAAK,MAAM;IACxB;;IAGA,QAAkB,MAA+C,SAAyB;AACxF,UAAI,QAAQ;AACZ,eAAS,OAAO,GAAG,OAAO,KAAK,MAAM,QAAQ,QAAQ;AACnD,cAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,YAAI,KAAK,QAAQ,OAAO,GAAG;AACzB,eAAK,MAAM,OAAO,IAAI;AACtB;QACF;AACA,aAAK,UAAU,MAAM;AACrB,aAAK,MAAM,KAAK,MAAM;MACxB;AACA,WAAK,MAAM,SAAS;IACtB;IAEA,QAAc;AACZ,iBAAW,UAAU,KAAK,OAAO;AAC/B,aAAK,UAAU,MAAM;AACrB,aAAK,MAAM,KAAK,MAAM;MACxB;AACA,WAAK,MAAM,SAAS;IACtB;EACF;ACrBA,MAAM,gBAAqB,CAAC,KAAO,KAAK,KAAO,KAAK,KAAO,GAAG;AAG9D,WAAS,oBAAoB,OAAoB;AAC/C,UAAM,OAAO,MAAM;AACnB,UAAM,OAAO;AACb,QAAI,CAAC,QAAQ,KAAK,WAAW,MAAO;AACpC,SAAK,IAAI,MAAM,IAAI,KAAK;AACxB,SAAK,IAAI,MAAM,IAAI,KAAK;AACxB,SAAK,IAAI,MAAM,IAAI,KAAK;AACxB,SAAK,KAAK,KAAK,KAAK,KAAK,KAAK;AAC9B,SAAK,SAAS;EAChB;AAEO,WAAS,gBAAgB,UAAkB,aAA+C;AAC/F,WAAO,IAAI;MACT;MACA,OAAO;QACL,GAAG;QAAG,GAAG;QAAG,GAAG;QAAG,IAAI;QAAG,IAAI;QAAG,IAAI;QAAG,IAAI;QAAG,IAAI;QAAG,IAAI;QAAG,IAAI;QAAG,IAAI;QAAG,IAAI;QAAG,IAAI;QAAK,IAAI;QAAK,IAAI;QAAK,OAAO;QAAe,OAAO;QAAO,KAAK;QAAO,MAAM;QAClK,OAAO;QAAO,OAAO;QAAO,GAAG;QAAG,OAAO;QAAG,MAAM;QAAM,KAAK;QAAa,UAAU,CAAC,GAAG,GAAG,CAAC;MAC9F;MACA;IACF;EACF;AAEA,WAAS,aAAa,QAAkC;AACtD,UAAM,QAAQ,OAAO,UAAU,CAAC,UAAU,MAAM,IAAI;AACpD,WAAO,SAAS,IAAI,QAAQ;EAC9B;AAGO,WAAS,WAAW,MAA0B,QAAsB,MAAwB;AACjG,UAAM,QAAQ,KAAK,QAAQ,YAAY;AACvC,UAAM,IAAI,KAAK,KAAK;AACpB,UAAM,IAAI,KAAK,KAAK;AACpB,UAAM,IAAI,KAAK,KAAK;AACpB,UAAM,KAAK,KAAK,MAAM;AACtB,UAAM,KAAK,KAAK,MAAM;AACtB,UAAM,KAAK,KAAK,MAAM;AACtB,UAAM,KAAK,OAAO,KAAK,IAAI;AAC3B,UAAM,KAAK,OAAO,KAAK,IAAI;AAC3B,UAAM,KAAK,OAAO,KAAK,IAAI;AAC3B,UAAM,KAAK,OAAO,QAAQ,KAAK,EAAE;AACjC,UAAM,KAAK,OAAO,QAAQ,KAAK,EAAE;AACjC,UAAM,KAAK,OAAO,QAAQ,KAAK,EAAE;AACjC,UAAM,KAAK,KAAK,MAAM;AACtB,UAAM,KAAK,KAAK,MAAM;AACtB,UAAM,KAAK,KAAK,MAAM;AACtB,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,MAAM,KAAK,OAAO;AACxB,UAAM,OAAO;AACb,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,QAAQ;AACd,UAAM,IAAI;AACV,UAAM,QAAQ;AACd,UAAM,OAAO;AACb,UAAM,MAAM;AACZ,WAAO;EACT;AAEO,MAAM,YAAiB,CAAC,GAAG,MAAM,GAAG;AACpC,MAAM,cAAc;AAC3B,MAAM,YAAY;AAGX,WAAS,aAAa,OAAiD;AAC5E,QAAI,CAAC,MAAM,OAAO,MAAM,KAAK,aAAa;AACxC,YAAM,SAAS,CAAC,IAAI,MAAM,MAAM,CAAC;AACjC,YAAM,SAAS,CAAC,IAAI,MAAM,MAAM,CAAC;AACjC,YAAM,SAAS,CAAC,IAAI,MAAM,MAAM,CAAC;AACjC,aAAO,MAAM;IACf;AACA,UAAM,SAAS,KAAK,IAAI,GAAG,IAAI,MAAM,IAAI,WAAW,IAAI;AACxD,UAAM,SAAS,CAAC,IAAI,MAAM,MAAM,CAAC,KAAK,UAAU,CAAC,IAAI,MAAM,MAAM,CAAC,KAAK;AACvE,UAAM,SAAS,CAAC,IAAI,MAAM,MAAM,CAAC,KAAK,UAAU,CAAC,IAAI,MAAM,MAAM,CAAC,KAAK;AACvE,UAAM,SAAS,CAAC,IAAI,MAAM,MAAM,CAAC,KAAK,UAAU,CAAC,IAAI,MAAM,MAAM,CAAC,KAAK;AACvE,WAAO,MAAM;EACf;AC/GO,WAAS,WAAW,IAAI,GAAG,IAAI,GAAG,IAAI,GAAgB;AAC3D,WAAO,EAAE,GAAG,GAAG,EAAE;EACnB;AAEO,WAAS,UAAU,QAAqB,WAAwB,OAA4B;AACjG,WAAO,KAAK,UAAU,IAAI;AAC1B,WAAO,KAAK,UAAU,IAAI;AAC1B,WAAO,KAAK,UAAU,IAAI;AAC1B,WAAO;EACT;AAEO,WAAS,UAAU,QAAkC;AAC1D,UAAM,SAAS,KAAK,KAAK,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK;AAC7F,UAAM,UAAU,IAAI;AACpB,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO,KAAK;AACZ,WAAO;EACT;AAEO,WAAS,gBAAgB,IAAY,IAAY,IAAY,IAAY,IAAY,IAAoB;AAC9G,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,KAAK;AAChB,WAAO,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;EAC9C;AAEO,WAAS,KAAK,MAAc,IAAY,QAAwB;AACrE,WAAO,QAAQ,KAAK,QAAQ;EAC9B;ACIA,MAAMC,iBAAqB,CAAC,GAAG,KAAK,IAAI;AAEjC,WAAS,eAAe,UAAqC;AAClE,WAAO,IAAI,YAAkB,UAAU,OAAO;MAC5C,GAAG;MAAG,GAAG;MAAG,GAAG;MAAG,GAAG;MAAG,IAAI;MAAM,GAAG;MAAG,GAAG;MAAG,MAAM;MAAK,OAAOA;MAAe,OAAO;MAAG,OAAO;MAAO,QAAQ;MAAM,IAAI;MAAG,IAAI;MAAG,IAAI;MACvI,MAAM;MAAG,MAAM;MAAG,MAAM;MAAG,SAAS;MAAG,cAAc;IACvD,EAAE;EACJ;AAEO,WAAS,UAAU,MAAyB,MAAsB;AACvE,UAAM,OAAO,KAAK,QAAQ;AAC1B,SAAK,IAAI,KAAK,KAAK;AACnB,SAAK,IAAI,KAAK,KAAK;AACnB,SAAK,IAAI,KAAK,KAAK;AACnB,SAAK,IAAI,KAAK,KAAK;AACnB,SAAK,KAAK,KAAK,MAAM;AACrB,SAAK,IAAI,KAAK,KAAK;AACnB,SAAK,IAAI;AACT,SAAK,OAAO,KAAK,QAAQ;AACzB,SAAK,QAAQ,KAAK,SAASA;AAC3B,SAAK,QAAQ,KAAK,SAAS;AAC3B,SAAK,QAAQ,KAAK,SAAS;AAC3B,SAAK,SAAS,KAAK,UAAU;AAC7B,SAAK,KAAK,KAAK,MAAM;AACrB,SAAK,KAAK,KAAK,MAAM;AACrB,SAAK,KAAK,KAAK,MAAM;AACrB,WAAO;EACT;AAEA,WAAS,UAAU,MAAY,IAAqB;AAClD,SAAK,KAAK;AACV,WAAO,KAAK,IAAI,KAAK;EACvB;AAEA,MAAM,eAAe;AACrB,MAAM,iBAAiB;AAGhB,WAAS,YAAY,MAAyB,IAAkB;AACrE,SAAK,QAAQ,WAAW,EAAE;AAC1B,eAAW,QAAQ,KAAK,OAAO;AAC7B,YAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,UAAI,IAAI,KAAK;AACb,UAAI,IAAI,KAAK;AACb,UAAI,IAAI,KAAK;AACb,UAAI,KAAK,QAAQ;AACf,YAAI,KAAK,OAAO,IAAI,KAAK;AACzB,YAAI,KAAK,OAAO,IAAI,KAAK;AACzB,YAAI,KAAK,OAAO,IAAI,KAAK;MAC3B;AACA,WAAK,OAAO;AACZ,WAAK,OAAO;AACZ,WAAK,OAAO;AACZ,WAAK,UAAU,KAAK,OAAO,OAAO,KAAK,KAAK,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,IAAI,KAAK;AACzF,YAAM,UAAU,KAAK,QAAQ,OAAO,OAAO,KAAK,IAAI,KAAK,IAAI,eAAe,KAAK,IAAI,cAAc,IAAI;AACvG,WAAK,eAAe,KAAK,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,IAAI;IAC/D;EACF;ACrCA,MAAM,iBAAiB;AACvB,MAAM,eAAe;AACrB,MAAM,gBAAgB;AACtB,MAAM,eAAe;AACrB,MAAM,qBAAqB;AAEpB,WAAS,eAAe,UAAqC;AAClE,UAAM,cAA4B,EAAE,MAAM,MAAM,GAAG,SAAS,CAACC,SAAQA,MAAK,WAAW,CAAC,QAAQ,KAAK,OAAO,EAAE;AAC5G,WAAO,IAAI,YAAkB,UAAU,OAAO;MAC5C,GAAG;MAAG,GAAG;MAAG,GAAG;MAAG,IAAI;MAAG,IAAI;MAAG,IAAI;MAAG,IAAI;MAAK,IAAI;MAAG,IAAI;MAAK,IAAI;MAAG,MAAM;MAAG,GAAG;MAAG,IAAI;MAAG,IAAI;MAAK,MAAM;MAAG,MAAM;MAAK,MAAM;MAAG,MAAM;MAAG,MAAM;MAAG,MAAM;MAC3J,OAAO,aAAa;MAAM,MAAM;MAAM,IAAI;MAAG,IAAI;MAAG,KAAK;MAAa,KAAK;MAAG,MAAM;MAAG,MAAM;IAC/F,EAAE;EACJ;AAGO,WAAS,UAAU,MAAyB,QAAsB,MAAsB;AAC7F,UAAMC,QAAO,KAAK,QAAQ;AAC1BA,UAAK,IAAI,KAAK,KAAK;AACnBA,UAAK,IAAI,KAAK,KAAK;AACnBA,UAAK,IAAI,KAAK,KAAK;AACnBA,UAAK,KAAK,KAAK,MAAM;AACrBA,UAAK,KAAK,KAAK,MAAM;AACrBA,UAAK,KAAK,KAAK,MAAM;AACrBA,UAAK,KAAK,KAAK,MAAM;AACrBA,UAAK,KAAK,KAAK,MAAM;AACrBA,UAAK,KAAK,KAAK,MAAM;AACrBA,UAAK,KAAK,KAAK,MAAM;AACrBA,UAAK,OAAO,KAAK,QAAQ;AACzBA,UAAK,IAAI;AACTA,UAAK,KAAK,KAAK,MAAM;AACrBA,UAAK,KAAK,KAAK,MAAM;AACrBA,UAAK,OAAO,KAAK,QAAQ;AACzBA,UAAK,OAAO,KAAK,QAAQ;AACzBA,UAAK,OAAO,KAAK,QAAQ;AACzBA,UAAK,OAAO,KAAK,QAAQ;AACzBA,UAAK,OAAO,OAAO,KAAK;AACxBA,UAAK,OAAO,KAAK,QAAQ;AACzBA,UAAK,QAAQ,KAAK,SAAS,aAAa;AACxCA,UAAK,OAAO,KAAK,QAAQ;AACzBA,UAAK,KAAK,KAAK,MAAM;AACrBA,UAAK,KAAK,KAAK,MAAM;AACrBA,UAAK,MAAM;AACXA,UAAK,MAAM;AACXA,UAAK,OAAO;AACZA,UAAK,OAAO;AACZ,WAAOA;EACT;AAEA,WAASC,WAAUD,OAAY,IAAqB;AAClDA,UAAK,KAAK;AACV,WAAOA,MAAK,IAAIA,MAAK;EACvB;AAEA,WAAS,WAAWA,OAAYE,OAAY,MAAsC;AAChF,UAAM,WAAWA,MAAK;AACtB,UAAM,UAAUA,MAAK,KAAKA,MAAK,QAAQ,IAAI,KAAK,IAAI,CAAC,WAAWA,MAAK,EAAE;AACvE,UAAM,cAAcA,MAAK,MAAMA,MAAK,KAAKA,MAAK,OAAO,IAAI,KAAK,IAAI,CAAC,WAAW,GAAG;AACjF,UAAM,QAAQF,MAAK,KAAK,WAAWE,MAAK;AACxC,UAAM,cAAcA,MAAK,KAAK,MAAM,MAAM,KAAK,IAAI,GAAG,QAAQ;AAC9D,UAAM,SAAS,cAAc,cAAc,KAAK,IAAI,KAAK;AACzDF,UAAK,IAAIE,MAAK,IAAI,KAAK,IAAIF,MAAK,EAAE,IAAI,SAAS,KAAK,IAAI,WAAW;AACnEA,UAAK,IAAIE,MAAK,IAAI,KAAK,IAAIF,MAAK,EAAE,IAAI,SAAS,KAAK,IAAI,WAAW;AACnEA,UAAK,IAAI,UAAU,cAAc,KAAK,IAAI,KAAK;EACjD;AAEA,WAAS,SAASA,OAAY,IAAY,KAAa,MAAc,MAAsC;AACzG,UAAM,UAAU,KAAK,IAAI,CAACA,MAAK,OAAO,EAAE;AACxCA,UAAK,MAAM;AACXA,UAAK,MAAM;AACXA,UAAK,MAAM;AACXA,UAAK,OAAOA,MAAK,QAAQ,OAAO,IAAI,MAAM,KAAKA,MAAK,QAAQ;AAC5DA,UAAK,MAAMA,MAAK,KAAK,KAAK,IAAIA,MAAK,OAAO,OAAO;AACjDA,UAAK,KAAKA,MAAK,KAAK;AACpBA,UAAK,MAAMA,MAAK,KAAK,KAAK,IAAIA,MAAK,OAAO,OAAO;AACjD,QAAIA,MAAK,IAAIA,MAAK,KAAK,gBAAgB;AACrCA,YAAK,IAAIA,MAAK,KAAK;AACnB,UAAIA,MAAK,KAAK,EAAGA,OAAK,MAAM;IAC9B;EACF;AAGO,WAAS,YAAY,MAAyB,IAAY,MAAsC;AACrG,SAAK,QAAQC,YAAW,EAAE;AAC1B,eAAWD,SAAQ,KAAK,OAAO;AAC7B,YAAM,MAAMA,MAAK,IAAIA,MAAK;AAC1B,YAAM,OAAOA,MAAK,KAAK,IAAIA,MAAK,KAAK,KAAK,IAAI,KAAK,IAAI,GAAG,IAAIA,MAAK,IAAIA,MAAK,EAAE,GAAG,IAAI,IAAI;AACzF,UAAIA,MAAK,KAAM,YAAWA,OAAMA,MAAK,MAAM,IAAI;UAC1C,UAASA,OAAM,IAAI,KAAK,MAAM,IAAI;AACvC,YAAM,OAAOA,MAAK,MAAMA,MAAK,KAAKA,MAAK,OAAO,IAAI,KAAK,IAAI,CAACA,MAAK,IAAIA,MAAK,EAAE,KAAKA,MAAK,KAAK,KAAK,IAAIA,MAAK,GAAG,kBAAkB;AAC9HA,YAAK,OAAO,OAAO,KAAK,IAAI,GAAGA,MAAK,IAAI,gBAAgB,YAAY;AACpEA,YAAK,MAAM;AACXA,YAAK,OAAO;IACd;EACF;AC/HA,MAAM,cAAc;AACpB,MAAM,eAAe;AAEd,WAAS,gBAAgB,UAAsC;AACpE,WAAO,IAAI,YAAmB,UAAU,OAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,MAAM,GAAG,MAAM,KAAK,GAAG,KAAK,QAAQ,MAAM,KAAK,EAAE,EAAE;EAClL;AAEO,WAAS,WAAW,MAA0B,MAAwB;AAC3E,UAAM,QAAQ,KAAK,QAAQ;AAC3B,UAAM,IAAI,KAAK,KAAK;AACpB,UAAM,IAAI,KAAK,KAAK;AACpB,UAAM,IAAI,KAAK,KAAK;AACpB,UAAM,KAAK,KAAK,MAAM;AACtB,UAAM,KAAK,KAAK,MAAM;AACtB,UAAM,KAAK,KAAK,MAAM;AACtB,UAAM,IAAI;AACV,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,IAAI,KAAK,KAAK;AACpB,UAAM,KAAK,KAAK,MAAM;AACtB,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,IAAI,KAAK,KAAK;AACpB,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,MAAM;AACZ,WAAO;EACT;AAEA,WAASC,WAAU,OAAc,IAAqB;AACpD,UAAM,KAAK;AACX,WAAO,MAAM,IAAI,MAAM;EACzB;AAQO,WAAS,aAAa,MAA0B,MAAuB;AAC5E,SAAK,QAAQA,YAAW,KAAK,EAAE;AAC/B,eAAW,SAAS,KAAK,OAAO;AAC9B,YAAM,UAAU,KAAK,IAAI,CAAC,MAAM,OAAO,KAAK,EAAE;AAC9C,YAAM,MAAM;AACZ,YAAM,MAAM;AACZ,YAAM,MAAM;AACZ,YAAM,MAAM,MAAM,IAAI,KAAK;AAC3B,YAAM,KAAK,MAAM,KAAK,KAAK;AAC3B,YAAM,KAAK,MAAM,KAAK,KAAK;AAC3B,YAAM,KAAK,MAAM,KAAK,KAAK;AAC3B,YAAME,SAAQ,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,IAAI;AAChD,UAAI,MAAM,IAAIA,QAAO;AACnB,cAAM,IAAIA;AACV,YAAI,MAAM,KAAK,GAAG;AAChB,gBAAM,MAAM,CAAC,MAAM;AACnB,gBAAM,MAAM;AACZ,gBAAM,MAAM;QACd;MACF;AACA,YAAM,MAAM,MAAM,IAAI,MAAM;IAC9B;EACF;ACxEA,MAAM,iBAAiB,CAAC,GAAG,MAAM,IAAI;AAG9B,WAAS,QAAQ,MAAe,QAAsB,MAAsB;AACjF,SAAK,QAAQ;AACb,UAAMH,QAAO,UAAU,KAAK,OAAO,QAAQ,IAAI;AAC/C,SAAK,OAAO,OAAOA,KAAI;AACvB,WAAOA;EACT;AAEO,WAAS,SAAS,MAAe,MAAwB;AAC9D,SAAK,QAAQ;AACb,UAAM,QAAQ,WAAW,KAAK,QAAQ,IAAI;AAC1C,SAAK,OAAO,QAAQ,KAAK;AACzB,WAAO;EACT;AAEO,WAAS,QAAQ,MAAe,MAAsB;AAC3D,UAAM,OAAO,UAAU,KAAK,OAAO,IAAI;AACvC,SAAK,OAAO,OAAO,IAAI;AACvB,WAAO;EACT;AAEO,WAAS,SAAS,MAAe,QAAsB,MAAwB;AACpF,UAAM,QAAQ,WAAW,KAAK,QAAQ,QAAQ,IAAI;AAClD,SAAK,QAAQ;AACb,QAAI,MAAM,OAAO,KAAK,OAAO,UAAU;AACrC,YAAM,OAAO,QAAQ,MAAM,EAAE,QAAQ,OAAO,GAAG,OAAO,MAAM,IAAI,GAAG,KAAK,MAAM,OAAO,QAAQ,GAAG,GAAG,GAAG,OAAO,gBAAgB,OAAO,IAAI,CAAC;IAC3I;AACA,SAAK,OAAO,QAAQ,KAAK;AACzB,WAAO;EACT;ACPO,WAAS,eAAe,UAAkB,aAA8C;AAC7F,WAAO,IAAI,YAAkB,UAAU,OAAO;MAC5C,GAAG;MAAG,GAAG;MAAG,GAAG;MAAG,GAAG;MAAK,IAAI;MAAK,MAAM;MAAG,MAAM;MAAG,GAAG;MAAG,MAAM;MAAI,KAAK;MAAG,OAAO;MAAK,UAAU;MAAG,MAAM;MAAG,QAAQ;MAAM,IAAI;MAAG,IAAI;MAAG,IAAI;MAAG,OAAO,aAAa;MACtK,KAAK;MAAa,QAAQ;IAC5B,EAAE;EACJ;AAEO,WAAS,UAAU,MAAyB,QAAsB,MAAgB,QAAsB;AAC7G,UAAM,OAAO,KAAK,QAAQ;AAC1B,SAAK,IAAI,KAAK,KAAK;AACnB,SAAK,IAAI,KAAK,KAAK;AACnB,SAAK,IAAI,KAAK,KAAK;AACnB,SAAK,IAAI,KAAK,KAAK;AACnB,SAAK,KAAK,KAAK,eAAe,KAAK;AACnC,SAAK,OAAO,KAAK,QAAQ;AACzB,SAAK,OAAO,KAAK,QAAQ;AACzB,SAAK,IAAI;AACT,SAAK,OAAO,KAAK,QAAQ;AACzB,SAAK,MAAM;AACX,SAAK,QAAQ,KAAK,SAAS;AAC3B,SAAK,WAAW;AAChB,SAAK,OAAO;AACZ,SAAK,SAAS,KAAK,UAAU;AAC7B,SAAK,KAAK,KAAK,MAAM;AACrB,SAAK,KAAK,KAAK,MAAM;AACrB,SAAK,KAAK,KAAK,MAAM;AACrB,SAAK,QAAQ,KAAK,SAAS,aAAa;AACxC,SAAK,MAAM;AACX,SAAK,SAAS;AACd,WAAO;EACT;AAEO,WAAS,QAAQ,MAAe,QAAsB,MAAgB,QAAsB;AACjG,UAAM,OAAO,UAAU,KAAK,OAAO,QAAQ,MAAM,MAAM;AACvD,SAAK,OAAO,OAAO,IAAI;AACvB,WAAO;EACT;AAEA,WAAS,WAAW,QAAqD;AACvE,WAAO,cAAc,SAAS,OAAO,WAAW;EAClD;AAEA,WAAS,WAAW,MAAe,MAAY,QAAgB,IAAkB;AAC/E,UAAM,SAAS,KAAK;AACpB,SAAK,OAAO,KAAK,KAAK,QAAQ,MAAM,SAAS,OAAO,KAAK,OAAO,KAAK,MAAM;AAC3E,WAAO,KAAK,OAAO,GAAG;AACpB,WAAK,OAAO;AACZ,YAAM,QAAQ,OAAO,KAAK,IAAI,KAAK,KAAK;AACxC,YAAM,WAAW,KAAK,KAAK,OAAO,KAAK,CAAC,IAAI;AAC5C,cAAQ,MAAM,QAAQ;QACpB,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI;QAAU,GAAG,KAAK,IAAI;QAAM,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI;QACxF,IAAI,OAAO,QAAQ,MAAM,GAAG;QAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;QAAG,IAAI,OAAO,QAAQ,MAAM,GAAG;QACzF,IAAI;QAAK,IAAI,OAAO,QAAQ,MAAM,IAAI,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,IAAI;QAAO,IAAI;QAClF,MAAM,OAAO,QAAQ,MAAM,IAAI;QAAG,IAAI,OAAO,QAAQ,GAAG,IAAI;QAAG,IAAI,OAAO,QAAQ,MAAM,GAAG;QAC3F,MAAM;QAAK,MAAM;QAAK,OAAO,KAAK;QAAO,MAAM;QAAG,MAAM;MAC1D,CAAC;IACH;EACF;AAEA,WAAS,UAAU,MAAe,MAAY,QAAgB,IAAkB;AAC9E,UAAM,SAAS,KAAK;AACpB,SAAK,YAAY,KAAK,KAAK,SAAS,IAAI,SAAS,OAAO,KAAK,OAAO,KAAK,MAAM;AAC/E,WAAO,KAAK,YAAY,KAAK,KAAK,OAAO,OAAO;AAC9C,WAAK,YAAY;AACjB,cAAQ,MAAM,QAAQ;QACpB,GAAG,KAAK,IAAI,OAAO,QAAQ,CAAC,QAAQ,MAAM,IAAI;QAAK,GAAG,KAAK,IAAI,MAAM,SAAS;QAAK,GAAG,KAAK,IAAI,OAAO,QAAQ,CAAC,QAAQ,MAAM,IAAI;QACjI,IAAI,OAAO,QAAQ,KAAK,GAAG;QAAG,IAAI;QAAM,IAAI,MAAM,KAAK,IAAI,QAAQ,CAAC,IAAI;QAAK,IAAI;QAAK,MAAM,OAAO,QAAQ,GAAG,GAAG;QACjH,IAAI;QAAM,IAAI;QAAM,MAAM;QAAK,MAAM;QAAM,OAAO,KAAK;QAAO,MAAM;MACtE,CAAC;IACH;EACF;AAEA,WAAS,UAAU,MAAe,MAAY,QAAgB,IAAkB;AAC9E,UAAM,SAAS,KAAK;AACpB,QAAI,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,KAAK,QAAQ,KAAK,OAAO,UAAW;AACnE,aAAS,MAAM;MACb,GAAG,KAAK,IAAI,OAAO,QAAQ,CAAC,QAAQ,MAAM,IAAI;MAAK,GAAG,KAAK,IAAI;MAAK,GAAG,KAAK,IAAI,OAAO,QAAQ,CAAC,QAAQ,MAAM,IAAI;MAClH,IAAI,OAAO,QAAQ,MAAM,GAAG;MAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;MAAG,IAAI,OAAO,QAAQ,MAAM,GAAG;MACzF,MAAM,OAAO,QAAQ,KAAK,GAAG;MAAG,GAAG;MAAO,IAAI;MAAM,MAAM;MAAG,GAAG;MAAM,MAAM;IAC9E,CAAC;EACH;AAGO,WAAS,YAAY,MAAe,IAAkB;AAC3D,UAAM,OAAO,KAAK;AAClB,aAAS,QAAQ,KAAK,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS;AAC3D,YAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,WAAK,KAAK;AACV,UAAI,KAAK,QAAQ;AACf,cAAM,QAAQ,WAAW,KAAK,MAAM;AACpC,aAAK,IAAI,MAAM,IAAI,KAAK;AACxB,aAAK,IAAI,MAAM,IAAI,KAAK;AACxB,aAAK,IAAI,MAAM,IAAI,KAAK;MAC1B;AACA,YAAM,SAAS,KAAK,OAAO,KAAK,KAAK,IAAI,KAAK,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK;AACzF,WAAK,OAAO,KAAK,IAAI,KAAK,OAAO,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,OAAO,KAAK,KAAK,GAAG;AACvG,UAAI,KAAK,KAAK,KAAK,MAAM;AACvB,aAAK,SAAS,KAAK;AACnB;MACF;AACA,UAAI,CAAC,KAAK,OAAO,KAAM;AACvB,iBAAW,MAAM,MAAM,QAAQ,EAAE;AACjC,gBAAU,MAAM,MAAM,QAAQ,EAAE;AAChC,gBAAU,MAAM,MAAM,QAAQ,EAAE;IAClC;EACF;ACzIA,MAAM,OACJ,CAAC,SACD,IAAI,UAAoC,EAAE,GAAG,MAAM,GAAG,KAAK;AAEtD,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,OAAO,KAAK,MAAM;AACxB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,SAAS,KAAK,QAAQ;AAC5B,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,OAAO,KAAK,MAAM;AACxB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,QAAQ,KAAK,OAAO;AAC1B,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,QAAQ,KAAK,OAAO;AAC1B,MAAM,OAAO,KAAK,MAAM;AACxB,MAAM,QAAQ,KAAK,OAAO;AAC1B,MAAM,QAAQ,KAAK,OAAO;AAC1B,MAAMI,QAAO,KAAK,MAAM;AACxB,MAAM,OAAO,KAAK,MAAM;AACxB,MAAM,KAAK,KAAK,IAAI;AACpB,MAAM,KAAK,KAAK,IAAI;AACpB,MAAM,KAAK,KAAK,IAAI;AACpB,MAAM,KAAK,KAAK,IAAI;AACpB,MAAM,KAAK,KAAK,IAAI;AACpB,MAAM,KAAK,KAAK,IAAI;AACpB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,KAAK,KAAK,IAAI;AACpB,MAAM,MAAM,KAAK,KAAK;AACtB,MAAM,OAAO,KAAK,MAAM;AACxB,MAAM,OAAO,KAAK,MAAM;AACxB,MAAM,SAAS,KAAK,QAAQ;AAC5B,MAAM,QAAQ,KAAK,OAAO;AAC1B,MAAM,OAAO,KAAK,MAAM;AACxB,MAAM,QAAQ,KAAK,OAAO;AAC1B,MAAM,KAAK,KAAK,IAAI;AACpB,MAAM,KAAK,KAAK,IAAI;AACpB,MAAM,KAAK,KAAK,IAAI;AACpB,MAAM,QAAQ,KAAK,OAAO;AAC1B,MAAM,QAAQ,KAAK,MAAM;AACzB,MAAM,OAAO,KAAK,IAAI;AACtB,MAAM,SAAS,KAAK,QAAQ;AAC5B,MAAM,QAAQ,IAAI,YAAsC,EAAE,GAAG,SAAS,GAAG,CAAC,MAAM,EAAE;AAElF,MAAM,QAAQ,CAAC,MAAc,OAAgB,UAAyB,EAAE,GAAG,OAAO,GAAG,CAAC,MAAM,OAAO,IAAI,EAAE;AACzG,MAAM,QAAQ,CAACC,WAAkB,SAAiB,UAAoC,EAAE,GAAG,SAAS,GAAG,CAACA,WAAU,MAAM,GAAG,IAAI,EAAE;AACjI,MAAM,WAAW,CAAC,UAAwB,EAAE,GAAG,OAAO,GAAG,CAAC,IAAI,EAAE;AAChE,MAAM,gBAAgB,KAAK,eAAe;AAC1C,MAAM,OAAa,EAAE,GAAG,IAAI;AAC5B,MAAM,QAAc,EAAE,GAAG,aAAa;AACtC,MAAM,QAAc,EAAE,GAAG,KAAK;AAC9B,MAAM,QAAc,EAAE,GAAG,QAAQ;AACjC,MAAM,UAAgB,EAAE,GAAG,UAAU;AACrC,MAAM,QAAc,EAAE,GAAG,QAAQ;AAGjC,MAAM,kBAAwB,EAAE,GAAG,iBAAiB;AC7DpD,MAAM,QAAQ,CAAC,QAAgB,OAAiBC,YAAiC,EAAE,IAAI,SAAS,QAAQ,OAAO,OAAAA,OAAM;AACrH,MAAM,QAAQ,CAAC,QAAgB,aAAmC,EAAE,IAAI,SAAS,QAAQ,OAAO,QAAQ;AACxG,MAAM,OAAO,CAAC,KAAa,QAAgB,MAAgB,aAAmC,EAAE,IAAI,QAAQ,KAAK,QAAQ,MAAM,OAAO,QAAQ;AAC9I,MAAM,SAAS,CAAC,aAAmC,EAAE,IAAI,UAAU,OAAO,QAAQ;AAClF,MAAM,QAAQ,IAAI,UAA2C,EAAE,IAAI,SAAS,KAAK;AACjF,MAAM,OAAO,IAAI,UAA2C,EAAE,IAAI,QAAQ,KAAK;AAC/E,MAAM,QAAQ,IAAI,UAA2C,EAAE,IAAI,SAAS,KAAK;AACjF,MAAM,OAAO,IAAI,UAA2C,EAAE,IAAI,QAAQ,KAAK;AAC/E,MAAM,SAAS,CAAC,YAAgK,EAAE,IAAI,UAAU,GAAG,OAAO;AAC1M,MAAM,YAAY,CAAC,MAAa,OAAiB,WAAqB,UAAgC,EAAE,IAAI,cAAc,MAAM,OAAO,WAAW,KAAK;AACvJ,MAAM,eAAe,CAAC,UAA6B,EAAE,IAAI,kBAAkB,KAAK;AAChF,MAAM,MAAM,CAAC,MAAc,MAAiB,WAAgC,EAAE,IAAI,OAAO,KAAK,MAAM,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC,GAAI,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC,EAAG;AACvL,MAAMC,QAAO,CAAC,UAAkB,UAA2C,EAAE,IAAI,QAAQ,OAAO,KAAK;AACrG,MAAM,QAAQ,CAAC,SAAmB,WAA8C,EAAE,IAAI,MAAM,MAAM,MAAM;AACxG,MAAM,OAAO,CAAC,WAAqB,OAA8B,eAAmD,EAAE,IAAI,QAAQ,IAAI,WAAW,OAAO,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC,EAAG;AAC5L,MAAM,SAAS,CAAC,UAAoB,WAA8C,EAAE,IAAI,UAAU,OAAO,MAAM;AAC/G,MAAM,MAAM,CAAC,MAAc,WAAiC,EAAE,IAAI,OAAO,MAAM,MAAM;AACrF,MAAM,WAAW,CAAC,IAAY,QAAgB,UAAiC,EAAE,IAAI,YAAY,IAAI,QAAQ,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC,EAAG;AACrJ,MAAM,SAAS,CAAC,MAAc,WAAiC,EAAE,IAAI,UAAU,MAAM,MAAM;AAC3F,MAAM,SAAS,CAAC,KAAe,QAAkB,aAAmC,EAAE,IAAI,UAAU,KAAK,QAAQ,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC,EAAG;AACjJ,MAAM,OAAO,CAAC,YAA4D,EAAE,IAAI,QAAQ,OAAO;ACrBtG,MAAM,SAA4C,CAAC,GAAG,KAAK,CAAC;AAC5D,MAAM,KAAwC,CAAC,GAAG,GAAG,CAAC;AAG/C,MAAM,gBAA2B;IACtC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,IAAI;IACzB,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,CAAC,GAAG,QAAQ,CAAC,GAAG,GAAG,CAAC,EAAE;IAC9C,UAAU;MACR;QACE;QACA,MAAM,UAAU,IAAI,EAAE,GAAG,QAAQ,GAAG,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,GAAG,IAAI,SAAU,IAAI,SAAU,GAAG,MAAM,IAAI,MAAM,GAAG,KAAK,CAAC;QACjK,MAAM,UAAU,IAAI,EAAE,GAAG,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,SAAU,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QACrJ,OAAO,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,SAAU,OAAQ,GAAG,MAAM,EAAE,CAAC,CAAC;QACrK,MAAM,GAAG,GAAG,GAAG,KAAK,SAAU,EAAE,MAAM,KAAK,MAAM,IAAI,OAAO,OAAO,CAAC;QACpE,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,GAAG,SAAU,IAAI,IAAI;QAC9C,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC;MACjC;IACF;IACA,MAAM;MACJ,KAAK,IAAI,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG;QAClC,KAAK,OAAO,UAAU,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,MAAM,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI,CAAC,KAAK,IAAI,GAAG,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,IAAI,SAAU,IAAI,SAAU,GAAG,MAAM,IAAI,IAAI,CAAC;QACxM,KAAK,QAAQ,OAAO,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,MAAM,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,SAAU,GAAG,KAAK,IAAI,IAAI,CAAC;MAC3K,CAAC;IACH;EACF;AC5BA,MAAM,QAAQ,MAAM,SAAU,SAAU,SAAU,OAAQ;AAC1D,MAAM,QAAQ,CAAC,GAAG,KAAK,IAAI;AAGpB,MAAM,YAAuB;IAClC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,IAAI,OAAO,SAAS,CAAC,SAAS,UAAU,OAAO,UAAU,GAAG,SAAS,EAAE;IACjF,QAAQ,EAAE,WAAW,IAAI,QAAQ,EAAE;IACnC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,GAAG,GAAG,IAAI,EAAE;IACnD,UAAU;MACR,MAAM,KAAKA,MAAK,aAAa,CAAC,GAAG,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC;MAC1E,MAAM,KAAKA,MAAK,aAAa,CAAC,KAAK,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,MAAM,EAAE,CAAC,GAAG,OAAO,GAAG,CAAC;MACnF,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,GAAG,GAAG,MAAM,IAAI,KAAK,IAAI,KAAK,KAAK,OAAO,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,GAAG,KAAK,OAAO,KAAK,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,QAAS,CAAC,CAAC,CAAC,CAAC;IAC1K;IACA,MAAM;MACJ,KAAK,IAAI,GAAG,OAAO,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG;QACrC,KAAK,QAAQ,UAAU,MAAM,GAAG,CAAC,GAAG;UAClC,GAAG,CAAC,MAAM,MAAM,IAAI;UAAG,KAAK,CAAC,MAAM,MAAM,CAAC;UAAG,KAAK,CAAC,GAAG,GAAG,CAAC;UAAG,MAAM;UAAK,IAAI,CAAC,GAAG,GAAG;UAAG,MAAM;UAAK,MAAM;UAAM,IAAI;UAAO,GAAG;UAAK,IAAI;UAAG,KAAK;UAAG,IAAI,CAAC,MAAM,IAAI;QAChK,CAAC;MACH,CAAC;IACH;EACF;ACxBA,MAAMC,MAAwC,CAAC,GAAG,GAAG,CAAC;AAG/C,MAAM,eAA0B;IACrC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,GAAG;IACxB,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAK,IAAI,EAAE;IACrD,UAAU,CAAC,MAAM,KAAK,MAAM,GAAG,GAAG,MAAM,KAAK,SAAU,EAAE,MAAM,KAAK,MAAM,GAAG,KAAK,QAAS,CAAC,CAAC,CAAC;IAC9F,MAAM;MACJ,KAAK,IAAI,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG;QACpC,KAAK,OAAO,UAAU,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG,GAAG,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,MAAM,IAAI,QAAU,GAAG,GAAG,IAAI,IAAI,CAAC;MACpI,CAAC;MACD,KAAK,IAAI,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG;QACtC,KAAK,QAAQ,UAAU,IAAI,EAAE,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,MAAM,GAAG,GAAG,KAAKA,KAAI,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,IAAI,CAAC;MAC3L,CAAC;IACH;EACF;AClBA,MAAM,UAAU,CAAC,OAAO,MAAM,OAAO,OAAO,OAAO,MAAM,OAAO,OAAO,OAAO,IAAI;AAClF,MAAM,YAAY;AAClB,MAAM,aAAa;AACnB,MAAM,QAAQ,IAAI,KAAK,SAAS,KAAK,GAAG,WAAW,UAAU;AAC7D,MAAM,SAAS,SAAS,WAAW,QAAQ,EAAE,OAAO,OAAO,IAAI,CAAC,KAAK,GAAG,MAAM,WAAW,KAAK,KAAK,CAAC,GAAG,OAAO,MAAM,CAAC;AAG9G,MAAM,cAAyB;IACpC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,GAAG;IACxB,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,QAAQ,CAAC,GAAG,KAAK,CAAC,EAAE;IAC/C,OAAO;MACL,OAAO,IAAI,IAAI,UAAU,IAAI,GAAG,EAAE,CAAC,GAAG,IAAI,UAAU,IAAI,MAAM,GAAG,CAAC,GAAG,SAAS,WAAW,SAAS,EAAE,OAAO,OAAO,GAAG,SAAS,QAAQ,GAAG,GAAG,SAAS,QAAQ,GAAG,QAAQ,CAAC,KAAK,KAAK,EAAE,CAAC,GAAG,MAAM;IACjM;IACA,UAAU,CAAC;IACX,MAAM;MACJ;QACE;QACA,KAAK,GAAG,MAAM,WAAW,KAAK,KAAK,GAAG,EAAE,GAAG,CAAC,SAAS,WAAW,UAAU,EAAE,OAAO,OAAO,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,KAAK,IAAI,MAAM,WAAW,cAAc,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAClL,KAAK,IAAI,KAAK,SAAS,KAAK,GAAG,GAAG,SAAS,CAAC,CAAC,GAAG;UAC9C,MAAM,UAAU,EAAE,GAAG,MAAM,WAAW,SAAS,OAAO,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,GAAG,IAAI,WAAW,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,GAAG,MAAM,MAAM,KAAK,MAAM,IAAI,UAAU,IAAI,SAAU,GAAG,IAAI,CAAC;QACnM,CAAC;MACH;IACF;EACF;AC5BA,MAAM,WAA8C,CAAC,MAAM,MAAM,IAAI;AACrE,MAAM,cAAc;AAGb,MAAM,YAAuB;IAClC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,IAAI,QAAQ,GAAG,QAAQ,EAAE;IAC9C,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,GAAG,GAAG,QAAQ,CAAC,KAAK,KAAK,CAAC,EAAE;IAClD,UAAU;MACR;QACE;QACA,OAAO,EAAE,GAAG,UAAU,GAAG,CAAC,KAAK,KAAK,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,MAAM,IAAI,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,KAAK,CAAC;QAC1H,MAAM,UAAU,IAAI,EAAE,GAAG,UAAU,GAAG,MAAM,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,MAAM,GAAG,IAAI,aAAa,GAAG,IAAI,CAAC;MAC9I;IACF;IACA,MAAM;MACJ,KAAK,IAAI,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG;QACtC,KAAK,OAAO,UAAU,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,UAAU,KAAK,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,aAAa,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;MAClP,CAAC;IACH;EACF;ACvBA,MAAMC,eAAc;AAGb,MAAM,WAAsB;IACjC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,IAAI,QAAQ,GAAG,QAAQ,EAAE;IAC9C,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,CAAC,GAAG,QAAQ,CAAC,GAAG,KAAK,IAAI,EAAE;IACnD,UAAU;MACR;QACE;QACA,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,GAAG,IAAIA,cAAa,GAAG,IAAI,CAAC;QAC/I,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,OAAO,KAAK,GAAG,IAAIA,cAAa,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;QACnL,OAAO,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,UAAU,OAAQ,GAAG,MAAM,EAAE,CAAC,CAAC;QAC5L,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,SAAU,KAAK,MAAM,CAAC;MAC3C;MACA,MAAM,KAAK,MAAM,GAAG,GAAG,MAAM,KAAKA,cAAa,EAAE,MAAM,KAAK,MAAM,IAAI,KAAK,QAAS,CAAC,CAAC;IACxF;EACF;ACpBA,MAAMD,MAAwC,CAAC,GAAG,GAAG,CAAC;AAG/C,MAAM,cAAyB;IACpC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,GAAG;IACxB,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAK,IAAI,EAAE;IACrD,UAAU,CAAC;IACX,MAAM;MACJ,KAAK,GAAG,MAAM,GAAG,GAAG;QAClB,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,qBAAqB,QAAW,CAAC,CAAC,CAAC;QAC1D,KAAK,GAAG,MAAM,GAAG,GAAG;UAClB,KAAK,QAAQ,OAAO,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC,MAAM,MAAM,GAAG,GAAG,KAAKA,KAAI,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,UAAU,GAAG,KAAK,IAAI,IAAI,CAAC;QAC7K,CAAC;MACH,CAAC;MACD,KAAK,IAAI,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG;QACpC,KAAK,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,GAAG,KAAK,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,UAAU,GAAG,IAAI,CAAC;MAC5K,CAAC;IACH;EACF;ACtBA,MAAM,aAAa;AACnB,MAAM,kBAAkB;AACxB,MAAM,aAAa;AAGZ,MAAM,kBAA6B;IACxC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,IAAI;IACzB,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,GAAG,EAAE,EAAE;IAC3C,UAAU;MACR;QACE;QACA,OAAO,GAAG,MAAM,IAAI,iBAAiB,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,KAAK,GAAG,KAAK,UAAU,CAAC,CAAC;QACpG,OAAO,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,KAAK,EAAE,CAAC;MAC5C;IACF;IACA,MAAM;MACJ,KAAK,GAAG,MAAM,eAAe,GAAG;QAC9B,KAAK,OAAO,UAAU,IAAI,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,GAAG,KAAK,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,UAAU,GAAG,IAAI,CAAC;MACpL,GAAG;QACD,KAAK,GAAG,MAAM,UAAU,GAAG;UACzB,IAAI,gBAAgB,IAAI,IAAI,IAAI,MAAM,eAAe,GAAG,GAAG,GAAG,CAAC,CAAC;UAChE;YACE;YAAQ;YAAU;YAClB,MAAM,SAAS,IAAI,KAAK,GAAG,KAAK,GAAG;cACjC,GAAG,CAAC,IAAI,IAAI,SAAS,OAAO,CAAC,GAAG,SAAS,cAAc,CAAC,GAAG,MAAM,IAAI,IAAI,SAAS,OAAO,CAAC,GAAG,SAAS,cAAc,CAAC,CAAC;cACtH,KAAK,MAAM,CAAC,IAAI,SAAS,OAAO,CAAC,GAAG,KAAK,IAAI,SAAS,OAAO,CAAC,CAAC,CAAC;cAChE,MAAM;cAAK,IAAI,CAAC,KAAK,GAAG;cAAG,MAAM;cAAG,MAAM,CAAC,KAAK,GAAG;cAAG,MAAM,CAAC,KAAK,IAAI;cAAG,MAAM;cAAG,IAAI;cAAU,GAAG;YACrG,CAAC;UACH;QACF,CAAC;MACH,CAAC;IACH;EACF;AClCO,WAAS,aAAa,aAAwB,UAAqBE,QAA6B;AACrG,UAAM,CAAC,GAAG,GAAG,CAAC,IAAIA;AAClB,UAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC;AACtF,UAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC;AACtF,UAAM,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACpD,WAAO;MACL,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,YAAY,CAAC;OAC7C,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,YAAY,CAAC;OACjE,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,IAAI,IAAI,IAAI,YAAY,CAAC;IACnE;EACF;ACXA,MAAM,YAAY,CAAC,YAAY,SAAS,QAAQ,SAAS,SAAS,OAAO;AACzE,MAAM,aAAa,CAAC,KAAK,GAAG,GAAG;AAC/B,MAAM,eAAe,CAAC,GAAG,MAAM,CAAC;AAChC,MAAM,cAAc,CAAC,GAAG,GAAG,CAAC;AAC5B,MAAMF,MAAK,CAAC,GAAG,GAAG,CAAC;AACnB,MAAM,QAAQ;AACd,MAAM,QAAQ;AACd,MAAM,QAAQ;AACd,MAAM,aAAa,CAAC,GAAG,MAAM,GAAG;AAChC,MAAM,YAAY;AAClB,MAAM,SAAS,aAAa,YAAY,cAAc,CAAC,MAAM,KAAK,GAAG,CAAC;AACtE,MAAM,WAAW,CAAC,KAAK,IAAI,aAAa,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,IAAI,aAAa,CAAC,CAAC,CAAC;AAE1E,MAAM,SAAS,CAAC,CAAC,IAAI,KAAK,KAAK,GAAG,QAAQ,CAAC,GAAG,KAAK,KAAK,GAAG,CAAC,IAAI,KAAK,KAAK,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,MAAM,OAAO,GAAG,CAAC;AAChH,MAAM,UAAU,CAAC,aAAa,UAAU,aAAa,aAAa,aAAaA,GAAE;AAEjF,MAAM,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,GAAG,aAAa,YAAY,cAAc,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC;AAEtJ,MAAM,SAAS,EAAE,SAAS,IAAI,SAAS,KAAK,OAAO,KAAK,QAAQ,KAAK,SAAS,KAAK,SAAS,IAAI;AAEhG,MAAM,UAAU,IAAI,GAAG,OAAO,KAAK,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG,GAAG,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,OAAO,KAAK,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG,IAAI,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC;AAC5K,MAAM,OAAO,EAAE,GAAG,MAAM,GAAG,CAAC,SAAS,KAAK,CAAC,EAAE;AAC7C,MAAM,OAAO,EAAE,GAAG,MAAM,GAAG,CAAC,SAAS,KAAK,CAAC,EAAE;AAC7C,MAAM,SAAS,EAAE,GAAG,OAAO,GAAG,CAAC,EAAE,GAAG,OAAO,GAAG,CAAC,EAAE,GAAG,OAAO,GAAG,CAAC,EAAE,GAAG,OAAO,GAAG,CAAC,MAAM,OAAO,OAAO,EAAE,GAAG,OAAO,KAAK,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,OAAO,EAAE;AACjJ,MAAM,SAAS,EAAE,GAAG,OAAO,GAAG,CAAC,EAAE,GAAG,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,CAAC,EAAE,GAAG,OAAO,GAAG,CAAC,EAAE,GAAG,OAAO,GAAG,CAAC,MAAM,OAAO,OAAO,EAAE,GAAG,OAAO,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC,EAAE,GAAG,OAAO,OAAO,EAAE;AAGjK,MAAM,qBAAgC;IAC3C,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,IAAI,YAAY,SAAS,WAAW,SAAS,EAAE;IACzD,QAAQ,EAAE,WAAW,IAAI,QAAQ,EAAE;IACnC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAK,EAAE,EAAE;IACjD,OAAO,CAAC,QAAQ;IAChB,UAAU;MACR,KAAK,EAAE,GAAG,MAAM,GAAG,CAAC,OAAO,KAAK,EAAE,GAAG,CAAC,MAAM,MAAM,GAAG,KAAK,KAAK,QAAU,EAAE,MAAM,GAAG,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;MAC1G;QACE,WAAW;QACX;UACE,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC;UAChC,IAAI,OAAO,KAAK,KAAK,QAAQ,KAAK,GAAG,OAAO,CAAC;UAC7CD,MAAK,UAAU,KAAK,WAAW,KAAK,GAAG,SAAS,KAAK,GAAG,KAAK,SAAS,KAAK,GAAG,GAAG,CAAC;UAClF,KAAK,GAAG,OAAO,KAAK,GAAG,CAAC,SAAS,UAAU,SAAS,EAAE,GAAG,QAAQ,GAAG,QAAQ,KAAK,GAAG,OAAO,SAAS,EAAE,CAAC,CAAC,CAAC;QAC3G;MACF;MACA,KAAK,OAAO,CAAC,OAAO,KAAK,MAAM,KAAK,GAAG,KAAK,QAAQ,KAAK,CAAC,CAAC,CAAC;IAC9D;EACF;AClDA,MAAMI,SAAQ,CAAC,SAAU,SAAU,SAAU,OAAQ;AAErD,MAAM,SAAS,CAAC,KAAK,GAAG,MAAM,MAAM,IAAI;AACxC,MAAM,WAAW;AACjB,MAAMC,SAAQ;AACd,MAAM,SAAS;AACf,MAAM,UAAU,CAAC,GAAG,GAAG,EAAE;AACzB,MAAM,WAAW,CAAC,GAAG,MAAM,SAAS,SAAS,CAAC;AAGvC,MAAM,cAAyB;IACpC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,IAAI;IACzB,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAK,IAAI,EAAE;IACrD,OAAO;MACL,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC;MACnD;QACE,OAAO;QACP,IAAI,SAAS,IAAI,OAAO,IAAI,CAAC;QAC7B,IAAI,YAAY,IAAI,MAAM,GAAG,CAAC;QAC9B,OAAO,WAAW,SAAS,OAAO,CAAC;QACnC,IAAI,gBAAgB,EAAE,OAAO,OAAO,GAAG,SAAS,OAAO,GAAG,GAAG,KAAK,QAAQ,KAAK,GAAG,MAAM,SAAS,UAAU,EAAE,CAAC;MAChH;IACF;IACA,UAAU,CAAC,IAAI,WAAW,QAAQ,GAAG,IAAI,YAAY,IAAI,GAAGL,MAAK,UAAU,WAAW,CAAC,GAAG,MAAM,QAAQ,GAAG,OAAO,CAAC;IACnH,MAAM;MACJ,KAAK,SAAS,UAAU,GAAG;QACzB,IAAI,aAAa,SAAS,SAAS,CAAC;QACpC,IAAI,WAAW,IAAI,SAAS,SAAS,GAAG,IAAIK,QAAO,KAAK,CAAC,CAAC;QAC1D,MAAM,UAAU,EAAE,GAAG,UAAU,KAAK,SAAS,MAAM,GAAG,IAAI,IAAI,MAAM,MAAM,KAAK,MAAM,IAAI,SAAS,CAAC;QACnG,MAAM,OAAO,EAAE,GAAG,UAAU,MAAM,MAAM,MAAM,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC;QACzE,MAAM,UAAU,EAAE,GAAG,UAAU,GAAG,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,MAAM,MAAM,GAAG,IAAI,UAAU,GAAG,MAAM,IAAI,IAAI,CAAC;QAC5H;UACE,OAAO;UACP,KAAK,IAAI,GAAG,SAAS,WAAW,GAAG,KAAK,QAAQ,KAAK,CAAC,GAAG,GAAG,SAAS,SAAS,GAAG,KAAK,QAAQ,KAAK,CAAC,CAAC,GAAG;YACtGL,MAAK,aAAa,CAAC,GAAG,MAAM,IAAI,KAAK,QAAQ,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,GAAG;YAC7F,IAAI,eAAe,EAAE,OAAO,OAAO,OAAO,MAAM,UAAU,IAAI,CAAC;YAC/D;cACE,IAAI,MAAM,GAAG;cACb,MAAM,KAAK,SAAS,SAAS,GAAG,KAAK,GAAG,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG,GAAG,GAAG,KAAK,KAAKI,QAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,IAAI,KAAK,QAAS,CAAC;YACjJ;UACF,CAAC;QACH;QACA,KAAK,GAAG,SAAS,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,YAAY,KAAK,GAAGJ,MAAK,UAAU,YAAY,CAAC,GAAG,MAAM,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;MAC9H,CAAC;IACH;EACF;ACjDA,MAAM,MAAM,CAAC,MAAM,MAAM,MAAM,IAAI;AACnC,MAAM,OAAO,CAAC,OAAO,KAAK,IAAI;AAC9B,MAAMM,WAAU,CAAC,GAAG,GAAG,EAAE;AACzB,MAAML,MAAK,CAAC,GAAG,GAAG,CAAC;AACnB,MAAM,cAAc;AAGb,MAAM,uBAAkC;IAC7C,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,GAAG;IACrC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;IACvD,OAAO,CAAC,IAAI,eAAe,EAAE,SAAS,KAAK,CAAC,GAAG,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,CAAC;IACnG,UAAU;MACR;QACE;QACA,MAAM,IAAI,KAAK,IAAI,OAAO,GAAG,CAAC,GAAGD,MAAK,UAAU,MAAM,KAAKM,QAAO,GAAGN,MAAK,UAAU,MAAM,EAAE,GAAG,IAAI,cAAc,EAAE,MAAM,KAAK,CAAC,CAAC;MAClI;MACA,MAAM,KAAK,OAAO,EAAE,GAAG,CAAC,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,MAAM,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,IAAI,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,IAAI,CAAC,CAAC;IAC/I;IACA,MAAM;MACJ,KAAK,IAAI,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG;QACtC,KAAK,OAAO,UAAU,IAAI,EAAE,GAAG,KAAK,KAAKC,KAAI,MAAM,MAAM,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,UAAU,GAAG,MAAM,GAAG,MAAM,IAAI,IAAI,CAAC;MACnK,CAAC;IACH;EACF;AC3BA,MAAM,OAAO,CAAC,IAAI,KAAK,CAAC;AACxB,MAAM,SAAS,CAAC,GAAG,GAAG,IAAI;AAC1B,MAAMA,MAAK,CAAC,GAAG,GAAG,CAAC;AACnB,MAAM,SAAS;AACf,MAAM,aAAa;AACnB,MAAM,cAAc;AACpB,MAAM,kBAAkB;AACxB,MAAM,KAAK,CAAC,WAA8C,KAAK,QAAQ,MAAM;AAGtE,MAAM,UAAqB;IAChC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,KAAK;IACL,QAAQ,EAAE,WAAW,KAAK,QAAQ,EAAE;IACpC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,GAAG,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAK,IAAI,EAAE;;IAEjD,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,GAAG,KAAK,OAAO,CAAC,IAAI,gBAAgB,EAAE,MAAM,SAAS,GAAG,eAAe,CAAC,CAAC,CAAC;IACrI,UAAU,CAAC,IAAI,UAAU,KAAK,GAAG,IAAI,kBAAkB,EAAE,SAAS,KAAK,CAAC,CAAC;IACzE,MAAM;MACJ,KAAK,GAAG,MAAM,MAAM,GAAG;QACrB,IAAI,UAAU,MAAM,MAAM,MAAM,QAAQ,IAAI,GAAG,GAAG,IAAIJ,MAAK,KAAK,CAAC,GAAG,OAAO,CAAC,GAAG,IAAI,GAAG,IAAI,IAAI,IAAI,MAAM,KAAK,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;QAChI,IAAI,eAAe,EAAE,UAAU,SAAS,QAAQ,GAAG,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzE,KAAK,QAAQ,OAAO,IAAI,EAAE,GAAG,KAAK,SAAS,QAAQ,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,KAAK,IAAI,UAAU,IAAI,UAAU,IAAI,GAAG,GAAG,GAAG,CAAC;QAC1L,KAAK,OAAO,UAAU,IAAI,EAAE,GAAG,SAAS,QAAQ,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,IAAI,SAAU,GAAG,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;MACvI,GAAG;QACD,KAAK,IAAI,SAAS,QAAQ,CAAC,GAAG;UAC5B,IAAI,UAAU,IAAI;UAClB,IAAI,kBAAkB,EAAE,SAAS,MAAM,CAAC;UACxC,OAAO,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,KAAKI,KAAI,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,MAAM,IAAI,GAAG,GAAG,aAAa,MAAM,GAAG,CAAC,CAAC;UACrI,MAAM,OAAO,IAAI,EAAE,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,KAAKA,KAAI,MAAM,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,IAAI,UAAU,IAAI,UAAU,IAAI,KAAK,CAAC;UAC5J,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,UAAU,GAAG,KAAK,IAAI,IAAI;UACjD,MAAM,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,KAAK,QAAU,EAAE,MAAM,KAAK,MAAM,GAAG,CAAC;QACvE,CAAC;MACH,CAAC;MACD,KAAK,IAAI,GAAG,MAAM,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG;QACzC,IAAI,cAAc,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAC5D,IAAI,YAAY,IAAI,GAAG,MAAM,CAAC,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7ED,MAAK,aAAa,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,SAAS,YAAY,GAAG,IAAI,KAAK,SAAS,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,CAAC;QAChH,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,KAAK,SAAS,UAAU,CAAC,GAAG,IAAI;MAClE,GAAG;QACD,KAAK,GAAG,MAAM,GAAG,GAAG;UAClB,aAAa,CAAC;UACd,KAAK,OAAO,OAAO,GAAG,EAAE,GAAG,QAAQ,GAAG,GAAG,MAAM,MAAM,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,IAAI,UAAU,GAAG,KAAK,IAAI,IAAI,CAAC;QAC5H,CAAC;MACH,CAAC;IACH;EACF;AChDA,MAAM,SAAS,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK,IAAI,CAAC;AAC3E,MAAM,SAAS,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AACpC,MAAMO,UAAS,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC;AACtC,MAAM,SAAS,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AACxD,MAAM,OAAO;AACb,MAAM,UAAU;AAChB,MAAM,QAAQ;AACd,MAAM,SAAS;AACf,MAAM,YAAY;AAGX,MAAM,UAAqB;IAChC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,KAAK;IACL,QAAQ,EAAE,WAAW,KAAK,QAAQ,IAAI,QAAQ,EAAE;IAChD,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAK,IAAI,EAAE;IACnD,OAAO;MACL,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC;;MAEnD,KAAK,OAAO,CAAC,IAAI,gBAAgB,EAAE,MAAM,UAAU,GAAG,EAAE,CAAC,CAAC;MAC1D,OAAO,OAAO,QAAQ,IAAI,gBAAgB,EAAE,OAAO,OAAO,GAAG,KAAK,QAAQ,KAAK,GAAG,GAAG,KAAKA,SAAQ,KAAK,GAAG,MAAM,KAAK,QAAQ,KAAK,EAAE,CAAC,CAAC;IACxI;IACA,UAAU;MACR,IAAI,MAAM,EAAE;MAAG,IAAI,MAAM,GAAG;MAAG,IAAI,MAAM,GAAG;MAC5C,IAAI,MAAM,GAAG;MAAG,IAAI,MAAM,GAAG;MAAG,IAAI,MAAM,IAAI;MAC9C,IAAI,QAAQ,KAAK;MACjB,IAAI,mBAAmB,EAAE,SAAS,KAAK,CAAC;IAC1C;IACA,MAAM;MACJ,KAAK,GAAG,MAAM,IAAI,GAAG;QACnB,IAAI,MAAM,IAAI,SAAS,IAAI,GAAG,IAAI,SAAS,KAAK,CAAC,CAAC;QAClD,IAAI,MAAM,IAAI,SAAS,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,KAAK,CAAC,CAAC;QACzD,IAAI,MAAM,IAAI,SAAS,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,KAAK,CAAC,CAAC;QACzD,IAAI,MAAM,IAAI,SAAS,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,KAAK,CAAC,CAAC;QACzD,KAAK,GAAG,SAAS,IAAI,GAAG,KAAK,GAAG;UAC9B,IAAI,MAAM,KAAK;UACf,IAAI,MAAM,IAAI,SAAS,IAAI,GAAG,MAAM,CAAC;UACrC,IAAI,MAAM,IAAI,SAAS,IAAI,GAAG,SAAS,CAAC;UACxC,IAAI,MAAM,IAAI,SAAS,IAAI,GAAG,SAAS,CAAC;QAC1C,CAAC;QACD,IAAI,gBAAgB,EAAE,UAAU,CAAC,SAAS,IAAI,GAAG,SAAS,IAAI,GAAG,SAAS,IAAI,CAAC,EAAE,CAAC;MACpF,GAAG;QACD,KAAK,IAAI,SAAS,MAAM,CAAC,GAAG;UAC1B,IAAI,QAAQ,IAAI;UAChB,IAAI,mBAAmB,EAAE,SAAS,MAAM,CAAC;UACzCP,MAAK,WAAW,CAAC,SAAS,IAAI,GAAG,GAAG,SAAS,IAAI,CAAC,GAAG,CAAC;UACtD;YACE,OAAO;YACP,IAAI,wBAAwB;cAC1B,OAAO;cACP,MAAM,MAAM,IAAI,IAAI,KAAK,QAAQ,KAAK,GAAG,SAAS,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,KAAKO,SAAQ,KAAK,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC;cACxG,OAAO;cACP,UAAU;YACZ,CAAC;UACH;QACF,CAAC;MACH,CAAC;IACH;EACF;AC9DA,MAAM,SAAS,CAAC,MAAM,GAAG,GAAG;AAC5B,MAAMN,MAAK,CAAC,GAAG,GAAG,CAAC;AACnB,MAAM,MAAM;AACZ,MAAM,SAAS;AACf,MAAM,QAAQ;AACd,MAAM,QAAQ,CAAC,WAAmB,KAAK,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC;AAGtD,MAAM,mBAA8B;IACzC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,KAAK;IACL,QAAQ,EAAE,WAAW,KAAK,QAAQ,EAAE;IACpC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,GAAG,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;IACrD,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,CAAC;IAC5D,UAAU;MACR,IAAI,SAAS,CAAC,CAAC;MACf;QACE;QACA,IAAI,kBAAkB,EAAE,SAAS,MAAM,CAAC;QACxCD,MAAK,WAAW,QAAQ,KAAK,GAAG;QAChC,MAAM,OAAO,IAAI,EAAE,GAAG,MAAM,GAAG,GAAG,GAAG,KAAK,KAAKC,KAAI,MAAM,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,IAAI,UAAU,IAAI,SAAU,GAAG,IAAI,IAAI,KAAK,CAAC;QAChL,OAAO,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,MAAM,GAAG,GAAG,GAAG,KAAK,MAAM,GAAG,MAAM,GAAG,CAAC;QAClG,OAAO,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,QAAQ,KAAKA,KAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,KAAK,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC;QAC7I;UACE;UACA,IAAI,aAAa,IAAI,IAAI,OAAO,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;UAClD,OAAO,SAAS,KAAK,QAAQ,CAAC,IAAI,IAAI,SAAS,WAAW,CAAC,GAAG,GAAG,GAAG,MAAM,IAAI,IAAI,SAAS,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAClH;MACF;IACF;IACA,MAAM;MACJ,KAAK,IAAI,SAAS,OAAO,GAAG,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG;QACvD,IAAI,YAAY,IAAI,GAAG,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QACzD,OAAO,OAAOD,MAAK,aAAa,OAAO,MAAM,KAAK,GAAG,EAAE,GAAG,MAAM,GAAG,CAAC,SAAS,OAAO,GAAG,KAAK,EAAE,GAAG,MAAM,IAAI,KAAK,SAAS,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QACpJ,UAAU,GAAG,MAAM,CAAC,GAAG,IAAI,KAAK,SAAS,UAAU,CAAC,GAAG,IAAI;MAC7D,CAAC;MACD,KAAK,IAAI,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG;QACpC,KAAK,OAAO,UAAU,GAAG,EAAE,GAAG,MAAM,GAAG,GAAG,GAAG,KAAK,KAAKC,KAAI,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,MAAM,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,IAAI,SAAU,IAAI,QAAU,GAAG,KAAK,IAAI,IAAI,CAAC;MAC1M,CAAC;MACD,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IACrC;EACF;AC5CA,MAAM,UAAU,CAAC,SAAS,MAAM,QAAQ,SAAS;AACjD,MAAMO,OAAM,CAAC,MAAM,MAAM,MAAM,IAAI;AACnC,MAAMC,QAAO,CAAC,OAAO,KAAK,IAAI;AAC9B,MAAMH,WAAU,CAAC,GAAG,GAAG,EAAE;AACzB,MAAM,SAAS,CAAC,GAAG,GAAG,CAAC;AACvB,MAAMI,UAAS;AACf,MAAM,QAAQ,CAAC,CAAC,GAAG,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1E,MAAM,YAAY,KAAK,KAAK,OAAO,KAAK,GAAG,KAAK;AAChD,MAAM,KAAK;AACX,MAAM,UAAU;AAChB,MAAM,UAAU;AAGT,MAAM,eAA0B;IACrC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,IAAI,UAAU,SAAS,CAAC,SAAS,MAAM,QAAQ,SAAS,GAAG,SAAS,EAAE;IAChF,QAAQ,EAAE,WAAW,IAAI,QAAQ,EAAE;IACnC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;IACvD,UAAU;MACR;QACE,MAAM,GAAG,GAAG,GAAG,CAAC;QAChB;UACE,IAAI,KAAK,SAAS;UAClBV,MAAK,UAAU,KAAK,SAAS,KAAK,GAAGQ,MAAKF,QAAO;UACjD,KAAK,GAAG,OAAO,OAAO,GAAG,CAACN,MAAK,UAAUS,OAAM,IAAI,GAAG,OAAO,OAAO,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;UAClF,IAAI,UAAU,CAAC,IAAI,MAAM,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,KAAK,IAAI,MAAM,GAAG,CAAC,GAAGC,OAAM,CAAC;UAC3E;YACE,GAAG,OAAO,OAAO;YACjB,CAAC,OAAO,GAAGV,MAAK,UAAU,YAAY,CAAC,IAAI,MAAM,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,KAAK,IAAI,MAAM,GAAG,CAAC,GAAGU,OAAM,GAAG,QAAQ,IAAI,CAAC,CAAC;YACnH,CAACV,MAAK,UAAU,YAAY,SAAS,QAAQ,GAAG,QAAQ,IAAI,GAAG,OAAO,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC;UACxF;UACA,KAAK,IAAI,GAAG,OAAO,EAAE,GAAG,GAAG,IAAI,MAAM,IAAI,WAAW,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,UAAU,EAAE,GAAGQ,MAAK,KAAKF,UAAS,MAAM,GAAG,IAAI,IAAI,MAAM,MAAM,KAAK,OAAO,IAAI,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC;QAC7K;MACF;MACA,KAAK,GAAG,OAAO,OAAO,GAAG,CAAC,MAAM,MAAMN,MAAK,UAAUS,OAAM,OAAO,CAAC,CAAC,CAAC;IACvE;EACF;ACvCA,MAAME,UAAS,CAAC,GAAG,GAAG,CAAC;AAGhB,MAAM,kBAA6B;IACxC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,QAAQ,IAAI,QAAQ,EAAE;IAChC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,GAAG,GAAG,QAAQ,CAAC,IAAI,KAAK,EAAE,EAAE;IACrD,UAAU;MACR,MAAM,KAAKX,MAAK,UAAU,SAAS,CAAC,MAAM,KAAK,KAAK,GAAGW,OAAM,GAAG,SAAS,UAAU,SAAS,EAAE,GAAG,IAAI,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC;MACzH,MAAM,GAAGX,MAAK,UAAU,SAAS,CAAC,MAAM,KAAK,KAAK,GAAGW,OAAM,GAAG,SAAS,UAAU,SAAS,EAAE,GAAG,KAAK,GAAG,KAAK,KAAK,KAAK,CAAC,CAAC;MACxH;QACE;QACA,IAAI,iBAAiB;QACrB,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC;QAC/B;UACE,OAAO,EAAE;UACT,OAAO,EAAE,GAAG,CAAC,IAAI,KAAK,KAAK,GAAG,KAAK,CAAC,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,IAAI,MAAM,IAAI,GAAG,MAAO,IAAI,MAAM,IAAI,CAAC,GAAG,GAAG,UAAU,MAAM,IAAI,MAAM,IAAI,QAAQ,KAAK,CAAC;QAClN;QACA,MAAM,OAAO,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,CAAC,KAAK,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,IAAI,UAAU,GAAG,KAAK,IAAI,IAAI,CAAC;QACnI,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,UAAU,GAAG,IAAI,CAAC;MAC/J;IACF;EACF;AC1BO,WAAS,WAAW,QAA8B;AACvD,UAAM,SAAS,KAAK,KAAK,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC,CAAC,KAAK;AACnG,UAAM,UAAU,IAAI;AACpB,WAAO,CAAC,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,IAAI,OAAO;EACvE;AAEO,WAAS,KAAK,QAAmB,GAAW,GAAW,GAAsB;AAClF,WAAO,CAAC,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;EACrD;AAEO,WAAS,SAAS,QAAmB,QAA2B;AACrE,WAAO,CAAC,OAAO,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI,MAAM;EACpE;AAEO,WAAS,WAAW,QAAmB,WAAsB,QAA2B;AAC7F,WAAO,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI,UAAU,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI,UAAU,CAAC,IAAI,MAAM;EACjH;AAEO,WAAS,QAAQ,QAA8B;AACpD,WAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;EAC5C;AClBA,MAAM,aAAa,WAAW,CAAC,GAAG,MAAM,CAAC,CAAC;AAC1C,MAAM,qBAAqB,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC;AACjD,MAAM,eAAe;AAGrB,MAAM,OAAO,CAAC,UAAiC;IAC7C,IAAI,cAAc,EAAE,UAAU,KAAK,CAAC;IACpC,MAAM,UAAU,QAAQ,KAAK,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,KAAK,GAAG,KAAK,CAAC,KAAK,MAAM,IAAI,GAAG,KAAK,YAAY,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,MAAM,GAAG,IAAI,CAAC;IACpN,OAAO,OAAO,QAAQ,IAAI,CAAC,GAAG,OAAO,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,KAAK,oBAAoB,MAAM,KAAK,IAAI,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,OAAO,GAAG,GAAG,GAAG,SAAU,MAAM,GAAG,CAAC,CAAC;EAC/L;AAGO,MAAM,cAAyB;IACpC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,EAAE;IACpC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAK,EAAE,EAAE;IACnD,OAAO,CAAC,SAAS,WAAW,SAAS,EAAE,OAAO,GAAG,GAAG,GAAG,GAAG,MAAM,QAAQ,EAAE,CAAC,CAAC;IAC5E,UAAU;MACR,MAAM,KAAK,GAAG,KAAK,KAAK,CAAC;MACzB,MAAM,KAAK,GAAG,KAAK,KAAK,CAAC;MACzB,MAAM,KAAK,GAAG,KAAK,IAAI,GAAG,IAAI,oBAAoB,EAAE,OAAO,EAAE,CAAC,CAAC;MAC/D,MAAM,KAAK,GAAG,KAAK,KAAK,CAAC;MACzB;QACE;QACA,GAAG,KAAK,IAAI;QACZ,IAAI,mBAAmB,EAAE,OAAO,EAAE,CAAC;QACnC,OAAO,GAAG,OAAO,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG,KAAK,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,MAAM,IAAI,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,KAAK,CAAC,CAAC;MACrL;MACA,MAAM,KAAK,IAAI,QAAQ,CAAC,GAAG,IAAI,WAAW,IAAI,GAAG,IAAI,aAAa,EAAE,OAAO,EAAE,CAAC,CAAC;MAC/E,MAAM,KAAK,SAAS,WAAW,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,OAAO,IAAI,CAAC,CAAC;IACpF;IACA,MAAM;MACJ,KAAK,SAAS,SAAS,GAAG;QACxB,IAAI,QAAQ,IAAI,SAAS,MAAM,GAAG,KAAK,CAAC;QACxC,IAAI,YAAY,IAAI,GAAG,IAAI,SAAS,MAAM,GAAG,YAAY,CAAC,CAAC;QAC3D,KAAK,IAAI,GAAG,SAAS,UAAU,GAAG,CAAC,GAAG,IAAI,SAAS,QAAQ,CAAC,CAAC,GAAG;UAC9D,IAAI,UAAU,IAAI;UAClB,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;UAC9B,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,KAAK,CAAC;QAC1L,CAAC;MACH,CAAC;IACH;EACF;AC9CA,MAAMC,UAAS,CAAC,MAAM,MAAM,KAAK;AAG1B,MAAM,oBAA+B;IAC1C,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,GAAG;IACrC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE;IACpD,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,CAAC;IAC5D,UAAU;MACR;QACE;QACA,IAAI,WAAW;QACf,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;QAC9B,OAAO,GAAG,OAAO,EAAE,GAAGA,SAAQ,KAAK,CAAC,GAAG,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,GAAG,GAAG,MAAM,IAAI,KAAK,GAAG,CAAC,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,IAAI,CAAC,CAAC;QACpM,OAAO,OAAO,EAAE,GAAG,OAAO,EAAE,GAAGA,SAAQ,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,SAAU,MAAM,GAAG,CAAC,CAAC;MAChL;MACA;QACE;QACA,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC;QAC/B;UACE,OAAO,EAAE;UACT,MAAM,UAAU,MAAM,SAAS,IAAI,MAAM,GAAG,GAAG;YAC7C,GAAG,CAAC,IAAI,MAAM,IAAI,IAAI,CAAC,CAAC,GAAG,KAAK,IAAI,MAAM,IAAI,MAAM,GAAG,CAAC,CAAC;YACzD,KAAK,MAAM,CAAC,IAAI,IAAI,SAAS,OAAO,CAAC,GAAG,GAAG,GAAG,MAAM,IAAI,IAAI,SAAS,OAAO,CAAC,CAAC,CAAC,CAAC;YAChF,MAAM;YAAK,IAAI,CAAC,GAAG,GAAG;YAAG,MAAM;YAAK,MAAM,CAAC,GAAG,CAAC;YAAG,MAAM,CAAC,KAAK,GAAG;YAAG,MAAM;YAAG,IAAI;YAAU,IAAI;YAAU,GAAG;YAAK,IAAI;UACvH,CAAC,CAAC;QACJ;MACF;IACF;IACA,MAAM;MACJ,KAAK,IAAI,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG;QACtC,KAAK,OAAO,UAAU,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,IAAI,IAAI,CAAC,CAAC,GAAG,KAAK,KAAK,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,KAAK,IAAI,SAAU,GAAG,KAAK,GAAG,EAAE,CAAC;QAC3L,KAAK,GAAG,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,MAAM,IAAI,IAAI,CAAC,CAAC,GAAG,KAAK,KAAK,GAAG,IAAI,KAAK,MAAM,CAAC,MAAM,MAAM,IAAI,GAAG,GAAG,SAAU,MAAM,GAAG,CAAC,CAAC,CAAC;MAChJ,CAAC;IACH;EACF;ACrCA,MAAM,cAAc,CAAC,KAAK,KAAK,CAAC;AAChC,MAAM,mBAAmB,WAAW,CAAC,MAAM,MAAM,IAAI,CAAC;AACtD,MAAM,cAAc,CAAC,MAAM,GAAG,GAAG;AAG1B,MAAM,aAAwB;IACnC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,GAAG;IACrC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;IACvD,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,GAAG,IAAI,cAAc,EAAE,WAAW,IAAI,CAAC,CAAC;IACnG,UAAU;MACR;QACE;QACA;UACE,IAAI,KAAK,IAAI,OAAO,IAAI,CAAC;UACzBZ,MAAK,UAAU,MAAM,aAAa,gBAAgB;UAClD,SAAS,UAAU,OAAO,EAAE,GAAG,IAAI,MAAM,GAAG,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG,OAAO,EAAE,CAAC;QAC7E;MACF;MACA,MAAM,KAAK,SAAS,UAAU,OAAO,EAAE,GAAG,MAAM,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC;MACrE;QACE;QACA,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;QAC9B,SAAS,UAAU,YAAY,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;QAClD,MAAM,UAAU,IAAI,EAAE,GAAG,aAAa,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,IAAI,SAAU,IAAI,SAAU,GAAG,KAAK,CAAC;QACzK,OAAO,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,aAAa,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,SAAU,MAAM,GAAG,CAAC,CAAC;MACjJ;MACA;QACE;QACA,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC;QAC/B;UACE,OAAO,EAAE;UACT,MAAM,UAAU,MAAM,SAAS,IAAI,GAAG,KAAK,GAAG;YAC5C,GAAG,CAAC,IAAI,MAAM,IAAI,MAAM,GAAG,CAAC,GAAG,KAAK,IAAI,KAAK,IAAI,MAAM,GAAG,CAAC,CAAC;YAC5D,KAAK,MAAM,CAAC,IAAI,SAAS,OAAO,CAAC,GAAG,KAAK,IAAI,SAAS,OAAO,CAAC,CAAC,CAAC;YAChE,MAAM;YAAK,IAAI,CAAC,KAAK,GAAG;YAAG,MAAM;YAAK,MAAM,CAAC,KAAK,GAAG;YAAG,MAAM,CAAC,KAAK,CAAC;YAAG,MAAM;YAAG,IAAI;YAAU,IAAI;YAAU,GAAG;YAAM,IAAI;UAC5H,CAAC,CAAC;QACJ;MACF;IACF;EACF;AC9CO,MAAM,OAAkB,CAAC,MAAM,GAAG,GAAG;AACrC,MAAMC,MAAgB,CAAC,GAAG,GAAG,CAAC;ACErC,MAAM,OAAO,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC;AACzE,MAAM,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AACjC,MAAM,QAAQ,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC;AACnC,MAAM,kBAAkB,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC;AAC9C,MAAM,iBAAiB,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC;AAC7C,MAAM,kBAAkB,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC;AAC9C,MAAM,mBAAmB,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC;AAC/C,MAAMY,gBAAe;AACrB,MAAM,UAAU;AAGT,MAAM,oBAA+B;IAC1C,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,GAAG;IACrC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;IACvD,OAAO,CAAC,OAAO;IACf,OAAO;MACL,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC;MACnD,IAAI,cAAc,EAAE,WAAW,IAAI,CAAC;MACpC,SAAS,WAAW,SAAS,EAAE,OAAO,GAAG,GAAG,KAAK,CAAC,IAAI,KAAK,GAAG,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;IAC1F;IACA,UAAU;MACR;QACE,KAAK;QACL;UACE,IAAI,KAAK,IAAI,OAAO,IAAI,CAAC;UACzB,IAAI,gBAAgB,EAAE,OAAO,GAAG,MAAM,IAAI,OAAO,CAAC,EAAE,CAAC;UACrD;YACE,IAAI,KAAK,IAAI,OAAO,IAAI,GAAG,IAAI;YAC/B,SAAS,SAAS,QAAQ,EAAE,GAAG,KAAK,OAAO,KAAK,GAAG,GAAG,KAAK,OAAO,KAAK,GAAG,QAAQ,MAAM,OAAO,IAAI,MAAM,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;YAC7H,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,KAAK,OAAO,KAAK,CAAC,GAAG,KAAK,OAAO,KAAK,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC;YACzFb,MAAK,YAAY,SAAS,MAAM,GAAG,iBAAiB,CAAC;YACrD,OAAO,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,MAAM,GAAG,KAAK,gBAAgB,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,OAAO,MAAO,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,SAAU,OAAQ,GAAG,MAAM,IAAI,MAAM,GAAG,CAAC,CAAC;YAC3MA,MAAK,WAAW,SAAS,MAAM,GAAG,CAAC;YACnC,IAAI,aAAa,EAAE,OAAO,IAAI,GAAG,IAAI,GAAG,MAAM,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;UACpE;QACF;MACF;MACA,MAAM,KAAKA,MAAK,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,KAAK,CAAC,IAAI,IAAI,GAAG,iBAAiB,IAAI,GAAG,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,IAAI,WAAW,IAAI,GAAG,IAAI,kBAAkB,CAAC;MAC7L,MAAM,KAAK,SAAS,WAAW,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,GAAG,GAAG,OAAO,IAAI,CAAC,CAAC;IACnG;IACA,MAAM;MACJ,KAAK,SAAS,SAAS,GAAG;QACxB,IAAI,QAAQ,IAAI,SAAS,MAAM,GAAG,KAAK,CAAC;QACxC,IAAI,YAAY,IAAI,GAAG,IAAI,SAAS,MAAM,GAAGa,aAAY,CAAC,CAAC;QAC3D,KAAK,IAAI,GAAG,SAAS,UAAU,GAAG,CAAC,GAAG,IAAI,SAAS,QAAQ,CAAC,CAAC,GAAG;UAC9D,IAAI,UAAU,IAAI;UAClB,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;UAC9B,OAAO,SAASb,MAAK,YAAY,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,OAAO,IAAI,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,GAAG,kBAAkB,GAAG,CAAC,CAAC;UACrH,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,GAAG,KAAK,CAAC,KAAK,MAAM,CAAC,GAAG,KAAKC,KAAI,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,KAAK,CAAC;QAClM,CAAC;MACH,CAAC;IACH;EACF;ACvDA,MAAM,UAAU,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;AACjE,MAAM,aAAa;AACnB,MAAM,YAAY;AAClB,MAAMY,gBAAe;AACrB,MAAM,OAAO,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC;AAG5B,MAAM,eAA0B;IACrC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,IAAI;IACzB,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;IACvD,OAAO;MACL,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC;MACnD,IAAI,cAAc,EAAE,WAAW,IAAI,CAAC;MACpC,IAAI,QAAQ,CAAC;MACb,GAAG,QAAQ,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,SAAS,WAAW,SAAS,EAAE,OAAO,GAAG,KAAK,CAAC,IAAI,GAAI,GAAG,KAAK,CAAC,IAAI,IAAK,QAAQ,EAAE,CAAC,CAAC;IAC1H;IACA,UAAU;MACR,MAAM,KAAKb,MAAK,YAAY,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC,GAAG,IAAI,YAAY,CAAC;MAC9H,MAAM,KAAKA,MAAK,YAAY,CAAC,KAAK,CAAC,IAAI,MAAM,KAAK,KAAK,CAAC,IAAI,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;MAC/G;QACE;QACA,IAAI,QAAQ,CAAC;QACb,IAAI,WAAW,IAAI;QACnBA,MAAK,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,KAAK,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;QAClFA,MAAK,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,KAAK,CAAC,CAAC,GAAG,WAAW,CAAC,KAAK,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;QACjF,IAAI,kBAAkB;MACxB;MACA;QACE;QACA,OAAO,QAAQ,QAAQ,SAAS,WAAW,QAAQ,EAAE,OAAO,OAAO,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,OAAO,GAAG,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;MACnL;IACF;IACA,MAAM;MACJ,KAAK,GAAG,MAAM,GAAG,GAAG;QAClB,IAAI,UAAU,IAAI,YAAY,IAAI,MAAM,GAAG,CAAC,CAAC;QAC7C,KAAK,GAAG,IAAI,SAAS,QAAQ,GAAG,SAAS,MAAM,CAAC,GAAG,SAAS,GAAG,CAAC,IAAI,QAAQ,SAAS,QAAQ,CAAC,GAAG,IAAI,gBAAgB,EAAE,QAAQ,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;QACnJ,KAAK,QAAQ,UAAU,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,CAAC,GAAG,IAAI,SAAS,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,GAAG,IAAI,SAAU,GAAG,KAAK,GAAG,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;MAC3N,CAAC;MACD,KAAK,SAAS,SAAS,GAAG;QACxB,IAAI,QAAQ,IAAI,SAAS,MAAM,GAAG,KAAK,CAAC;QACxC,IAAI,YAAY,IAAI,GAAG,IAAI,SAAS,MAAM,GAAGa,aAAY,CAAC,CAAC;QAC3D,KAAK,IAAI,GAAG,SAAS,UAAU,GAAG,CAAC,GAAG,IAAI,SAAS,QAAQ,CAAC,CAAC,GAAG;UAC9D,IAAI,UAAU,IAAI;UAClB,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC;UAC/B,OAAO,GAAGb,MAAK,YAAY,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,OAAO,GAAG,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,GAAG,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;UACrH,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,GAAG,KAAK,CAAC,KAAK,MAAM,GAAG,GAAG,KAAKC,KAAI,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,IAAI,CAAC;QACpM,CAAC;MACH,CAAC;IACH;EACF;ACrDA,MAAM,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAClC,MAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,GAAG,GAAG,CAAC,GAAG,UAAU,QAAQ,QAAQ,IAAI;AAC7E,MAAMa,UAAS,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACjD,MAAMC,sBAAqB,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC;AACjD,MAAMF,gBAAe;AACrB,MAAM,eAAe;AAGd,MAAM,eAA0B;IACrC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,GAAG;IACrC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;IACnD,OAAO;MACL,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC;MACnD,IAAI,cAAc,EAAE,WAAW,IAAI,CAAC;MACpC,GAAGC,QAAO,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,SAAS,WAAW,SAAS,EAAE,OAAO,GAAG,KAAK,CAAC,IAAI,GAAI,GAAG,KAAK,CAAC,IAAI,IAAK,QAAQ,EAAE,CAAC,CAAC;IACzH;IACA,UAAU;MACR;QACE,MAAM;QACN;UACE,IAAI,KAAK,IAAI,OAAO,GAAG,CAAC;UACxB,IAAI,OAAO,IAAI,MAAM,GAAG,CAAC;UACzB,IAAI,OAAO,IAAI,cAAc,SAAS,KAAK,CAAC,CAAC;UAC7C,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,KAAK,OAAO,KAAK,CAAC,CAAC,GAAG,SAAS,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;UACxF,IAAI,gBAAgB,EAAE,OAAO,IAAI,OAAO,CAAC,GAAG,MAAM,IAAI,OAAO,CAAC,EAAE,CAAC;UACjE,IAAI,cAAc,EAAE,OAAO,KAAK,OAAO,KAAK,GAAG,KAAK,SAAS,KAAK,EAAE,CAAC;UACrE,OAAO,EAAE,GAAG,KAAK,SAAS,OAAO,GAAG,CAAC,GAAG,IAAI,SAAS,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,SAAS,KAAK,GAAG,KAAK,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,IAAI,CAAC;UAC/M,OAAO,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,OAAO,GAAG,KAAKC,qBAAoB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,OAAO,GAAG,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,UAAU,MAAM,GAAG,CAAC,CAAC;UACnK,MAAM,UAAU,GAAG,EAAE,GAAG,SAAS,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,IAAI,CAAC;QACrK;MACF;MACA;QACE;QACA,IAAI,QAAQ,CAAC;QACb,IAAI,WAAW,IAAI;QACnB,OAAO,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,GAAG,KAAKA,qBAAoB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,OAAO,GAAG,GAAG,GAAG,UAAU,MAAM,GAAG,CAAC,CAAC;QAC9K,IAAI,oBAAoB;MAC1B;MACA,MAAM,KAAK,OAAOD,QAAO,QAAQ,SAAS,WAAW,QAAQ,EAAE,OAAO,OAAO,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,KAAKA,QAAO,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,GAAG,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC;IACzK;IACA,MAAM;MACJ,KAAK,SAAS,SAAS,GAAG;QACxB,IAAI,QAAQ,IAAI,SAAS,MAAM,GAAG,KAAK,CAAC;QACxC,IAAI,YAAY,IAAI,GAAG,IAAI,SAAS,MAAM,GAAGD,aAAY,CAAC,CAAC;QAC3D,KAAK,IAAI,GAAG,SAAS,UAAU,GAAG,CAAC,GAAG,IAAI,SAAS,QAAQ,CAAC,CAAC,GAAG;UAC9D,IAAI,UAAU,IAAI;UAClB,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;UAC9B,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,GAAG,KAAK,CAAC,KAAK,MAAM,GAAG,GAAG,KAAKZ,KAAI,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,IAAI,CAAC;QACtM,CAAC;MACH,CAAC;IACH;EACF;ACxDA,MAAMe,MAAK,CAAC,GAAW,GAAW,MAAiD,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;AAKzH,MAAM,YAAYA,IAAG,OAAO,KAAK,IAAI;AACrC,MAAM,aAAaA,IAAG,KAAK,MAAM,GAAG;AACpC,MAAM,YAAYA,IAAG,MAAM,MAAM,IAAI;AACrC,MAAM,aAAaA,IAAG,KAAK,MAAM,IAAI;AACrC,MAAM,uBAAuB;AAC7B,MAAM,QAAQ;AACd,MAAM,aAAa,CAAC,MAAM,GAAG,CAAC;AAC9B,MAAM,eAAe,CAAC,KAAK,KAAK,GAAG;AACnC,MAAM,SAAS,CAAC,QAA2C,SAA4C,WAAW,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;AAG1K,MAAM,qBAAgC;IAC3C,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,GAAG;IACrC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;IACvD,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,GAAG,IAAI,cAAc,EAAE,WAAW,IAAI,CAAC,CAAC;IACnG,UAAU;MACR;QACE;QACAhB,MAAK,UAAU,SAAS,YAAY,OAAO,WAAW,UAAU,CAAC;QACjEA,MAAK,SAAS,WAAW,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC;QACnD,IAAI,uBAAuB,EAAE,MAAM,YAAY,CAAC;QAChD,OAAO,EAAE,GAAG,WAAW,GAAG,CAAC,KAAK,KAAK,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,IAAI,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,KAAK,CAAC;QACzH,IAAI,YAAY;MAClB;MACA;QACE;QACA,OAAO,GAAGA,MAAK,SAAS,KAAK,YAAY,CAAC,IAAI,MAAM,IAAI,OAAO,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC;QAClH,IAAI,uBAAuB,EAAE,MAAM,aAAa,CAAC;QACjD,OAAO,EAAE,GAAG,YAAY,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,MAAM,GAAG,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,KAAK,CAAC;MACzH;MACA;QACE;QACA,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC;QAC/BA,MAAK,SAAS,WAAWC,KAAI,IAAI,GAAG;QACpC,IAAI,mBAAmB,EAAE,MAAM,YAAY,CAAC;QAC5C,OAAO,GAAG,OAAO,EAAE,GAAG,CAAC,IAAI,UAAU,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,IAAI,UAAU,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC,GAAG,KAAKA,KAAI,MAAM,KAAK,IAAI,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,MAAM,GAAG,GAAG,MAAM,IAAI,MAAM,IAAI,CAAC,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,IAAI,CAAC,CAAC;QAC3O,MAAM,UAAU,IAAI,EAAE,GAAG,WAAW,GAAG,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,IAAI,CAAC;MACvI;MACA;QACE;QACAD,MAAK,UAAU,QAAQ,cAAc,OAAO,YAAY,YAAY,CAAC;QACrE,OAAO,OAAO,IAAI,SAAS,IAAI,OAAO,IAAI,CAAC,GAAG,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,cAAc,EAAE,GAAG,SAAS,OAAO,GAAG,GAAG,SAAS,OAAO,EAAE,GAAG,oBAAoB,CAAC;QACnKA,MAAK,SAAS,YAAYC,KAAI,IAAI,CAAC;MACrC;IACF;EACF;ACtDA,MAAM,SAAS;AACf,MAAM,cAAc;AACpB,MAAM,cAAc;AACpB,MAAM,cAAc;AACpB,MAAM,YAAY,CAAC,KAAK,KAAK,GAAG;AAChC,MAAM,iBAAiB,WAAW,CAAC,MAAM,OAAO,EAAE,CAAC;AACnD,MAAMgB,oBAAmB,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC;AAC/C,MAAM,cAAc,SAAS,KAAK;AAClC,MAAM,WAAW,GAAG,OAAO,MAAM;AAG1B,MAAM,qBAAgC;IAC3C,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,IAAI,YAAY,SAAS,CAAC,gBAAgB,QAAQ,GAAG,SAAS,EAAE;IAC1E,QAAQ,EAAE,WAAW,IAAI;IACzB,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;IACvD,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,GAAG,IAAI,cAAc,EAAE,WAAW,IAAI,CAAC,GAAG,SAAS,YAAY,UAAU,EAAE,QAAQ,SAAS,CAAC,GAAG,IAAI,oBAAoB,EAAE,QAAQ,SAAS,CAAC,CAAC;IACxM,UAAU;MACR;QACE;QACAjB,MAAK,UAAU,SAAS,WAAW,cAAc;QACjD,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;QAC9B,SAAS,YAAY,UAAU;QAC/B,KAAK,UAAU,CAACA,MAAK,YAAY,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,GAAGC,KAAI,IAAI,GAAG,CAAC,CAAC;MACzE;IACF;IACA,MAAM;MACJ,KAAK,MAAM,YAAY,MAAM,GAAG;QAC9B,IAAI,OAAO,MAAM,IAAI,GAAG,IAAI,IAAI,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC;QACxE,SAAS,YAAY,QAAQ,EAAE,IAAI,OAAO,GAAG,KAAK,CAAC;QACnD,KAAK,IAAI,QAAQ,GAAG;UAClB,KAAK,GAAG,aAAa,CAAC,GAAG;YACvB,KAAK,OAAO,UAAU,IAAI,EAAE,GAAG,MAAM,YAAY,KAAK,GAAG,KAAK,MAAM,YAAY,WAAW,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,UAAU,IAAI,UAAU,GAAG,MAAM,GAAG,OAAO,IAAI,KAAK,CAAC;UACvO,CAAC;UACD,KAAK,GAAG,MAAM,WAAW,GAAG;YAC1B,KAAK,SAAS,UAAU,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,GAAG,GAAG,KAAK,MAAM,MAAM,IAAI,CAAC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,IAAI,UAAU,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,WAAW,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC;UAChN,CAAC;QACH,GAAG;UACD,KAAK,GAAG,aAAa,CAAC,GAAG;YACvB,KAAK,OAAO,UAAU,IAAI,EAAE,GAAG,MAAM,YAAY,MAAM,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,IAAI,UAAU,GAAG,IAAI,CAAC;UAChL,CAAC;UACD,KAAK,GAAG,IAAI,MAAM,YAAY,SAAS,CAAC,GAAG,GAAG,GAAG;YAC/C,KAAK,OAAO,UAAU,KAAK,EAAE,GAAG,CAAC,GAAG,MAAM,YAAY,UAAU,CAAC,GAAG,MAAM,GAAG,MAAM,YAAY,UAAU,CAAC,CAAC,GAAG,KAAKgB,mBAAkB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,MAAM,YAAY,SAAS,GAAG,GAAG,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,UAAU,IAAI,UAAU,GAAG,KAAK,KAAK,EAAE,CAAC;UAC3R,CAAC;QACH,CAAC;MACH,CAAC;IACH;EACF;ACnDA,MAAM,UAAU,CAAC,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC;AAG3C,MAAM,gBAA2B;IACtC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,EAAE;IACpC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,GAAG,GAAG,QAAQ,CAAC,KAAK,GAAG,EAAE,EAAE;IACjD,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,CAAC;IAC5D,UAAU,CAAC;IACX,MAAM;MACJ;QACE,QAAQ;QACRjB,MAAK,aAAa,OAAO,KAAK,KAAK,GAAG,KAAK,KAAK,SAAS,KAAK,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,MAAM,KAAK,EAAE,KAAK,WAAW,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,GAAG,OAAO,IAAI,YAAY,IAAI,CAAC;QAC9K,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,KAAK,KAAK,SAAS,KAAK,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,MAAM,KAAK,CAAC,CAAC,GAAG,CAAC,UAAU,GAAG,KAAK,KAAK,SAAS,KAAK,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,MAAM,KAAK,CAAC,CAAC,CAAC;MAC/K;IACF;EACF;ACpBA,MAAM,MAAM,CAAC,KAAK,KAAK;AACvB,MAAM,MAAM,KAAK,IAAI,GAAG;AACxB,MAAM,MAAM,KAAK,IAAI,GAAG;AACxB,MAAM,UAAU;AAChB,MAAMK,SAAQ;AAEd,MAAM,WAAW,CAAC,SAA0B,IAAI,MAAM,KAAK,IAAI,MAAM,MAAM,MAAM,IAAI;AACrF,MAAM,WAAW,IAAI,CAAC,MAAM,KAAK,IAAI,MAAM,MAAM,MAAM,GAAG;AAC1D,MAAM,WAAW,WAAW,CAAC,GAAG,MAAM,CAAC,CAAC;AAGjC,MAAM,kBAA6B;IACxC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,EAAE;IACpC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAK,GAAG,EAAE;IAClD,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,GAAG,IAAI,YAAY,EAAE,GAAG,SAAS,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC;IAC/G,UAAU,CAAC;IACX,MAAM;MACJ,IAAI,QAAQ,IAAI,SAAS,IAAI,MAAMA,MAAK,CAAC,CAAC;MAC1C,IAAI,WAAW,CAAC,SAAS,SAAS,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC;MAC3D,IAAI,YAAY,EAAE,GAAG,SAAS,MAAM,GAAG,GAAG,KAAK,KAAK,IAAI,CAAC;MACzD,KAAK,MAAM,UAAU,KAAK,EAAE,GAAG,SAAS,SAAS,GAAG,KAAK,UAAU,MAAM,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,KAAK,MAAM,IAAI,UAAU,IAAI,UAAU,GAAG,KAAK,KAAK,EAAE,CAAC;MACrL,KAAK,MAAM,OAAO,IAAI,EAAE,GAAG,SAAS,SAAS,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC;MAC9G,KAAK,GAAG,KAAK,GAAG,IAAI,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,SAAS,CAAC,GAAG,GAAG,IAAI,GAAG,SAAS,SAAS,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC,GAAG,MAAM,QAAU,EAAE,MAAM,GAAG,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;MACrK,UAAU,GAAG,CAAC,GAAG,SAAS,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,SAAS,CAAC,CAAC,GAAG,KAAK,IAAI,MAAM,CAAC,CAAC;IAC1F;EACF;AC7BO,MAAMa,cAAwB,CAAC,KAAK,GAAG,GAAG;AAC1C,MAAMC,gBAA0B,CAAC,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,CAAC,GAAW,GAAW,MAAyB,aAAaD,aAAYC,eAAc,CAAC,GAAG,GAAG,CAAC,CAAC;AACjH,MAAM,eAAe,CAAC,MAAiB,OAA6B,WAAW,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;ACJzI,MAAM,OAAO,SAAS,GAAG,MAAM,GAAG;AAClC,MAAM,UAAU,SAAS,KAAK,KAAK,IAAI;AACvC,MAAM,oBAAoB,aAAa,SAAS,SAAS,KAAK,KAAK,EAAE,CAAC;AACtE,MAAM,aAAa,SAAS,GAAG,KAAK,GAAG;AACvC,MAAMC,mBAAkB,aAAa,YAAY,SAAS,GAAG,KAAK,CAAC,CAAC;AACpE,MAAM,OAAO;AACb,MAAM,MAAM;AACZ,MAAM,WAAW;AAGV,MAAM,eAA0B;IACrC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,IAAI,aAAa,SAAS,CAAC,OAAO,MAAM,MAAM,IAAI,GAAG,SAAS,EAAE;IAC1E,QAAQ,EAAE,WAAW,KAAK,QAAQ,EAAE;IACpC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,KAAK,KAAK,GAAG,EAAE;IACtD,UAAU,CAAC;IACX,MAAM;MACJ,KAAK,MAAM,UAAU,IAAI,GAAG,OAAO,QAAQ,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,SAAS,KAAK,mBAAmB,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,SAAU,QAAQ,GAAG,GAAG,MAAM,GAAG,KAAK,CAAC;MAC3O,KAAK,GAAG,OAAO,IAAI,GAAG;QACpB,KAAK,MAAM,UAAU,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,GAAG,GAAG,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,UAAU,GAAG,MAAM,GAAG,KAAK,CAAC;MAC9L,CAAC;MACD,KAAK,GAAG,OAAO,GAAG,GAAG;QACnB,KAAK,MAAM,UAAU,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,GAAG,GAAG,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,MAAM,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,IAAI,SAAU,GAAG,KAAK,GAAG,MAAM,CAAC;QACvM,KAAK,GAAG,KAAK,GAAG,IAAI,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,UAAU,GAAG,EAAE,GAAG,YAAY,KAAKA,kBAAiB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,KAAK,MAAM,IAAI,UAAU,IAAI,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;MAClL,CAAC;MACD,KAAK,GAAG,OAAO,QAAQ,GAAG;QACxB,KAAK,MAAM,UAAU,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,GAAG,GAAG,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,IAAI,SAAU,IAAI,QAAU,GAAG,KAAK,GAAG,KAAK,CAAC;QAC1MpB,MAAK,aAAa,QAAQ,SAAS,GAAG,KAAK,CAAG,GAAG,KAAK,MAAM,EAAE,SAAS,KAAK,CAAC;QAC7E,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,GAAG,KAAK,IAAI;MAC/C,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IACtB;EACF;AClCA,MAAMC,MAAK,CAAC,GAAG,GAAG,CAAC;AAGnB,MAAM,eAAe,CAAC,SAAoD;AACxE,UAAM,MAAM,SAAS,OAAO,GAAG,GAAG,GAAG;AACrC,UAAM,SAAS,SAAS,GAAG,GAAG,GAAG;AACjC,WAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC;EACnD;AAGO,MAAM,eAAsC;IACjDD,MAAK,WAAW,KAAK,MAAM,OAAO,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,OAAQ;IAC1E,IAAI,WAAW;IACf,SAAS,OAAO,UAAU,EAAE,MAAM,KAAK,MAAM,IAAI,CAAC;IAClD,OAAO,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,MAAM,OAAO,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,KAAKC,KAAI,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,MAAO,IAAI,GAAG,GAAG,UAAU,MAAM,GAAG,CAAC,CAAC;IAC/J,OAAO,EAAE,GAAG,SAAS,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,MAAM,GAAG,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,IAAI,CAAC;IAC7I,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,OAAO,EAAE,GAAG,SAAS,OAAO,MAAM,KAAK,GAAG,GAAG,GAAG,aAAa,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,IAAI,CAAC,CAAC;IAC1K,OAAO,EAAE,GAAG,SAAS,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,MAAM,IAAI,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,IAAI,CAAC;EACrI;ACjBA,MAAM,OAAO,SAAS,MAAM,MAAM,IAAI;AACtC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;AACvC,MAAM,OAAO,CAAC,WAAW,CAAC,IAAI,KAAK,GAAG,WAAW,CAAC,IAAI,GAAG;AACzD,MAAM,UAAU;AAChB,MAAM,OAAO,SAAS,OAAO,KAAK,IAAI;AAG/B,MAAM,YAAuB;IAClC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,EAAE;IACpC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,IAAI,KAAK,GAAG,GAAG,QAAQ,CAAC,KAAK,KAAK,CAAC,EAAE;IACnD,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,CAAC;IAC5D,UAAU;MACR,MAAM,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,KAAK,SAAU,EAAE,MAAM,GAAG,MAAM,IAAI,IAAI,KAAK,OAAO,MAAM,CAAC;MACtF;QACE;QACAD,MAAK,UAAU,SAAS,MAAM,aAAa,MAAM,SAAS,IAAI,KAAK,IAAI,CAAC,GAAG,GAAG;QAC9E,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,KAAK,MAAM,IAAI,UAAU,IAAI,UAAU,GAAG,IAAI,CAAC;MACtI;MACA,MAAM,SAAS,GAAG,YAAY;IAChC;IACA,MAAM;MACJ,KAAK,GAAG,MAAM,OAAO,GAAG;QACtB,KAAK,QAAQ,UAAU,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,MAAM,IAAI,SAAU,GAAG,KAAK,GAAG,KAAK,IAAI,GAAG,KAAK,EAAE,CAAC;MACvI,CAAC;MACD,KAAK,IAAI,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG;QAC1C,IAAI,UAAU,MAAM,IAAI,IAAI,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;QACnD,IAAI,SAAS,MAAM,MAAM,YAAY,IAAI,SAAS,QAAQ,GAAG,GAAG,CAAC,CAAC;QAClEA,MAAK,aAAa,MAAM,SAAS,OAAO,GAAG,IAAI,KAAK,IAAI,SAAS,QAAQ,GAAG,GAAG,CAAC,GAAG,KAAK,EAAE,OAAO,GAAG,CAAC;QACrGA,MAAK,aAAa,OAAO,MAAM,KAAK,KAAK,EAAE,OAAO,EAAE,CAAC;QACrD,UAAU,GAAG,KAAK,SAAS,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,IAAI;MAC1D,CAAC;MACD,KAAK,GAAG,MAAM,OAAO,GAAG;QACtBA,MAAK,aAAa,MAAM,KAAK,MAAM,OAAO,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,KAAK,EAAE,OAAO,IAAI,YAAY,KAAK,CAAC;QAC9G,UAAU,GAAG,KAAK,MAAM,OAAO,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,IAAI;QACnE,SAAS,OAAO,QAAQ,EAAE,IAAI,MAAM,CAAC;MACvC,CAAC;IACH;EACF;ACzCO,MAAM,gBAA2B;IACtC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,KAAK;IACL,QAAQ,EAAE,WAAW,KAAK,QAAQ,IAAI,QAAQ,EAAE;IAChD,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,QAAQ,CAAC,KAAK,GAAG,GAAG,EAAE;IACjD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,CAAC;IAC5D,UAAU,CAAC,MAAM,KAAK,GAAG,YAAY,CAAC;IACtC,MAAM;MACJ,KAAK,GAAG,MAAM,GAAG,GAAG;QAClBA,MAAK,aAAa,MAAM,KAAK,MAAM,OAAO,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,KAAK,EAAE,OAAO,IAAI,YAAY,KAAK,CAAC;QAC9G,UAAU,GAAG,KAAK,MAAM,OAAO,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,IAAI;MACrE,CAAC;MACD,SAAS,OAAO,QAAQ,EAAE,IAAI,MAAM,CAAC;IACvC;EACF;ACnBA,MAAMqB,QAAO,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;AACtD,MAAMC,SAAQD,MAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AACjC,MAAME,SAAQF,MAAK,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC;AACnC,MAAM,SAAS,SAAS,GAAG,GAAG,GAAG;AACjC,MAAM,UAAU;AAGT,MAAM,aAAwB;IACnC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,GAAG,QAAQ,EAAE;IAClC,MAAM;IACN,OAAO;MACL,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC;MACnD,SAAS,WAAW,SAAS,EAAE,OAAO,GAAG,GAAG,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,QAAQ,UAAU,KAAK,GAAG,CAAC;MAChG,OAAO,SAAS,MAAM,MAAM,IAAI,GAAG,SAAS,GAAG,KAAK,GAAG,GAAG,IAAI;IAChE;IACA,UAAU;MACR;QACEA,MAAK;QACL;UACE,IAAI,KAAK,IAAI,OAAO,IAAI,CAAC;UACzB,IAAI,gBAAgB,EAAE,OAAO,GAAG,MAAM,IAAI,OAAO,CAAC,EAAE,CAAC;UACrD;YACE,IAAI,KAAK,IAAI,OAAO,IAAI,GAAG,IAAI;YAC/B,SAAS,UAAU,SAAS,EAAE,GAAG,KAAKC,QAAO,KAAK,GAAG,GAAG,KAAKC,QAAO,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC;YAC/F,KAAK,GAAG,GAAG,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,UAAU,iBAAiB,EAAE,GAAG,KAAKD,QAAO,KAAK,GAAG,GAAG,KAAKC,QAAO,KAAK,EAAE,CAAC,CAAC,CAAC;YAC5H,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,EAAE,GAAG,SAAS,MAAM,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,IAAI,UAAU,GAAG,KAAK,IAAI,IAAI,CAAC;YAC7I,IAAI,oBAAoB,EAAE,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC;UAClD;QACF;MACF;IACF;EACF;ACpCA,MAAMrB,eAAc;AACpB,MAAM,YAAY;AAGlB,MAAMsB,QAAO,CAAC,SAA8B;IAC1C,IAAI,gBAAgB,EAAE,OAAO,IAAI,KAAK,CAAC;IACvC;MACE,IAAI,MAAM,IAAI;MACd,OAAO,EAAE,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;MAC3E,OAAO,GAAG,KAAK,SAAS,IAAI,IAAI,MAAM,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG,WAAW,GAAG,CAAC;MAC5G,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,GAAG,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,IAAItB,cAAa,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACzK;EACF;AAGO,MAAM,kBAA6B;IACxC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,CAAC;IACT,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAK,CAAC,EAAE;IAChD,UAAU;MACR,MAAM,KAAK,GAAGsB,MAAK,CAAC,CAAC;MACrB,MAAM,KAAK,GAAGA,MAAK,CAAC,CAAC;MACrB,MAAM,GAAG,IAAI,gBAAgB,EAAE,GAAG,KAAK,CAAC,CAAC;MACzC;QACE;QACA,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,IAAI,GAAG,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;QAC3D,IAAI,QAAQ,EAAE,WAAW,EAAE,CAAC;QAC5B,OAAO,GAAG,KAAK,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC;MAC5E;IACF;IACA,MAAM;MACJ,KAAK,IAAI,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,IAAI,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,OAAO,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACzI;EACF;ACpCA,MAAM,UAAU;AAChB,MAAM,QAAQ;AACd,MAAM,WAAW;AACjB,MAAM,aAAa;AACnB,MAAM,SAAS,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC;AAG3C,MAAM,mBAA8B;IACzC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,IAAI,SAAS,SAAS,CAAC,WAAW,SAAS,YAAY,YAAY,GAAG,SAAS,EAAE;IAC3F,QAAQ,EAAE,WAAW,GAAG;IACxB,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC,GAAG,KAAK,EAAE,EAAE;IAC/C,OAAO;MACL,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC;MACnD,GAAG,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,UAAU,IAAI,eAAe,EAAE,OAAO,GAAG,GAAG,MAAM,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC;IAC5F;IACA,UAAU,CAAC,IAAI,aAAa,CAAC,CAAC;IAC9B,MAAM;MACJ,KAAK,GAAG,OAAO,OAAO,GAAG,CAAC,KAAK,EAAE,OAAO,MAAM,QAAQ,IAAI,MAAM,IAAI,MAAM,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,IAAI,GAAG,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;MAChJ,KAAK,GAAG,OAAO,KAAK,GAAG;QACrB,KAAK,EAAE,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC;QAChH,KAAK,GAAG,MAAM,SAAS,WAAW,CAAC,GAAG;UACpC,IAAI,aAAa,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC;UACrC,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC;UAC/B,MAAM,UAAU,IAAI,EAAE,GAAG,KAAK,iBAAiB,cAAc,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,cAAc,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,UAAU,GAAG,IAAI,CAAC;QACtN,CAAC;MACH,CAAC;MACD,KAAK,GAAG,OAAO,QAAQ,GAAG;QACxB,KAAK,EAAE,QAAQ,IAAI,GAAG,IAAI,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,IAAI,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC,GAAG,QAAQ,KAAK,OAAO,KAAK,CAAC;QACrI,OAAO,OAAO,QAAQ,IAAI,iBAAiB,EAAE,OAAO,OAAO,SAAS,GAAG,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;QAC7I,KAAK,GAAG,KAAK,GAAG,IAAI,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC;MACtE,CAAC;MACD,KAAK,GAAG,OAAO,UAAU,GAAG;QAC1B,KAAK,EAAE,OAAO,MAAM,WAAW,MAAM,WAAW,aAAa,QAAQ,MAAM,MAAM,IAAI,CAAC;QACtF,KAAK,GAAG,IAAI,IAAI,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC;MACxG,CAAC;IACH;EACF;ACxCA,MAAM,UAAU;AAChB,MAAM,OAAO;AACb,MAAM,QAAQ;AACd,MAAM,cAAc;AACpB,MAAM,WAAW;AACjB,MAAM,cAAc,CAAC,MAAM,WAAW,KAAK,KAAK,GAAG,GAAG,MAAM,WAAW,KAAK,KAAK,CAAC;AAG3E,MAAM,QAAmB;IAC9B,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,CAAC;IACT,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,KAAK,EAAE,EAAE;IAChD,OAAO;MACL,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC;MACnD;QACE;QACA,IAAI,UAAU,IAAI,IAAI,CAAC,CAAC;QACxB,IAAI,UAAU,IAAI,IAAI,IAAI,EAAE,GAAG,IAAI,OAAO,GAAG,CAAC,CAAC;QAC/C,SAAS,WAAW,SAAS,EAAE,OAAO,OAAO,GAAG,SAAS,QAAQ,GAAG,GAAG,SAAS,QAAQ,GAAG,QAAQ,EAAE,CAAC;QACtG,SAAS,WAAW,QAAQ,EAAE,OAAO,OAAO,IAAI,CAAC,IAAI,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,OAAO,IAAI,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;MACtH;IACF;IACA,UAAU,CAAC;IACX,MAAM;MACJ,IAAI,WAAW,EAAE;MACjB,OAAO,SAAS,IAAI,WAAW,IAAI,SAAS,SAAS,GAAG,MAAM,aAAa,eAAe,CAAC,CAAC,CAAC;MAC7F,IAAI,QAAQ,MAAM,IAAI,IAAI,MAAM,SAAS,SAAS,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;MACnE,IAAI,OAAO,IAAI,aAAa,IAAI,UAAU,SAAS,MAAM,CAAC,CAAC,CAAC;MAC5D,KAAK,GAAG,IAAI,IAAI,IAAI,MAAM,SAAS,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,IAAI,OAAO,SAAS,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,IAAI,KAAK,SAAS,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;MAC7J,KAAK,EAAE,QAAQ,IAAI,KAAK,IAAI,MAAM,SAAS,MAAM,CAAC,CAAC,GAAG,OAAO,IAAI,MAAM,SAAS,MAAM,CAAC,EAAE,CAAC;MAC1F,IAAI,UAAU,IAAI,OAAO,IAAI,OAAO,SAAS,MAAM,CAAC,CAAC,CAAC;IACxD;EACF;AClCO,MAAM,oBAA+B;IAC1C,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,GAAG;IACxB,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,GAAG,KAAK,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAK,CAAC,EAAE;IAChD,OAAO,CAAC,IAAI,gBAAgB,EAAE,MAAM,SAAU,MAAM,SAAU,OAAO,CAAC,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC;IACxF,UAAU;MACR;QACE;QACA,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC;QACnD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;QAC/C,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,GAAG,GAAG,GAAG,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,IAAI,SAAU,IAAI,SAAU,GAAG,KAAK,IAAI,KAAK,CAAC;QAChK,OAAO,GAAG,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG,cAAc,GAAG,CAAC;MACrF;MACA,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;MACxC,MAAM,KAAK,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;IAC5C;EACF;ACpBA,MAAM,OAAO,CAAC,MAAM,KAAK,CAAG;AAGrB,MAAM,WAAsB;IACjC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,EAAE;IACpC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;IACrD,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,GAAG,IAAI,iBAAiB,EAAE,GAAG,MAAM,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;IAClH,UAAU,CAAC;IACX,MAAM;MACJxB,MAAK,aAAa,QAAQ,MAAM,MAAM,MAAM,EAAE,OAAO,GAAG,YAAY,SAAU,YAAY,KAAK,CAAC;MAChG,UAAU,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,GAAG,KAAK,IAAI;IAC3D;EACF;ACfA,MAAMW,UAAS;AAEf,MAAM,QAAQ,CAAC,KAAK,IAAIA,OAAM,IAAI,MAAM,MAAM,MAAM,KAAK,IAAIA,OAAM,IAAI,MAAM,GAAG;AAChF,MAAM,SAAS,WAAW,CAAC,KAAK,IAAIA,OAAM,GAAG,OAAO,KAAK,IAAIA,OAAM,CAAC,CAAC;AACrE,MAAM,eAAe;AACrB,MAAM,cAAc;AAGpB,MAAM,OAAO,CAAC,aACZ,MAAM,UAAU,IAAI,UAAU,EAAE,GAAG,OAAO,KAAK,QAAQ,MAAM,MAAM,IAAI,CAAC,KAAK,MAAM,QAAQ,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,UAAU,GAAG,MAAM,GAAG,KAAK,CAAC;AAGnL,MAAM,mBAA8B;IACzC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ,EAAE,WAAW,IAAI,QAAQ,EAAE;IACnC,MAAM;IACN,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;IACvD,OAAO,CAAC,IAAI,kBAAkB,EAAE,OAAO,IAAI,SAAS,MAAM,CAAC,GAAG,IAAI,iBAAiB,EAAE,GAAG,MAAM,GAAG,KAAK,MAAMA,QAAO,CAAC,GAAG,IAAI,SAAS,EAAE,IAAI,KAAK,CAAC,CAAC;IACjJ,UAAU,CAAC,IAAI,cAAc,GAAG,GAAG,IAAI,aAAa,CAAC,CAAC;IACtD,MAAM;MACJ,KAAK,GAAG,MAAM,SAAS,YAAY,CAAC,GAAG,CAAC,IAAI,cAAc,IAAI,MAAM,YAAY,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;MAC5F,KAAK,GAAG,MAAM,SAAS,WAAW,CAAC,GAAG;QACpC,IAAI,aAAa,IAAI,MAAM,WAAW,CAAC;QACvC,GAAG,CAAC,GAAG,MAAM,GAAG,EAAE,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,IAAI,iBAAiB,EAAE,MAAM,KAAK,CAAC,CAAC,CAAC;MAC3G,CAAC;IACH;EACF;AC7BA,MAAMA,UAAS,CAAC,GAAG,GAAG,CAAC;AACvB,MAAMV,OAAK,CAAC,GAAG,GAAG,CAAC;AACnB,MAAM,SAAS,CAAC,GAAG,GAAG,CAAC;AACvB,MAAMK,WAAU,CAAC,GAAG,GAAG,EAAE;AACzB,MAAM,mBAAmB,CAAC,YAAY,SAAS,QAAQ,SAAS,SAAS,OAAO;AAGhF,MAAM,eAAe,CAAC,cAA4D;IAChF,IAAI,UAAU,QAAQ;IACtB,QAAQ,gBAAgB,QAAQ;IAChC,MAAM;IACN,QAAQ,EAAE,WAAW,IAAI,QAAQ,EAAE;IACnC,MAAM;IACN,UAAU,CAACN,MAAK,UAAU,UAAU,QAAQW,SAAQ,GAAG,CAAC,CAAC;EAC3D;AAGA,MAAM,eAAe,CAAC,YAA4D;IAChF,IAAI,UAAU,MAAM;IACpB,QAAQ,gBAAgB,MAAM;IAC9B,MAAM;IACN,QAAQ,EAAE,WAAW,IAAI,QAAQ,EAAE;IACnC,MAAM;IACN,UAAU,CAACX,MAAK,UAAU,QAAQ,QAAQM,QAAO,CAAC;EACpD;AAGA,MAAM,eAAe,CAAC,IAAY,UAA0C;IAC1E;IACA,QAAQ,SAAS,EAAE;IACnB,MAAM;IACN,QAAQ,EAAE,QAAQ,EAAE;IACpB,MAAM;IACN,UAAU,CAACN,MAAK,UAAU,QAAQ,IAAI,CAAC;EACzC;AAMO,MAAM,gBAAsC;IACjD,GAAG,iBAAiB,IAAI,YAAY;IACpC,GAAI,CAAC,SAAS,MAAM,QAAQ,SAAS,EAAY,IAAI,YAAY;IACjE,aAAa,gBAAgB,EAAE;IAC/B,aAAa,gBAAgB,OAAO;IACpC,aAAa,aAAa,IAAI;IAC9B;;MAEE,IAAI;MACJ,QAAQ;MACR,MAAM;MACN,QAAQ,EAAE,WAAW,IAAI,QAAQ,EAAE;MACnC,MAAM;MACN,UAAU;QACR,MAAM,UAAU,IAAI,EAAE,GAAG,QAAQ,KAAK,CAAC,KAAK,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,QAAQ,KAAK,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,MAAM,GAAG,IAAI,CAAC;QACtM,OAAO,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,OAAO,KAAK,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,OAAO,GAAG,GAAG,GAAG,SAAU,MAAM,GAAG,CAAC,CAAC;MACtK;IACF;IACA;;MAEE,IAAI;MACJ,QAAQ;MACR,MAAM;MACN,QAAQ,EAAE,WAAW,IAAI,QAAQ,GAAG;MACpC,MAAM;MACN,UAAU;QACR,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC;QAC/B,MAAM,UAAU,IAAI,EAAE,GAAG,QAAQ,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,IAAI,SAAU,IAAI,SAAU,GAAG,KAAK,CAAC;QACpK,OAAO,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,QAAQ,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,SAAU,MAAM,GAAG,CAAC,CAAC;QAC1I;UACE,OAAO,EAAE;UACT,MAAM,UAAU,MAAM,SAAS,IAAI,GAAG,KAAK,GAAG;YAC5C,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG,KAAK,IAAI,MAAM,GAAG,CAAC;YACvC,KAAK,MAAM,CAAC,IAAI,SAAS,OAAO,CAAC,GAAG,KAAK,IAAI,SAAS,OAAO,CAAC,CAAC,CAAC;YAChE,MAAM;YAAK,IAAI,CAAC,KAAK,GAAG;YAAG,MAAM;YAAK,MAAM,CAAC,KAAK,GAAG;YAAG,MAAM,CAAC,KAAK,CAAC;YAAG,MAAM;YAAG,IAAI;YAAU,IAAI;YAAU,GAAG;YAAM,IAAI;UAC5H,CAAC,CAAC;QACJ;MACF;IACF;IACA;;MAEE,IAAI;MACJ,QAAQ;MACR,MAAM;MACN,QAAQ,EAAE,WAAW,KAAK,QAAQ,GAAG;MACrC,MAAM;MACN,UAAU;QACR,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC;QAC/B,OAAO,GAAG,OAAO,EAAE,GAAG,QAAQ,KAAK,CAAC,GAAG,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,GAAG,GAAG,MAAM,IAAI,KAAK,GAAG,CAAC,GAAG,GAAG,SAAU,MAAM,GAAG,MAAM,IAAI,QAAQ,IAAI,CAAC,CAAC;QACpM,OAAO,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,QAAQ,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,SAAU,MAAM,GAAG,CAAC,CAAC;QAC9K;UACE,OAAO,EAAE;UACT,MAAM,UAAU,MAAM,SAAS,IAAI,MAAM,GAAG,GAAG;YAC7C,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,MAAM,GAAG,CAAC;YACnC,KAAK,MAAM,CAAC,IAAI,IAAI,SAAS,OAAO,CAAC,GAAG,GAAG,GAAG,MAAM,IAAI,SAAS,OAAO,CAAC,CAAC,CAAC;YAC3E,MAAM;YAAK,IAAI,CAAC,GAAG,GAAG;YAAG,MAAM;YAAK,MAAM,CAAC,GAAG,CAAC;YAAG,MAAM,CAAC,KAAK,GAAG;YAAG,MAAM;YAAG,IAAI;YAAU,IAAI;YAAU,GAAG;YAAK,IAAI;UACvH,CAAC,CAAC;QACJ;MACF;IACF;IACA;;MAEE,IAAI;MACJ,QAAQ;MACR,MAAM;MACN,QAAQ,EAAE,QAAQ,IAAI,WAAW,GAAG;MACpC,MAAM;MACN,UAAU;QACR,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,CAAC;QAC/B;UACE,OAAO,EAAE;UACT,OAAO,EAAE,GAAG,QAAQ,KAAK,CAAC,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,IAAI,MAAM,IAAI,GAAG,MAAO,IAAI,MAAM,IAAI,CAAC,GAAG,GAAG,UAAU,MAAM,IAAI,MAAM,IAAI,QAAQ,KAAK,CAAC;QACxM;QACA,MAAM,OAAO,IAAI,EAAE,GAAG,QAAQ,KAAK,CAAC,KAAK,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,IAAI,UAAU,GAAG,KAAK,IAAI,IAAI,CAAC;QAC1H,MAAM,UAAU,IAAI,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,KAAK,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,UAAU,GAAG,IAAI,CAAC;MAC9J;IACF;IACA;;MAEE,IAAI;MACJ,QAAQ;MACR,MAAM;MACN,QAAQ,EAAE,WAAW,IAAI,QAAQ,EAAE;MACnC,MAAM;MACN,UAAU,CAACA,MAAK,SAAS,QAAQC,MAAI,GAAG,GAAG,GAAGD,MAAK,WAAW,QAAQ,CAAC,CAAC;IAC1E;EACF;AC3FA,MAAM,cAAoC,CAAC,WAAW,UAAU,WAAW,eAAe,iBAAiB,cAAc,aAAa,aAAa,cAAc,oBAAoB,aAAa,sBAAsB,SAAS,SAAS,kBAAkB,iBAAiB,aAAa,mBAAmB,YAAY,mBAAmB,cAAc,cAAc,oBAAoB,oBAAoB,eAAe,iBAAiB,cAAc,WAAW,eAAe,YAAY,iBAAiB,kBAAkB,OAAO,mBAAmB,UAAU,gBAAgB;AAGpjB,MAAM,mBAAwD,OAAO,YAAY,YAAY,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC;AAGjI,MAAM,eAAoD,EAAE,GAAG,kBAAkB,GAAG,OAAO,YAAY,cAAc,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,EAAE;AC7ClK,MAAM,oBAAoB;AAC1B,MAAM,iBAAiB;AAIvB,MAAM,WAAW;AAmBjB,WAAS,oBAAoB,MAAsB;AACjD,UAAM,QAAQ,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,iBAAiB;AAC7D,WAAO,UAAU,IAAI,IAAI;EAC3B;AAGO,WAAS,OAAO,MAA4B;AACjD,QAAI,QAAQ,oBAAoB,IAAI;AACpC,UAAM,OAAO,MAAc;AACzB,cAAS,QAAQ,oBAAqB;AACtC,cAAQ,QAAQ,MAAM,iBAAiB;IACzC;AACA,WAAO;MACL;MACA,SAAS,CAACyB,MAAKC,SAAQD,QAAOC,OAAMD,QAAO,KAAK;MAChD,UAAU,KAAK;AACb,cAAM,KAAK,KAAK,IAAI,IAAI;AACxB,cAAM,QAAQ,KAAK,IAAI,KAAK,KAAK;AACjC,cAAME,QAAO,KAAK,KAAK,IAAI,KAAK,EAAE;AAClC,YAAI,IAAIA,QAAO,KAAK,IAAI,KAAK;AAC7B,YAAI,IAAI;AACR,YAAI,IAAIA,QAAO,KAAK,IAAI,KAAK;AAC7B,eAAO;MACT;MACA,IAAI,QAAQ;AACV,eAAO;MACT;IACF;EACF;AA2BA,WAAS,aAAa,WAA2B;AAC/C,QAAI,QAAQ,KAAK,MAAM,YAAY,KAAK,UAAU,UAAU;AAC5D,aAAS,UAAU;AACnB,YAAQ,KAAK,KAAK,OAAO,UAAU;AACnC,aAAS,UAAU;AACnB,YAAQ,UAAU,MAAM,iBAAiB,KAAK;EAChD;AAGO,WAAS,UAAU,WAAiC;AACzD,WAAO,OAAO,aAAa,SAAS,CAAC;EACvC;ACvFA,MAAM,QAAoH;IACxH,UAAU,EAAE,MAAM,SAAU,MAAM,SAAU,OAAO,EAAE;IACrD,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG;IACrC,MAAM,EAAE,MAAM,SAAU,MAAM,SAAU,OAAO,EAAE;IACjD,OAAO,EAAE,MAAM,UAAU,MAAM,UAAU,OAAO,EAAE;IAClD,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE;IACpC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE;EACtC;AAEO,WAAS,UAAU,UAAoG;AAC5H,WAAO,MAAM,QAAQ;EACvB;ACRO,MAAM,eAAe,CAAC,SAAU,SAAU,SAAU,OAAQ;AACnE,MAAM,eAAe,CAAC,GAAG,KAAK,MAAM,GAAG;AAGvC,WAAS,UAAU,QAAwB,OAAkB,eAA0B,OAAqB;AAC1G,WAAO,MAAM,UAAU,KAAK,OAAO,EAAE,GAAG,OAAO,KAAK,eAAe,MAAM,GAAG,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,IAAI,SAAU,IAAI,SAAU,GAAG,KAAK,GAAG,MAAM,CAAC;AAChM,aAAS,QAAQ,GAAG,QAAQ,OAAO,OAAO,CAAC,GAAG,QAAS,QAAO,YAAY,EAAE,GAAG,OAAO,KAAK,eAAe,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,MAAO,IAAI,GAAG,GAAG,SAAU,MAAM,EAAE,CAAC;AAClL,WAAO,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,cAAc,CAAC,IAAI,KAAK,MAAM,SAAU,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC;EACvG;AAGO,WAAS,SAAS,QAAwB,OAAkB,eAA0B,KAAa,QAAQ,GAAS;AACzH,QAAI,QAAQ,EAAG,QAAO,UAAU,QAAQ,OAAO,eAAe,KAAK;AACnE,UAAM,SAAS,aAAa,GAAG;AAC/B,UAAM,QAAQ,aAAa,GAAG;AAC9B,WAAO,MAAM,UAAU,KAAK,SAAS,OAAO,EAAE,GAAG,OAAO,KAAK,QAAQ,aAAa,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,OAAO,GAAG,KAAK,CAAC;AAC7L,WAAO,MAAM,UAAU,KAAK,SAAS,OAAO,EAAE,GAAG,OAAO,KAAK,eAAe,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,GAAG,IAAI,OAAO,GAAG,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;AACxM,WAAO,MAAM,UAAU,KAAK,SAAS,OAAO,EAAE,GAAG,OAAO,KAAK,eAAe,MAAM,KAAK,IAAI,CAAC,GAAG,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,MAAM,GAAG,IAAI,OAAO,GAAG,KAAK,CAAC;EACpL;AAKA,WAAS,YAAY,QAAwB,OAAkB,OAAqB;AAClF,WAAO,MAAM,UAAU,KAAK,OAAO,EAAE,GAAG,OAAO,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,UAAU,GAAG,KAAK,GAAG,KAAK,IAAI,GAAG,KAAK,EAAE,CAAC;AAC7K,WAAO,KAAK,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,GAAG,MAAM,KAAK,KAAK,OAAQ,CAAC;AAChE,WAAO,KAAK,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,OAAQ,CAAC;EACnE;AAGO,WAAS,OAAO,QAAwB,UAA0B,OAAkB,QAAmB,QAAQ,GAAG,MAAM,GAAS;AACtI,QAAI,aAAa,QAAS,QAAO,SAAS,QAAQ,OAAO,QAAQ,MAAM,GAAG,KAAK,KAAK;AACpF,QAAI,aAAa,QAAS,QAAO,YAAY,QAAQ,OAAO,KAAK;AACjE,UAAM,OAAO,UAAU,QAAQ;AAC/B,QAAI,KAAK,KAAM,QAAO,MAAM,UAAU,KAAK,OAAO,EAAE,GAAG,OAAO,KAAK,QAAQ,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,KAAK,MAAM,IAAI,SAAU,GAAG,MAAM,GAAG,KAAK,CAAC;AAC/M,QAAI,KAAK,MAAM;AACb,YAAM,OAAO,aAAa,SAAU,CAAC,OAAO,OAAO,IAAI,IAAc,aAAa,UAAW,CAAC,MAAM,MAAO,IAAI,IAAe,CAAC,MAAM,MAAM,IAAI;AAC/I,eAAS,QAAQ,GAAG,QAAQ,OAAO,OAAO,aAAa,SAAS,IAAI,CAAC,IAAI,OAAO,SAAS;AACvF,eAAO,YAAY,EAAE,GAAG,OAAO,KAAK,QAAQ,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,KAAK,MAAM,MAAM,EAAE,CAAC;MACnH;IACF;AACA,QAAI,KAAK,SAAS,OAAO,UAAU,GAAG;AACpC,aAAO,MAAM,UAAU,KAAK,QAAQ,OAAO,EAAE,GAAG,OAAO,KAAK,QAAQ,MAAM,aAAa,UAAU,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,OAAO,IAAI,UAAU,IAAI,UAAU,GAAG,KAAK,KAAK,EAAE,CAAC;AACpM,aAAO,MAAM,OAAO,aAAa,UAAU,IAAI,GAAG,EAAE,GAAG,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC;AAClH,UAAI,aAAa,QAAS,QAAO,MAAM,CAAC,WAAW,OAAO,QAAQ,GAAG,GAAG,UAAU,GAAG,MAAM,CAAC,CAAC;IAC/F;AACA,QAAI,aAAa,QAAS,QAAO,MAAM,OAAO,GAAG,EAAE,GAAG,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,IAAI,UAAU,GAAG,KAAK,IAAI,IAAI,CAAC;AAC3I,QAAI,OAAO,UAAU,GAAG;AACtB,YAAM,OAAO,aAAa,UAAU,OAAO,aAAa,UAAU,OAAO;AACzE,aAAO,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,aAAa,UAAU,UAAW,QAAU,EAAE,GAAG,QAAQ,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC;IACjI;EACF;ACtDA,MAAM,UAAU;AAChB,MAAM,OAAO;AACb,MAAMC,UAAS,CAAC,MAAM,GAAG,GAAG;AAC5B,MAAM,aAAa,CAAC,KAAK,MAAM,IAAI;AACnC,MAAMC,mBAAkB;AACxB,MAAMC,SAAQ;AACd,MAAM,eAAe;AAsBrB,MAAMC,SAAQ,CAAC,OAAe,KAAa,SAA0B,QAAQ,MAAM,MAAM,QAAQ,OAAO,OAAO;AAE/G,WAAS,eAA4B;AACnC,UAAM,SAAsB,CAAC;AAC7B,aAAS,MAAM,GAAG,MAAM,MAAM,OAAO;AACnC,eAAS,SAAS,GAAG,SAAS,SAAS,UAAU;AAC/C,cAAM,OAAO,EAAE,SAAS,OAAO,WAAW,CAAC,KAAK,MAAM,IAAI,OAAO,IAAI,OAAO,MAAM,WAAW,CAAC,CAAC;AAC/F,eAAO,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,QAAQ,OAAU,CAAC;MACjG;IACF;AACA,WAAO;EACT;AAOO,WAAS,uBAAiC;AAC/C,QAAI,SAAS,aAAa;AAC1B,WAAO;MACL,QAAQ;AACN,iBAAS,aAAa;MACxB;MACA,IAAI,MAAM,QAAQ,MAAM;AACtB,cAAM,SAAS,KAAK,OAAO;AAC3B,YAAI,WAAW,OAAO;AACpB,gBAAM,EAAE,GAAG,GAAG,MAAM,IAAI;AACxB,cAAI;AACJ,cAAI,eAAe;AACnB,qBAAW,SAAS,QAAQ;AAC1B,kBAAM,WAAW,KAAK,MAAM,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;AACpD,gBAAI,WAAW,cAAc;AAC3B,6BAAe;AACf,qBAAO;YACT;UACF;AACA,cAAI,CAAC,KAAM;AACX,gBAAM,UAAUA,OAAM,IAAI,KAAK,GAAG,MAAM,GAAG;AAC3C,gBAAM,UAAUA,OAAM,IAAI,KAAK,GAAG,OAAO,IAAI;AAC7C,mBAAS,OAAO,GAAG,OAAOF,kBAAiB,OAAQ,QAAO,KAAK;AAC/D,gBAAM,WAAW,OAAO,QAAQ,GAAG,CAAC;AACpC,gBAAM,YAAY,OAAO,QAAQ,KAAK,GAAG,IAAI;AAC7C,mBAAS,OAAO,GAAG,OAAOA,kBAAiB,OAAQ,QAAO,KAAK;AAC/D,eAAK,MAAM,KAAK,EAAE,GAAG,SAAS,GAAG,SAAS,OAAO,UAAU,UAAU,CAAC;AACtE,iBAAO,KAAK,QAAQ,YAAY,CAACD,QAAO,CAAC,IAAI,GAAG,GAAGA,QAAO,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG;QACtF,WAAW,WAAW,YAAY;AAChC,gBAAM,EAAE,GAAG,EAAE,IAAI;AACjB,qBAAW,SAAS,QAAQ;AAC1B,kBAAM,KAAK,MAAM,IAAI;AACrB,kBAAM,KAAK,MAAM,IAAI;AACrB,kBAAM,SAAS;cACb,IAAI,KAAK,OAAO,QAAQ,KAAK,CAAC;cAC9B,IAAI,OAAO,QAAQ,KAAK,GAAG,IAAI,KAAK;cACpC,IAAI,OAAO,QAAQ,MAAM,IAAI;cAC7B,IAAI,OAAO,QAAQ,IAAI,CAAC;cACxB,IAAI,OAAO,QAAQ,IAAI,CAAC;cACxB,IAAI,OAAO,QAAQ,IAAI,CAAC;cACxB,MAAM;YACR;UACF;QACF;MACF;MACA,MAAM,OAAO,MAAM;AACjB,YAAI,SAAS,SAAU,QAAO;AAC9B,cAAM,IAAI,MAAM,yBAAyB,IAAI,EAAE;MACjD;MACA,OAAO,OAAO,IAAI;AAChB,mBAAW,SAAS,QAAQ;AAC1B,gBAAM,SAAS,MAAM;AACrB,cAAI,CAAC,UAAU,OAAO,KAAM;AAC5B,iBAAO,MAAM,MAAM;AACnB,gBAAM,KAAK,OAAO,KAAK;AACvB,gBAAM,KAAK,OAAO,KAAK;AACvB,gBAAM,SAAS,CAAC,KAAK,OAAO,KAAK;AACjC,gBAAM,SAAS,CAAC,KAAK,OAAO,KAAK;AACjC,gBAAM,SAAS,CAAC,KAAK,OAAO,KAAK;AACjC,cAAI,MAAM,IAAIE,QAAO;AACnB,kBAAM,IAAIA;AACV,mBAAO,MAAM;AACb,mBAAO,MAAM;AACb,mBAAO,MAAM;AACb,mBAAO,MAAM;AACb,mBAAO,MAAM;AACb,mBAAO,MAAM;AACb,gBAAI,KAAK,IAAI,OAAO,EAAE,IAAI,OAAO,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,IAAI,KAAK;AACvE,qBAAO,OAAO;AACd,oBAAM,SAAS,CAAC,IAAI,KAAK,MAAM,MAAM,SAAS,CAAC,IAAI,YAAY,IAAI;AACnE,oBAAM,SAAS,CAAC,IAAI,KAAK,MAAM,MAAM,SAAS,CAAC,IAAI,YAAY,IAAI;YACrE;UACF;QACF;MACF;IACF;EACF;AC1HA,MAAMF,UAAoB,CAAC,KAAK,GAAG,GAAG;AACtC,MAAM,WAAW;AAMV,WAAS,oBAA8B;AAC5C,QAAI,IAAI;AACR,QAAI;AACJ,QAAI,OAAO;AACX,QAAI,OAAO;AACX,WAAO;MACL,QAAQ;AACN,YAAI;AACJ,eAAO;AACP,eAAO;AACP,eAAO;MACT;MACA,IAAI,OAAO,QAAQ,MAAM;AACvB,YAAI,WAAW,UAAU;AACvB,gBAAM,SAAS;AACf,iBAAO,OAAO;AACd,iBAAO,OAAO;QAChB,WAAW,WAAW,QAAQ;AAC5B,cAAI,SAAS,OAAW;AACxB,gBAAM,KAAM,KAAiC;AAC7C,kBAAQ,MAAM;AACd,cAAI,KAAK,IAAI,GAAG,IAAI,OAAO,EAAE;AAC7B,kBAAQ,OAAO;AACf,kBAAQ,KAAK,IAAI,CAAC,KAAK,CAAC;AACxB,cAAI,MAAM,KAAK,OAAO,GAAG;AACvB,mBAAO;AACP,mBAAO,KAAK,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU,IAAI,CAAC;UACrD;QACF;MACF;MACA,MAAM,OAAO,MAAM;AACjB,YAAI,SAAS,WAAY,QAAO,CAACA,QAAO,CAAC,GAAG,GAAGA,QAAO,CAAC,CAAC;AACxD,YAAI,SAAS,OAAQ,QAAO;AAC5B,cAAM,IAAI,MAAM,sBAAsB,IAAI,EAAE;MAC9C;MACA,SAAS;MAAC;IACZ;EACF;AC5BA,MAAM,oBAAoB;AAC1B,MAAM,aAAa;AACnB,MAAM,YAAY;AAClB,MAAM,kBAAkB;AAGjB,WAAS,uBAAiC;AAC/C,QAAI,SAAkB,CAAC;AACvB,QAAI,UAA2B,CAAC;AAChC,WAAO;MACL,QAAQ;AACN,iBAAS,CAAC;AACV,kBAAU,CAAC;MACb;MACA,IAAI,MAAM,QAAQ,MAAM;AACtB,YAAI,WAAW,iBAAiB;AAC9B,gBAAM,EAAE,GAAAI,IAAG,GAAAC,GAAE,IAAI;AACjB,gBAAMC,UAAS,KAAK,OAAO;AAC3B,gBAAM,QAAuB,CAAC;AAC9B,mBAAS,QAAQ,GAAG,QAAQ,iBAAiB,SAAS;AACpD,kBAAM,KAAK,EAAE,GAAGF,KAAI,KAAK,QAAQ,GAAG,GAAGC,KAAI,IAAI,IAAIC,QAAO,QAAQ,IAAI,CAAC,GAAG,IAAIA,QAAO,QAAQ,IAAI,EAAE,GAAG,OAAOA,QAAO,QAAQ,GAAG,CAAC,EAAE,CAAC;UACrI;AACA,kBAAQ,KAAK,KAAK;AAClB;QACF;AACA,YAAI,WAAW,QAAS;AACxB,cAAM,EAAE,GAAG,GAAG,IAAI,IAAI;AACtB,cAAM,SAAS,KAAK,OAAO;AAC3B,cAAM,QAAQ,MAAM,YAAY;AAChC,cAAM,OAA6B,CAAC;AACpC,iBAAS,MAAM,GAAG,MAAM,OAAO,OAAO;AACpC,cAAI,QAAS,MAAM,QAAS,oBAAoB,OAAO,QAAQ,MAAM,GAAG;AACxE,gBAAM,WAA+B,CAAC;AACtC,cAAI,YAAY,MAAM,OAAO,QAAQ,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAI,EAAE;AACrE,iBAAO,YAAY,GAAG;AACpB,kBAAM,SAAS,OAAO,QAAQ,GAAG,EAAE;AACnC,qBAAS,OAAO,QAAQ,OAAO,IAAI;AACnC,qBAAS,KAAK,CAAC,KAAK,IAAI,KAAK,IAAI,QAAQ,KAAK,IAAI,KAAK,IAAI,MAAM,CAAC;AAClE,yBAAa;UACf;AACA,eAAK,KAAK,QAAQ;QACpB;AACA,eAAO,KAAK,EAAE,GAAG,GAAG,MAAM,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;MACzD;MACA,MAAM,OAAO,MAAM;AACjB,YAAI,SAAS,SAAU,QAAO;AAC9B,YAAI,SAAS,UAAW,QAAO;AAC/B,cAAM,IAAI,MAAM,yBAAyB,IAAI,EAAE;MACjD;MACA,SAAS;MAAC;IACZ;EACF;AClEO,WAAS,MAAM,QAAwB,OAAkB,WAAsB,OAAe,QAAuB;AAC1H,aAAS,QAAQ,GAAG,QAAQ,OAAO,OAAO,KAAK,GAAG,SAAS;AACzD,aAAO,YAAY,EAAE,GAAG,OAAO,KAAK,WAAW,MAAM,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,OAAO,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,UAAU,MAAM,GAAG,CAAC;IACpJ;AACA,WAAO,MAAM,UAAU,OAAO,EAAE,GAAG,OAAO,KAAK,WAAW,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,IAAI,CAAC;EACrK;AAGO,WAAS,QAAQ,QAAwB,OAAkB,WAAsB,OAAe,QAAuB;AAC5H,WAAO,MAAM,UAAU,OAAO,EAAE,GAAG,OAAO,KAAK,WAAW,MAAM,UAAU,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,KAAK,OAAO,IAAI,UAAU,IAAI,UAAU,GAAG,KAAK,KAAK,EAAE,CAAC;AACvK,WAAO,MAAM,OAAO,GAAG,EAAE,GAAG,OAAO,MAAM,CAAC,KAAK,IAAI,GAAG,MAAM,MAAM,IAAI,UAAU,IAAI,EAAE,CAAC;EACzF;AAGO,WAAS,OAAO,QAAwB,OAAkB,OAAqB;AACpF,WAAO,MAAM,UAAU,OAAO,EAAE,GAAG,OAAO,GAAG,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,SAAU,GAAG,KAAK,GAAG,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;AAClJ,WAAO,MAAM,UAAU,KAAK,KAAK,QAAQ,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,IAAI,CAAC;EAClK;AChBA,MAAMC,QAAkB,CAAC,MAAM,GAAG,GAAG;AACrC,MAAM,SAAS;AACf,MAAMC,gBAAe,KAAK,KAAK;AAE/B,MAAMC,QAAO,CAAC,MAAc,IAAY,WAA2B,QAAQ,KAAK,QAAQ;AACxF,MAAMN,SAAQ,CAAC,OAAe,KAAa,SAA0B,QAAQ,MAAM,MAAM,QAAQ,OAAO,OAAO;AAOxG,WAAS,yBAAmC;AACjD,QAAI,WAAsBI;AAC1B,QAAI,WAAsB,CAAC,GAAG,GAAG,CAAC;AAClC,QAAI,YAAY;AAChB,QAAI,QAAQ;AACZ,QAAI,OAAO;AACX,QAAI,OAAO;AACX,QAAI,SAAS;AACb,QAAI,YAAuB,CAAC,GAAG,GAAG,CAAC;AAEnC,UAAM,QAAQ,MAAY;AACxB,iBAAWA;AACX,iBAAW,CAAC,GAAG,GAAG,CAAC;AACnB,kBAAY;AACZ,cAAQ;AACR,aAAO;AACP,aAAO;AACP,kBAAY,CAAC,GAAG,GAAG,CAAC;IACtB;AAEA,WAAO;MACL,OAAO;MACP,IAAI,MAAoB,QAAgB,MAAe;AACrD,YAAI,WAAW,UAAU;AACvB,gBAAM;AACN,mBAAU,KAAsC;QAClD,WAAW,WAAW,YAAY;AAChC,iBAAO;AACP,cAAI,OAAQ,YAAW,CAAC,IAAI,GAAG,IAAI;cAC9B,QAAO;QACd,WAAW,WAAW,QAAQ;AAC5B,cAAI,CAAC,KAAM;AACX,gBAAM,EAAE,IAAI,EAAE,IAAI;AAClB,gBAAM,IAAIJ,OAAM,KAAK,IAAI,OAAO,KAAK,GAAG,CAAC;AACzC,cAAI,CAAC,QAAQ;AACX,wBAAYM,MAAK,WAAWD,eAAc,KAAK,CAAC;AAChD,kBAAM,IAAIC,MAAK,SAAS,CAAC,GAAG,MAAM,KAAK,CAAC;AACxC,qBAAS,OAAO,IAAI;AACpB,wBAAY,CAAC,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC;AACjD,uBAAW,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,KAAK,OAAO,IAAI,KAAK,IAAI,UAAU,CAAC,KAAK,OAAO,IAAI,KAAK,SAAS,CAAC,IAAI,UAAU,CAAC,KAAK,OAAO,IAAI,GAAG;AAC1I;UACF;AACA,cAAI,CAACC,KAAIC,KAAIC,GAAE,IAAI;AACnB,cAAI,IAAI,EAAGF,QAAM,IAAI,IAAI;AACzB,gBAAM,UAAU,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,MAAM,EAAE;AAChDA,iBAAM;AACNC,iBAAM;AACNC,iBAAM;AACN,qBAAW,CAACF,KAAIC,KAAIC,GAAE;AACtB,sBAAYH,MAAK,WAAW,CAACD,eAAc,KAAK,EAAE;AAClD,qBAAW,CAAC,SAAS,CAAC,IAAIE,MAAK,IAAID,MAAK,SAAS,CAAC,GAAG,MAAM,KAAK,EAAE,IAAIE,MAAK,IAAI,SAAS,CAAC,IAAIC,MAAK,EAAE;AACpG,cAAI,SAAS,CAAC,IAAI,QAAQ;AACxB,uBAAW,CAAC,QAAQ,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC;AAC5C,uBAAW,CAAC,SAAS,CAAC,IAAI,MAAM,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC;AACxD,iBAAK,OAAO,OAAO,SAAS;AAC5B,oBAAQ,KAAK,QAAQ,UAAU,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;UAC/D;QACF;MACF;MACA,MAAM,OAAO,MAAM;AACjB,gBAAQ,MAAM;UACZ,KAAK;AAAQ,mBAAO;UACpB,KAAK;AAAU,mBAAO;UACtB,KAAK;AAAY,mBAAO;UACxB,KAAK;AAAa,mBAAO;UACzB,KAAK;AAAW,mBAAO,SAAS,CAAC;UACjC,KAAK;AAAc,mBAAO;UAC1B,KAAK;AAAO,mBAAO,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,IAAI,KAAK,KAAK,SAAS,CAAC,IAAI,UAAU,CAAC,IAAI,GAAG;UAC3F,KAAK;AAAQ,mBAAO,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC;UAChE;AAAS,kBAAM,IAAI,MAAM,2BAA2B,IAAI,EAAE;QAC5D;MACF;MACA,SAAS;MAAC;IACZ;EACF;AC9EO,MAAM,aAA4B,EAAE,OAAO,KAAK,QAAQ,KAAK,SAAS,IAAI,MAAM,IAAI,QAAQ,MAAM,QAAQ,IAAI;AAG9G,WAAS,cAAc,UAAiE;AAC7F,UAAM,EAAE,OAAO,QAAQ,SAAS,MAAM,QAAQ,OAAO,IAAI;AACzD,UAAM,KAAK,MAAM,KAAK,EAAE,QAAQ,UAAU,EAAE,GAAG,CAAC,GAAG,WAAY,SAAS,QAAS,UAAU,QAAQ,CAAC;AACpG,UAAM,KAAK,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE,GAAG,CAAC,GAAG,QAAS,MAAM,SAAU,OAAO,SAAS,CAAC;AAC1F,UAAM,WAA+B,CAAC;AAEtC,eAAW,KAAK,CAAC,QAAQ,GAAG,CAAC,QAAQ,CAAC,EAAG,YAAW,KAAK,GAAI,UAAS,QAAQ,GAAG,QAAQ,GAAG,QAAS,UAAS,KAAK,CAAC,GAAG,CAAC,CAAC;AACzH,eAAW,KAAK,CAAC,SAAS,GAAG,CAAC,SAAS,CAAC,EAAG,YAAW,KAAK,GAAI,UAAS,QAAQ,GAAG,QAAQ,GAAG,QAAS,UAAS,KAAK,CAAC,GAAG,CAAC,CAAC;AAC3H,aAAS,OAAO,GAAG,OAAO,GAAG,OAAQ,YAAW,KAAK,GAAI,YAAW,KAAK,GAAI,UAAS,KAAK,CAAC,GAAG,CAAC,CAAC;AACjG,WAAO,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,QAAQ,IAAI,MAAM,CAAU;EACnE;AAaA,MAAI;AAEG,WAAS,oBAAoB,WAA0B,YAAsB;AAClF,UAAM,WAAW,aAAa,aAAc,iBAAA,eAAiB,cAAc,QAAQ,KAAK,cAAc,QAAQ;AAC9G,QAAI,QAAqF,CAAC;AAC1F,WAAO;MACL,QAAQ;AACN,gBAAQ,CAAC;MACX;MACA,IAAI,MAAM,QAAQ,MAAM;AACtB,YAAI,WAAW,OAAQ;AACvB,cAAM,EAAE,GAAG,GAAG,QAAQ,MAAM,IAAI;AAChC,YAAI,UAAU;AACd,mBAAW,CAAC,SAAS,OAAO,KAAK,UAAU;AACzC,cAAI,KAAK,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,QAAQ;AACjD,iBAAK,OAAO,OAAO,KAAK;AACxB;UACF;QACF;AACA,cAAM,KAAK,EAAE,GAAG,GAAG,QAAQ,OAAO,UAAU,QAAQ,CAAC;MACvD;MACA,MAAM,OAAO,MAAM;AACjB,YAAI,SAAS,QAAS,QAAO;AAC7B,cAAM,IAAI,MAAM,wBAAwB,IAAI,EAAE;MAChD;MACA,SAAS;MAAC;IACZ;EACF;AChEA,MAAM,eAAe;AACrB,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,gBAAgB;AACtB,MAAM,gBAAgB;AAOtB,MAAM,SAAS,CAAC,GAAG,GAAG,SAAS,GAAG,GAAG,GAAG,UAAU,GAAG,GAAG,GAAG,OAAO;AAWlE,WAAS,gBAA0B;AACjC,WAAO,MAAM,KAAK,EAAE,QAAQ,aAAa,GAAG,OAAO,EAAE,GAAG,GAAG,GAAG,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,OAAU,EAAE;EACjH;AAUO,WAAS,sBAAsB,SAA4B,QAAkB;AAClF,QAAI,UAAU,cAAc;AAC5B,WAAO;MACP,QAAQ;AACN,kBAAU,cAAc;MAC1B;MACA,IAAI,OAAO,QAAQ,MAAM;AACvB,YAAI,WAAW,SAAS;AACtB,gBAAM,EAAE,OAAO,GAAG,GAAG,OAAO,IAAI;AAChC,iBAAO,OAAO,QAAQ,KAAK,GAAI,EAAE,GAAG,GAAG,OAAO,CAAC;QACjD,WAAW,WAAW,QAAQ;AAC5B,gBAAM,EAAE,OAAO,IAAI,MAAM,IAAI;AAC7B,kBAAQ,KAAK,EAAG,OAAO,EAAE,KAAK,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,MAAM;QACzD,WAAW,WAAW,UAAU;AAC9B,gBAAM,EAAE,OAAO,EAAE,IAAI;AACrB,kBAAQ,KAAK,EAAG,IAAI;QACtB;MACF;MACA,MAAM,OAAO,MAAM,MAAM;AACvB,cAAM,SAAS,QAAQ,KAAK,CAAC,CAAW;AACxC,YAAI,SAAS,IAAK,QAAO,OAAO;AAChC,YAAI,SAAS,IAAK,QAAO,OAAO;AAChC,YAAI,SAAS,aAAc,QAAO,OAAO,SAAS;AAClD,YAAI,SAAS,QAAS,OAAM,IAAI,MAAM,0BAA0B,IAAI,EAAE;AACtE,cAAM,CAAC,QAAQ,QAAQ,MAAM,IAAI,KAAK,CAAC;AACvC,cAAM,UAAU,KAAK,IAAI,OAAO,IAAI,IAAI,SAAS,KAAK,IAAI,OAAO,IAAI,IAAI;AACzE,cAAM,UAAU,KAAK,IAAI,OAAO,IAAI,IAAI,SAAS,KAAK,IAAI,OAAO,IAAI,IAAI,SAAS,OAAO;AACzF,eAAO,CAAC,KAAK,IAAI,OAAO,MAAM,IAAI,UAAU,KAAK,IAAI,OAAO,MAAM,IAAI,SAAS,OAAO,GAAG,SAAS,CAAC,KAAK,IAAI,OAAO,MAAM,IAAI,UAAU,KAAK,IAAI,OAAO,MAAM,IAAI,SAAS,OAAO,CAAC;MACpL;MACA,OAAO,OAAO,IAAI,SAAS;AACzB,gBAAQ,QAAQ,CAAC,QAAQ,UAAU;AACjC,iBAAO,OAAO,KAAK,IAAI,UAAU,MAAM,OAAO,QAAQ,CAAC,CAAE,IAAI;AAC7D,gBAAM,OAAO,OAAO;AACpB,cAAI,CAAC,KAAM;AACX,gBAAM,KAAK,KAAK,MAAM,OAAO;AAC7B,gBAAM,KAAK,KAAK,MAAM,OAAO;AAC7B,gBAAM,WAAW,KAAK,MAAM,IAAI,EAAE;AAClC,cAAI,YAAY,kBAAkB;AAChC,mBAAO,OAAO;AACd;UACF;AACA,gBAAM,OAAO,KAAK,IAAI,UAAU,KAAK,QAAQ,EAAE;AAC/C,iBAAO,KAAM,KAAK,WAAY;AAC9B,iBAAO,KAAM,KAAK,WAAY;AAC9B,iBAAO,SAAS,KAAK,MAAM,IAAI,EAAE;AACjC,iBAAO,MAAM,KAAK,IAAI,KAAK,IAAI,UAAU,KAAK,QAAQ,gBAAgB,OAAO,QAAQ,CAAC,CAAE,CAAC,IAAI;QAC/F,CAAC;MACH;IACF;EACA;AC5EO,MAAM,qBAA+D;IAC1E,SAAS,MAAM,sBAAsB;IACrC,QAAQ,MAAM,qBAAqB;IACnC,QAAQ,MAAM,qBAAqB;IACnC,OAAO,MAAM,oBAAoB;IACjC,UAAU,MAAM,uBAAuB;IACvC,KAAK,MAAM,kBAAkB;EAC/B;ACFA,MAAM,OAAO,MAAY;EAAC;AAEnB,WAAS,iBAA2B;AACzC,UAAM,UAAmB,CAAC;AAC1B,UAAM,QAAiB,CAAC;AACxB,WAAO;MACL,GAAG,MAAM,QAAQ;AACf,cAAM,QAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,GAAG,QAAQ,KAAK;AACrD,cAAM,OAAO;AACb,cAAM,SAAS;AACf,gBAAQ,KAAK,KAAK;MACpB;MACA,OAAO,KAAK;AACV,iBAAS,QAAQ,QAAQ,SAAS,GAAG,SAAS,GAAG,SAAS;AACxD,gBAAM,QAAQ,QAAQ,KAAK;AAC3B,cAAI,CAAC,SAAS,MAAM,OAAO,IAAK;AAChC,gBAAM,SAAS,MAAM;AACrB,kBAAQ,OAAO,OAAO,CAAC;AACvB,gBAAM,SAAS;AACf,gBAAM,KAAK,KAAK;AAChB,iBAAO;QACT;MACF;MACA,QAAQ;AACN,mBAAW,SAAS,SAAS;AAC3B,gBAAM,SAAS;AACf,gBAAM,KAAK,KAAK;QAClB;AACA,gBAAQ,SAAS;MACnB;MACA,IAAI,UAAU;AACZ,eAAO,QAAQ;MACjB;IACF;EACF;AClBO,WAAS,OAAO,OAA+B;AACpD,WAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK,KAAK,OAAO;EACxF;AAGA,MAAM,WAAW,CAAC,UAA2B;AAC7C,MAAM,WAAW,CAAC,UAA2B;AAC7C,MAAM,aAAa;AAEnB,WAASC,MAAK,OAAuB;AACnC,WAAO,QAAQ,IAAI,IAAI,QAAQ,aAAa,aAAa,QAAQ,SAAS,IAAI,IAAI;EACpF;AAEA,WAAS,cAAc,UAA8B,SAAgE;AACnH,UAAM,CAAC,OAAO,GAAG,IAAI,IAAI,SAAS,IAAI,QAAQ;AAC9C,WAAO,KAAK,OAAe,CAAC,OAAO,SAAS,CAAC,QAAQ,MAAM,CAAC,GAAI,KAAK,CAAC,CAAE,GAAG,QAAQ,MAAM,CAAC,GAAI,KAAK,CAAC,CAAE,GAAG,QAAQ,MAAM,CAAC,GAAI,KAAK,CAAC,CAAE,CAAC,GAAG,KAAM;EAChJ;AAEA,WAAS,aAAa,MAAc,MAAmC;AACrE,UAAM,CAAC,OAAO,QAAQ,KAAK,IAAI;AAC/B,YAAQ,MAAM;MACZ,KAAK;AAAU,eAAO,KAAK,IAAI,MAAM,EAAE,KAAK,EAAE;MAC9C,KAAK;AAAO,eAAO,KAAK,OAAe,CAAC,OAAO,SAAS,QAAQ,SAAS,IAAI,GAAG,CAAC;MACjF,KAAK;AAAO,eAAO,SAAS,KAAK,IAAI,SAAS,MAAM;MACpD,KAAK;AAAO,eAAO,KAAK,OAAe,CAAC,OAAO,SAAS,QAAQ,SAAS,IAAI,GAAG,CAAC;MACjF,KAAK;AAAO,eAAO,SAAS,KAAK,IAAI,SAAS,MAAM;MACpD,KAAK;AAAO,eAAO,SAAS,KAAK,IAAI,SAAS,MAAM;MACpD,KAAK;AAAO,eAAO,CAAC,SAAS,KAAK;MAClC,KAAK;AAAO,eAAO,KAAK,IAAI,SAAS,KAAK,CAAC;MAC3C,KAAK;AAAQ,eAAO,KAAK,KAAK,SAAS,KAAK,CAAC;MAC7C,KAAK;AAAO,eAAO,KAAK,IAAI,SAAS,KAAK,CAAC;MAC3C,KAAK;AAAO,eAAO,KAAK,IAAI,SAAS,KAAK,CAAC;MAC3C,KAAK;AAAS,eAAO,KAAK,MAAM,SAAS,KAAK,GAAG,SAAS,MAAM,CAAC;MACjE,KAAK;AAAO,eAAO,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,CAAC;MACjD,KAAK;AAAO,eAAO,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,CAAC;MACjD,KAAK;AAAS,eAAO,KAAK,MAAM,SAAS,KAAK,CAAC;MAC/C,KAAK;AAAQ,eAAO,KAAK,KAAK,SAAS,KAAK,CAAC;MAC7C,KAAK;AAAS,eAAO,KAAK,MAAM,SAAS,KAAK,CAAC;MAC/C,KAAK;AAAS,eAAO,SAAS,KAAK,IAAI,SAAS,MAAM,IAAI,SAAS,MAAM,IAAI,SAAS,KAAK,IAAI,SAAS,KAAK,IAAI,SAAS,KAAK,IAAI,SAAS,KAAK;MACjJ,KAAK;AAAQ,eAAO,SAAS,KAAK,KAAK,SAAS,MAAM,IAAI,SAAS,KAAK,KAAK,SAAS,KAAK;MAC3F,KAAK;AAAQ,eAAOA,MAAK,SAAS,KAAK,CAAC;MACxC,KAAK;AAAM,eAAO,SAAS,KAAK,IAAI,SAAS,MAAM;MACnD,KAAK;AAAM,eAAO,SAAS,KAAK,IAAI,SAAS,MAAM;MACnD,KAAK;AAAM,eAAO,SAAS,KAAK,KAAK,SAAS,MAAM;MACpD,KAAK;AAAM,eAAO,SAAS,KAAK,KAAK,SAAS,MAAM;MACpD,KAAK;AAAM,eAAO,UAAU;MAC5B,KAAK;AAAM,eAAO,UAAU;MAC5B,KAAK;AAAO,eAAO,CAAC;MACpB,KAAK;AAAQ,eAAO,cAAc,MAAM,CAAC,OAAO,SAAS,QAAQ,IAAI;MACrE,KAAK;AAAQ,eAAO,cAAc,MAAM,CAAC,OAAO,SAAS,QAAQ,IAAI;MACrE,KAAK;AAAU,eAAO,SAAS,KAAK,EAAE,IAAI,CAAC,cAAc,YAAY,SAAS,MAAM,CAAC;MACrF,KAAK;AAAS,eAAO,WAAW,SAAS,KAAK,CAAsC;MACpF,KAAK;AAAQ,eAAO,SAAS,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,SAAS;MACjE,KAAK;AAAS,eAAO,SAAS,KAAK,EAAE,IAAI,CAAC,WAAWC,UAAS,aAAa,SAAS,MAAM,EAAEA,KAAI,IAAK,aAAa,SAAS,KAAK,CAAC;MACjI,KAAK;AAAM,eAAO,SAAS,KAAK,EAAE,CAAC;MACnC,KAAK;AAAM,eAAO,SAAS,KAAK,EAAE,CAAC;MACnC,KAAK;AAAM,eAAO,SAAS,KAAK,EAAE,CAAC;MACnC,KAAK,SAAS;AACZ,cAAM,KAAK,SAAS,KAAK,EAAE,CAAC,IAAK,SAAS,MAAM,EAAE,CAAC;AACnD,cAAM,KAAK,SAAS,KAAK,EAAE,CAAC,IAAK,SAAS,MAAM,EAAE,CAAC;AACnD,cAAM,KAAK,SAAS,KAAK,EAAE,CAAC,IAAK,SAAS,MAAM,EAAE,CAAC;AACnD,eAAO,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;MAC9C;MACA,KAAK;AAAQ,eAAO,SAAS,KAAK,EAAE,IAAI,CAAC,WAAWA,UAAUA,UAAS,SAAS,MAAM,IAAI,SAAS,KAAK,IAAI,SAAU;MACtH;AAAS,cAAM,IAAI,MAAM,uBAAuB,IAAI,EAAE;IACxD;EACF;AAGO,WAAS,QAAQ,OAAgB,SAA+B;AACrE,QAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,CAAC,UAAU,QAAQ,OAAO,OAAO,CAAC;AAC7E,QAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAI,CAAC,OAAO,KAAK,EAAG,QAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,OAAO,CAAC,CAAC,CAAC;AACzH,UAAM,OAAO,MAAM,KAAK,CAAC;AACzB,YAAQ,MAAM,GAAG;MACf,KAAK;AAAO,eAAO,QAAQ,OAAO,QAAQ,SAAS,QAAQ,KAAK,CAAC,GAAG,OAAO,CAAC,GAAG,SAAS,QAAQ,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC;MAClH,KAAK;AAAQ,eAAO,QAAQ,OAAO,KAAK;MACxC,KAAK;AAAS,eAAQ,KAAK,CAAC,EAAyB,QAAQ,KAAK;MAClE,KAAK;AAAc,eAAO,QAAQ;MAClC,KAAK;AAAK,eAAO,QAAQ;MACzB,KAAK;AAAM,eAAO,QAAQ;MAC1B,KAAK;AAAS,eAAO,QAAQ;MAC7B,KAAK;AAAW,eAAO,QAAQ;MAC/B,KAAK;AAAS,eAAO,QAAQ;MAC7B,KAAK;AAAa,eAAO,QAAQ;MACjC,KAAK;AAAU,eAAO,QAAQ;MAC9B,KAAK;AAAU,eAAO,QAAQ,OAAO,SAAS,QAAQ,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC;MACxE,KAAK;AAAO,eAAO,QAAQ,UAAU,IAAI,KAAK,CAAC,CAAW;MAC1D,KAAK;AAAM,eAAQ,QAAQ,KAAK,CAAC,GAAG,OAAO,EAAyB,SAAS,QAAQ,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC;MACvG,KAAK;AAAS,eAAO,QAAQ,MAAM,KAAK,CAAC,GAAa,KAAK,CAAC,GAAa,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,UAAU,QAAQ,OAAO,OAAO,CAAC,CAAC;MAC9H,KAAK;AAAkB,eAAO,QAAQ,OAAO;MAC7C,KAAK;AAAiB,eAAO,QAAQ,OAAO,QAAQ,SAAS,QAAQ,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC;MACvF,KAAK;AAAO,eAAO,QAAQ,KAAK,CAAC,GAAG,EAAE,GAAG,SAAS,WAAW,IAAI,IAAI,CAAC,GAAG,QAAQ,WAAW,CAAC,KAAK,CAAC,GAAa,QAAQ,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;MAC9I,KAAK;AAAO,eAAO,QAAQ,QAAQ,KAAK,CAAC,GAAG,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,OAAO;MACjF,KAAK;AAAO,eAAO,KAAK,OAAgB,CAAC,QAAQ,SAAU,SAAS,QAAQ,MAAM,OAAO,IAAI,QAAS,IAAI;MAC1G,KAAK;AAAM,eAAO,KAAK,OAAgB,CAAC,QAAQ,SAAU,SAAS,SAAS,QAAQ,MAAM,OAAO,GAAI,KAAK;MAC1G;AAAS,eAAO,aAAa,MAAM,GAAG,KAAK,IAAI,CAAC,UAAU,QAAQ,OAAO,OAAO,CAAC,CAAC;IACpF;EACF;AC5HA,MAAMC,OAAgB,CAAC,GAAG,GAAG,CAAC;AAC9B,MAAM,OAAkB,CAAC,GAAG,GAAG,CAAC;AAChC,MAAM,kBAAkB;AAWxB,WAAS,YAAY,OAAkC,QAA2C;AAChG,WAAO,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK,MAAM,GAAG,MAAM,CAAC,IAAI,KAAK,KAAK,MAAM,CAAC;EACpE;AAGO,WAAS,SAAS,QAAwB,KAAa,IAAY,QAAmB,QAAgB,QAAgB,UAA2B,CAAC,GAAS;AAChK,UAAM,OAAO,QAAQ,QAAQ;AAC7B,UAAM,aAAa,KAAK,KAAK,MAAM;AACnC,WAAO,KAAK,GAAG,GAAG,KAAK,OAAO,KAAK,QAAQ,IAAI,OAAO;MACpD,GAAG;MAAQ,GAAG;MAAQ,MAAM;MAAM,KAAK,QAAQ,OAAOA;MAAI,MAAM;MAAM,IAAI,CAAC,KAAK,GAAG;MAAG,GAAG;MAAM,MAAM,CAAC,MAAM,IAAI;MAAG,MAAM,YAAY,CAAC,MAAM,GAAG,GAAG,MAAM;MAAG,MAAM;MAAM,IAAI;MAAU,IAAI;MAAU,GAAG;MAAM,IAAI;MAAM,GAAG;IAC3N,EAAE;AACF,WAAO,KAAK,GAAG,GAAG,KAAK,OAAO,KAAK,QAAQ,IAAI,OAAO;MACpD,GAAG;MAAQ,GAAG,SAAS;MAAK,MAAM;MAAM,KAAKA;MAAI,MAAM;MAAK,IAAI,CAAC,KAAK,GAAG;MAAG,MAAM,CAAC,KAAK,GAAG;MAAG,MAAM,YAAY,CAAC,MAAM,GAAG,GAAG,MAAM;MAAG,MAAM;MAAK,IAAI;MAAU,IAAI;MAAU,GAAG;MAAK,IAAI;MAAK,GAAG;IACnM,EAAE;AACF,QAAI,OAAO,UAAU,GAAG;AACtB,aAAO,KAAK,GAAG,GAAG,KAAK,UAAU,KAAK,QAAQ,IAAI,MAAM;AACtD,cAAM,SAAS,KAAK,MAAM,OAAO,OAAO,QAAQ,MAAM,GAAG,GAAG,GAAG,OAAO,OAAO,QAAQ,MAAM,GAAG,CAAC;AAC/F,eAAO,EAAE,GAAG,QAAQ,KAAK,CAAC,QAAQ,GAAG,MAAM,GAAG,KAAKA,MAAI,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,GAAG,QAAQ,MAAM,CAAC,KAAK,GAAG,GAAG,KAAK,MAAM,IAAI,UAAU,IAAI,SAAU,GAAG,MAAM,MAAM,IAAI;MAC3K,CAAC;IACH;AACA,QAAI,QAAQ,QAAS;AACrB,WAAO,KAAK,GAAG,GAAG,KAAK,WAAW,QAAQ,SAAS,MAAM,QAAQ,IAAI,OAAO;MAC1E,GAAG,KAAK,QAAQ,GAAG,MAAM,YAAY,CAAC;MAAG,GAAG,SAAS;MAAK,KAAKA;MAAI,MAAM;MAAM,IAAI,CAAC,KAAK,GAAG;MAAG,GAAG;MAAM,MAAM;MAAM,MAAM,CAAC,KAAK,GAAG;MAAG,MAAM,YAAY,CAAC,KAAK,GAAG,GAAG,MAAM;MAAG,MAAM;MAAG,IAAI,QAAQ,cAAc;MAAU,IAAI;MAAU,GAAG,QAAQ,cAAc;MAAM,IAAI;MAAK,GAAG;IACrR,EAAE;EACJ;AAEA,WAAS,WAAW,QAAwB,OAAkB,OAAqB;AACjF,aAAS,QAAQ,GAAG,QAAQ,OAAO,OAAO,EAAE,GAAG,SAAS;AACtD,YAAM,QAAQ,OAAO,OAAO,KAAK,IAAI;AACrC,YAAM,OAAoB;QACxB,GAAG,KAAK,OAAO,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,GAAG;QAAG,KAAK,CAAC,KAAK,IAAI,KAAK,GAAG,MAAM,KAAK,IAAI,KAAK,CAAC;QAAG,MAAM;QAAM,IAAI,CAAC,GAAG,IAAI,KAAK;QAAG,MAAM;QAAK,MAAM,CAAC,KAAK,GAAG;QAAG,MAAM,CAAC,KAAK,GAAG;QAAG,MAAM;QAAG,IAAI;QAAU,IAAI;QAAU,GAAG;QAAK,IAAI;MACrP;AACA,aAAO,MAAM,UAAU,IAAI;IAC7B;EACF;AAGO,WAAS,QAAQ,QAAwB,OAAkB,OAAe,gBAA2B,WAA0B;AACpI,WAAO,MAAM,CAAC,KAAK,OAAO,GAAG,GAAG,CAAC,GAAG,UAAU,KAAK,OAAO,KAAK,IAAI,MAAM,CAAC;AAC1E,WAAO,OAAO,SAAS,MAAM;AAC7B,WAAO,OAAO,SAAS,OAAO;AAC9B,WAAO,MAAM,OAAO,KAAK,OAAO,EAAE,GAAG,OAAO,GAAG,MAAM,OAAO,IAAI,CAAC,GAAG,IAAI,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,OAAO,MAAM,KAAK,GAAG,MAAM,KAAK,IAAI,UAAU,IAAI,UAAU,IAAI,KAAK,CAAC;AAC/L,WAAO,MAAM,OAAO,KAAK,OAAO,EAAE,GAAG,KAAK,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,KAAKA,MAAI,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,KAAK,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,OAAO,IAAI,KAAK,GAAG,MAAM,KAAK,IAAI,UAAU,IAAI,SAAU,GAAG,IAAI,IAAI,KAAK,CAAC;AAClO,WAAO,KAAK,CAAC,KAAK,OAAO,GAAG,MAAM,CAAC,GAAG,KAAK,IAAI,OAAO,MAAM,QAAQ,CAAC;AACrE,UAAM,WAAW,WAAW,CAAC,eAAe,CAAC,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC;AACtH,WAAO,KAAK,CAAC,KAAK,OAAO,GAAG,GAAG,CAAC,GAAG,KAAK,IAAI,OAAO,MAAM,UAAU,QAAQ,CAAC;AAC5E,WAAO,MAAM,UAAU,KAAK,OAAO,EAAE,GAAG,KAAK,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,MAAM,OAAO,KAAKA,MAAI,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,OAAO,MAAM,KAAK,GAAG,MAAM,KAAK,IAAI,SAAU,IAAI,QAAU,GAAG,KAAK,IAAI,MAAM,GAAG,MAAM,CAAC;AAC5O,eAAW,QAAQ,OAAO,KAAK;AAC/B,QAAI,OAAO,UAAU,EAAG,QAAO,MAAM,UAAU,KAAK,OAAO,EAAE,GAAG,OAAO,KAAKA,MAAI,MAAM,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,KAAK,MAAM,IAAI,UAAU,IAAI,SAAU,GAAG,KAAK,KAAK,EAAE,CAAC;AACnL,aAAS,QAAQ,GAAG,QAAQ,OAAO,OAAO,KAAK,KAAK,GAAG,SAAS;AAC9D,aAAO,YAAY,EAAE,GAAG,OAAO,KAAKA,MAAI,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,aAAa,SAAU,MAAM,EAAE,CAAC;IAC5I;AACA,WAAO,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,QAAQ,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,OAAO,QAAU,EAAE,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC;EAC/H;AClEA,MAAMC,mBAAkB;AAMxB,MAAM,eAAgG;IACpG,OAAO,CAAC,MAAM,GAAG,GAAG,GAAG,IAAI;IAC3B,IAAI,CAAC,KAAK,GAAG,GAAG,GAAG,IAAI;IACvB,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,GAAG;IAC1B,SAAS,CAAC,MAAM,GAAG,IAAI,IAAI,GAAG;EAChC;AAEA,WAAS,aAAa,QAAwB,KAAgB,WAA4B;AACxF,UAAM,OAAO,WAAW,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;AACxD,eAAW,QAAQ,CAAC,IAAI,CAAC,GAAG;AAC1B,YAAM,WAAW,SAAS,MAAM,IAAI;AACpC,eAAS,QAAQ,GAAG,QAAQ,OAAO,OAAO,CAAC,GAAG,SAAS;AACrD,eAAO,MAAM,OAAO,EAAE,GAAG,WAAW,KAAK,MAAM,OAAO,IAAI,GAAG,KAAK,UAAU,MAAM,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,MAAM,MAAM,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,UAAU,IAAI,UAAU,IAAI,EAAE,CAAC;MACjL;AACA,aAAO,MAAM,UAAU,IAAI,EAAE,GAAG,KAAK,KAAK,WAAW,KAAK,UAAU,GAAG,KAAK,CAAC,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,KAAK,GAAG,KAAK,CAAC;IACjM;AACA,aAAS,QAAQ,GAAG,QAAQ,OAAO,OAAO,EAAE,GAAG,SAAS;AACtD,YAAM,QAAQ,OAAO,OAAO,KAAK,IAAIA;AACrC,aAAO,MAAM,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,GAAG,MAAM,KAAK,IAAI,KAAK,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,GAAG,IAAI,CAAC;IAC3P;EACF;AAGO,WAAS,OAAO,QAAwB,QAAoB,KAAgB,WAA4B;AAC7G,UAAM,CAAC,WAAW,QAAQ,OAAO,OAAO,MAAM,IAAI,aAAa,MAAM;AACrE,WAAO,MAAM,OAAO,GAAG,EAAE,GAAG,KAAK,MAAM,CAAC,YAAY,MAAM,YAAY,IAAI,GAAG,MAAM,OAAO,IAAI,UAAU,IAAI,EAAE,CAAC;AAC/G,aAAS,QAAQ,GAAG,QAAQ,OAAO,OAAO,SAAS,CAAC,GAAG,SAAS;AAC9D,aAAO,MAAM,OAAO,EAAE,GAAG,WAAW,KAAK,WAAW,OAAO,OAAO,QAAQ,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,MAAM,YAAY,IAAI,GAAG,MAAM,MAAM,IAAI,UAAU,IAAI,UAAU,IAAI,EAAE,CAAC;IAC7L;AACA,WAAO,MAAM,UAAU,QAAQ,EAAE,GAAG,KAAK,KAAK,WAAW,MAAM,MAAM,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,MAAM,KAAK,OAAO,IAAI,SAAS,CAAC;AACxH,QAAI,WAAW,UAAW,cAAa,QAAQ,KAAK,SAAS;AAC7D,WAAO,MAAM,UAAU,OAAO,EAAE,GAAG,KAAK,KAAK,WAAW,MAAM,MAAM,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,KAAK,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,SAAU,IAAI,SAAU,GAAG,MAAM,GAAG,OAAO,IAAI,KAAK,CAAC;AACrM,WAAO,MAAM,CAAC,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;EAC/C;AAKO,WAAS,OAAO,QAAwB,MAAiB,MAAwB;AACtF,UAAM,OAAO,SAAS,UAAW,CAAC,MAAM,MAAM,IAAI,IAAc,SAAS,OAAQ,CAAC,OAAO,OAAO,IAAI,IAAe,CAAC,OAAO,OAAO,IAAI;AACtI,WAAO,YAAY,EAAE,GAAG,MAAM,KAAK,WAAW,CAAC,KAAK,KAAK,GAAG,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,GAAG,MAAM,GAAG,SAAS,UAAU,WAAW,UAAU,MAAM,IAAI,QAAQ,MAAM,MAAM,GAAG,CAAC;EAChL;AChCO,MAAM,SAAqF;IAChG,WAAW,CAAC,EAAE,OAAO,GAAG,CAAC,OAAO,WAAW,KAAK,KAAK,MAAM,SAAS,QAAQ,OAAoB,WAAwB,KAAe,KAA2B;IAClK,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,UAAU,OAAO,QAAQ,OAAO,GAAG,MAAM,OAAO,QAAQ,UAA4B,OAAoB,QAAqB,OAA6B,GAAyB;IACzM,WAAW,CAAC,EAAE,QAAQ,GAAG,GAAG,CAAC,KAAK,QAAQ,QAAQ,QAAQ,OAAO,MAAM,SAAS,QAAQ,KAAe,IAAI,QAAqB,QAAkB,QAAkB,OAAsC;IAC1M,SAAS,CAAC,EAAE,QAAQ,eAAe,GAAG,CAAC,OAAO,OAAO,SAAS,MAAM,QAAQ,QAAQ,OAAoB,OAAiB,gBAAgB,SAA+B;IACxK,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,QAAQ,KAAK,SAAS,MAAM,OAAO,QAAQ,QAAsB,KAAkB,SAAsB;IAC/H,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,IAAI,MAAM,OAAO,QAAQ,MAAmB,IAAkB;IAC1F,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,OAAO,WAAW,OAAO,MAAM,MAAM,MAAM,QAAQ,OAAoB,WAAwB,OAAiB,MAA4B;IACjK,UAAU,CAAC,EAAE,OAAO,GAAG,CAAC,OAAO,WAAW,OAAO,MAAM,MAAM,QAAQ,QAAQ,OAAoB,WAAwB,OAAiB,MAA4B;IACtK,SAAS,CAAC,EAAE,OAAO,GAAG,CAAC,OAAO,KAAK,MAAM,OAAO,QAAQ,OAAoB,KAAe;EAC7F;ACnBA,MAAM,oBAA+B,CAAC,GAAG,GAAG,EAAE;AAC9C,MAAM,iBAA4B,CAAC,GAAG,GAAG,CAAC;AAC1C,MAAM,gBAAgE;IACpE,OAAO;IAAS,OAAO;IAAS,KAAK;IAAO,MAAM;IAAiB,MAAM;IAAkB,QAAQ;IAAU,OAAO;IAAS,KAAK;IAAO,MAAM;EACjJ;AAiCO,MAAM,iBAAN,MAAqB;IAgB1B,YAA6B,MAAoB;AAApB,oBAAA,MAAA,QAAA,IAAA;AAf7B,oBAAA,MAAS,aAAY,oBAAI,IAAqB,CAAA;AAC9C,oBAAA,MAAA,KAAA;AACA,oBAAA,MAAA,SAAQ,CAAA;AAER,oBAAA,MAAA,SAAQ,KAAA;AACR,oBAAA,MAAA,QAAO,CAAA;AAEP,oBAAA,MAAA,WAAU,CAAA;AACV,oBAAA,MAAA,SAAuB,CAAC,CAAA;AACxB,oBAAA,MAAQ,MAAK,CAAA;AACb,oBAAA,MAAQ,SAAQ,CAAA;AAChB,oBAAA,MAAiB,YAAW,eAAe,CAAA;AAC3C,oBAAA,MAAiB,MAAA;AACjB,oBAAA,MAAiB,SAAA;AAGf,YAAM,WAAW,MAAsB;AACvC,WAAK,OAAO;QACV,QAAQ,KAAK;QACb,QAAQ,KAAK;QACb,WAAW,KAAK;QAChB,IAAI,QAAQ;AAAE,iBAAO,SAAS,EAAE;QAAM;QACtC,IAAI,OAAO;AAAE,iBAAO,SAAS,EAAE;QAAK;QACpC,OAAO,CAAC,SAAS,WAAW,KAAK,SAAS,GAAG,SAAS,MAAM;MAC9D;AACA,WAAK,UAAU;QACb,IAAI,SAAS;AAAE,iBAAO,KAAK,OAAO;QAAO;QACzC,IAAI,QAAQ;AAAE,iBAAO,SAAS,EAAE;QAAM;QACtC,IAAI,OAAO;AAAE,iBAAO,SAAS,EAAE;QAAK;QACpC,IAAI,KAAK;AAAE,iBAAO,SAAS,EAAE;QAAG;QAChC,IAAI,QAAQ;AAAE,iBAAO,SAAS,EAAE;QAAM;QACtC,WAAW,KAAK;QAChB,QAAQ,CAAC,UAAU,KAAK,OAAO,OAAO,KAAK;QAC3C,OAAO,CAACC,WAAU,MAAM,SAAS,KAAK,SAASA,SAAQ,EAAE,MAAM,KAAK,MAAM,MAAM,IAAI;QACpF,IAAI,UAAU;AAAE,iBAAO,KAAK,OAAO;QAAQ;QAC3C,IAAI,QAAQ;AAAE,iBAAO,SAAS,EAAE;QAAM;QACtC,IAAI,YAAY;AAAE,iBAAO,SAAS,EAAE,MAAM,aAAa;QAAkB;QACzE,IAAI,SAAS;AAAE,iBAAO,SAAS,EAAE,MAAM,UAAU;QAAe;QAChE,QAAQ,EAAE,IAAI,WAAW;AAAE,iBAAO,KAAK,KAAK;QAAS,GAAG,SAAS,CAACC,WAAU,KAAK,KAAK,QAAQA,MAAK,EAAE;MACvG;IACF;;IAGA,MAAM,KAAgBC,QAA2B,QAAuB,CAAC,GAAS;AAChF,WAAK,MAAM;AACX,WAAK,QAAQA,UAAS,IAAI,QAAQ,WAAW;AAC7C,WAAK,UAAU;AACf,WAAK,QAAQ;AACb,WAAK,QAAQ;AACb,WAAK,QAAQ;IACf;;IAGA,UAAgB;AACd,YAAM,MAAM,KAAK;AACjB,UAAI,CAAC,IAAK;AACV,WAAK,SAAS,MAAM;AACpB,WAAK,UAAU,MAAM;AACrB,iBAAWF,aAAY,KAAK,KAAK,UAAU,EAAGA,WAAS,MAAM,KAAK,IAAI;AACtE,WAAK,OAAO;AACZ,WAAK,OAAO,MAAM;AAChB,aAAK,QAAQ,IAAI,SAAS,CAAC,CAAC;AAC5B,aAAK,QAAQ,IAAI,QAAQ;MAC3B,CAAC;AACD,WAAK,QAAQ;IACf;;IAGA,KAAK,IAAkB;AACrB,YAAM,MAAM,KAAK;AACjB,WAAK,KAAK;AACV,UAAI,KAAK;AACP,aAAK,QAAQ;AACb,aAAK,WAAW;AAChB,aAAK,OAAO,MAAM;AAChB,eAAK,SAAS,OAAO,KAAK,IAAI;AAC9B,eAAK,QAAQ,IAAI,QAAQ,CAAC,CAAC;QAC7B,CAAC;MACH;AACA,iBAAWA,aAAY,KAAK,KAAK,UAAU,EAAGA,WAAS,OAAO,KAAK,MAAM,IAAI,KAAK,OAAO;IAC3F;;IAGA,IAAI,WAAoB;AACtB,YAAM,MAAM,KAAK;AACjB,UAAI,CAAC,IAAK,QAAO;AACjB,UAAI,IAAI,QAAQ,IAAI,OAAO,EAAG,QAAO,KAAK,QAAQ,IAAI;AACtD,aAAO;IACT;;IAGA,IAAI,SAAiB;AACnB,aAAQ,KAAK,UAAU,IAAI,QAAQ,KAA4B;IACjE;IAEQ,OAAO,QAA0B;AACvC,YAAM,SAAS,KAAK,KAAK;AACzB,YAAM,WAAW,OAAO;AACxB,aAAO,YAAY,KAAK,MAAM;AAC9B,UAAI;AACF,eAAO;MACT,UAAA;AACE,eAAO,YAAY;MACrB;IACF;IAEQ,MAAM,YAA8B;AAC1C,aAAO,QAAQ,YAAY,KAAK,OAAO;IACzC;IAEA,QAAQ,OAAoC;AAC1C,iBAAW,QAAQ,MAAO,MAAK,IAAI,IAAI;IACzC;IAEQ,IAAI,MAAwB;AAClC,YAAM,SAAS,KAAK,KAAK;AACzB,cAAQ,KAAK,IAAI;QACf,KAAK;AAAS,iBAAO,OAAO,MAAM,KAAK,QAAQ,KAAK,MAAM,KAAK,KAAK,GAAa,KAAK,MAAM,KAAK,KAAK,CAAgB;QACtH,KAAK;AAAS,iBAAO,OAAO,MAAM,KAAK,QAAQ,KAAK,MAAM,KAAK,KAAK,CAAgB;QACpF,KAAK;AAAQ,iBAAO,OAAO,KAAK,KAAK,KAAK,KAAK,QAAQ,KAAK,MAAM,KAAK,IAAI,GAAa,KAAK,IAAI,MAAM,KAAK,MAAM,KAAK,KAAK,CAAgB;QAC5I,KAAK;AAAU,iBAAO,OAAO,YAAY,KAAK,MAAM,KAAK,KAAK,CAAgB;QAC9E,KAAK;AAAS,iBAAO,OAAO,MAAM,KAAK,MAAM,KAAK,IAAI,CAA2C;QACjG,KAAK;AAAQ,iBAAO,OAAO,KAAK,KAAK,MAAM,KAAK,IAAI,CAA0C;QAC9F,KAAK;AAAS,iBAAO,OAAO,MAAM,KAAK,MAAM,KAAK,IAAI,CAA2C;QACjG,KAAK;AAAQ,iBAAO,OAAO,SAAS,GAAI,KAAK,MAAM,KAAK,IAAI,CAA8C;QAC1G,KAAK;AAAU,iBAAO,KAAK,aAAa,IAAI;QAC5C,KAAK;AAAc,iBAAO,OAAO,UAAU,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,GAAgB,KAAK,MAAM,KAAK,SAAS,GAAa,KAAK,MAAM,KAAK,IAAI,CAAW;QAChK,KAAK;AAAkB,iBAAO,OAAO,KAAK,KAAK,IAAI,EAAG,YAAY;AAAG;QACrE,KAAK;AAAO,iBAAO,KAAK,IAAI,IAAI;QAChC,KAAK;AAAQ,iBAAO,OAAO,KAAK,KAAK,EAAG,EAAE,QAAQ,gBAAgB,KAAK,KAAK,KAAK,UAAU,IAAI,KAAK,GAAG,GAAG,KAAK,MAAM,KAAK,IAAI,CAAuB;QACrJ,KAAK;AAAM,iBAAO,KAAK,cAAc,IAAI;QACzC,KAAK;AAAQ,iBAAO,KAAK,QAAQ,KAAK,MAAM,KAAK,EAAE,IAAI,KAAK,QAAS,KAAK,aAAa,CAAC,CAAE;QAC1F,KAAK;AAAU,iBAAO,KAAK,OAAO,IAAI;QACtC,KAAK,OAAO;AAAE,eAAK,UAAU,IAAI,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC;AAAG;QAAO;QAC5E,KAAK,UAAU;AAAE,eAAK,UAAU,IAAI,KAAK,MAAM,CAAC,GAAK,KAAK,UAAU,IAAI,KAAK,IAAI,KAA+B,CAAC,GAAI,KAAK,MAAM,KAAK,KAAK,CAAC,CAAC;AAAG;QAAO;QACtJ,KAAK;AAAU,iBAAO,KAAK,SAAS,IAAI;QACxC,KAAK,QAAQ;AAAE,iBAAO,OAAO,OAAO,MAAM,KAAK,MAAM,KAAK,MAAM,CAAC;AAAG;QAAO;QAC3E,KAAK;AAAY,iBAAO,KAAK,KAAK,SAAS,KAAK,EAAE,EAAE,IAAI,KAAK,MAAM,KAAK,QAAQ,KAAK,MAAM,KAAK,IAAI,CAAC;MACvG;IACF;IAEQ,SAAS,MAAmD;AAClE,YAAM,MAAM,KAAK,MAAM,KAAK,GAAG;AAC/B,YAAM,SAAS,KAAK,MAAM,KAAK,MAAM;AACrC,UAAI,KAAK,QAAS,MAAK,KAAK,KAAK,QAAQ,KAAK,MAAM;UAC/C,MAAK,KAAK,KAAK,OAAO,KAAK,MAAM;IACxC;IAEQ,aAAa,MAAmD;AACtE,YAAMG,UAAS,KAAK,KAAK,OAAO;AAChC,iBAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,EAAGA,SAAO,cAAc,GAAgB,CAAC,KAAK,KAAK,MAAM,UAAU;AAChI,iBAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,EAAGA,SAAO,cAAc,GAAgB,CAAC,IAAI,KAAK,MAAM,UAAU;AAC/H,iBAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,EAAGA,SAAO,cAAc,GAAgB,CAAC,IAAI,KAAK,IAAIA,QAAO,cAAc,GAAgB,CAAC,GAAG,KAAK,MAAM,UAAU,CAAW;IAC9L;IAEQ,IAAI,MAAgD;AAC1D,YAAM,OAAO,KAAK,MAAM,KAAK,IAAI;AACjC,eAAS,OAAO,GAAG,QAAQ,KAAK,SAAS,IAAI,OAAQ,MAAK,KAAK,OAAO,OAAO,KAAK;AAClF,WAAK,KAAK,QAAQ,EAAE,KAAK,KAAK,KAAK,MAAM,MAAM,KAAK,KAAK,CAAC;IAC5D;IAEQ,cAAc,MAA+C;AACnE,YAAM,WAAW,KAAK;AACtB,WAAK,SAAS,GAAG,KAAK,MAAM,KAAK,IAAI,GAAa,MAAM;AACtD,cAAM,WAAW,KAAK;AACtB,aAAK,QAAQ;AACb,aAAK,QAAQ,KAAK,KAAK;AACvB,aAAK,QAAQ;MACf,CAAC;IACH;IAEQ,OAAO,MAAmD;AAChE,YAAM,WAAW,KAAK;AACtB,YAAM,QAAQ,KAAK,MAAM,KAAK,KAAK;AACnC,eAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS;AAC1C,aAAK,QAAQ;AACb,aAAK,QAAQ,KAAK,KAAK;MACzB;AACA,WAAK,QAAQ;IACf;EACF;ACzNA,MAAMC,UAAoB,CAAC,GAAG,GAAG,CAAC;AAClC,MAAM,kBAA6B,CAAC,GAAG,GAAG,EAAE;AAC5C,MAAM,wBAAwB;AAE9B,MAAM,kBAAkB;AAoDxB,MAAMC,cAAa,CAAC,WAA8B;AAChD,UAAM,SAAS,cAAc,SAAS,OAAO,WAAW;AACxD,WAAO,CAAC,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;EACtC;AAGA,WAAS,WAAW,KAAgBH,QAAwD;AAC1F,QAAI,OAAOA,WAAU,SAAU,QAAOA;AACtC,UAAM,QAAQ,IAAI,QAAQ,QAAQ,QAAQA,MAAK,KAAK;AACpD,WAAO,SAAS,IAAI,QAAQ;EAC9B;AAGA,WAAS,MAAM,SAAoB,WAA0C;AAC3E,QAAI,CAAC,aAAc,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,EAAI,QAAO;AACrE,WAAO,KAAK,MAAM,UAAU,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,KAAK,MAAM,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC;EACnF;AAMO,WAAS,mBAAmB,SAA4C;AAC7E,UAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,UAAM,YAAY,QAAQ,aAAa;AACvC,UAAM,WAAW,QAAQ,cAAc,CAAC,SAAiB,OAAO,IAAI;AACpE,UAAM,QAAQ,QAAQ,gBAAgB;AACtC,UAAM,UAAqB,CAAC;AAC5B,QAAI,OAAO;AAEX,aAAS,eAA+B;AACtC,YAAM,OAAO,oBAAI,IAAsB;AACvC,aAAO,IAAI,eAAe;QACxB;QACA;QACA,UAAU,CAAC,OAAO;AAChB,cAAIF,YAAW,KAAK,IAAI,EAAE;AAC1B,cAAI,CAACA,WAAU;AACb,kBAAM,OAAO,UAAU,EAAE;AACzB,gBAAI,CAAC,KAAM,OAAM,IAAI,MAAM,gBAAgB,EAAE,EAAE;AAC/CA,wBAAW,KAAK;AAChB,iBAAK,IAAI,IAAIA,SAAQ;UACvB;AACA,iBAAOA;QACT;QACA,WAAW,MAAM,KAAK,OAAO;QAC7B,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;MAClD,CAAC;IACH;AAEA,aAAS,YAAY,OAA2B;AAC9C,YAAM,SAAS,MAAM,SAAS,CAAC,MAAM,OAAO,CAAC,IAAIK,YAAW,MAAM,MAAM,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,IAAIA,YAAW,MAAM,MAAM,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,IAAIA,YAAW,MAAM,MAAM,EAAE,CAAC,CAAC,IAAa,MAAM;AAC7L,aAAO,EAAE,QAAQ,QAAQ,MAAM,QAAQ,KAAK,MAAM,IAAI;IACxD;AAGA,aAAS,QAAQ,OAAgB,QAA0B;AACzD,YAAM,UAAU,OAAO;AACvB,YAAM,SAAS,QAAQ;AACvB,UAAI,MAAM,OAAQ,SAAQ,SAAS,MAAM;AACzC,UAAI;AACF,eAAO;MACT,UAAA;AACE,gBAAQ,SAAS;MACnB;IACF;AAEA,WAAO;MACL,KAAK,IAAI,OAAO,cAAc,CAAC,GAAG;AAChC,cAAM,MAAM,QAAQ,QAAQ,EAAE;AAC9B,YAAI,CAAC,OAAO,QAAQ,UAAU,MAAO,QAAO;AAC5C,cAAM,UAAU,IAAI,WAAW;AAC/B,cAAM,WAAW,aAAa;AAC9B,cAAM,QAAiB;UACrB,QAAQ,EAAE;UACV;UACA,QAAQ,YAAY,SAAS,SAAY,SAAS,YAAY,IAAI,IAAI;UACtE,QAAQ,YAAY;UACpB,QAAQ;UACR,QAAQ,IAAI,UAAUD;UACtB,KAAK,MAAM,SAAS,YAAY,SAAS;UACzC,SAAS,YAAY,YAAY,IAAI,QAAQ,IAAI,OAAO,IAAI,IAAI,OAAO;QACzE;AACA,gBAAQ,KAAK,KAAK;AAClB;UAAQ;UAAO,MACb,SAAS,MAAM,KAAK,WAAW,KAAK,YAAY,KAAK,GAAG;YACtD,WAAW,YAAY,KAAK;YAC5B,GAAI,YAAY,YAAY,EAAE,WAAW,YAAY,UAAU,IAAI,CAAC;YACpE,GAAI,YAAY,SAAS,EAAE,QAAQ,YAAY,OAAO,IAAI,CAAC;UAC7D,CAAC;QACH;AACA,eAAO,MAAM;MACf;MACA,KAAK,QAAQ;AACX,cAAM,QAAQ,QAAQ,UAAU,CAAC,UAAU,MAAM,WAAW,MAAM;AAClE,YAAI,SAAS,EAAG,SAAQ,OAAO,OAAO,CAAC;MACzC;MACA,OAAO,IAAI;AACT,iBAAS,QAAQ,QAAQ,SAAS,GAAG,SAAS,GAAG,SAAS;AACxD,gBAAM,QAAQ,QAAQ,KAAK;AAC3B,gBAAM,WAAW,MAAM;AACvB,mBAAS,QAAQ,EAAE,GAAG,SAAS,OAAO,WAAW,YAAY,KAAK,EAAE;AACpE,kBAAQ,OAAO,MAAM,SAAS,KAAK,EAAE,CAAC;AACtC,cAAI,SAAS,QAAQ,MAAM,QAAS,SAAQ,OAAO,OAAO,CAAC;QAC7D;MACF;MACA,QAAQ;AACN,gBAAQ,SAAS;MACnB;MACA,IAAI,SAAS;AACX,eAAO,QAAQ;MACjB;MACA,KAAK,CAAC,OAAO,MAAM,QAAQ;MAC3B,KAAK,MAAM,OAAO,KAAK,QAAQ,OAAO;IACxC;EACF;AC1IO,MAAM,eAAe;AACrB,MAAM,cAAc;AAC3B,MAAM,sBAAsB;AAC5B,MAAM,kBAAuB,CAAC,GAAG,MAAM,IAAI;AAC3C,MAAM,YAAY;AAEX,WAAS,kBAA6B;AAC3C,WAAO;MACL,OAAO,MAAM,KAAK,EAAE,QAAQ,aAAa,GAAG,OAAO,EAAE,GAAG,GAAG,GAAG,KAAK,GAAG,GAAG,UAAU,IAAI,MAAM,GAAG,MAAM,GAAG,GAAG,GAAG,OAAO,SAAS,mBAAmB,GAAG,OAAO,GAAG,WAAW,EAAE,EAAE;MAC9K,MAAM,MAAM,KAAK,EAAE,QAAQ,YAAY,GAAG,OAAO,EAAE,GAAG,GAAG,GAAG,KAAK,GAAG,GAAG,UAAU,IAAI,WAAW,EAAE,EAAE;MACpG,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,OAAO,CAAC,GAAG,KAAK,GAAG,GAAG,WAAW,EAAE;MAC7D,QAAQ;IACV;EACF;AAEO,WAAS,eAAe,MAAuB;AACpD,eAAW,SAAS,KAAK,OAAO;AAC9B,YAAM,IAAI;AACV,YAAM,QAAQ;AACd,YAAM,YAAY;IACpB;AACA,SAAK,SAAS;EAChB;AAaO,WAAS,WAAW,MAAiB,MAA4B;AACtE,UAAM,QAAQ,KAAK,MAAM,KAAK,WAAW,KAAK,MAAM,MAAM;AAC1D,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK;AACf,UAAM,WAAW,KAAK;AACtB,UAAM,OAAO,KAAK;AAClB,UAAM,OAAO,KAAK;AAClB,UAAM,IAAI;AACV,UAAM,QAAQ,SAAS,KAAK,KAAK;EACnC;AAkBA,WAAS,YAAY,OAAgC,MAAgD;AACnG,QAAI,OAA4B;AAChC,eAAW,QAAQ,OAAO;AACxB,UAAI,SAAS,KAAM;AACnB,UAAI,SAAS,QAAQ,KAAK,IAAI,KAAK,EAAG,QAAO;IAC/C;AACA,WAAO;EACT;AAEA,WAAS,kBAAkB,MAAiB,MAAoC;AAC9E,QAAI,YAA+B;AACnC,eAAW,SAAS,KAAK,OAAO;AAC9B,YAAM,KAAK,KAAK;AAChB,YAAM,MAAM,MAAM,IAAI,MAAM;AAC5B,YAAM,QAAQ,MAAM,IAAI,MAAM,QAAQ,MAAM,IAAI,YAAY,IAAI,KAAK,IAAI,IAAI,KAAK,GAAG,MAAM,OAAO,OAAO,KAAK,IAAI,MAAM,IAAI,EAAE,KAAK;AACnI,YAAM,QAAQ;AACd,YAAM,YAAY,QAAQ,KAAK;AAC/B,UAAI,SAAS,WAAW,SAAS,GAAI,aAAY;IACnD;AACA,WAAO;EACT;AAGO,WAAS,aAAa,MAAiB,MAAuB;AACnE,UAAM,YAAY,kBAAkB,MAAM,IAAI;AAC9C,UAAM,aAAa,WAAW,SAAS;AACvC,UAAM,QAAQ,YAAY,KAAK,OAAO,IAAI;AAC1C,UAAM,SAAS,YAAY,KAAK,OAAO,KAAK;AAC5C,UAAM,UAAU,CAAC,OAAO,MAAM;AAC9B,aAAS,QAAQ,GAAG,QAAQ,aAAa,SAAS;AAChD,YAAM,OAAO,QAAQ,KAAK;AAC1B,YAAM,QAAQ,KAAK,KAAK,KAAK;AAC7B,UAAI,CAAC,MAAM;AACT,cAAM,YAAY;AAClB;MACF;AACA,YAAM,IAAI,KAAK;AACf,YAAM,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG;AAC7C,YAAM,IAAI,KAAK;AACf,YAAM,aAAa,MAAM,KAAK,IAAI,QAAQ,OAAO,OAAO,KAAK,IAAI,KAAK,QAAQ,KAAK,QAAQ,CAAC,IAAI,MAAM,KAAK,IAAI,KAAK,QAAQ,EAAE,KAAK,KAAK;AACxI,YAAM,WAAW,KAAK,KAAK,IAAI;IACjC;AACA,QAAI,aAAa,aAAa,MAAM;AAClC,WAAK,KAAK,IAAI,UAAU;AACxB,WAAK,KAAK,IAAI,UAAU;AACxB,WAAK,KAAK,IAAI,UAAU;AACxB,WAAK,KAAK,MAAM,CAAC,IAAI,oBAAoB,UAAU,MAAM,CAAC,CAAC;AAC3D,WAAK,KAAK,MAAM,CAAC,IAAI,oBAAoB,UAAU,MAAM,CAAC,CAAC;AAC3D,WAAK,KAAK,MAAM,CAAC,IAAI,oBAAoB,UAAU,MAAM,CAAC,CAAC;AAC3D,WAAK,KAAK,YAAY,aAAa,OAAO,KAAK;IACjD,WAAW,OAAO;AAChB,WAAK,KAAK,IAAI,MAAM;AACpB,WAAK,KAAK,IAAI,MAAM,IAAI;AACxB,WAAK,KAAK,IAAI,MAAM;AACpB,WAAK,KAAK,MAAM,CAAC,IAAI,gBAAgB,CAAC;AACtC,WAAK,KAAK,MAAM,CAAC,IAAI,gBAAgB,CAAC;AACtC,WAAK,KAAK,MAAM,CAAC,IAAI,gBAAgB,CAAC;AACtC,WAAK,KAAK,aAAa,OAAO,MAAM,IAAI,QAAQ,MAAM;IACxD,MAAO,MAAK,KAAK,YAAY;EAC/B;ACnKO,MAAM,WAAqB,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE,GAAG,QAAQ,CAAC,GAAG,KAAK,KAAK,GAAG,GAAG,cAAc,EAAE;AAM9F,WAAS,SAAS,OAAiB,UAAkB,cAA8B;AACxF,UAAM,YAAY,WAAW,eAAe,MAAM;AAClD,QAAI,YAAY,MAAM,MAAM,CAAC,EAAG,QAAO,MAAM,OAAO,CAAC;AACrD,QAAI,YAAY,MAAM,MAAM,CAAC,EAAG,QAAO,MAAM,OAAO,CAAC;AACrD,QAAI,YAAY,MAAM,MAAM,CAAC,EAAG,QAAO,MAAM,OAAO,CAAC;AACrD,WAAO,MAAM,OAAO,CAAC;EACvB;ACgDA,MAAM,cAAc;AACpB,MAAM,kBAAkB;AACxB,MAAM,aAAa,CAAC,SAAU,OAAQ;AAE/B,WAAS,kBAA6B;AAC3C,UAAM,UAAkB,CAAC;AACzB,QAAI,UAAU;AACd,QAAI,aAAa;AACjB,UAAM,YAAY,oBAAI,IAAgC;AACtD,WAAO;MACL;MACA,IAAI,UAAU;AACZ,eAAO;MACT;MACA,IAAI,aAAa;AACf,eAAO;MACT;MACA,MAAM;MACN,IAAI,MAAM;AACR,gBAAQ,KAAK,IAAI;AACjB,YAAI,KAAK,SAAS,QAAS;AAC3B;AACA,mBAAW,YAAY,UAAW,UAAS,EAAE,MAAM,OAAO,KAAK,CAAC;MAClE;MACA,QAAQ;AACN,gBAAQ,SAAS;AACjB,qBAAa;AACb,aAAK,OAAO;AACZ;AACA,mBAAW,YAAY,UAAW,UAAS,EAAE,MAAM,QAAQ,CAAC;MAC9D;MACA,UAAU,UAAU;AAClB,kBAAU,IAAI,QAAQ;AACtB,eAAO,MAAM;AACX,oBAAU,OAAO,QAAQ;QAC3B;MACF;IACF;EACF;AAEA,WAAS,SAAS,OAA0B;AAC1C,WAAO,MAAM,SAAS;EACxB;AAGO,WAAS,UAAU,OAAkB,QAAsB,GAAW,GAAW,QAAsB;AAC5G,UAAM,UAAU,KAAK,MAAM,OAAO,KAAK,IAAI,eAAe;AAC1D,UAAM,OAAO,OAAO,SAAS,KAAK,IAAI;AACtC,UAAM,WAAW,OAAO,KAAK,IAAI;AACjC,UAAM,IAAI,EAAE,MAAM,UAAU,GAAG,GAAG,QAAQ,SAAS,MAAM,SAAS,CAAC;EACrE;AAEA,WAAS,YAAY,OAAkB,QAAiC,QAAsB,GAAW,GAAW,QAAsB;AACxI,UAAM,QAAQ,KAAK,MAAM,IAAI,SAAS,CAAC;AACvC,aAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS;AAC1C,YAAM,QAAS,QAAQ,QAAS,KAAK,KAAK,IAAI,OAAO,QAAQ,OAAO,IAAI;AACxE,YAAM,WAAW,SAAS,OAAO,QAAQ,MAAM,GAAG;AAClD,YAAM,OAAO,OAAO,QAAQ,MAAM,IAAI,IAAI,KAAK,IAAI,KAAK,MAAM,SAAS,GAAG;AAC1E,YAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI;AACjC,YAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI;AACjC,YAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,YAAM,QAAQ,WAAW,OAAO,KAAK,IAAI,MAAM,IAAI,CAAC;AACpD,YAAM,QAAQ,OAAO,QAAQ,MAAM,GAAG;AACtC,YAAM,QAAQ,OAAO,QAAQ,MAAM,GAAG;AACtC,YAAM,IAAI;QACR,MAAM;QACN,GAAG;QACH,IAAI,QAAQ,SAAS,IAAI,EAAE,KAAK,KAAK,OAAO;QAC5C,GAAG;QACH,OAAO,CAAC,OAAO,GAAG,OAAO,MAAM,OAAO,GAAG;QACzC,UAAU,CAAC,OAAO,OAAO,KAAK;QAC9B;QACA;MACF,CAAC;IACH;EACF;AAGO,WAAS,UAAU,OAAkB,QAAiC,QAAsB,MAAqF;AACtL,YAAQ,KAAK,QAAQ,KAAK,GAAG,KAAK,GAAG,KAAK,QAAQ,KAAK,KAAK;AAC5D,QAAI,CAAC,KAAK,MAAO;AACjB,UAAM,WAAW,OAAO,KAAK,IAAI;AACjC,UAAM,IAAI,EAAE,MAAM,QAAQ,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,QAAQ,KAAK,SAAS,MAAM,MAAM,OAAO,SAAS,CAAC;AACnG,gBAAY,OAAO,QAAQ,QAAQ,KAAK,GAAG,KAAK,GAAG,KAAK,MAAM;EAChE;AAGO,WAAS,cAAc,OAAkB,QAAiC,QAAsB,MAAsD;AAC3J,QAAI,MAAM,aAAa,YAAa;AACpC,UAAM,KAAK,QAAQ,SAAS,KAAK,GAAG,KAAK,CAAC,KAAK,KAAK,OAAO,SAAS,KAAK,IAAI;AAC7E,UAAM,SAAS,KAAK,SAAS,OAAO,QAAQ,KAAK,GAAG;AACpD,UAAM,SAAS,KAAK,SAAS,OAAO,QAAQ,KAAK,CAAC;AAClD,UAAM,IAAI,EAAE,MAAM,SAAS,GAAG,KAAK,GAAG,GAAG,GAAG,KAAK,GAAG,QAAQ,QAAQ,UAAU,OAAO,KAAK,IAAI,EAAE,CAAC;EACnG;ACzJO,WAAS,eAAe,UAAqC;AAClE,WAAO,IAAI,YAAkB,UAAU,OAAO,EAAE,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,EAAE,EAAE;EAClI;AAEA,WAASE,WAAUC,OAAY,IAAqB;AAClDA,UAAK,KAAK;AACV,WAAOA,MAAK,KAAKA,MAAK,OAAO;EAC/B;AAGO,WAAS,YAAY,MAAyB,IAAkB;AACrE,SAAK,QAAQD,YAAW,EAAE;EAC5B;AAEO,WAAS,UAAU,MAAyB,MAA6B;AAC9E,UAAMC,QAAO,KAAK,QAAQ;AAC1BA,UAAK,IAAI,KAAK;AACdA,UAAK,IAAI,KAAK;AACdA,UAAK,KAAK,KAAK;AACfA,UAAK,OAAO,KAAK;AACjBA,UAAK,KAAK,KAAK;AACfA,UAAK,KAAK,KAAK;AACfA,UAAK,KAAK,KAAK;AACfA,UAAK,IAAI,KAAK;AACdA,UAAK,OAAO,KAAK;AACjBA,UAAK,IAAI;AACTA,UAAK,OAAO,KAAK;AACjB,WAAOA;EACT;ACbA,MAAM,mBAAmB;AACzB,MAAM,uBAAuB;AAC7B,MAAM,qBAAqB;AAC3B,MAAM,YAAY;AAClB,MAAM,eAAe;AACrB,MAAM,iBAAiB;AAEhB,WAAS,gBAAgB,UAAsC;AACpE,WAAO,IAAI,YAAmB,UAAU,OAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,KAAK,kBAAkB,YAAY,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,EAAE,EAAE;EAC3K;AAEO,WAAS,WAAW,MAA0B,MAA+G;AAClK,UAAM,QAAQ,KAAK,QAAQ;AAC3B,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK;AACf,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,KAAK;AAChB,UAAM,IAAI;AACV,UAAM,MAAM,KAAK,YAAY;AAC7B,UAAM,aAAa;AACnB,UAAM,aAAa;AACnB,UAAM,YAAY;AAClB,UAAM,YAAY;AAClB,WAAO;EACT;AAEA,WAAS,UAAU,OAAwB,OAAc,OAAe,IAAY,KAAmB;AACrG,eAAWC,SAAQ,OAAO;AACxB,UAAIA,MAAK,QAAQA,MAAK,IAAI,eAAgB;AAC1C,YAAM,KAAKA,MAAK,IAAI,MAAM;AAC1B,YAAM,KAAKA,MAAK,IAAI,MAAM;AAC1B,YAAM,WAAW,KAAK,MAAM,IAAI,EAAE,IAAI;AACtC,UAAI,KAAK,IAAI,WAAW,KAAK,IAAI,aAAaA,MAAK,IAAI,cAAc;AACnE,cAAM,WAAW,IAAI,MAAM,IAAI;AAC/BA,cAAK,MAAO,KAAK,WAAY,WAAW;AACxCA,cAAK,MAAO,KAAK,WAAY,WAAW;MAC1C;IACF;EACF;AAGO,WAAS,aAAa,MAA0B,OAAwB,IAAkB;AAC/F,aAAS,QAAQ,KAAK,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS;AAC3D,YAAM,QAAQ,KAAK,MAAM,KAAK;AAC9B,YAAM,KAAK;AACX,YAAM,MAAM,MAAM,IAAI,MAAM;AAC5B,YAAM,YAAY,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI,oBAAoB,GAAG,CAAC;AACjF,YAAM,aAAa,KAAK,IAAI,MAAM,MAAM,KAAK,SAAS;AACtD,YAAM,aAAa,KAAK,IAAI,GAAG,IAAI,MAAM,IAAI,kBAAkB,IAAI;AACnE,YAAM,WAAW,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,GAAG,GAAG,GAAG;AACvD,YAAM,YAAY,KAAK,IAAI,MAAM,MAAM,KAAK,QAAQ;AACpD,YAAM,YAAY,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI;AACzC,gBAAU,OAAO,OAAO,MAAM,KAAK,UAAU,IAAI,GAAG;AACpD,UAAI,OAAO,EAAG,MAAK,SAAS,KAAK;IACnC;EACF;AC9BA,MAAM,gBAAgB;AACtB,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAC5B,MAAM,0BAA0B;AAChC,MAAM,yBAAyB;AAC/B,MAAM,sBAAsB;AAC5B,MAAM,cAAc,CAAC,SAAU,OAAQ;AACvC,MAAM,UAAU,WAAW;AAE3B,WAASC,MAAQ,QAAsB,OAAwB;AAC7D,WAAO,MAAM,KAAK,MAAM,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;EACvD;AAEA,WAAS,aAAa,SAAwB;AAC5C,UAAM,EAAE,MAAM,KAAK,GAAG,GAAG,GAAG,KAAK,IAAI;AACrC,QAAI,CAAC,KAAK,OAAO,MAAO;AACxB,UAAMC,SAAQ,IAAI;AAClB,UAAM,QAAQ,EAAE,GAAG,GAAG,IAAI,OAAO,KAAK,GAAG,OAAOA,OAAM,SAAS,iBAAiB,KAAK,WAAW,IAAI,UAAU,MAAM,KAAK,MAAMA,OAAM,QAAQ,oBAAoB,OAAOA,OAAM,SAAS,oBAAoB;AAC3M,SAAK,OAAO,QAAQ,KAAK;AACzB,eAAW,KAAK,QAAQ,KAAK;AAC7B,SAAK,QAAQ;AACb,UAAM,WAAWA,OAAM,aAAa;AACpC,YAAQ,MAAM,EAAE,GAAG,GAAG,IAAI,OAAO,KAAK,GAAG,GAAG,OAAO,KAAK,IAAI,OAAO,KAAK,GAAGA,OAAM,aAAa,yBAAyB,MAAM,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC;AACvK,QAAI,CAAC,SAAU,SAAQ,MAAM,EAAE,GAAG,GAAG,IAAI,OAAO,KAAK,GAAG,GAAG,OAAO,KAAK,IAAI,OAAO,KAAK,GAAG,KAAK,MAAM,IAAI,OAAO,MAAM,KAAK,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC;AAC/J,QAAI,KAAK,cAAe;AACxB,UAAM,WAAW,QAAQ;AACzB,UAAMC,UAAS,KAAK;AACpB,QAAI,WAAW,IAAI;AACjBA,cAAO,QAAQ,KAAK,IAAIA,QAAO,QAAQ,WAAW,IAAI,SAAS,IAAI,WAAW,GAAG;AACjFA,cAAO,aAAa,WAAW,OAAO;IACxC;AACA,QAAI,YAAY,WAAW,IAAI;AAC7BA,cAAO,QAAQ,KAAK,IAAIA,QAAO,OAAO,CAAC;AACvCA,cAAO,aAAa;IACtB;EACF;AAEA,WAAS,iBAAiB,SAAwB;AAChD,UAAM,EAAE,MAAM,KAAK,QAAQ,GAAG,GAAG,GAAG,MAAM,OAAO,UAAU,IAAI;AAC/D,QAAI,CAAC,KAAK,OAAO,QAAQ,CAAC,IAAI,UAAW;AACzC,UAAM,QAAQ,KAAK,MAAM,IAAI,YAAY,KAAK,IAAI,OAAO,IAAI,CAAC;AAC9D,UAAM,OAAO,IAAI,SAAS;AAC1B,UAAM,OAAO,IAAI,QAAQ;AACzB,aAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS;AAC1C,YAAM,IAAI,OAAO,UAAU,OAAO;AAClC,QAAE,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC,IAAI,MAAM,OAAO,KAAK,IAAI,EAAE,CAAC,IAAI,MAAM;AAChE,UAAI,UAAW,WAAU,UAAU,GAAG,WAAW,IAAI,iBAAiB,GAAG,CAAC;AAC1E,YAAM,QAAQ,OAAO,OAAO,QAAQ,KAAK,GAAG,KAAK,OAAO,OAAO;AAC/D,YAAM,KAAK,OAAO,OAAO,QAAQ,MAAM,IAAI;AAC3C,YAAM,KAAK,OAAO,OAAO,QAAQ,MAAM,IAAI;AAC3C,YAAM,OAAO,OAAO,QAAQ,IAAI,MAAM,OAAO,KAAK,IAAI,MAAM,IAAI;AAChE,YAAM,KAAK,OAAO,QAAQ,MAAM,IAAI,IAAI;AACxC,YAAM,KAAK,OAAO,OAAO,QAAQ,KAAK,GAAG,KAAK,IAAI,iBAAiB,KAAK,OAAO,QAAQ,MAAM,IAAI;AACjG,cAAQ,MAAM,QAAQ;QACpB,GAAG,IAAI,EAAE,IAAI,OAAO;QAAM,GAAG,IAAI,OAAO,OAAO,EAAE,IAAI,OAAO;QAAK,GAAG,IAAI,EAAE,IAAI,OAAO;QACrF,IAAI,EAAE,IAAI;QAAO,IAAI,EAAE,IAAI,SAAS,OAAO,OAAO,MAAM,OAAO;QAAM,IAAI,EAAE,IAAI;QAC/E,IAAI,OAAO;QAAM;QAAI;QAAI,IAAI;QAAG;QAAM;QAAI;QAAI,MAAM,OAAO,MAAM;QAAK,MAAM,OAAO,MAAM;QAAK,OAAO,QAAQ;QAAY,MAAM;MACjI,CAAC;IACH;EACF;AAEA,WAAS,aAAa,SAAwB;AAC5C,UAAM,EAAE,MAAM,KAAK,QAAQ,GAAG,GAAG,GAAG,MAAM,MAAM,IAAI;AACpD,QAAI,CAAC,KAAK,OAAO,SAAS,CAAC,IAAI,MAAM,MAAO;AAC5C,UAAM,QAAQ,KAAK,MAAM,IAAI,MAAM,QAAQ,KAAK,IAAI,OAAO,GAAG,CAAC;AAC/D,aAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS;AAC1C,YAAM,IAAI,OAAO,UAAU,OAAO;AAClC,QAAE,IAAI,KAAK,IAAI,EAAE,CAAC;AAClB,YAAMC,MAAK,OAAO,OAAO,QAAQ,KAAK,GAAG;AACzC,YAAM,KAAK,OAAO,OAAO,QAAQ,MAAM,IAAI;AAC3C,YAAM,KAAK,OAAO,OAAO,QAAQ,MAAM,GAAG;AAC1C,YAAM,OAAO,OAAO,QAAQ,IAAI,MAAM,OAAO,KAAK,IAAI,MAAM,OAAO,GAAG;AACtE,cAAQ,MAAM,QAAQ;QACpB,GAAG,IAAI,EAAE,IAAI,OAAO;QAAK,GAAG,IAAI,OAAO,MAAM,EAAE,IAAI,OAAO;QAAK,GAAG,IAAI,EAAE,IAAI,OAAO;QACnF,IAAI,EAAE,IAAI,OAAO;QAAK,IAAAA;QAAI,IAAI,EAAE,IAAI,OAAO;QAAK,IAAI,OAAO;QAAM;QAAI;QAAI,IAAI;QAAG;QAAM,IAAI;QAAM,IAAI;QAAM,MAAM;QAAG,MAAM;QAAM,OAAO,QAAQ;QAAY,MAAM,IAAI,MAAM,QAAQ;MACpL,CAAC;IACH;EACF;AAEA,WAAS,aAAa,SAAwB;AAC5C,UAAM,EAAE,MAAM,KAAK,GAAG,GAAG,GAAG,MAAM,MAAM,IAAI;AAC5C,QAAI,CAAC,KAAK,OAAO,SAAS,IAAI,UAAU,SAAS,EAAE,QAAQ,MAAO;AAClE,UAAM,WAAW,IAAI,QAAQ,IAAI,MAAM,WAAW;AAClD,UAAM,OAAO,EAAE,GAAG,GAAG,IAAI,OAAO,KAAK,GAAG,aAAa,IAAI,SAAS,KAAK,cAAc,IAAI,SAAS,KAAK,SAAS;AAChH,SAAK,OAAO,QAAQ,IAAI;AACxB,eAAW,KAAK,QAAQ,IAAI;EAC9B;AAEA,WAAS,YAAY,SAAwB;AAC3C,UAAM,EAAE,MAAM,KAAK,QAAQ,GAAG,GAAG,MAAM,MAAM,IAAI;AACjD,QAAI,CAAC,KAAK,OAAO,SAAS,CAAC,IAAI,KAAK,SAAS,EAAE,QAAQ,MAAO;AAC9D,UAAM,QAAQ,KAAK,MAAM,IAAI,KAAK,QAAQ,KAAK;AAC/C,UAAM,QAAQ,eAAe,IAAI,KAAK,KAAK;AAC3C,UAAM,OAAO,IAAI;AACjB,aAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS;AAC1C,UAAI,QAAQ,OAAO,KAAK,IAAI,KAAK,KAAK;AACtC,UAAI,KAAM,SAAQ,UAAU,OAAO,IAAI,OAAO,QAAQ,CAAC,KAAK,MAAM,KAAK,IAAI;AAC3E,YAAM,QAAQ,OAAO,QAAQ,KAAK,CAAC,IAAI,IAAI,UAAU,OAAO,MAAM;AAClE,YAAMA,MAAK,OAAO,QAAQ,KAAK,GAAG;AAClC,YAAM,KAAK,OAAO,OAAO,QAAQ,KAAK,GAAG;AACzC,YAAM,KAAK,OAAO,OAAO,QAAQ,KAAK,IAAI;AAC1C,YAAM,OAAO,OAAO,QAAQ,KAAK,CAAC;AAClC,cAAQ,MAAM,QAAQ;QACpB,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI;QAAK,GAAG;QAAM,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI;QAChE,IAAI,KAAK,IAAI,KAAK,IAAI;QAAO,IAAAA;QAAI,IAAI,KAAK,IAAI,KAAK,IAAI;QAAO,IAAI,OAAO;QAAK;QAAI;QAAI,IAAI;QAAG;QAAM,MAAM;QAAK,MAAM;QAAK;QAAO,MAAM;MACxI,CAAC;IACH;EACF;AAGA,WAAS,UAAU,SAA0B;AAC3C,UAAM,OAAO,QAAQ,IAAI;AACzB,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO,QAAQ,YAAY,KAAK,MAAM,QAAQ,UAAU,GAAG,QAAQ,UAAU,CAAC,IAAI,KAAK;EACzF;AAEA,WAAS,eAAe,SAA+B;AACrD,UAAM,EAAE,KAAK,QAAQ,UAAU,IAAI;AACnC,UAAM,OAAO,IAAI;AACjB,QAAI,MAAM;AACR,YAAM,QAAQ,UAAU,OAAO,IAAI,OAAO,QAAQ,CAAC,KAAK,MAAM,KAAK,IAAI;AACvE,cAAQ,IAAI,KAAK,IAAI,KAAK;AAC1B,cAAQ,IAAI,OAAO,QAAQ,OAAO,IAAI;AACtC,cAAQ,IAAI,KAAK,IAAI,KAAK;AAC1B,aAAO;IACT;AACA,UAAM,IAAI,OAAO,UAAU,OAAO;AAClC,MAAE,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,MAAM;AAC5B,QAAI,UAAW,WAAU,UAAU,GAAG,WAAW,IAAI,iBAAiB,CAAC,CAAC;AACxE,WAAO;EACT;AAEA,WAAS,cAAc,SAAwB;AAC7C,UAAM,EAAE,MAAM,KAAK,QAAQ,GAAG,GAAG,GAAG,MAAM,MAAM,IAAI;AACpD,UAAM,SAAS,IAAI,SAAS;AAC5B,QAAI,CAAC,OAAQ;AACb,aAAS,QAAQ,GAAG,QAAQ,SAAS,OAAO,SAAS;AACnD,YAAM,IAAI,OAAO,UAAU,OAAO;AAClC,QAAE,IAAI,KAAK,IAAI,EAAE,CAAC;AAClB,YAAMC,MAAK,EAAE,IAAI,OAAO,QAAQ,GAAG,CAAC;AACpC,YAAMD,MAAK,OAAO,QAAQ,GAAG,CAAC;AAC9B,YAAME,MAAK,EAAE,IAAI,OAAO,QAAQ,GAAG,CAAC;AACpC,eAAS,MAAM,EAAE,GAAG,GAAG,IAAI,OAAO,KAAK,GAAG,IAAAD,KAAI,IAAAD,KAAI,IAAAE,KAAI,MAAM,OAAO,QAAQ,KAAK,GAAG,GAAG,GAAG,MAAM,IAAI,MAAM,MAAM,GAAG,MAAM,KAAK,GAAG,IAAI,CAAC;IACvI;EACF;AAEA,WAAS,gBAAgB,SAAwB;AAC/C,UAAM,EAAE,MAAM,KAAK,QAAQ,GAAG,GAAG,GAAG,MAAM,MAAM,IAAI;AACpD,QAAI,CAAC,KAAK,OAAO,YAAY,CAAC,IAAI,SAAS,MAAO;AAClD,UAAM,QAAQ,KAAK,MAAM,IAAI,SAAS,QAAQ,KAAK;AACnD,aAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS;AAC1C,YAAM,IAAI,eAAe,OAAO;AAChC,YAAM,QAAQ,IAAI,SAAS,QAAQ,OAAO,QAAQ,MAAM,CAAC;AACzD,eAAS,MAAM;QACb,GAAG,IAAI,EAAE,IAAI;QAAK,GAAG,IAAI,OAAO;QAAM,GAAG,IAAI,EAAE,IAAI;QAAK,IAAI,EAAE,IAAI;QAAO,IAAI,EAAE,IAAI;QAAO,IAAI,EAAE,IAAI;QACpG,MAAM,OAAO,QAAQ,MAAM,GAAG;QAAG,GAAG,IAAI,SAAS,SAAS;QAAO,IAAI;QAAM,MAAM,IAAI,SAAS;QAAM,MAAM,IAAI,SAAS,SAAS,IAAI,OAAO;MAC7I,CAAC;IACH;AACA,kBAAc,OAAO;EACvB;AAEA,WAAS,cAAc,SAAwB;AAC7C,UAAM,EAAE,MAAM,KAAK,QAAQ,GAAG,GAAG,GAAG,OAAO,UAAU,IAAI;AACzD,UAAM,SAAS,IAAI;AACnB,QAAI,CAAC,KAAK,OAAO,YAAY,CAAC,OAAO,SAAS,QAAQ,IAAK;AAC3D,UAAM,QAAQ,KAAK,MAAM,OAAO,SAAS,SAAS,IAAI,IAAI,IAAI;AAC9D,aAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS;AAC1C,YAAM,IAAI,OAAO,UAAU,OAAO;AAClC,QAAE,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,MAAM;AAC5B,UAAI,UAAW,WAAU,UAAU,GAAG,WAAW,GAAG,CAAC;AACrD,YAAM,QAAQ,OAAO,QAAQ,GAAG,EAAE,KAAK,OAAO,SAAS;AACvD,YAAM,IAAI,OAAO,QAAQ,MAAM,GAAG,KAAK,OAAO,QAAQ;AACtD,YAAM,QAAQ,OAAO,QAAQ,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK,IAAI;AACnE,YAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,OAAO,QAAQ,KAAK,CAAC;AACtD,YAAM,QAAQ,SAAS,OAAO,OAAO,SAAS,IAAIL,MAAK,QAAQ,OAAO,MAAM,IAAI,mBAAmB;AACnG,YAAM,MAAM,OAAO,KAAK,IAAI,OAAO;AACnC,eAAS,MAAM,QAAQ;QACrB,GAAG,IAAI,EAAE,IAAI;QAAK,GAAG,IAAI;QAAK,GAAG,IAAI,EAAE,IAAI;QAAK,IAAI,EAAE,IAAI;QAAO,IAAI,EAAE,IAAI,QAAQ;QAAG,IAAI,EAAE,IAAI;QAChG,IAAI,QAAQ,IAAI,MAAM;QAAG;QAAI,IAAI,QAAQ,IAAI,MAAM;QAAG;QAAO;QAAO;MACtE,CAAC;IACH;EACF;AAEA,WAAS,iBAAiB,SAAwB;AAChD,UAAM,EAAE,MAAM,QAAQ,GAAG,EAAE,IAAI;AAC/B,UAAM,SAAS,QAAQ,IAAI,KAAK,UAAU;AAC1C,QAAI,CAAC,KAAK,OAAO,SAAU;AAC3B,UAAM,aAAa,QAAQ,IAAI,OAAO,SAAS;AAC/C,UAAM,QAAQ,KAAK,MAAM,IAAI,SAAS,CAAC;AACvC,aAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS;AAC1C,YAAM,QAAQ,OAAO,KAAK,IAAI,KAAK,KAAK;AACxC,YAAM,QAAQ,OAAO,QAAQ,GAAG,CAAC,IAAI;AACrC,YAAM,IAAI,OAAO,QAAQ,MAAM,IAAI;AACnC,YAAMG,MAAK,OAAO,QAAQ,GAAG,EAAE;AAC/B,YAAM,QAAQ,SAAS,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC,IAAI,YAAY,CAAC,CAAC;AAC5E,eAAS,MAAM,QAAQ;QACrB,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI;QAAK,GAAG;QAAK,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI;QAAK,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;QAAK,IAAAA;QAAI,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;QACzI,IAAI,IAAI;QAAK,IAAI,IAAI;QAAM,IAAI,IAAI;QAAK;QAAO,OAAO;MACxD,CAAC;IACH;EACF;AAEA,WAAS,gBAAgB,SAAkB,MAA0B;AACnE,UAAM,EAAE,MAAM,QAAQ,GAAG,GAAG,EAAE,IAAI;AAClC,SAAK,OAAO,WAAW,GAAG,GAAG,GAAG,IAAI;AACpC,UAAM,QAAQ,KAAK,UAAU,SAAY,eAAe,KAAK,KAAK,IAAI,aAAa;AACnF,UAAML,QAAO,UAAU,KAAK,OAAO;MACjC;MAAG;MAAG,IAAI,IAAI,KAAK,SAAS;MAAM,MAAM,KAAK;MAAQ,IAAI,KAAK,YAAY;MAAM,IAAI,KAAK,SAAS;MAAK,IAAI,KAAK;MAAQ,GAAG,KAAK,SAAS;MAAM,MAAM,KAAK,QAAQ;MAAK,MAAM,KAAK,QAAQ;IAC5L,CAAC;AACD,UAAM,MAAM,KAAK,MAAM;AACvB,UAAM,QAAQ,KAAK,OAAO,KAAK,SAAS,MAAM,KAAK,IAAI,KAAK,GAAG,CAAC;AAChE,aAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS;AAC1C,YAAM,KAAK,KAAK,SAAS,OAAO,QAAQ,MAAM,GAAG;AACjD,YAAM,OAAO,OAAO,QAAQA,MAAK,OAAO,MAAMA,MAAK,IAAI;AACvD,YAAM,KAAK,OAAO,QAAQ,GAAG,IAAI;AACjC,YAAM,KAAK,OAAO,QAAQ,KAAK,GAAG;AAClC,YAAMC,QAAO,QAAQ,MAAM,QAAQ,EAAE,GAAG,GAAG,GAAG,IAAI,KAAK,SAAS,KAAK,IAAI,IAAI,KAAK,SAAS,MAAM,IAAI,GAAG,MAAM,IAAI,IAAI,OAAO,MAAM,EAAE,CAAC;AACtIA,YAAK,OAAOD;AACZC,YAAK,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK;AACpCA,YAAK,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK;IACtC;AACA,UAAM,YAAY,KAAK,OAAO,KAAK,QAAQ,MAAM,KAAK,IAAI,KAAK,GAAG,CAAC;AACnE,aAAS,QAAQ,GAAG,QAAQ,WAAW,SAAS;AAC9C,YAAM,SAAS,OAAO,KAAK,IAAI;AAC/B,YAAM,KAAK,IAAI,OAAO,QAAQ,MAAM,GAAG,IAAI,KAAK,SAAS;AACzD,YAAM,KAAK,IAAI,OAAO,QAAQ,MAAM,GAAG,IAAI,KAAK,SAAS;AACzD,YAAMK,MAAK,OAAO,QAAQ,MAAM,GAAG;AACnC,YAAMD,MAAK,KAAK,SAAS,OAAO,QAAQ,KAAK,GAAG,KAAK,IAAI;AACzD,YAAME,MAAK,OAAO,QAAQ,MAAM,GAAG;AACnC,YAAM,KAAK,KAAK,SAAS,OAAO,QAAQ,MAAM,IAAI;AAClD,YAAM,OAAO,OAAO,QAAQ,GAAG,CAAC;AAChC,YAAM,KAAK,OAAO,QAAQ,KAAK,GAAG;AAClC,YAAM,KAAK,OAAO,QAAQ,KAAK,GAAG;AAClC,cAAQ,MAAM,QAAQ,EAAE,GAAG,IAAI,GAAG,IAAI,KAAK,GAAG,IAAI,IAAAD,KAAI,IAAAD,KAAI,IAAAE,KAAI,IAAI,KAAK,SAAS,MAAM,IAAI,IAAI,KAAK,SAAS,MAAM,IAAI,GAAG,MAAM,IAAI,IAAI,MAAM,KAAK,MAAM,KAAK,MAAM,CAAC;IACtK;EACF;AAEA,WAAS,oBAAoB,SAAwB;AACnD,UAAM,EAAE,MAAM,KAAK,QAAQ,GAAG,GAAG,EAAE,IAAI;AACvC,UAAM,OAAO,IAAI;AACjB,QAAI,KAAK,UAAU,KAAK,QAAQ,IAAI,KAAK;AACvC,WAAK,KAAK,EAAE,MAAM,UAAU,GAAG,GAAG,QAAQ,KAAK,QAAQ,OAAO,KAAK,KAAK,CAAC;AACzE,WAAK,OAAO,SAAS,GAAG,GAAG,KAAK,QAAQ,KAAK,IAAI;AACjD,gBAAU,KAAK,OAAO,KAAK,QAAQ,QAAQ,EAAE,GAAG,GAAG,QAAQ,KAAK,QAAQ,OAAO,KAAK,MAAM,OAAO,KAAK,OAAO,KAAK,CAAC;AACnH,UAAI,KAAK,OAAO,SAAU,kBAAiB,OAAO;IACpD;AACA,QAAI,KAAK,UAAU,IAAI,OAAO,KAAK,OAAO,MAAM;AAC9C,WAAK,OAAO,SAAS,GAAG,GAAG,KAAK,MAAM;AACtC,gBAAU,KAAK,OAAO,QAAQ,GAAG,GAAG,KAAK,MAAM;IACjD;AACA,QAAI,IAAI,YAAY,KAAK,OAAO,KAAM,iBAAgB,SAAS,IAAI,QAAQ;AAC3E,QAAI,IAAI,iBAAiB,KAAK,OAAO,MAAM;AACzC,iBAAW,QAAQ,IAAI,eAAe;AACpC,gBAAQ,MAAM,QAAQ;UACpB,GAAG,KAAK,KAAK,MAAM;UAAI,GAAG;UAAG,GAAG,KAAK,KAAK,MAAM;UAAI,GAAG,KAAK;UAAQ,MAAM,KAAK;UAAM,MAAM,KAAK;UAAM,OAAO,KAAK;UAAO,aAAa,KAAK;UAAa,MAAM,KAAK;UACnK,OAAO,KAAK,eAAe,SAAY,eAAe,KAAK,UAAU,IAAI;QAC3E,GAAG,QAAQ,KAAK,MAAM;MACxB;IACF;EACF;AAEA,WAAS,aAAa,SAAwB;AAC5C,UAAM,EAAE,MAAM,KAAK,GAAG,GAAG,EAAE,IAAI;AAC/B,UAAM,QAAQ,CAAC,GAAG,GAAG,CAAC;AACtB,SAAK,KAAK;MACR,MAAM;MAAe,WAAW,IAAI;MAAI;MAAO,aAAa,KAAK,IAAI,IAAI,QAAQ,EAAE,IAAI;MAAM,OAAO;MAAK,QAAQ,IAAI;MAAQ,QAAQ,IAAI;MAAQ,MAAM,IAAI;MAC3J,UAAU,IAAI,aAAa;MAAM,UAAU,IAAI,MAAM,aAAa;MAAM,MAAM,IAAI,OAAO,EAAE,OAAO,UAAU,OAAO,GAAG,MAAM,IAAI,KAAK,MAAM,QAAQ,IAAI,KAAK,OAAO,IAAI;IACzK,CAAC;AACD,QAAI,IAAI,OAAQ,MAAK,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,IAAI,OAAO,CAAC;EACzE;AAMO,WAAS,iBAAiB,MAAe,KAAmBC,OAA6B;AAC9F,UAAM,iBAAiB,gBAAgB,KAAK,OAAO,GAAG,KAAK,OAAO,GAAG,KAAK,OAAO,GAAGA,MAAK,GAAGA,MAAK,GAAGA,MAAK,CAAC;AAC1G,UAAM,SAAS,KAAK,MAAM;AAC1B,UAAM,YAAY,UAAU,SAAS,KAAK,OAAO,gBAAgB,IAAI,YAAY;AACjF,UAAM,WAAW,KAAK,UAAU,KAAK,QAAQ,SAAS,KAAK,MAAM,MAAMA,MAAK,GAAGA,MAAK,CAAC,IAAI;AACzF,UAAM,QAAQ,UAAU,YAAY;AACpC,SAAK,MAAM,MAAM;AACjB,SAAK,MAAM,YAAY,KAAK,MAAM;AAClC,SAAK,QAAQ,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ,SAAS,KAAK,QAAQ,SAAS;AACvF,UAAM,UAAmB;MACvB;MAAM;MAAK,MAAAA;MAAM,QAAQA,MAAK;MAAQ,GAAGA,MAAK;MAAG,GAAGA,MAAK;MAAG,GAAGA,MAAK;MAAG,MAAM,IAAI;MAAc;MAAO,WAAWA,MAAK;MACtH,YAAY,eAAe,IAAI,MAAM,KAAK;MAAG;IAC/C;AACA,iBAAa,OAAO;AACpB,SAAK,OAAO,QAAQ,KAAK,IAAI,KAAK,OAAO,QAAQ,IAAI,SAAS,MAAM,IAAI,iBAAiB,KAAK;AAC9F,qBAAiB,OAAO;AACxB,iBAAa,OAAO;AACpB,iBAAa,OAAO;AACpB,gBAAY,OAAO;AACnB,oBAAgB,OAAO;AACvB,kBAAc,OAAO;AACrB,wBAAoB,OAAO;AAC3B,iBAAa,OAAO;AACpB,WAAO;EACT;ACjVA,MAAM,cAAc;AACpB,MAAM,kBAAkB;AACxB,MAAM,aAAa;AACnB,MAAM,aAAa;AACnB,MAAM,gBAAgB;AACtB,MAAM,aAAa;AACnB,MAAMC,gBAAe,KAAK,KAAK;AAE/B,WAAS,OAAO,MAAe,OAAcC,QAAqB;AAChE,UAAM,IAAIA;AACV,QAAI,MAAM,SAAS,CAAC,MAAM,SAAS,KAAK,OAAO,MAAM;AACnD,YAAM,QAAQ;AACd,oBAAc,KAAK,OAAO,KAAK,QAAQ,MAAM,KAAK,EAAE,GAAG,MAAM,GAAG,GAAG,MAAM,GAAG,QAAQ,MAAM,IAAI,QAAQ,MAAM,IAAI,EAAE,CAAC;IACrH;AACA,UAAM,MAAM;AACZ,UAAM,MAAM;AACZ,UAAM,MAAM;AACZ,UAAM,MAAM;AACZ,UAAM,MAAM;AACZ,UAAM,MAAM;AACZ,QAAI,KAAK,IAAI,MAAM,EAAE,IAAI,cAAc,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,IAAI,YAAY;AAClF,YAAM,OAAO;AACb,YAAM,KAAK,KAAK,MAAM,MAAM,KAAKD,aAAY,IAAIA;AACjD,YAAM,KAAK,KAAK,MAAM,MAAM,KAAKA,aAAY,IAAIA;IACnD;EACF;AAEA,WAAS,WAAW,MAAe,OAAc,IAAkB;AACjE,UAAM,SAAS;AACf,QAAI,MAAM,QAAQ,EAAG;AACrB,UAAM,QAAQ;AACd,UAAM,SAAS,MAAM;AACrB,aAAS,MAAM;MACb,GAAG,MAAM;MAAG,GAAG,MAAM;MAAG,GAAG,MAAM;MAAG,IAAI,MAAM,KAAK;MAAM,IAAI,MAAM,KAAK;MAAM,IAAI,MAAM,KAAK;MAC7F,MAAM,OAAO,QAAQ,MAAM,IAAI;MAAG,GAAG,OAAO,MAAM,KAAK;MAAK,IAAI;MAAM,MAAM;MAAG,GAAG;MAAG,MAAM;IAC7F,CAAC;AACD,QAAI,OAAO,KAAK,IAAI,MAAM;AACxB,cAAQ,MAAM,QAAQ,EAAE,GAAG,MAAM,GAAG,GAAG,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,KAAK,IAAI,MAAM,MAAM,OAAO,QAAQ,GAAG,GAAG,GAAG,MAAM,GAAG,MAAM,KAAK,OAAO,aAAa,MAAM,MAAM,EAAE,CAAC;IAClM;EACF;AAGO,WAAS,aAAa,MAAe,IAAkB;AAC5D,eAAW,SAAS,KAAK,OAAO,OAAO;AACrC,YAAM,KAAK;AACX,UAAI,MAAM,KAAM;AAChB,YAAM,MAAM,KAAK,UAAU;AAC3B,YAAM,KAAK,MAAM,KAAK;AACtB,YAAM,KAAK,MAAM,KAAK;AACtB,YAAM,KAAK,MAAM,KAAK;AACtB,YAAM,MAAM,MAAM,KAAK;AACvB,YAAM,MAAM,MAAM,KAAK;AACvB,YAAM,MAAM,MAAM,KAAK;AACvB,YAAMC,SAAQ,MAAM,KAAK,OAAO,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC;AAC9D,UAAI,MAAM,IAAIA,OAAO,QAAO,MAAM,OAAOA,MAAK;AAC9C,UAAI,MAAM,OAAO,MAAM,IAAI,iBAAiB,KAAK,OAAO,MAAO,YAAW,MAAM,OAAO,EAAE;IAC3F;EACF;AC7DA,MAAM,QAAQ,EAAE,OAAO,GAAG,OAAO,GAAG,KAAK,KAAK,MAAM,GAAG,QAAQ,GAAG,OAAO,KAAK,YAAY,GAAG,MAAM,EAAE;AAC9F,MAAM,sBAAsB;AAE5B,WAAS,oBAAiC;AAC/C,WAAO,EAAE,OAAO,GAAG,OAAO,GAAG,YAAY,qBAAqB,OAAO,GAAG,KAAK,GAAG,eAAe,GAAG,gBAAgB,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,EAAE;EAC5J;AAEO,WAAS,iBAAiB,OAA0B;AACzD,WAAO,OAAO,OAAO,kBAAkB,CAAC;EAC1C;AAMO,WAAS,aAAa,OAAoB,IAAkB;AACjE,UAAM,SAAS,KAAK,IAAI,CAAC,MAAM,aAAa,EAAE;AAC9C,UAAM,SAAS,KAAK,IAAI,CAAC,MAAM,QAAQ,EAAE;AACzC,UAAM,SAAS,KAAK,IAAI,CAAC,MAAM,QAAQ,EAAE;AACzC,UAAM,OAAO,KAAK,IAAI,CAAC,MAAM,MAAM,EAAE;AACrC,UAAM,iBAAiB,KAAK,IAAI,CAAC,MAAM,OAAO,EAAE;AAChD,UAAM,kBAAkB,KAAK,IAAI,CAAC,MAAM,OAAO,EAAE;AACjD,UAAM,UAAU,KAAK,IAAI,CAAC,MAAM,SAAS,EAAE;AAC3C,UAAM,SAAS,KAAK,IAAI,CAAC,MAAM,QAAQ,EAAE;AACzC,UAAM,MAAM,KAAK,IAAI,GAAG,MAAM,MAAM,KAAK,MAAM,UAAU;AACzD,UAAM,QAAQ,KAAK,IAAI,CAAC,MAAM,OAAO,EAAE;EACzC;AC1BA,MAAMC,SAAQ,CAAC,GAAW,IAAY,OAAwB,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK;AAC1F,MAAMC,QAAO,CAAC,GAAW,GAAW,MAAsB,KAAK,IAAI,KAAK;AAExE,WAAS,IAAI,KAAgD;AAC3D,WAAO,EAAG,OAAO,KAAM,OAAO,MAAO,OAAO,IAAK,OAAO,MAAM,MAAM,OAAO,GAAG;EAChF;AA6BO,WAAS,aAAa,MAA4B;AACvD,QAAI,IAAI,SAAS;AACjB,WAAO,MAAM;AACX,UAAK,IAAI,eAAgB;AACzB,UAAI,IAAI;AACR,UAAI,KAAK,KAAK,IAAK,MAAM,IAAK,IAAI,CAAC;AACnC,WAAK,IAAI,KAAK,KAAK,IAAK,MAAM,GAAI,IAAI,EAAE;AACxC,eAAS,IAAK,MAAM,QAAS,KAAK;IACpC;EACF;AAMO,MAAM,iBAAN,MAAqB;IA2B1B,YACW,UACQ,MACA,QACjB;AAHS,oBAAA,MAAA,YAAA,QAAA;AACQ,oBAAA,MAAA,QAAA,IAAA;AACA,oBAAA,MAAA,UAAA,MAAA;AA7BnB,oBAAA,MAAA,QAAO,CAAA;AAEP,oBAAA,MAAA,aAAY,CAAA;AACZ,oBAAA,MAAS,UAAA;AACT,oBAAA,MAAS,OAAA;AACT,oBAAA,MAAS,OAAA;AACT,oBAAA,MAAS,MAAA;AACT,oBAAA,MAAQ,QAAO,CAAA;AACf,oBAAA,MAAQ,QAAO,CAAA;AACf,oBAAA,MAAiB,UAAA;AACjB,oBAAA,MAAiB,KAAA;AACjB,oBAAA,MAAiB,MAAA;AACjB,oBAAA,MAAiB,OAAA;AACjB,oBAAA,MAAiB,OAAA;AACjB,oBAAA,MAAiB,MAAA;AACjB,oBAAA,MAAiB,MAAA;AACjB,oBAAA,MAAiB,UAAA;AACjB,oBAAA,MAAiB,KAAA;AACjB,oBAAA,MAAiB,OAAA;AACjB,oBAAA,MAAiB,UAAA;AACjB,oBAAA,MAAiB,UAAA;AACjB,oBAAA,MAAiB,QAAA;AACjB,oBAAA,MAAiB,SAAA;AACjB,oBAAA,MAAiB,OAAA;AACjB,oBAAA,MAAiB,SAAA;AAOf,YAAM,IAAI,KAAK,IAAI,GAAG,QAAQ;AAC9B,WAAK,WAAW,IAAI,aAAa,IAAI,CAAC;AACtC,WAAK,QAAQ,IAAI,aAAa,IAAI,CAAC;AACnC,WAAK,QAAQ,IAAI,aAAa,CAAC;AAC/B,WAAK,OAAO,IAAI,aAAa,CAAC;AAC9B,WAAK,WAAW,IAAI,aAAa,IAAI,CAAC;AACtC,WAAK,MAAM,IAAI,aAAa,CAAC;AAC7B,WAAK,OAAO,IAAI,aAAa,CAAC;AAC9B,WAAK,QAAQ,IAAI,aAAa,CAAC;AAC/B,WAAK,QAAQ,IAAI,WAAW,CAAC;AAC7B,WAAK,OAAO,IAAI,WAAW,CAAC;AAC5B,WAAK,OAAO,IAAI,aAAa,CAAC;AAC9B,WAAK,WAAW,IAAI,aAAa,CAAC;AAClC,WAAK,MAAM,IAAI,WAAW,CAAC;AAC3B,WAAK,QAAQ,IAAI,WAAW,CAAC;AAC7B,WAAK,WAAW,IAAI,WAAW,CAAC;AAChC,WAAK,WAAW,IAAI,aAAa,IAAI,CAAC;AACtC,WAAK,SAAS,IAAI,aAAa,IAAI,CAAC;AACpC,WAAK,UAAU,IAAI,WAAW,CAAC;AAC/B,WAAK,QAAQ,IAAI,aAAa,CAAC;AAC/B,WAAK,UAAU,IAAI,aAAa,CAAC;IACnC;IAEA,MAAM,MAAc,GAAsB,GAAsB,QAAsB,SAAoC;AACxH,UAAI,KAAK,YAAY,EAAG;AACxB,YAAM,MAAM,KAAK,KAAK,IAAI;AAC1B,YAAM,IAAI,KAAK;AACf,WAAK,QAAQ,KAAK,OAAO,KAAK,KAAK;AACnC,UAAI,KAAK,MAAM,CAAC,EAAG,MAAK;AACxB,WAAK,MAAM,CAAC,IAAI;AAChB,WAAK;AACL,UAAI,IAAI,IAAI,KAAK,KAAM,MAAK,OAAO,IAAI;AACvC,WAAK,KAAK,CAAC,IAAI;AACf,WAAK,SAAS,IAAI,GAAG,IAAI,CAAC;AAC1B,WAAK,SAAS,IAAI,GAAG,IAAI,CAAC;AAC1B,WAAK,IAAI,CAAC,IAAI;AACd,WAAK,KAAK,CAAC,IAAIA,MAAK,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,SAAS,QAAQ;AAC5E,WAAK,MAAM,CAAC,IAAIA,MAAK,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,SAAS,QAAQ;AAC7E,WAAK,KAAK,CAAC,IAAI,OAAO;AACtB,WAAK,SAAS,CAAC,IAAI,SAAS,SAAS;AACrC,WAAK,IAAI,CAAC,IAAI,SAAS,OAAO;AAC9B,WAAK,MAAM,CAAC,IAAI,SAAS,UAAU,SAAY,KAAK,KAAK,WAAW,QAAQ,KAAK;AACjF,WAAK,SAAS,CAAC,IAAI,SAAS,SAAS;AACrC,WAAK,SAAS,IAAI,IAAI,SAAS,SAAS,IAAI,EAAE,GAAG,IAAI,CAAC;AACtD,WAAK,OAAO,IAAI,IAAI,SAAS,SAAS,IAAI,EAAE,GAAG,IAAI,CAAC;AACpD,WAAK,QAAQ,CAAC,IAAI;AAClB,WAAK,MAAM,CAAC,IAAI,SAAS,SAAS,OAAO;AACzC,WAAK,QAAQ,CAAC,IAAI,SAAS,QAAQ;AACnC,WAAK,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC;AAC3B,WAAK,MAAM,CAAC,IAAI;IAClB;IAEQ,WAAW,MAAsB;AACvC,UAAI,QAAQ,KAAK,OAAO,QAAQ,IAAI;AACpC,UAAI,QAAQ,EAAG,SAAQ,KAAK,OAAO,KAAK,IAAI,IAAI;AAChD,aAAO;IACT;IAEQ,KAAK,GAAiB;AAC5B,UAAI,CAAC,KAAK,MAAM,CAAC,EAAG;AACpB,WAAK,MAAM,CAAC,IAAI;AAChB,WAAK;AACL,WAAK,MAAM,CAAC,IAAI;AAChB,WAAK,KAAK,CAAC,IAAI;IACjB;IAEA,QAAc;AACZ,WAAK,MAAM,KAAK,CAAC;AACjB,WAAK,MAAM,KAAK,CAAC;AACjB,WAAK,KAAK,KAAK,CAAC;AAChB,WAAK,OAAO;AACZ,WAAK,OAAO;AACZ,WAAK,OAAO;AACZ,WAAK,YAAY;IACnB;;IAGA,KAAK,IAAY,IAAY,IAAY,QAAgB,OAAqB;AAC5E,eAAS,IAAI,GAAG,IAAI,KAAK,MAAM,KAAK;AAClC,YAAI,CAAC,KAAK,MAAM,CAAC,EAAG;AACpB,cAAM,KAAK,KAAK,SAAS,IAAI,CAAC,IAAK;AACnC,cAAM,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,IAAK;AACvC,cAAM,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,IAAK;AACvC,cAAM,IAAI,KAAK,MAAM,IAAI,IAAI,EAAE;AAC/B,YAAI,IAAI,UAAU,IAAI,KAAM;AAC5B,cAAM,KAAK,IAAI,IAAI,UAAU;AAC7B,aAAK,SAAS,IAAI,CAAC,KAAO,KAAK,IAAK;AACpC,aAAK,SAAS,IAAI,IAAI,CAAC,KAAO,KAAK,IAAK;AACxC,aAAK,SAAS,IAAI,IAAI,CAAC,KAAO,KAAK,IAAK;MAC1C;IACF;IAEA,OAAO,IAAY,MAA0B;AAC3C,UAAI,MAAM;AACV,eAAS,IAAI,GAAG,IAAI,KAAK,MAAM,KAAK;AAClC,YAAI,CAAC,KAAK,MAAM,CAAC,EAAG;AACpB,cAAM,MAAM,KAAK,KAAK,KAAK,KAAK,CAAC,CAAE;AACnC,cAAM,MAAO,KAAK,IAAI,CAAC,IAAK;AAC5B,aAAK,IAAI,CAAC,IAAI;AACd,cAAM,OAAO,KAAK,KAAK,CAAC;AACxB,YAAI,OAAO,MAAM;AACf,eAAK,KAAK,CAAC;AACX;QACF;AACA,cAAM,IAAI,MAAM;AAChB,cAAM,KAAK,IAAI;AACf,YAAIN,MAAK,KAAK,SAAS,EAAE;AACzB,YAAID,MAAK,KAAK,SAAS,KAAK,CAAC;AAC7B,YAAIE,MAAK,KAAK,SAAS,KAAK,CAAC;AAC7BF,gBAAO,IAAI,OAAO,KAAK,QAAQ,CAAC,IAAK,IAAI,UAAU,KAAK,WAAW;AACnE,YAAI,IAAI,SAAS;AACf,gBAAM,QAAQ,MAAM,IAAI,KAAK,KAAK,CAAC,IAAK;AACxCC,iBAAM,KAAK,IAAI,KAAK,IAAI,IAAI,UAAU;AACtCC,iBAAM,KAAK,IAAI,QAAQ,GAAG,IAAI,IAAI,UAAU;QAC9C;AACA,YAAI,IAAI,OAAO,GAAG;AAChB,gBAAM,IAAI,KAAK,IAAI,CAAC,IAAI,OAAO,EAAE;AACjCD,iBAAM;AACND,iBAAM;AACNE,iBAAM;QACR;AACA,cAAM,IAAI,KAAK,SAAS,EAAE,IAAKD,MAAK;AACpC,YAAI,IAAI,KAAK,SAAS,KAAK,CAAC,IAAKD,MAAK;AACtC,cAAM,IAAI,KAAK,SAAS,KAAK,CAAC,IAAKE,MAAK;AACxC,YAAI,IAAI,WAAW,QAAQ;AACzB,gBAAM,MAAM,KAAK,MAAM,CAAC;AACxB,gBAAM,KAAK,OAAO,MAAM,GAAG,IAAI,KAAK,SAAS,GAAG,CAAC,IAAI,OAAQ;AAC7D,cAAI,IAAI,IAAI;AACV,gBAAI,IAAI,WAAW,QAAQ;AACzB,oBAAM,MAAM,KAAK,IAAI,CAAC;AACtB,oBAAM,QAAQ,KAAK,MAAM,CAAC;AAC1B,kBAAI,QAAQ,KAAK,SAAS,EAAG,MAAK,KAAK,KAAK,OAAO,KAAK,GAAI,GAAG,IAAI,GAAG,KAAK,SAAS,CAAC,KAAM,IAAI,KAAK,SAAS,CAAC,IAAK,IAAI,IAAI,GAAG;AAC9H,mBAAK,KAAK,CAAC;AACX;YACF;AACA,gBAAI;AACJ,gBAAI,IAAI,WAAW,YAAY,CAAC,KAAK,QAAQ,CAAC,GAAG;AAC/C,mBAAK,QAAQ,CAAC,IAAI;AAClBF,oBAAK,KAAK,IAAIA,GAAE,IAAI;AACpBC,qBAAM;AACNC,qBAAM;YACR,OAAO;AACLD,oBAAKD,MAAKE,MAAK;YACjB;UACF;QACF;AACA,aAAK,SAAS,EAAE,IAAID;AACpB,aAAK,SAAS,KAAK,CAAC,IAAID;AACxB,aAAK,SAAS,KAAK,CAAC,IAAIE;AACxB,aAAK,SAAS,EAAE,IAAI;AACpB,aAAK,SAAS,KAAK,CAAC,IAAI;AACxB,aAAK,SAAS,KAAK,CAAC,IAAI;AACxB,aAAK,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,IAAKK,MAAK,GAAG,IAAI,MAAM,CAAC;AACnD,aAAK,MAAM,EAAE,IAAIA,MAAK,KAAK,SAAS,EAAE,GAAI,KAAK,OAAO,EAAE,GAAI,CAAC;AAC7D,aAAK,MAAM,KAAK,CAAC,IAAIA,MAAK,KAAK,SAAS,KAAK,CAAC,GAAI,KAAK,OAAO,KAAK,CAAC,GAAI,CAAC;AACzE,aAAK,MAAM,KAAK,CAAC,IAAIA,MAAK,KAAK,SAAS,KAAK,CAAC,GAAI,KAAK,OAAO,KAAK,CAAC,GAAI,CAAC;AACzE,YAAI,WAAW,IAAI,IAAI,SAAS,IAAI,IAAI,SAAS,KAAK,IAAI,IAAI,WAAW,IAAI,IAAI;AACjF,YAAI,IAAI,QAAS,aAAY,IAAI,IAAI,WAAW,MAAM,MAAM,KAAK,IAAI,MAAM,KAAK,KAAK,KAAK,CAAC,IAAK,EAAE;AAClG,aAAK,MAAM,CAAC,IAAID,OAAM,UAAU,GAAG,CAAC,IAAI,IAAI,QAAQ,KAAK,SAAS,CAAC;AACnE,cAAM,IAAI;MACZ;AACA,WAAK,OAAO;AACZ,WAAK,YAAY;IACnB;EACF;ACvPA,MAAA,uBAAA;IACE,MAAQ;MACN,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;MACV,SAAW;IACb;IACA,OAAS;MACP,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;IACZ;IACA,QAAU;MACR,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;IACZ;IACA,MAAQ;MACN,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;IACZ;IACA,QAAU;MACR,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;MACV,SAAW;IACb;IACA,WAAa;MACX,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;IACZ;IACA,OAAS;MACP,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;IACZ;IACA,QAAU;MACR,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;MACV,SAAW;IACb;IACA,QAAU;MACR,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;MACV,SAAW;IACb;IACA,OAAS;MACP,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;IACZ;IACA,KAAO;MACL,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;MACV,SAAW;IACb;IACA,OAAS;MACP,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;IACZ;IACA,OAAS;MACP,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;IACZ;IACA,MAAQ;MACN,IAAM;MACN,UAAY;MACZ,MAAQ;QACN;QACA;MACF;MACA,MAAQ;QACN;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,MAAQ;MACR,MAAQ;MACR,IAAM;MACN,IAAM;MACN,OAAS;MACT,QAAU;MACV,MAAQ;MACR,QAAU;IACZ;EACF;ACrRO,MAAM,eAA4D;ACblE,MAAM,mBAAN,MAAuB;IAU5B,YAA6B,SAAkC;AAAlC,oBAAA,MAAA,WAAA,OAAA;AAT7B,oBAAA,MAAS,UAAA;AACT,oBAAA,MAAS,QAAA;AACT,oBAAA,MAAiB,QAAA;AACjB,oBAAA,MAAiB,KAAA;AACjB,oBAAA,MAAiB,MAAA;AACjB,oBAAA,MAAiB,SAAQ,oBAAI,IAAoB,CAAA;AACjD,oBAAA,MAAiB,UAAmB,CAAC,CAAA;AACrC,oBAAA,MAAiB,aAAY,oBAAI,IAA0B,CAAA;AAGzD,YAAM,QAAiD,QAAQ,SAAS;AACxE,WAAK,MAAM,OAAO,KAAK,KAAK;AAC5B,WAAK,OAAO,KAAK,IAAI,IAAI,CAAC,OAAO,MAAM,EAAE,CAAE;AAC3C,WAAK,IAAI,QAAQ,CAAC,IAAIE,QAAO,KAAK,MAAM,IAAI,IAAIA,GAAE,CAAC;AACnD,YAAM,mBAAmB,KAAK,MAAM,QAAQ,WAAW,GAAG;AAC1D,WAAK,WAAW,IAAI,eAAe,kBAAkB,KAAK,MAAM,KAAK,MAAM;AAC3E,WAAK,SAAS,IAAI,eAAe,QAAQ,WAAW,kBAAkB,KAAK,MAAM,KAAK,MAAM;AAC5F,WAAK,SAAS,aAAa,QAAQ,IAAI;IACzC;IAEA,IAAI,WAAmB;AACrB,aAAO,KAAK,SAAS,WAAW,KAAK,OAAO;IAC9C;IAEA,IAAI,OAAe;AACjB,aAAO,KAAK,SAAS,OAAO,KAAK,OAAO;IAC1C;;IAGA,OAAO,OAAe,UAAoC;AACxD,WAAK,UAAU,IAAI,OAAO,QAAQ;AAClC,aAAO,MAAM;AACX,YAAI,KAAK,UAAU,IAAI,KAAK,MAAM,SAAU,MAAK,UAAU,OAAO,KAAK;MACzE;IACF;IAEQ,OAAO,MAAqD;AAClE,YAAM,QAAQ,KAAK,MAAM,IAAI,IAAI;AACjC,UAAI,UAAU,OAAW,OAAM,IAAI,MAAM,uBAAuB,IAAI,EAAE;AACtE,aAAO,EAAE,OAAO,KAAK,KAAK,KAAK,KAAK,EAAG;IACzC;;IAGA,MAAM,MAA2B,OAAa,UAAgB,SAAoC;AAChG,YAAM,EAAE,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI;AACtC,OAAC,IAAI,WAAW,KAAK,WAAW,KAAK,QAAQ,MAAM,OAAO,OAAO,UAAU,KAAK,QAAQ,OAAO;IAClG;;IAGA,MAAM,MAA2B,OAAa,QAAc,OAAe,QAAQ,GAAG,SAAoC;AACxH,YAAM,EAAE,IAAI,IAAI,KAAK,OAAO,IAAI;AAChC,YAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,KAAK,QAAQ,OAAO,CAAC;AAC9D,YAAMC,OAAM,KAAK;AACjB,YAAM,SAAS,KAAK,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,KAAK;AAC9D,YAAM,KAAK,OAAO,CAAC,IAAI;AACvB,YAAM,KAAK,OAAO,CAAC,IAAI;AACvB,YAAM,KAAK,OAAO,CAAC,IAAI;AACvB,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,IAAIA,KAAI,IAAI,IAAI;AACtB,cAAM,QAAQA,KAAI,IAAI,KAAK,KAAK;AAChC,cAAM,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC;AAC7B,cAAM,KAAK,IAAI,KAAK,IAAI,KAAK;AAC7B,cAAM,KAAK;AACX,cAAM,KAAK,IAAI,KAAK,IAAI,KAAK;AAC7B,YAAI,KAAK,KAAK,IAAI,OAAO,MAAM,IAAI,IAAI;AACvC,YAAI,KAAK,KAAK,IAAI,OAAO,MAAM,IAAI,IAAI;AACvC,YAAI,KAAK,KAAK,IAAI,OAAO,MAAM,IAAI,IAAI;AAEvC,cAAM,KAAK;AACX,cAAM,KAAK;AACX,cAAM,KAAK;AACX,cAAM,IAAI,KAAK,MAAM,IAAI,IAAI,EAAE,KAAK;AACpC,cAAM,KAAK,SAAS,OAAO,OAAOA,KAAI;AACtC,cAAM,SAAS,QAAQ,IAAI,KAAK,CAAC,IAAI,MAAM,OAAO;AAClD,aAAK;UACH,IAAI;UACJ,CAAC,MAAM,CAAC,KAAKA,KAAI,IAAI,OAAO,QAAQ,MAAM,CAAC,KAAKA,KAAI,IAAI,OAAO,QAAQ,MAAM,CAAC,KAAKA,KAAI,IAAI,OAAO,MAAM;UACxG,CAAE,KAAK,IAAK,IAAK,KAAK,IAAK,IAAK,KAAK,IAAK,EAAE;UAC5C;QACF;MACF;IACF;;IAGA,KAAK,OAAa,QAAgB,OAAqB;AACrD,WAAK,SAAS,KAAK,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,QAAQ,KAAK;AAC9D,WAAK,OAAO,KAAK,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,QAAQ,KAAK;IAC9D;IAEA,OAAO,IAAkB;AACvB,YAAM,OAAO;QACX,UAAU,KAAK,QAAQ;QACvB,SAAS,KAAK,QAAQ;QACtB,MAAM,CAAC,OAAe,GAAW,GAAW,GAAW,OAAe,QAAgB,KAAK,UAAU,IAAI,KAAK,IAAI,GAAG,GAAG,GAAG,OAAO,GAAG;MACvI;AACA,UAAI,KAAK,SAAS,OAAO,KAAK,KAAK,SAAS,YAAY,EAAG,MAAK,SAAS,OAAO,IAAI,IAAI;AACxF,UAAI,KAAK,OAAO,OAAO,KAAK,KAAK,OAAO,YAAY,EAAG,MAAK,OAAO,OAAO,IAAI,IAAI;IACpF;IAEA,QAAc;AACZ,WAAK,SAAS,MAAM;AACpB,WAAK,OAAO,MAAM;IACpB;EACF;AC5HA,MAAM,iBAAiB;AACvB,MAAM,YAAY;AAClB,MAAMC,OAAgB,CAAC,GAAG,GAAG,CAAC;AAEvB,WAAS,UAAU,QAAsB,OAAwC;AACtF,QAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,OAAO,QAAQ,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAClE,WAAQ,SAAgC;EAC1C;AAGO,WAAS,WAAW,QAAsB,KAA+B;AAC9E,UAAM,KAAK,OAAO,KAAK,IAAI,IAAI;AAC/B,UAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,UAAMC,QAAO,KAAK,KAAK,IAAI,KAAK,EAAE;AAClC,QAAI,IAAIA,QAAO,KAAK,IAAI,KAAK;AAC7B,QAAI,IAAI;AACR,QAAI,IAAIA,QAAO,KAAK,IAAI,KAAK;AAC7B,WAAO;EACT;AAEA,MAAM,WAAwB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AACjD,MAAM,WAAwB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AACjD,MAAM,OAAoB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAE7C,WAAS,MAAM,KAAkB,GAAgB,GAA6B;AAC5E,UAAM,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAC9B,UAAM,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAC9B,UAAM,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAC9B,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI,IAAI;AACR,WAAO;EACT;AAGO,WAAS,cAAc,QAAsB,WAAkC,MAAc,KAA+B;AACjI,QAAI,QAAQ,UAAW,QAAO,WAAW,QAAQ,GAAG;AACpD,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,aAAaD;AAClC,UAAM,UAAU,IAAI,OAAO,KAAK,KAAK,IAAI,KAAK,IAAI,IAAI;AACtD,UAAM,UAAU,KAAK,KAAK,IAAI,UAAU,OAAO;AAC/C,UAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,IAAI;AACT,aAAS,IAAI;AACb,aAAS,IAAI;AACb,aAAS,IAAI;AACb,QAAI,KAAK,IAAI,EAAE,IAAI,KAAK;AACtB,eAAS,IAAI;AACb,eAAS,IAAI;IACf;AACA,cAAU,MAAM,UAAU,MAAM,QAAQ,CAAC;AACzC,cAAU,MAAM,UAAU,UAAU,IAAI,CAAC;AACzC,QAAI,IAAI,KAAK;AACb,QAAI,IAAI,KAAK;AACb,QAAI,IAAI,KAAK;AACb,cAAU,KAAK,UAAU,UAAU,KAAK,IAAI,KAAK,CAAC;AAClD,cAAU,KAAK,UAAU,UAAU,KAAK,IAAI,KAAK,CAAC;AAClD,WAAO;EACT;AC3DA,MAAM,WAAW;AACjB,MAAME,WAAU;AAChB,MAAMC,gBAAe;AACrB,MAAM,eAAe;AACrB,MAAM,eAAe,CAAC,MAAM,MAAM,IAAI;AACtC,MAAM,eAAe;AACrB,MAAMC,iBAAgB;AACtB,MAAM,eAAe;AACrB,MAAM,iBAAiB;AACvB,MAAMC,mBAAkB;AAyBxB,WAAS,cAA2B;AAClC,WAAO,EAAE,IAAI,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,OAAO,OAAOD,eAAc;EAClL;AAGO,MAAM,aAAN,MAAiB;IAMtB,YAA6B,SAA0B;AAA1B,oBAAA,MAAA,WAAA,OAAA;AAL7B,oBAAA,MAAS,UAAwB,MAAM,KAAK,EAAE,QAAQ,SAAS,GAAG,WAAW,CAAA;AAC7E,oBAAA,MAAA,SAAQ,CAAA;AACR,oBAAA,MAAQ,QAAO,CAAA;AACf,oBAAA,MAAiB,aAAyB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,CAAA;IAEL;IAExD,MAAM,SAA4B;AAChC,YAAM,SAAS,KAAK,QAAQ;AAC5B,YAAM,QAAQ,KAAK,OAAO,KAAK,SAAS,QAAQ;AAChD,oBAAc,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,KAAK,KAAK,SAAS;AACtE,YAAM,QAAQ,UAAU,QAAQ,QAAQ,EAAE;AAC1C,YAAM,OAAO,QAAQ,QAAQ;AAC7B,YAAM,QAAQ,QAAQ,IAAI,UAAU,QAAQ,QAAQ,CAAC,IAAI;AACzD,YAAM,MAAM,QAAQ;AACpB,YAAM,OAAO,QAAQ,QAAQ;AAC7B,YAAM,KAAK;AACX,YAAM,IAAI,QAAQ,EAAE,CAAC,KAAK,MAAM,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI;AAClE,YAAM,IAAI,QAAQ,EAAE,CAAC,KAAK,MAAM,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI;AAClE,YAAM,IAAI,QAAQ,EAAE,CAAC,KAAK,MAAM,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI;AAClE,YAAM,KAAK,KAAK,UAAU,IAAI,SAAS,QAAQ,IAAI,QAAQ,EAAE,CAAC,IAAI;AAClE,YAAM,KAAK,KAAK,UAAU,IAAI,SAAS,QAAQ,IAAI,QAAQ,EAAE,CAAC,IAAI;AAClE,YAAM,KAAK,KAAK,UAAU,IAAI,SAAS,QAAQ,IAAI,QAAQ,EAAE,CAAC,IAAI;AAClE,YAAM,KAAM,KAAK,CAAC,IAAe;AACjC,YAAM,KAAM,KAAK,CAAC,IAAe;AACjC,YAAM,KAAM,KAAK,CAAC,IAAe;AACjC,YAAM,KAAK,OAAO,QAAQ,GAAGC,gBAAe;AAC5C,YAAM,KAAK,OAAO,QAAQ,GAAGA,gBAAe;AAC5C,YAAM,KAAK,OAAO,QAAQ,GAAGA,gBAAe;AAC5C,YAAM,KAAK,OAAO,QAAQ,IAAI,CAAC,IAAI;AACnC,YAAM,KAAK,OAAO,QAAQ,IAAI,CAAC,IAAI;AACnC,YAAM,KAAK,OAAO,QAAQ,IAAI,CAAC,IAAI;AACnC,YAAM,OAAO,QAAQ,QAAQ;AAC7B,YAAM,SAAS,QAAQ,UAAU;AACjC,YAAM,OAAO;AACb,YAAM,QAAQ,QAAQ,KAAKD;IAC7B;IAEA,QAAc;AACZ,iBAAW,SAAS,KAAK,OAAQ,OAAM,KAAK;AAC5C,WAAK,QAAQ;IACf;IAEA,OAAO,IAAkB;AACvB,WAAK,QAAQ;AACb,iBAAW,SAAS,KAAK,QAAQ;AAC/B,YAAI,CAAC,MAAM,GAAI;AACf,aAAK;AACL,cAAM,QAAQ;AACd,YAAI,MAAM,QAAQ,GAAG;AACnB,gBAAM,KAAK;AACX;QACF;AACA,YAAI,CAAC,MAAM,KAAM,MAAK,KAAK,OAAO,EAAE;MACtC;IACF;;IAGA,OAAO,KAAK,OAA4B;AACtC,aAAO,KAAK,IAAI,GAAG,MAAM,OAAO,YAAY;IAC9C;IAEQ,KAAK,OAAoB,IAAkB;AACjD,YAAM,MAAMF,WAAU;AACtB,YAAM,KAAK,MAAM,KAAK;AACtB,YAAM,KAAK,MAAM,KAAK;AACtB,YAAM,KAAK,MAAM,KAAK;AACtB,YAAM,MAAM,MAAM,KAAK;AACvB,YAAM,MAAM,MAAM,KAAK;AACvB,YAAM,MAAM,MAAM,KAAK;AACvB,YAAM,eAAe,KAAK,QAAQ,SAAS,MAAM,GAAG,MAAM,CAAC,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE,IAAI;AACxG,UAAI,MAAM,KAAK,aAAc;AAC7B,YAAM,IAAI;AACV,YAAM,MAAM,CAAC,MAAM;AACnB,YAAM,MAAM;AACZ,YAAM,MAAM;AACZ,YAAM,MAAM;AACZ,YAAM,MAAM;AACZ,YAAM,MAAM;AACZ,UAAI,KAAK,IAAI,MAAM,EAAE,IAAI,OAAO,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,IAAI,KAAK;AACpE,cAAM,OAAO;AACb,cAAM,KAAK,KAAK,MAAM,MAAM,KAAKC,aAAY,IAAIA;AACjD,cAAM,KAAK,KAAK,MAAM,MAAM,KAAKA,aAAY,IAAIA;MACnD;IACF;EACF;AC/HA,MAAMG,YAAW;AACjB,MAAMN,OAAgB,CAAC,GAAG,GAAG,CAAC;AAC9B,MAAMO,gBAAe;AACrB,MAAM,eAAe;AAGrB,MAAM,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE;AAqBpD,WAAS,cAAqB;AAC5B,WAAO,EAAE,IAAI,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQP,MAAI,OAAO,QAAW,UAAU,IAAI,OAAO,GAAG,SAAS,EAAE;EACzJ;AAGO,MAAM,YAAN,MAAgB;IAKrB,YAA6B,SAA0B;AAA1B,oBAAA,MAAA,WAAA,OAAA;AAJ7B,oBAAA,MAAS,UAAkB,MAAM,KAAK,EAAE,QAAQM,UAAS,GAAG,WAAW,CAAA;AACvE,oBAAA,MAAA,SAAQ,CAAA;AACR,oBAAA,MAAQ,QAAO,CAAA;IAEyC;IAExD,IAAI,GAAW,GAAW,GAAW,MAAc,OAAe,UAAwB,CAAC,GAAS;AAClG,YAAM,SAAS,KAAK,QAAQ;AAC5B,YAAM,QAAQ,KAAK,SAASA;AAC5B,YAAME,SAAQ,KAAK,OAAO,KAAK;AAC/B,YAAM,SAAS,QAAQ,KAAKR;AAC5B,aAAO,QAAQ,GAAG,IAAI;AACtB,YAAM,SAAS,OAAS,QAAQ,KAAM;AACtCQ,aAAM,KAAK;AACXA,aAAM,IAAI,IAAI,OAAO,CAAC,IAAI;AAC1BA,aAAM,IAAI,IAAI,OAAO,CAAC,IAAI;AAC1BA,aAAM,IAAI,IAAI,OAAO,CAAC,IAAI;AAC1BA,aAAM,KAAK,QAAQ,QAAQ,KAAK,IAAI,OAAO,QAAQ,KAAK,GAAG;AAC3DA,aAAM,KAAK,QAAQ,QAAQ,MAAM,OAAO,QAAQ,MAAM,GAAG;AACzDA,aAAM,IAAI,EAAE,QAAQ,SAAS;AAC7BA,aAAM,OAAO,QAAQ,QAAQ;AAC7BA,aAAM,OAAO,QAAQ,QAAQD;AAC7BC,aAAM,QAAQ;AACdA,aAAM,SAAS;AACf,YAAM,QAAQ,QAAQ,UAAU,QAAQ,OAAO,UAAU;AACzDA,aAAM,QAAQ;AACdA,aAAM,QAAQ,QAAQ,QAAQ,CAAC,QAAQ,QAAQ,IAAI,QAAQ,UAAU,UAAU,WAAW,UAAU,SAAS,KAAK;AAClHA,aAAM,UAAU,QAAQ,QAAQ,CAAC,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,SAAS,UAAU,WAAW,UAAU,SAAS,KAAK;AAC9HA,aAAM,WAAW,QAAQ,QAAQ,UAAU,SAAS,UAAW;IACjE;IAEA,QAAc;AACZ,iBAAWA,UAAS,KAAK,OAAQA,QAAM,KAAK;AAC5C,WAAK,QAAQ;IACf;IAEA,OAAO,IAAkB;AACvB,WAAK,QAAQ;AACb,iBAAWA,UAAS,KAAK,QAAQ;AAC/B,YAAI,CAACA,OAAM,GAAI;AACf,aAAK;AACLA,eAAM,KAAK;AACX,YAAIA,OAAM,IAAI,EAAG;AACjBA,eAAM,QAAQ;AACd,YAAIA,OAAM,QAAQ,GAAG;AACnBA,iBAAM,KAAK;AACX;QACF;AACA,cAAM,cAAcA,OAAM,UAAU,UAAUA,OAAM,UAAU,UAAU,YAAYA,OAAM,KAAK,IAAI;AACnG,YAAI,gBAAgBA,OAAM,IAAI,YAAY,CAAC,KAAK,YAAY,CAAC,KAAK,EAAGA,QAAM,KAAK;MAClF;IACF;EACF;AChFA,MAAM,kBAAkB;AACxB,MAAM,oBAAoB;AAC1B,MAAMC,YAAW;AAUV,MAAM,aAAN,MAAiB;IAyBtB,YAAqB,UAAmC,SAA0B;AAA7D,oBAAA,MAAA,YAAA,QAAA;AAAmC,oBAAA,MAAA,WAAA,OAAA;AAxBxD,oBAAA,MAAA,SAAQ,CAAA;AACR,oBAAA,MAAS,UAAA;AACT,oBAAA,MAAS,UAAA;AACT,oBAAA,MAAS,YAAA;AACT,oBAAA,MAAS,UAAA;AACT,oBAAA,MAAS,MAAA;AACT,oBAAA,MAAS,SAAA;AACT,oBAAA,MAAS,WAAA;AACT,oBAAA,MAAS,QAAA;AACT,oBAAA,MAAS,YAAA;AACT,oBAAA,MAAS,SAAA;AACT,oBAAA,MAAS,MAAA;AACT,oBAAA,MAAS,QAAA;AACT,oBAAA,MAAS,YAAA;AACT,oBAAA,MAAS,WAAA;AAET,oBAAA,MAAS,OAAA;AACT,oBAAA,MAAS,MAAA;AACT,oBAAA,MAAS,OAAA;AACT,oBAAA,MAAiB,cAAA;AACjB,oBAAA,MAAiB,cAAA;AACjB,oBAAA,MAAiB,aAAyB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,CAAA;AAC7D,oBAAA,MAAiB,QAAoB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,CAAA;AAGtD,YAAM,cAAc,MAAoB,IAAI,aAAa,WAAW,iBAAiB;AACrF,YAAM,cAAc,MAAoB,IAAI,aAAa,QAAQ;AACjE,WAAK,WAAW,YAAY;AAC5B,WAAK,WAAW,YAAY;AAC5B,WAAK,aAAa,YAAY;AAC9B,WAAK,WAAW,YAAY;AAC5B,WAAK,QAAQ,YAAY;AACzB,WAAK,OAAO,YAAY;AACxB,WAAK,UAAU,YAAY;AAC3B,WAAK,YAAY,YAAY;AAC7B,WAAK,SAAS,YAAY;AAC1B,WAAK,aAAa,YAAY;AAC9B,WAAK,UAAU,YAAY;AAC3B,WAAK,OAAO,YAAY;AACxB,WAAK,SAAS,YAAY;AAC1B,WAAK,YAAY,YAAY;AAC7B,WAAK,OAAO,YAAY;AACxB,WAAK,QAAQ,YAAY;AACzB,WAAK,aAAa,IAAI,WAAW,QAAQ;AACzC,WAAK,eAAe,CAAC,KAAK,UAAU,KAAK,UAAU,KAAK,YAAY,KAAK,QAAQ;AACjF,WAAK,eAAe,CAAC,KAAK,MAAM,KAAK,SAAS,KAAK,WAAW,KAAK,QAAQ,KAAK,YAAY,KAAK,SAAS,KAAK,MAAM,KAAK,QAAQ,KAAK,YAAY,KAAK,SAAS;IACnK;IAEA,MAAM,SAA4B;AAChC,UAAI,KAAK,SAAS,KAAK,SAAU;AACjC,YAAM,SAAuB,KAAK,QAAQ;AAC1C,YAAM,QAAQ,KAAK;AACnB,YAAM,SAAS,QAAQ;AACvB,UAAI,CAAC,GAAG,GAAG,CAAC,IAAI,QAAQ;AACxB,UAAI,QAAQ,GAAG;AACb,mBAAW,QAAQ,KAAK,IAAI;AAC5B,cAAM,QAAQ,KAAK,KAAK,OAAO,KAAK,CAAC,IAAI,QAAQ;AACjD,aAAK,KAAK,KAAK,IAAI;AACnB,aAAK,KAAK,KAAK,IAAI,SAAS,QAAQ,OAAO,IAAI;AAC/C,aAAK,KAAK,KAAK,IAAI;MACrB;AACA,UAAI,QAAQ,KAAK;AACf,aAAK,OAAO,QAAQ,CAAC,QAAQ,IAAI,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC;AACnD,aAAK,OAAO,QAAQ,CAAC,QAAQ,IAAI,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC;AACnD,aAAK,OAAO,QAAQ,CAAC,QAAQ,IAAI,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC;MACrD;AACA,WAAK,SAAS,MAAM,IAAI;AACxB,WAAK,SAAS,SAAS,CAAC,IAAI;AAC5B,WAAK,SAAS,SAAS,CAAC,IAAI;AAC5B,oBAAc,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,KAAK,KAAK,SAAS;AACtE,YAAM,QAAQ,UAAU,QAAQ,QAAQ,EAAE;AAC1C,WAAK,SAAS,MAAM,IAAI,KAAK,UAAU,IAAI,SAAS,QAAQ,IAAI,QAAQ,EAAE,CAAC,IAAI;AAC/E,WAAK,SAAS,SAAS,CAAC,IAAI,KAAK,UAAU,IAAI,SAAS,QAAQ,IAAI,QAAQ,EAAE,CAAC,IAAI;AACnF,WAAK,SAAS,SAAS,CAAC,IAAI,KAAK,UAAU,IAAI,SAAS,QAAQ,IAAI,QAAQ,EAAE,CAAC,IAAI;AACnF,YAAM,QAAQ,SAAS,QAAQ,MAAM,QAAQ;AAC7C,YAAM,MAAM,QAAQ,MAAM,OAAO,SAAS,QAAQ,EAAE,IAAI;AACxD,eAAS,UAAU,GAAG,UAAU,mBAAmB,WAAW;AAC5D,aAAK,WAAW,SAAS,OAAO,IAAI,MAAM,OAAO;AACjD,aAAK,SAAS,SAAS,OAAO,IAAI,IAAI,OAAO;MAC/C;AACA,WAAK,KAAK,KAAK,IAAI,KAAK,QAAQ,KAAK,IAAI,UAAU,QAAQ,QAAQ,QAAQ,CAAC;AAC5E,WAAK,UAAU,KAAK,IAAI,UAAU,QAAQ,QAAQ,QAAQ,GAAG;AAC7D,WAAK,OAAO,KAAK,IAAI,QAAQ,QAAQ;AACrC,WAAK,WAAW,KAAK,IAAI,QAAQ,KAAK;AACtC,WAAK,QAAQ,KAAK,IAAI,QAAQ,KAAK;AACnC,WAAK,KAAK,KAAK,IAAI,QAAQ,QAAQ;AACnC,WAAK,OAAO,KAAK,IAAI,QAAQ,MAAM;AACnC,WAAK,WAAW,KAAK,IAAI,QAAQ,OAAO;AACxC,WAAK,UAAU,KAAK,IAAI,QAAQ,KAAK,UAAU,QAAQ,QAAQ,EAAE,IAAI;IACvE;IAEA,KAAK,OAAqB;AACxB,YAAM,OAAO,EAAE,KAAK;AACpB,UAAI,UAAU,KAAM;AACpB,iBAAW,SAAS,KAAK,cAAc;AACrC,iBAAS,YAAY,GAAG,YAAY,mBAAmB,YAAa,OAAM,QAAQ,oBAAoB,SAAS,IAAI,MAAM,OAAO,oBAAoB,SAAS;MAC/J;AACA,iBAAW,SAAS,KAAK,aAAc,OAAM,KAAK,IAAI,MAAM,IAAI;IAClE;IAEA,QAAc;AACZ,WAAK,QAAQ;IACf;IAEA,OAAO,IAAY,YAAmC;AACpD,YAAM,EAAE,UAAU,SAAS,IAAI;AAC/B,eAAS,QAAQ,KAAK,QAAQ,GAAG,SAAS,GAAG,SAAS;AACpD,aAAK,KAAK,KAAK,KAAK;AACpB,YAAI,KAAK,KAAK,KAAK,KAAK,GAAG;AACzB,eAAK,KAAK,KAAK;AACf;QACF;AACA,cAAM,SAAS,QAAQ;AACvB,cAAM,MAAM,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,QAAQ,KAAK;AACrD,iBAAS,SAAS,CAAC,KAAK,KAAK,QAAQ,KAAK,IAAI;AAC9C,cAAM,SAAS,KAAK,IAAI,GAAG,IAAI,KAAK,KAAK,KAAK,IAAI,EAAE;AACpD,iBAAS,MAAM,KAAK;AACpB,iBAAS,SAAS,CAAC,KAAK;AACxB,iBAAS,SAAS,CAAC,KAAK;AACxB,iBAAS,MAAM,KAAK,SAAS,MAAM,IAAI;AACvC,iBAAS,SAAS,CAAC,KAAK,SAAS,SAAS,CAAC,IAAI;AAC/C,iBAAS,SAAS,CAAC,KAAK,SAAS,SAAS,CAAC,IAAI;AAC/C,cAAM,OAAO,KAAK,WAAW,KAAK;AAClC,YAAI,MAAM;AACR,gBAAM,eAAe,KAAK,QAAQ,SAAS,SAAS,MAAM,GAAG,SAAS,SAAS,CAAC,CAAC;AACjF,cAAI,SAAS,SAAS,CAAC,IAAI,cAAc;AACvC,gBAAI,SAAS,GAAG;AACd,mBAAK,KAAK,KAAK;AACf;YACF;AACA,gBAAI,SAAS,GAAG;AACd,uBAAS,SAAS,CAAC,IAAI,eAAe;AACtC,uBAAS,SAAS,CAAC,KAAK;AACxB,uBAAS,MAAM,KAAK;AACpB,uBAAS,SAAS,CAAC,KAAK;YAC1B;AACA,gBAAI,SAAS,GAAG;AACd,kBAAI,KAAK,QAAQ,QAAQ,QAAQ,GAAG;AAClC,sBAAM,MAAO,KAAK,WAAW,MAAM,IAAIA,aAAa;AACpD,sBAAM,QAAS,KAAK,WAAW,SAAS,CAAC,IAAIA,aAAa;AAC1D,2BAAW,SAAS,MAAM,GAAG,cAAc,SAAS,SAAS,CAAC,GAAG,KAAK,UAAU,KAAK,GAAG,MAAM,QAAS,KAAK,WAAW,SAAS,CAAC,IAAIA,WAAW,EAAE,MAAM,MAAM,OAAO,QAAQ,CAAC;cAChL;AACA,mBAAK,KAAK,KAAK;AACf;YACF;UACF;QACF;AACA,aAAK,KAAK,KAAK,IAAI,KAAK,UAAU,KAAK,KAAK,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK;AAC3E,cAAM,SAAS,KAAK,OAAO,KAAK;AAChC,aAAK,MAAM,KAAK,IAAI,KAAK,WAAW,KAAK,KAAK,SAAS,KAAK,MAAM,SAAS,MAAM,SAAS,KAAK,MAAM,WAAW,IAAI;AACpH,iBAAS,UAAU,GAAG,UAAU,mBAAmB,UAAW,MAAK,MAAM,SAAS,OAAO,IAAI,KAAK,KAAK,WAAW,SAAS,OAAO,GAAG,KAAK,SAAS,SAAS,OAAO,GAAG,GAAG;MAC3K;IACF;EACF;ACvKA,MAAMC,qBAAoB;AAC1B,MAAM,iBAAiB;AACvB,MAAM,kBAAkB;AAGjB,MAAM,aAAN,MAAiB;IAoBtB,YAAqB,UAAmC,SAA0B;AAA7D,oBAAA,MAAA,YAAA,QAAA;AAAmC,oBAAA,MAAA,WAAA,OAAA;AAnBxD,oBAAA,MAAA,SAAQ,CAAA;AACR,oBAAA,MAAS,OAAA;AACT,oBAAA,MAAS,UAAA;AACT,oBAAA,MAAS,YAAA;AACT,oBAAA,MAAS,UAAA;AACT,oBAAA,MAAS,MAAA;AACT,oBAAA,MAAS,SAAA;AACT,oBAAA,MAAS,QAAA;AACT,oBAAA,MAAS,SAAA;AACT,oBAAA,MAAS,MAAA;AACT,oBAAA,MAAS,YAAA;AACT,oBAAA,MAAS,YAAA;AAET,oBAAA,MAAS,SAAA;AACT,oBAAA,MAAS,cAAA;AACT,oBAAA,MAAiB,cAAA;AACjB,oBAAA,MAAiB,cAAA;AACjB,oBAAA,MAAiB,aAAyB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,CAAA;AAG3D,YAAM,cAAc,MAAoB,IAAI,aAAa,WAAWA,kBAAiB;AACrF,YAAM,cAAc,MAAoB,IAAI,aAAa,QAAQ;AACjE,WAAK,QAAQ,YAAY;AACzB,WAAK,WAAW,YAAY;AAC5B,WAAK,aAAa,YAAY;AAC9B,WAAK,WAAW,YAAY;AAC5B,WAAK,OAAO,YAAY;AACxB,WAAK,UAAU,YAAY;AAC3B,WAAK,SAAS,YAAY;AAC1B,WAAK,UAAU,YAAY;AAC3B,WAAK,OAAO,YAAY;AACxB,WAAK,aAAa,YAAY;AAC9B,WAAK,aAAa,IAAI,WAAW,QAAQ;AACzC,WAAK,UAAU,IAAI,aAAa,WAAW,cAAc;AACzD,WAAK,eAAe,IAAI,aAAa,WAAW,cAAc;AAC9D,WAAK,eAAe,CAAC,KAAK,OAAO,KAAK,UAAU,KAAK,YAAY,KAAK,QAAQ;AAC9E,WAAK,eAAe,CAAC,KAAK,MAAM,KAAK,SAAS,KAAK,QAAQ,KAAK,SAAS,KAAK,MAAM,KAAK,YAAY,KAAK,UAAU;IACtH;IAEA,MAAM,SAA4B;AAChC,UAAI,KAAK,SAAS,KAAK,SAAU;AACjC,YAAM,SAAS,KAAK,QAAQ;AAC5B,YAAM,QAAQ,KAAK;AACnB,YAAM,SAAS,QAAQA;AACvB,UAAI,CAAC,GAAG,GAAG,CAAC,IAAI,QAAQ;AACxB,UAAI,QAAQ,KAAK;AACf,aAAK,OAAO,QAAQ,CAAC,QAAQ,IAAI,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC;AACnD,aAAK,OAAO,QAAQ,CAAC,QAAQ,IAAI,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC;AACnD,aAAK,OAAO,QAAQ,CAAC,QAAQ,IAAI,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC;MACrD;AACA,WAAK,MAAM,MAAM,IAAI;AACrB,WAAK,MAAM,SAAS,CAAC,IAAI;AACzB,WAAK,MAAM,SAAS,CAAC,IAAI;AACzB,oBAAc,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,KAAK,KAAK,SAAS;AACtE,YAAM,QAAQ,UAAU,QAAQ,QAAQ,EAAE;AAC1C,WAAK,SAAS,MAAM,IAAI,KAAK,UAAU,IAAI,SAAS,QAAQ,IAAI,QAAQ,EAAE,CAAC,IAAI;AAC/E,WAAK,SAAS,SAAS,CAAC,IAAI,KAAK,UAAU,IAAI,SAAS,QAAQ,IAAI,QAAQ,EAAE,CAAC,IAAI;AACnF,WAAK,SAAS,SAAS,CAAC,IAAI,KAAK,UAAU,IAAI,SAAS,QAAQ,IAAI,QAAQ,EAAE,CAAC,IAAI;AACnF,YAAM,QAAQ,SAAS,QAAQ,MAAM,QAAQ;AAC7C,YAAM,MAAM,QAAQ,MAAM,OAAO,SAAS,QAAQ,EAAE,IAAI;AACxD,eAAS,UAAU,GAAG,UAAUA,oBAAmB,WAAW;AAC5D,aAAK,WAAW,SAAS,OAAO,IAAI,MAAM,OAAO;AACjD,aAAK,SAAS,SAAS,OAAO,IAAI,IAAI,OAAO;MAC/C;AACA,WAAK,KAAK,KAAK,IAAI,KAAK,QAAQ,KAAK,IAAI,UAAU,QAAQ,QAAQ,QAAQ,GAAG;AAC9E,WAAK,OAAO,KAAK,IAAI,QAAQ,OAAO;AACpC,WAAK,QAAQ,KAAK,IAAI,QAAQ,KAAK;AACnC,WAAK,KAAK,KAAK,IAAI,QAAQ,QAAQ;AACnC,WAAK,WAAW,KAAK,IAAI,QAAQ,OAAO;AACxC,WAAK,WAAW,KAAK,IAAI,QAAQ,KAAK;IACxC;IAEA,KAAK,OAAqB;AACxB,YAAM,OAAO,EAAE,KAAK;AACpB,UAAI,UAAU,KAAM;AACpB,iBAAW,SAAS,KAAK,cAAc;AACrC,iBAAS,YAAY,GAAG,YAAYA,oBAAmB,YAAa,OAAM,QAAQA,qBAAoB,SAAS,IAAI,MAAM,OAAOA,qBAAoB,SAAS;MAC/J;AACA,iBAAW,SAAS,KAAK,aAAc,OAAM,KAAK,IAAI,MAAM,IAAI;IAClE;IAEA,QAAc;AACZ,WAAK,QAAQ;IACf;IAEA,OAAO,IAAkB;AACvB,YAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,eAAS,QAAQ,KAAK,QAAQ,GAAG,SAAS,GAAG,SAAS;AACpD,aAAK,KAAK,KAAK,KAAK;AACpB,YAAI,KAAK,KAAK,KAAK,KAAK,GAAG;AACzB,eAAK,KAAK,KAAK;AACf;QACF;AACA,cAAM,SAAS,QAAQA;AACvB,cAAM,MAAM,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,QAAQ,KAAK;AACrD,iBAAS,SAAS,CAAC,KAAK,KAAK,QAAQ,KAAK,IAAI;AAC9C,cAAM,SAAS,KAAK,IAAI,GAAG,IAAI,KAAK,KAAK,KAAK,IAAI,EAAE;AACpD,iBAAS,MAAM,KAAK;AACpB,iBAAS,SAAS,CAAC,KAAK;AACxB,iBAAS,SAAS,CAAC,KAAK;AACxB,cAAM,MAAM,KAAK,SAAS,MAAM,IAAI;AACpC,cAAM,SAAS,CAAC,KAAK,SAAS,SAAS,CAAC,IAAI;AAC5C,cAAM,SAAS,CAAC,KAAK,SAAS,SAAS,CAAC,IAAI;AAC5C,YAAI,KAAK,WAAW,KAAK,GAAG;AAC1B,gBAAM,eAAe,KAAK,QAAQ,SAAS,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,CAAC;AAC3E,cAAI,MAAM,SAAS,CAAC,IAAI,cAAc;AACpC,gBAAI,KAAK,WAAW,KAAK,MAAM,GAAG;AAChC,mBAAK,KAAK,KAAK;AACf;YACF;AACA,kBAAM,SAAS,CAAC,IAAI,eAAe;AACnC,qBAAS,SAAS,CAAC,KAAK;AACxB,qBAAS,MAAM,KAAK;AACpB,qBAAS,SAAS,CAAC,KAAK;UAC1B;QACF;AACA,cAAM,SAAS,KAAK,OAAO,KAAK;AAChC,cAAM,QAAQ,KAAK,WAAW,KAAK,KAAK,IAAI;AAC5C,cAAMZ,MAAK,QAAQ;AACnB,aAAK,QAAQA,GAAE,IAAI,MAAM,MAAM;AAC/B,aAAK,QAAQA,MAAK,CAAC,IAAI,MAAM,SAAS,CAAC;AACvC,aAAK,QAAQA,MAAK,CAAC,IAAI,MAAM,SAAS,CAAC;AACvC,aAAK,QAAQA,MAAK,CAAC,IAAI,MAAM,MAAM,IAAI,SAAS,MAAM,IAAI;AAC1D,aAAK,QAAQA,MAAK,CAAC,IAAI,MAAM,SAAS,CAAC,IAAI,SAAS,SAAS,CAAC,IAAI;AAClE,aAAK,QAAQA,MAAK,CAAC,IAAI,MAAM,SAAS,CAAC,IAAI,SAAS,SAAS,CAAC,IAAI;AAClE,iBAAS,UAAU,GAAG,UAAUY,oBAAmB,WAAW;AAC5D,gBAAM,QAAQ,KAAK,KAAK,WAAW,SAAS,OAAO,GAAG,KAAK,SAAS,SAAS,OAAO,GAAG,GAAG,IAAI;AAC9F,eAAK,aAAaZ,MAAK,OAAO,IAAI;AAClC,eAAK,aAAaA,MAAK,IAAI,OAAO,IAAI,QAAQ;QAChD;MACF;IACF;EACF;AC9IA,MAAM,gBAAgB;AACtB,MAAM,iBAAiB;AACvB,MAAME,OAAgB,CAAC,GAAG,GAAG,CAAC;AAC9B,MAAM,yBAAyB;AAexB,MAAM,eAAN,MAAmB;IAAnB,cAAA;AACL,oBAAA,MAAS,SAAoB,MAAM,KAAK,EAAE,QAAQ,cAAc,GAAG,OAAO,EAAE,IAAI,OAAO,OAAOA,MAAI,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQA,MAAI,MAAM,EAAE,EAAE,CAAA;AACrK,oBAAA,MAAA,SAAQ,CAAA;AACR,oBAAA,MAAQ,QAAO,CAAA;IAAA;IAEf,IAAI,OAAkB,MAAc,IAAY,UAAkB,OAAe,QAAoB,MAAqB;AACxH,YAAMC,QAAO,KAAK,MAAM,KAAK,SAAS,aAAa;AACnDA,YAAK,KAAK;AACVA,YAAK,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAC1CA,YAAK,OAAO;AACZA,YAAK,KAAK;AACVA,YAAK,IAAI;AACTA,YAAK,WAAW;AAChBA,YAAK,QAAQ;AACbA,YAAK,SAAS,UAAUD;AACxBC,YAAK,OAAO,QAAQ;IACtB;IAEA,QAAc;AACZ,iBAAWA,SAAQ,KAAK,MAAOA,OAAK,KAAK;AACzC,WAAK,QAAQ;IACf;IAEA,OAAO,IAAkB;AACvB,WAAK,QAAQ;AACb,iBAAWA,SAAQ,KAAK,OAAO;AAC7B,YAAI,CAACA,MAAK,GAAI;AACd,aAAK;AACLA,cAAK,KAAK;AACV,YAAIA,MAAK,IAAIA,MAAK,YAAY,KAAK,CAACA,MAAK,KAAMA,OAAK,KAAK;MAC3D;IACF;EACF;AAsBO,MAAM,iBAAN,MAAqB;IAQ1B,YAA6B,SAA0B;AAA1B,oBAAA,MAAA,WAAA,OAAA;AAP7B,oBAAA,MAAS,UAAuB,MAAM,KAAK,EAAE,QAAQ,eAAe,GAAG,OAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,OAAO,UAAU,UAAU,wBAAwB,MAAM,GAAG,UAAU,GAAG,GAAG,GAAG,WAAW,EAAE,EAAE,CAAA;AAChM,oBAAA,MAAS,QAAwB;QAC/B,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,WAAW,EAAE;QACjC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,WAAW,EAAE;MACnC,CAAA;AACA,oBAAA,MAAQ,QAAO,CAAA;IAEyC;IAExD,IAAI,MAAc;AAChB,aAAO,KAAK,OAAO,OAAO,CAAC,UAAU,MAAM,YAAY,CAAC,EAAE;IAC5D;IAEA,MAAM,OAAkB,OAAe,WAAmB,UAAkB,UAAmB,OAAgC;AAC7H,YAAM,EAAE,MAAM,IAAI,KAAK,QAAQ;AAC/B,UAAI,SAAS,KAAK,CAAC,MAAO;AAC1B,UAAI,SAAS,KAAK,UAAU,OAAQ;AACpC,YAAM,QAAQ,KAAK,OAAO,KAAK,SAAS,cAAc;AACtD,YAAM,IAAI,MAAM,CAAC;AACjB,YAAM,IAAI,MAAM,CAAC;AACjB,YAAM,IAAI,MAAM,CAAC;AACjB,YAAM,QAAQ;AACd,YAAM,WAAW,YAAY;AAC7B,YAAM,OAAO;AACb,YAAM,WAAW;AACjB,YAAM,IAAI;AACV,YAAM,YAAY;IACpB;IAEA,QAAc;AACZ,iBAAW,SAAS,KAAK,OAAQ,OAAM,YAAY;AACnD,iBAAW,SAAS,KAAK,KAAM,OAAM,YAAY;IACnD;IAEA,OAAO,IAAkB;AACvB,iBAAW,SAAS,KAAK,QAAQ;AAC/B,YAAI,MAAM,aAAa,EAAG;AAC1B,cAAM,KAAK;AACX,cAAM,MAAM,MAAM,IAAI,MAAM;AAC5B,cAAM,YAAY,OAAO,IAAI,IAAI,MAAM,QAAQ,IAAI,QAAQ,IAAI;MACjE;IACF;EACF;AC1GA,MAAM,sBAAsB,CAAC,GAAG,KAAK,GAAG;AACxC,MAAM,oBAAoB;AAC1B,MAAM,sBAAsB;AAC5B,MAAM,YAAY;AA2CX,WAAS,eAAe,GAAW,GAAmB;AAC3D,WAAO,IAAI,QAAQ,IAAI,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO;EAC3D;AAMO,MAAM,iBAAN,MAAqB;IAgB1B,YAAY,SAA0B;AAftC,oBAAA,MAAS,SAAA;AACT,oBAAA,MAAS,KAAA;AACT,oBAAA,MAAS,QAAA;AACT,oBAAA,MAAS,SAAA;AACT,oBAAA,MAAS,QAAA;AACT,oBAAA,MAAS,QAAA;AACT,oBAAA,MAAS,SAAQ,IAAI,aAAa,CAAA;AAClC,oBAAA,MAAS,QAAA;AACT,oBAAA,MAAS,UAAsB,kBAAkB,CAAA;AACjD,oBAAA,MAAS,QAAmB,CAAC,CAAA;AAC7B,oBAAA,MAAA,QAAoB,CAAC,CAAA;AAErB,oBAAA,MAAA,WAAA;AACA,oBAAA,MAAiB,gBAAe,oBAAI,IAAoB,CAAA;AAGtD,YAAM,UAAU,QAAQ,WAAW,SAAS;AAC5C,WAAK,UAAU,EAAE,QAAQ,QAAQ,QAAQ,UAAU,QAAQ,YAAY,gBAAgB,SAAS,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,OAAO,QAAQ,MAAM;AAC5I,WAAK,MAAM,IAAI,WAAW,QAAQ,QAAQ,KAAK,KAAK,OAAO;AAC3D,WAAK,SAAS,IAAI,WAAW,QAAQ,QAAQ,QAAQ,KAAK,OAAO;AACjE,WAAK,UAAU,IAAI,WAAW,QAAQ,SAAS,KAAK,OAAO;AAC3D,WAAK,SAAS,IAAI,WAAW,KAAK,OAAO;AACzC,WAAK,SAAS,IAAI,UAAU,KAAK,OAAO;AACxC,WAAK,SAAS,IAAI,eAAe,KAAK,OAAO;IAC/C;IAEA,IAAI,SAAuB;AACzB,aAAO,KAAK,QAAQ;IACtB;IAEA,IAAI,UAAkB;AACpB,aAAO,KAAK,QAAQ,QAAQ;IAC9B;IAEA,WAAW,OAAqB;AAC9B,WAAK,QAAQ,QAAQ,QAAQ;AAC7B,WAAK,QAAQ,QAAQ,OAAO,oBAAoB,KAAK,KAAK;IAC5D;;IAGA,OAAO,OAAuB;AAC5B,aAAO,KAAK,IAAI,QAAQ,IAAI,IAAI,GAAG,KAAK,MAAM,QAAQ,KAAK,QAAQ,QAAQ,IAAI,CAAC;IAClF;;IAGA,MAAM,OAA6B;AACjC,YAAM,YAAY,KAAK;AACvB,UAAI,CAAC,UAAW,QAAO;AACvB,YAAM,EAAE,QAAQ,QAAQ,IAAI,IAAI;AAChC,YAAM,IAAI,MAAM,CAAC,IAAI,OAAO,CAAC;AAC7B,YAAM,IAAI,MAAM,CAAC,IAAI,OAAO,CAAC;AAC7B,YAAMU,OAAM,KAAK,IAAI,GAAG;AACxB,YAAMC,OAAM,KAAK,IAAI,GAAG;AACxB,aAAO,CAAC,OAAO,CAAC,IAAID,OAAM,IAAIC,OAAM,GAAG,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,IAAIA,OAAM,IAAID,OAAM,CAAC;IACxG;;IAGA,KAAK,QAA8B;AACjC,YAAM,YAAY,KAAK;AACvB,UAAI,CAAC,UAAW,QAAO;AACvB,YAAMA,OAAM,KAAK,IAAI,UAAU,GAAG;AAClC,YAAMC,OAAM,KAAK,IAAI,UAAU,GAAG;AAClC,aAAO,CAACD,OAAM,OAAO,CAAC,IAAIC,OAAM,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,CAACA,OAAM,OAAO,CAAC,IAAID,OAAM,OAAO,CAAC,CAAC;IAC1F;IAEQ,OAA8F,SAAe;AACnH,UAAI,CAAC,KAAK,UAAW,QAAO;AAC5B,aAAO,EAAE,GAAG,SAAS,GAAG,KAAK,MAAM,QAAQ,CAAC,GAAG,GAAI,QAAQ,MAAM,EAAE,KAAK,KAAK,KAAK,QAAQ,GAAG,EAAE,IAAI,CAAC,GAAI,GAAI,QAAQ,IAAI,EAAE,GAAG,KAAK,KAAK,QAAQ,CAAC,EAAE,IAAI,CAAC,EAAG;IAC5J;IAEA,MAAM,QAAsB,QAA2B;AACrD,YAAM,UAAU,KAAK,OAAO,MAAM;AAClC,WAAK,QAAQ,QAAQ,QAAQ,CAAC,OAAO,CAAC;AACtC,UAAI,WAAW,MAAO,MAAK,IAAI,MAAM,OAAO;eACnC,WAAW,SAAU,MAAK,OAAO,MAAM,OAAO;UAClD,MAAK,QAAQ,MAAM,OAAO;IACjC;IAEA,MAAM,QAAsB,OAAe,SAA4B;AACrE,YAAM,QAAQ,KAAK,OAAO,KAAK;AAC/B,eAAS,UAAU,GAAG,UAAU,OAAO,UAAW,MAAK,MAAM,QAAQ,OAAO;IAC9E;;IAGA,KAAK,KAAa,QAAsB,MAAc,IAAY,SAAkC;AAClG,UAAI,WAAW,KAAK,aAAa,IAAI,GAAG,KAAK,KAAK,OAAO,KAAK,QAAQ,QAAQ,OAAO;AACrF,aAAO,WAAW,GAAG;AACnB,mBAAW;AACX,aAAK,MAAM,QAAQ,QAAQ,CAAC;MAC9B;AACA,WAAK,aAAa,IAAI,KAAK,OAAO;IACpC;IAEA,YAAY,QAA2B;AACrC,YAAM,UAAU,KAAK,OAAO,MAAM;AAClC,WAAK,QAAQ,QAAQ,UAAU,CAAC,OAAO,CAAC;AACxC,WAAK,OAAO,MAAM,OAAO;IAC3B;IAEA,MAAM,QAAgF;AACpF,UAAI,OAAO;AACX,UAAI,KAAK,WAAW;AAClB,cAAM,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;AAC9D,cAAM,UAAU,OAAO,CAAC;AACxB,eAAO,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,SAAS,IAAI,EAAE,GAAG,SAAS,GAAG,KAAK,KAAK,QAAQ,CAAC,EAAE,IAAI,OAAO;MACvG;AACA,WAAK,QAAQ,QAAQ,SAAS,IAAI;AAClC,WAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;IACtE;IAEA,KAAK,QAAyF;AAC5F,YAAM,OAAO,KAAK,YAAa,CAAC,KAAK,MAAM,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,KAAK,KAAK,KAAK,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,IAAc;AAC7J,WAAK,QAAQ,QAAQ,QAAQ,IAAI;AACjC,WAAK,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;IAC9E;IAEA,MAAM,QAA0F;AAC9F,YAAM,OAAO,KAAK,YAAa,CAAC,KAAK,MAAM,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,IAAc;AAC1H,WAAK,QAAQ,QAAQ,SAAS,IAAI;AAClC,WAAK,OAAO,MAAM,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;IACxE;;IAGA,UAAU,MAAa,QAAmB,WAAmB,MAAoB;AAC/E,YAAM,QAAQ,KAAK,OAAO,KAAK,IAAI;AACnC,YAAM,QAAQ,KAAK,MAAM,MAAM;AAC/B,YAAM,IAAI,MAAM,CAAC;AACjB,YAAM,IAAI,MAAM,CAAC;AACjB,YAAM,IAAI,MAAM,CAAC;AACjB,YAAM,YAAY,aAAa,OAAO,oBAAoB,KAAK,IAAI,OAAO,EAAE,IAAI,KAAK,IAAI,OAAO,GAAG,IAAI,KAAK,OAAO,QAAQ,CAAC,qBAAqB,mBAAmB;IACtK;IAEA,SAAS,GAAW,GAAW,QAAgB,OAAe,OAAqB;AACjF,WAAK,KAAK,KAAK,EAAE,GAAG,GAAG,QAAQ,OAAO,OAAO,MAAM,KAAK,OAAO,QAAQ,GAAG,CAAC,EAAE,CAAC;IAChF;;IAGA,OAAO,IAAkB;AACvB,YAAM,aAAa,CAAC,GAAW,GAAW,GAAW,MAAc,OAAe,YAAgC;AAChH,aAAK,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,OAAO,OAAO,CAAC;MAC5C;AACA,WAAK,IAAI,OAAO,IAAI,UAAU;AAC9B,WAAK,OAAO,OAAO,IAAI,UAAU;AACjC,WAAK,QAAQ,OAAO,EAAE;AACtB,WAAK,OAAO,OAAO,EAAE;AACrB,WAAK,OAAO,OAAO,EAAE;AACrB,WAAK,MAAM,OAAO,EAAE;AACpB,WAAK,OAAO,OAAO,EAAE;AACrB,mBAAa,KAAK,QAAQ,EAAE;AAC5B,eAAS,QAAQ,KAAK,KAAK,SAAS,GAAG,SAAS,GAAG,SAAS;AAC1D,cAAM,OAAO,KAAK,KAAK,KAAK;AAC5B,aAAK,SAAS,KAAK;AACnB,aAAK,KAAK,KAAK,OAAO;AACtB,YAAI,KAAK,SAAS,EAAG,MAAK,KAAK,OAAO,OAAO,CAAC;MAChD;IACF;IAEA,QAAc;AACZ,WAAK,IAAI,MAAM;AACf,WAAK,OAAO,MAAM;AAClB,WAAK,QAAQ,MAAM;AACnB,WAAK,OAAO,MAAM;AAClB,WAAK,OAAO,MAAM;AAClB,WAAK,MAAM,MAAM;AACjB,WAAK,OAAO,MAAM;AAClB,WAAK,aAAa,MAAM;AACxB,uBAAiB,KAAK,MAAM;AAC5B,WAAK,KAAK,SAAS;AACnB,WAAK,OAAO,CAAC;IACf;EACF;ACnOO,MAAM,aAAkC,CAAC,SAAS,QAAQ,SAAS,SAAS,YAAY,MAAM;AC2JrG,MAAM,gBAAgB;AACtB,MAAME,iBAAgB;AACtB,MAAM,iBAAiB;AACvB,MAAM,YAAY;AAElB,WAAS,eAAe,SAA4C;AAClE,QAAI,YAAY,OAAW,QAAO,SAAS;AAC3C,WAAO,OAAO,YAAY,WAAW,SAAS,OAAO,IAAI;EAC3D;AAEA,WAAS,gBAAgB,KAAmB,QAA8B;AACxE,QAAI,WAAW,EAAG,QAAO;AACzB,UAAM,WAAW,IAAI,YAAY,EAAE,GAAG,IAAI,UAAU,QAAQ,IAAI,SAAS,SAAS,QAAQ,QAAQ,IAAI,SAAS,SAAS,OAAO;AAC/H,UAAM,WAAW,IAAI,eAAe,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,QAAQ,KAAK,SAAS,QAAQ,KAAK,KAAK,MAAM,KAAK,QAAQ,KAAK,KAAK,MAAM,KAAK,OAAO,EAAE;AACvJ,WAAO;MACL,GAAG;MACH,QAAQ,IAAI,SAAS;MACrB,QAAQ,IAAI,SAAS;MACrB,cAAc,IAAI,eAAe;MACjC,MAAM,EAAE,QAAQ,IAAI,KAAK,UAAU,IAAI,KAAK,SAAS,QAAQ,QAAQ,IAAI,KAAK,UAAU,IAAI,KAAK,SAAS,QAAQ,MAAM,IAAI,KAAK,QAAQ,IAAI,KAAK,OAAO,OAAO;MAChK,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;MAC/B,GAAI,WAAW,EAAE,eAAe,SAAS,IAAI,CAAC;IAChD;EACF;AAEO,WAAS,UAAU,UAAsB,CAAC,GAAa;AAC5D,UAAM,UAAU,eAAe,QAAQ,OAAO;AAC9C,UAAM,eAAe,OAAO,QAAQ,QAAQ,CAAC;AAC7C,UAAM,aAAa,QAAQ,cAAc;AACzC,UAAM,UAAU,QAAQ,WAAW;AACnC,UAAM,aAAa,QAAQ,cAAc;AACzC,UAAM,OAAoB,EAAE,GAAG,aAAa,GAAG,GAAG,aAAa,GAAG,GAAG,aAAa,EAAE;AACpF,QAAI,QAAQ,KAAM,EAAC,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC,IAAI,QAAQ;AACrD,UAAMC,UAAsB,EAAE,GAAG,GAAG,GAAG,KAAK,GAAG,EAAE;AACjD,UAAM,SAAS,OAAO,YAAY,WAAW,IAAI,CAACC,WAAU,CAACA,QAAO,IAAI,CAAC,CAAC;AAC1E,UAAM,SAAS,QAAQ;AACvB,UAAM,WAAW,QAAQ,aAAa,SAAS,CAAC,GAAW,MAAc,OAAO,SAAS,GAAG,CAAC,IAAI,MAAM;AACvG,UAAM,UAAU,EAAE,MAAM,GAAG,QAAQ,EAAE;AACrC,UAAM,MAAM,QAAQ,YAAY;AAChC,UAAM,eAAe,IAAI,iBAAiB;MACxC,UAAU,QAAQ,SAAS,aAAa,MAAM,OAAO;MACrD,SAAS,QAAQ,SAAS,YAAY,MAAM,MAAM;MAClD,MAAM,cAAc,QAAQ,QAAQ;MACpC;MACA,SAAS,QAAQ,WAAW;MAC5B,GAAI,QAAQ,SAAS,QAAQ,EAAE,OAAO,QAAQ,QAAQ,MAAM,IAAI,CAAC;IACnE,CAAC;AACD,UAAM,OAAgB;MACpB;MACA,OAAO,eAAe,QAAQ,KAAK;MACnC,QAAQ,gBAAgB,QAAQ,MAAM;MACtC,OAAO,eAAe,QAAQ,KAAK;MACnC,QAAQ,gBAAgB,QAAQ,QAAQ,YAAY;MACpD,OAAO,eAAe,eAAe,YAAY;MACjD,QAAQ,gBAAgB,cAAc;MACtC,OAAO,eAAeF,cAAa;MACnC,QAAQ,gBAAgB;MACxB,OAAO,gBAAgB;MACvB,QAAQ,kBAAkB;MAC1B;MACA,UAAU,eAAe;MACzB;MACA,QAAAC;MACA;MACA,OAAO,QAAQ,OAAO;MACtB,SAAS,QAAQ,YAAY,QAAQ,SAAY,cAAc,QAAQ,WAAW,aAAa;MAC/F;MACA;MACA,eAAe,QAAQ,iBAAiB;MACxC,SAAS,QAAQ,WAAW;MAC5B,OAAO,QAAQ;MACf,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,EAAE;MACrD,OAAO,EAAE,MAAM,GAAG,WAAW,IAAI,KAAK,GAAG,WAAW,KAAK;MACzD;MACA,MAAM,CAAC,YAAY,QAAQ,YAAY,OAAO;IAChD;AAEA,aAAS,aAAa,IAAsC;AAC1D,aAAO,WAAW,EAAE,KAAK,WAAW,QAAQ,EAAE,KAAK,EAAE;IACvD;AAEA,aAAS,SAAS,MAAwC;AACxD,UAAI,eAAe,SAAU,QAAO;AACpC,cAAQ;AACR,aAAO,UAAU,QAAQ,KAAK,KAAK,QAAQ,QAAQ,SAAS,KAAK,QAAQ,QAAQ,EAAE;IACrF;AAEA,aAAS,SAAS,KAAmB,OAAiBE,OAA0F;AAC9I,uBAAiB,MAAM,KAAK,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,WAAWA,MAAK,WAAW,QAAQA,MAAK,QAAQ,QAAQA,MAAK,OAAO,CAAC;IAC5I;AAEA,QAAI;AACJ,QAAI;AACJ,UAAM,UAAU,QAAQ,WAAW;AACnC,UAAM,OAAO,EAAE,IAAI,WAAsB;AAAE,aAAO,CAACF,QAAO,GAAGA,QAAO,GAAGA,QAAO,CAAC;IAAE,GAAG,SAAS,CAACG,WAAwC,CAACA,OAAM,CAAC,KAAK,GAAGA,OAAM,CAAC,KAAK,GAAGA,OAAM,CAAC,KAAK,CAAC,EAAE;AAEpL,aAAS,WAA2B;AAClC,aAAQ,WAAA,SAAW,IAAI,eAAe,EAAE,QAAQ,cAAc,SAAS,SAAS,CAAC;IACnF;AAEA,aAAS,eAA6B;AACpC,aAAQ,WAAA,SAAW,mBAAmB,EAAE,QAAQ,SAAS,GAAG,SAAS,KAAK,CAAC;IAC7E;AAEA,WAAO;MACL,KAAK,IAAI,OAAO,cAAc,CAAC,GAAG;AAChC,YAAI,EAAE,MAAM,SAAU,QAAO;AAC7B,cAAM,OAAO,YAAY,SAAS,eAAe,WAAW,SAAY,KAAK,KAAK,EAAE,QAAQ,QAAQ,SAAS,KAAK,QAAQ,QAAQ;AAClI,eAAO,aAAa,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,aAAa,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC,EAAG,CAAC;MAC5H;MACA,OAAO,CAAC,MAAM,OAAO,QAAQ,OAAO,OAAO,kBAAkB,aAAa,MAAM,MAAM,OAAO,QAAQ,OAAO,OAAO,aAAa;MAChI,OAAO,CAAC,MAAM,OAAO,UAAU,kBAAkB,aAAa,MAAM,MAAM,OAAO,UAAU,aAAa;MACxG,QAAQ,CAAC,OAAO,aAAa,aAAa,OAAO,OAAO,QAAQ;MAChE,SAAS,MAAM;MACf;MACA,cAAc,MAAM;MACpB,WAAW,MAAM,OAAO,KAAK,OAAO;MACpC,UAAU,IAAI,OAAO,mBAAmB,CAAC,GAAG;AAC1C,cAAM,OAAO,aAAa,EAAE;AAC5B,YAAI,CAAC,KAAM,QAAO;AAClB,cAAM,MAAM,gBAAgB,MAAM,iBAAiB,SAAS,CAAC;AAC7D,cAAM,SAAS,EAAE,QAAQ;AACzB,cAAM,YAAY,iBAAiB,aAAa,EAAE,GAAG,iBAAiB,UAAU,CAAC,GAAG,GAAG,iBAAiB,UAAU,CAAC,GAAG,GAAG,iBAAiB,UAAU,CAAC,EAAE;AACvJ,cAAM,SAAS,SAAS,iBAAiB,IAAI;AAC7C,YAAI,iBAAiB,MAAO,MAAK,SAAS,GAAG,KAAK,MAAM,OAAO,iBAAiB,OAAO,MAAM,SAAS,KAAK,OAAO,EAAE,WAAW,QAAQ,OAAO,CAAC,CAAC;YAC3I,UAAS,KAAK,OAAO,EAAE,WAAW,QAAQ,OAAO,CAAC;AACvD,eAAO;MACT;MACA,KAAK,aAAa;AAChB,cAAM,SAAS,EAAE,QAAQ;AACzB,cAAM,EAAE,OAAO,QAAQ,MAAM,QAAQ,YAAY,GAAG,KAAK,IAAI;AAC7D,gBAAQ,MAAM,SAAS,IAAI,GAAG;UAC5B,GAAG;UAAM,GAAG;UAAQ,GAAG,MAAM,CAAC;UAAG,GAAG,MAAM,CAAC;UAAG,GAAG,MAAM,CAAC;UAAG,IAAI,SAAS,CAAC,KAAK;UAAG,IAAI,SAAS,CAAC,KAAK;UAAG,IAAI,SAAS,CAAC,KAAK;UAC1H,GAAI,eAAe,SAAY,EAAE,OAAO,eAAe,UAAU,EAAE,IAAI,CAAC;QAC1E,GAAG,MAAM;AACT,eAAO;MACT;MACA,KAAK,OAAO,QAAQ,OAAO;AACzB,qBAAa,KAAK,OAAO,QAAQ,KAAK;AACtC,mBAAWC,SAAQ,KAAK,MAAM,OAAO;AACnC,gBAAM,KAAKA,MAAK,IAAI,MAAM,CAAC;AAC3B,gBAAM,KAAKA,MAAK,IAAI,MAAM,CAAC;AAC3B,gBAAM,KAAKA,MAAK,IAAI,MAAM,CAAC;AAC3B,gBAAM,WAAW,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AACtD,cAAI,YAAY,OAAQ;AACxB,gBAAM,WAAY,SAAS,IAAI,WAAW,WAAY,WAAW;AACjEA,gBAAK,MAAM,KAAK;AAChBA,gBAAK,MAAM,KAAK;AAChBA,gBAAK,MAAM,KAAK;QAClB;MACF;MACA,KAAK,QAAQ;AACX,gBAAQ,KAAK,MAAM;AACnB,cAAM,QAAQ,KAAK;AACnB,iBAAS,QAAQ,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAS,KAAI,MAAM,MAAM,KAAK,EAAG,WAAW,OAAQ,OAAM,SAAS,KAAK;MAC/H;MACA,SAASH,QAAO,IAAI;AAClB,eAAOA,MAAK,IAAI;MAClB;MACA,OAAO,CAACA,WAAU,OAAOA,MAAK;MAC9B,UAAU,UAAU;AAClBD,gBAAO,IAAI,SAAS,CAAC;AACrBA,gBAAO,IAAI,SAAS,CAAC;AACrBA,gBAAO,IAAI,SAAS,CAAC;MACvB;MACA,SAAS,OAAO;AACd,aAAK,MAAM,YAAY;MACzB;MACA,OAAO,IAAI;AACT,aAAK,MAAM,QAAQ;AACnB,aAAK,SAAS,OAAO,KAAK,MAAM,IAAI;AACpC,oBAAY,KAAK,OAAO,EAAE;AAC1B,oBAAY,KAAK,OAAO,IAAI,IAAI;AAChC,qBAAa,KAAK,QAAQ,EAAE,IAAI,SAAS,CAAC;AAC1C,oBAAY,KAAK,OAAO,EAAE;AAC1B,qBAAa,KAAK,QAAQ,KAAK,MAAM,OAAO,EAAE;AAC9C,qBAAa,MAAM,EAAE;AACrB,oBAAY,MAAM,EAAE;AACpB,qBAAa,KAAK,QAAQ,EAAE,IAAI,YAAY,OAAO,QAAQ,IAAI,GAAG,OAAO,KAAK,MAAM,MAAM,OAAO,KAAK,MAAM,MAAM,CAAC;AACnH,qBAAa,KAAK,QAAQ,EAAE;AAC5B,qBAAa,OAAO,EAAE;AACtB,YAAI,QAAQ;AACV,iBAAO,OAAO,CAAC;AACf,kBAAQ,OAAO,EAAE;AACjB,iBAAO,OAAO,EAAE;QAClB;MACF;MACA,QAAQ,MAAM,KAAK;MACnB,QAAQ;AACN,cAAM,SAAS,KAAK;AACpB,eAAO;UACL,OAAO,KAAK,MAAM;UAClB,QAAQ,KAAK,OAAO;UACpB,OAAO,KAAK,MAAM;UAClB,QAAQ,KAAK,OAAO;UACpB,OAAO,KAAK,MAAM;UAClB,QAAQ,KAAK,OAAO;UACpB,OAAO,KAAK,MAAM;UAClB,aAAa,OAAO,MAAM,OAAO,CAAC,UAAU,MAAM,YAAY,IAAI,EAAE;UACpE,YAAY,OAAO,KAAK,OAAO,CAAC,UAAU,MAAM,YAAY,IAAI,EAAE;UAClE,WAAW,EAAE,GAAG,KAAK,QAAQ;UAC7B,KAAK,KAAK,MAAM;UAChB,WAAW,KAAK,MAAM,YAAY,IAAI,KAAK,KAAK,MAAM,OAAO,KAAK,MAAM;QAC1E;MACF;MACA,OAAO,OAAO;QACZ,OAAO,KAAK;QAAO,QAAQ,KAAK;QAAQ,OAAO,KAAK;QAAO,QAAQ,KAAK;QAAQ,QAAQ,KAAK;QAAQ,OAAO,KAAK;QAAO,QAAQ,KAAK;QAAQ,OAAO,KAAK;QAAO;MAClK;MACA,OAAO,MAAM,KAAK,MAAM;MACxB,SAAS,CAAC,aAAa,KAAK,MAAM,UAAU,QAAQ;MACpD,MAAM,MAAM,KAAK,MAAM;MACvB,aAAa,MAAM,aAAa;MAChC,QAAQ;AACN,mBAAW,QAAQ,CAAC,KAAK,OAAO,KAAK,QAAQ,KAAK,OAAO,KAAK,QAAQ,KAAK,OAAO,KAAK,QAAQ,KAAK,KAAK,EAA4B,MAAK,MAAM;AAChJ,aAAK,MAAM,MAAM;AACjB,aAAK,SAAS,MAAM;AACpB,aAAK,SAAS,MAAM;AACpB,gBAAQ,MAAM;AACd,uBAAe,KAAK,MAAM;AAC1B,yBAAiB,KAAK,MAAM;AAC5B,qBAAa,MAAM;AACnB,gBAAQ,MAAM;AACd,gBAAQ,MAAM;AACd,aAAK,MAAM,OAAO;AAClB,aAAK,MAAM,YAAY;AACvB,aAAK,MAAM,MAAM;AACjB,aAAK,QAAQ,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ,SAAS,KAAK,QAAQ,SAAS;MACzF;MACA,SAAS,MAAM,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,UAAU,GAAG,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC;IACnF;EACF;AGvYO,MAAM,KAA4C;IACvD,WAAW;MACT,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,UAAU;MACR,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,WAAW;MACT,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,eAAe;MACb,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,iBAAiB;MACf,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,aAAa;MACX,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,cAAc;MACZ,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,aAAa;MACX,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,cAAc;MACZ,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,QAAQ;MACN,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,aAAa;MACX,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,sBAAsB;MACpB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,SAAS;MACP,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,SAAS;MACP,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,kBAAkB;MAChB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,iBAAiB;MACf,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,aAAa;MACX,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,mBAAmB;MACjB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,YAAY;MACV,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,YAAY;MACV,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,cAAc;MACZ,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,cAAc;MACZ,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,oBAAoB;MAClB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,oBAAoB;MAClB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,eAAe;MACb,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,iBAAiB;MACf,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,cAAc;MACZ,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,WAAW;MACT,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,eAAe;MACb,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,YAAY;MACV,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,iBAAiB;MACf,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,kBAAkB;MAChB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,OAAO;MACL,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,mBAAmB;MACjB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,UAAU;MACR,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,kBAAkB;MAChB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;EACF;AC/WO,MAAM,OAA8C;IACzD,WAAW;MACT,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,UAAU;MACR,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,WAAW;MACT,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,eAAe;MACb,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,iBAAiB;MACf,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,aAAa;MACX,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,cAAc;MACZ,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,aAAa;MACX,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,cAAc;MACZ,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,QAAQ;MACN,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,aAAa;MACX,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,sBAAsB;MACpB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,SAAS;MACP,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,SAAS;MACP,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,kBAAkB;MAChB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,iBAAiB;MACf,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,aAAa;MACX,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,mBAAmB;MACjB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,YAAY;MACV,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,YAAY;MACV,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,cAAc;MACZ,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,cAAc;MACZ,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,oBAAoB;MAClB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,oBAAoB;MAClB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,eAAe;MACb,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,iBAAiB;MACf,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,cAAc;MACZ,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,WAAW;MACT,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,eAAe;MACb,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,YAAY;MACV,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,iBAAiB;MACf,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,kBAAkB;MAChB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,YAAY;MACZ,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,OAAO;MACL,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,mBAAmB;MACjB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,UAAU;MACR,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;IACA,kBAAkB;MAChB,MAAM;MACN,OAAO;MACP,MAAM;MACN,UAAU;MACV,MAAM;MACN,MAAM;MACN,QAAQ;MACR,SAAS;IACX;EACF;AC5UO,MAAM,UAAyC;IACpD,IAAI;MACF,SAAS;MACT,OAAO,EAAE,MAAM,QAAQ,MAAM,QAAQ,QAAQ,UAAU,SAAS,WAAW,SAAS,WAAW,QAAQ,UAAU,MAAM,cAAc;MACrI,QAAQ,EAAE,YAAY,cAAc,WAAW,WAAW,SAAS,0BAA0B,OAAO,gCAAgC,aAAa,uBAAuB,UAAU,YAAY,QAAQ,gCAAgC;IACxO;IACA,SAAS;MACP,SAAS;MACT,OAAO,EAAE,MAAM,UAAU,MAAM,UAAU,QAAQ,gBAAa,SAAS,QAAQ,SAAS,aAAa,QAAQ,WAAW,MAAM,gCAAuB;MACrJ,QAAQ,EAAE,YAAY,gBAAa,WAAW,UAAU,SAAS,sBAAsB,OAAO,kCAA4B,aAAa,kCAAyB,UAAU,eAAY,QAAQ,gCAAgC;IAChO;EACF;AAEO,MAAM,iBAAiB,CAAC,WAA2C,QAAS,UAAwB,IAAI,KAAK,QAAQ;;;AIlDrH,MAAM,cAAc;AAAA;AAAA;AAIpB,MAAM,gBAAgB;AAAA;AAAA;AAAA;;;ACJtB,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKjB,MAAM,cAAc,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAe/B,MAAM,gBAAgB,GAAG,QAAQ;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;;;ACpBjC,MAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYrB,MAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACG9B,WAAS,QAAQ,OAAiB,OAAqB,MAAyB;AAC9E,WAAO,IAAI,MAAM,yBAAyB,OAAO,IAAI,EAAE,SAAS,MAAM,gBAAgB;AAAA,EACxF;AAYO,WAAS,gBAAgB,OAAiB,MAAyB,UAAoC;AAC5G,UAAM,WAAW,KAAK;AACtB,UAAM,WAAW,IAAI,MAAM,wBAAwB;AACnD,aAAS,aAAa,YAAY,IAAI,MAAM,oBAAoB,GAAG,CAAC,EAAE,aAAa,UAAU,CAAC;AAC9F,UAAM,IAAI,IAAI,aAAa,WAAW,CAAC;AACvC,UAAM,IAAI,IAAI,aAAa,WAAW,CAAC;AACvC,UAAM,IAAI,IAAI,aAAa,WAAW,CAAC;AACvC,UAAM,aAAa,CAAC,QAAQ,OAAO,GAAG,CAAC,GAAG,QAAQ,OAAO,GAAG,CAAC,GAAG,QAAQ,OAAO,GAAG,CAAC,CAAC;AACpF,aAAS,aAAa,MAAM,WAAW,CAAC,CAAC;AACzC,aAAS,aAAa,MAAM,WAAW,CAAC,CAAC;AACzC,aAAS,aAAa,MAAM,WAAW,CAAC,CAAC;AACzC,aAAS,gBAAgB;AACzB,UAAM,WAAW,IAAI,MAAM,eAAe,EAAE,UAA6B,cAAc,aAAa,gBAAgB,cAAc,CAAC;AACnI,UAAM,OAAO,IAAI,MAAM,KAAK,UAAU,QAAQ;AAC9C,SAAK,OAAO;AACZ,SAAK,gBAAgB;AACrB,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AACL,YAAI,IAAI;AACR,mBAAW,KAAK,KAAK,OAAO;AAC1B,YAAE,IAAI,CAAC,IAAI,EAAE;AACb,YAAE,IAAI,IAAI,CAAC,IAAI,EAAE;AACjB,YAAE,IAAI,IAAI,CAAC,IAAI,EAAE;AACjB,YAAE,IAAI,IAAI,CAAC,IAAI,EAAE;AACjB,YAAE,IAAI,CAAC,IAAI,EAAE;AACb,YAAE,IAAI,IAAI,CAAC,IAAI,EAAE;AACjB,YAAE,IAAI,IAAI,CAAC,IAAI,EAAE;AACjB,YAAE,IAAI,IAAI,CAAC,IAAI,EAAE;AACjB,YAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;AACpB,YAAE,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;AACxB,YAAE,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;AACxB;AAAA,QACF;AACA,iBAAS,gBAAgB;AACzB,mBAAW,aAAa,WAAY,WAAU,cAAc;AAC5D,eAAO;AAAA,MACT;AAAA,MACA,UAAU;AACR,iBAAS,QAAQ;AACjB,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEO,WAAS,iBAAiB,OAAiB,MAAsC;AACtF,UAAM,WAAW,KAAK;AACtB,UAAM,WAAW,IAAI,MAAM,wBAAwB;AACnD,aAAS,aAAa,YAAY,IAAI,MAAM,uBAAuB,CAAC,MAAM,GAAG,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;AACrH,aAAS,SAAS,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;AACpC,UAAM,WAAW,IAAI,aAAa,WAAW,CAAC;AAC9C,UAAM,WAAW,IAAI,aAAa,WAAW,CAAC;AAC9C,UAAM,QAAQ,IAAI,aAAa,WAAW,CAAC;AAC3C,UAAM,aAAa,CAAC,QAAQ,OAAO,UAAU,CAAC,GAAG,QAAQ,OAAO,UAAU,CAAC,GAAG,QAAQ,OAAO,OAAO,CAAC,CAAC;AACtG,aAAS,aAAa,QAAQ,WAAW,CAAC,CAAC;AAC3C,aAAS,aAAa,QAAQ,WAAW,CAAC,CAAC;AAC3C,aAAS,aAAa,MAAM,WAAW,CAAC,CAAC;AACzC,aAAS,gBAAgB;AACzB,UAAM,WAAW,IAAI,MAAM,eAAe,EAAE,aAAa,MAAM,YAAY,OAAO,UAAU,MAAM,kBAAkB,cAAc,cAAc,gBAAgB,eAAe,CAAC;AAChL,UAAM,OAAO,IAAI,MAAM,KAAK,UAAU,QAAQ;AAC9C,SAAK,OAAO;AACZ,SAAK,gBAAgB;AACrB,SAAK,cAAc;AACnB,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AACL,YAAI,IAAI;AACR,mBAAW,KAAK,KAAK,OAAO;AAC1B,mBAAS,IAAI,CAAC,IAAI,EAAE;AACpB,mBAAS,IAAI,IAAI,CAAC,IAAI,EAAE;AACxB,mBAAS,IAAI,IAAI,CAAC,IAAI,EAAE;AACxB,mBAAS,IAAI,CAAC,IAAI,EAAE;AACpB,mBAAS,IAAI,IAAI,CAAC,IAAI,EAAE;AACxB,mBAAS,IAAI,IAAI,CAAC,IAAI,EAAE;AACxB,gBAAM,IAAI,CAAC,IAAI,EAAE;AACjB,gBAAM,IAAI,IAAI,CAAC,IAAI,EAAE;AACrB,gBAAM,IAAI,IAAI,CAAC,IAAI,EAAE;AACrB,gBAAM,IAAI,IAAI,CAAC,IAAI,EAAE;AACrB;AAAA,QACF;AACA,iBAAS,gBAAgB;AACzB,mBAAW,aAAa,WAAY,WAAU,cAAc;AAC5D,eAAO;AAAA,MACT;AAAA,MACA,UAAU;AACR,iBAAS,QAAQ;AACjB,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEO,WAAS,gBAAgB,OAAiB,MAAqC;AACpF,UAAM,WAAW,KAAK;AACtB,UAAM,WAAW,IAAI,MAAM,wBAAwB;AACnD,aAAS,aAAa,YAAY,IAAI,MAAM,uBAAuB,CAAC,IAAI,IAAI,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;AAC/G,aAAS,SAAS,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;AACpC,UAAM,QAAQ,IAAI,aAAa,WAAW,CAAC;AAC3C,UAAM,QAAQ,IAAI,aAAa,WAAW,CAAC;AAC3C,UAAM,aAAa,CAAC,QAAQ,OAAO,OAAO,CAAC,GAAG,QAAQ,OAAO,OAAO,CAAC,CAAC;AACtE,aAAS,aAAa,MAAM,WAAW,CAAC,CAAC;AACzC,aAAS,aAAa,MAAM,WAAW,CAAC,CAAC;AACzC,aAAS,gBAAgB;AACzB,UAAM,WAAW,IAAI,MAAM,eAAe,EAAE,aAAa,MAAM,YAAY,OAAO,UAAU,MAAM,kBAAkB,cAAc,aAAa,gBAAgB,cAAc,CAAC;AAC9K,UAAM,OAAO,IAAI,MAAM,KAAK,UAAU,QAAQ;AAC9C,SAAK,OAAO;AACZ,SAAK,gBAAgB;AACrB,SAAK,cAAc;AACnB,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AACL,YAAI,IAAI;AACR,mBAAW,KAAK,KAAK,OAAO;AAC1B,gBAAM,IAAI,CAAC,IAAI,EAAE;AACjB,gBAAM,IAAI,IAAI,CAAC,IAAI,EAAE;AACrB,gBAAM,IAAI,IAAI,CAAC,IAAI,EAAE;AACrB,gBAAM,IAAI,IAAI,CAAC,IAAI,EAAE;AACrB,gBAAM,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;AACxB,gBAAM,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;AAC5B,gBAAM,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;AAC5B,gBAAM,IAAI,IAAI,CAAC,IAAI,EAAE;AACrB;AAAA,QACF;AACA,iBAAS,gBAAgB;AACzB,mBAAW,aAAa,WAAY,WAAU,cAAc;AAC5D,eAAO;AAAA,MACT;AAAA,MACA,UAAU;AACR,iBAAS,QAAQ;AACjB,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AASO,WAAS,iBAAiB,OAAiB,MAA0B,QAA2E,SAA0E;AAC/N,UAAM,WAAW,KAAK;AACtB,UAAM,eAAe,IAAI,MAAM,qBAAqB,EAAE,OAAO,UAAU,WAAW,MAAM,aAAa,KAAK,CAAC;AAC3G,UAAM,gBAAgB,aAAa,MAAM;AACzC,UAAM,OAAO,CAAC,UAAmC,aAAwD;AACvG,YAAM,OAAO,IAAI,MAAM,cAAc,UAAU,UAAU,QAAQ;AACjE,WAAK,eAAe,SAAS,MAAM,gBAAgB;AACnD,WAAK,aAAa;AAClB,WAAK,gBAAgB;AACrB,WAAK,gBAAgB;AACrB,WAAK,QAAQ;AACb,WAAK,WAAW,GAAG,IAAI,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC;AAC3C,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,KAAK,OAAO,MAAM,YAAY;AAC5C,UAAM,SAAS,KAAK,OAAO,OAAO,aAAa;AAC/C,UAAM,SAAS,IAAI,MAAM,QAAQ;AACjC,UAAM,aAAa,IAAI,MAAM,WAAW;AACxC,UAAM,QAAQ,IAAI,MAAM,MAAM;AAC9B,UAAM,WAAW,IAAI,MAAM,QAAQ;AACnC,UAAM,QAAQ,IAAI,MAAM,QAAQ;AAChC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO;AACL,YAAI,YAAY;AAChB,YAAI,aAAa;AACjB,mBAAW,SAAS,KAAK,OAAO;AAC9B,gBAAM,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE;AACtC,qBAAW,aAAa,KAAK;AAC7B,iBAAO,QAAQ,SAAS,IAAI,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,YAAY,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;AAC3G,gBAAM,OAAO,MAAM,QAAQ,SAAS;AACpC,gBAAM,QAAQ,MAAM,QAAQ,eAAe;AAC3C,eAAK,YAAY,OAAO,MAAM;AAC9B,gBAAM,QAAQ,QAAQ,KAAK;AAC3B,gBAAM,SAAS,KAAK,cAAe;AACnC,iBAAO,QAAQ,CAAC,IAAI,MAAM,CAAC;AAC3B,iBAAO,QAAQ,IAAI,CAAC,IAAI,MAAM,CAAC;AAC/B,iBAAO,QAAQ,IAAI,CAAC,IAAI,MAAM,CAAC;AAAA,QACjC;AACA,cAAM,QAAQ;AACd,eAAO,QAAQ;AACf,mBAAW,QAAQ,CAAC,OAAO,MAAM,GAAG;AAClC,eAAK,eAAe,cAAc;AAClC,eAAK,cAAe,cAAc;AAAA,QACpC;AACA,eAAO,YAAY;AAAA,MACrB;AAAA,MACA,UAAU;AACR,qBAAa,QAAQ;AACrB,sBAAc,QAAQ;AACtB,cAAM,QAAQ;AACd,eAAO,QAAQ;AAAA,MACjB;AAAA,IACF;AAAA,EACF;;;ACrNO,WAAS,iBAAiB,OAAiB,MAAiB,OAA2B;AAC5F,UAAM,QAAQ,IAAI,MAAM,MAAM;AAC9B,UAAM,QAAQ,KAAK,MAAM,IAAI,MAAM;AACjC,YAAM,QAAQ,IAAI,MAAM,WAAW,UAAU,GAAG,IAAI,CAAC;AACrD,YAAM,SAAS,IAAI,GAAG,KAAK,CAAC;AAC5B,YAAM,IAAI,KAAK;AACf,aAAO;AAAA,IACT,CAAC;AACD,UAAM,OAAO,KAAK,KAAK,IAAI,MAAM;AAC/B,YAAM,QAAQ,IAAI,MAAM,WAAW,UAAU,GAAG,IAAI,CAAC;AACrD,YAAM,SAAS,IAAI,GAAG,KAAK,CAAC;AAC5B,YAAM,IAAI,KAAK;AACf,aAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AACL,YAAI,MAAM;AACV,aAAK,MAAM,QAAQ,CAAC,OAAO,UAAU;AACnC,gBAAM,QAAQ,MAAM,KAAK;AACzB,gBAAM,SAAS,IAAI,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAC5C,gBAAM,WAAW,MAAM;AACvB,gBAAM,MAAM,OAAO,MAAM,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,GAAG,MAAM,oBAAoB;AAC7F,gBAAM,YAAY,MAAM,YAAY;AACpC,cAAI,MAAM,YAAY,KAAM;AAAA,QAC9B,CAAC;AACD,aAAK,KAAK,QAAQ,CAAC,OAAO,UAAU;AAClC,gBAAM,QAAQ,KAAK,KAAK;AACxB,gBAAM,SAAS,IAAI,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAC5C,gBAAM,WAAW,MAAM;AACvB,gBAAM,YAAY,MAAM,YAAY;AACpC,cAAI,MAAM,YAAY,KAAM;AAAA,QAC9B,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACA,UAAU;AACR,mBAAW,SAAS,CAAC,GAAG,OAAO,GAAG,IAAI,EAAG,OAAM,QAAQ;AAAA,MACzD;AAAA,IACF;AAAA,EACF;;;AC9CA,MAAM,cAAc;AACpB,MAAM,eAAe;AACrB,MAAM,YAAY,KAAK,KAAK;AAGrB,WAAS,sBAAoC;AAClD,WAAO,OAAO,WAAW;AAAA,EAC3B;AAGA,WAAS,cAA0B;AACjC,WAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,YAAY,MAAM,KAAK;AAAA,EACvD;AAEA,WAAS,gBAA4B;AACnC,QAAI,OAAO,aAAa,YAAa,QAAO,YAAY;AACxD,WAAO,SAAS,cAAc,QAAQ;AAAA,EACxC;AAEA,WAAS,MAAM,cAAgC,MAAsE;AACnH,UAAM,SAAS,aAAa;AAC5B,WAAO,QAAQ;AACf,WAAO,SAAS;AAChB,UAAM,UAAU,OAAO,WAAW,IAAI;AACtC,QAAI,QAAS,MAAK,SAAS,YAAY;AACvC,WAAO;AAAA,EACT;AAEA,WAAS,WAAW,SAA4B,MAAc,QAA4B;AACxF,YAAQ,UAAU,GAAG,GAAG,MAAM,IAAI;AAClC,UAAM,SAAS,OAAO;AACtB,aAAS,MAAM,GAAG,MAAM,IAAI,OAAO;AACjC,YAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,YAAM,SAAS,UAAU,OAAO,OAAO,KAAK,IAAI;AAChD,cAAQ,cAAc,cAAc,OAAO,OAAO,KAAK,IAAI,IAAI;AAC/D,cAAQ,YAAY,IAAI,OAAO,KAAK,IAAI;AACxC,cAAQ,UAAU;AAClB,cAAQ,OAAO,QAAQ,MAAM;AAC7B,cAAQ,OAAO,SAAS,KAAK,IAAI,KAAK,IAAI,QAAQ,SAAS,KAAK,IAAI,KAAK,IAAI,MAAM;AACnF,cAAQ,OAAO;AAAA,IACjB;AACA,UAAM,WAAW,QAAQ,qBAAqB,QAAQ,QAAQ,GAAG,QAAQ,QAAQ,SAAS,IAAI;AAC9F,aAAS,aAAa,GAAG,iBAAiB;AAC1C,aAAS,aAAa,MAAM,kBAAkB;AAC9C,aAAS,aAAa,GAAG,iBAAiB;AAC1C,YAAQ,YAAY;AACpB,YAAQ,SAAS,GAAG,GAAG,MAAM,IAAI;AACjC,aAAS,OAAO,GAAG,OAAO,IAAI,QAAQ;AACpC,cAAQ,YAAY,iBAAiB,OAAO,OAAO,KAAK,IAAI,GAAG;AAC/D,cAAQ,UAAU;AAClB,cAAQ,IAAI,SAAS,OAAO,QAAQ,MAAM,GAAG,IAAI,QAAQ,SAAS,OAAO,QAAQ,MAAM,GAAG,IAAI,QAAQ,IAAI,OAAO,KAAK,IAAI,GAAG,GAAG,CAAC;AACjI,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,WAAS,SAAS,SAA4B,MAAc,QAA4B;AACtF,UAAM,SAAS,OAAO;AACtB,YAAQ,UAAU,GAAG,GAAG,MAAM,IAAI;AAClC,UAAM,WAAW,QAAQ,qBAAqB,QAAQ,QAAQ,GAAG,QAAQ,QAAQ,MAAM;AACvF,aAAS,aAAa,GAAG,kBAAkB;AAC3C,aAAS,aAAa,KAAK,mBAAmB;AAC9C,aAAS,aAAa,MAAM,mBAAmB;AAC/C,aAAS,aAAa,GAAG,kBAAkB;AAC3C,YAAQ,YAAY;AACpB,YAAQ,SAAS,GAAG,GAAG,MAAM,IAAI;AACjC,aAAS,QAAQ,GAAG,QAAQ,KAAK,SAAS;AACxC,YAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,YAAM,WAAW,KAAK,KAAK,OAAO,KAAK,CAAC,IAAI,SAAS;AACrD,cAAQ,YAAY,OAAO,KAAK,IAAI,MAAM,sBAAsB;AAChE,cAAQ,UAAU;AAClB,cAAQ,IAAI,SAAS,KAAK,IAAI,KAAK,IAAI,UAAU,SAAS,KAAK,IAAI,KAAK,IAAI,UAAU,IAAI,OAAO,KAAK,IAAI,KAAK,GAAG,CAAC;AACnH,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAQO,WAAS,mBAAmB,OAAiB,cAA4D;AAC9G,UAAM,OAAO,gBAAgB;AAC7B,UAAM,SAAS,oBAAoB;AACnC,UAAM,UAAU,CAAC,WAA+C;AAC9D,YAAM,SAAS,IAAI,MAAM,cAAc,MAAsC;AAC7E,aAAO,aAAa,MAAM;AAC1B,aAAO,aAAa;AACpB,aAAO;AAAA,IACT;AACA,UAAM,SAAS,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,MAAM,QAAQ,MAAM,MAAM,CAAC,SAAS,SAAS,WAAW,SAAS,MAAM,MAAM,CAAC,CAAC,CAAC;AAC7G,UAAM,OAAO,QAAQ,MAAM,MAAM,CAAC,SAAS,SAAS,SAAS,SAAS,MAAM,MAAM,CAAC,CAAC;AACpF,WAAO,EAAE,QAAQ,KAAK;AAAA,EACxB;;;AC5FA,MAAM,oBAAoB;AAC1B,MAAM,oBAAoB;AAC1B,MAAM,kBAAkB;AA8BjB,WAAS,gBAAgB,OAAiB,SAAsC;AACrF,UAAM,QAAQ,IAAI,MAAM,MAAM;AAC9B,UAAM,WAAyB,mBAAmB,OAAO,QAAQ,YAAY;AAC7E,UAAM,QAA+B,CAAC,GAAG,SAAS,QAAQ,SAAS,IAAI;AACvE,UAAM,kBAAkB,SAAS,OAAO,IAAI,CAAC,QAAQ;AACnD,YAAM,WAAW,IAAI,MAAM,qBAAqB,EAAE,KAAK,aAAa,MAAM,YAAY,OAAO,WAAW,GAAG,eAAe,MAAM,qBAAqB,IAAI,oBAAoB,GAAG,CAAC;AACjL,YAAM,KAAK,QAAQ;AACnB,aAAO;AAAA,IACT,CAAC;AACD,UAAM,eAAe,IAAI,MAAM,qBAAqB;AAAA,MAClD,KAAK,SAAS;AAAA,MAAM,aAAa;AAAA,MAAM,YAAY;AAAA,MAAO,WAAW;AAAA,MAAG,aAAa;AAAA,MAAM,eAAe;AAAA,MAAM,qBAAqB;AAAA,MAAI,oBAAoB;AAAA,IAC/J,CAAC;AACD,UAAM,KAAK,YAAY;AACvB,UAAM,gBAAgB,IAAI,MAAM,qBAAqB,EAAE,OAAO,SAAU,WAAW,MAAM,WAAW,KAAK,eAAe,MAAM,qBAAqB,IAAI,oBAAoB,GAAG,CAAC;AAC/K,UAAM,gBAAgB,IAAI,MAAM,eAAe,KAAK,CAAC,EAAE,QAAQ,CAAC,KAAK,KAAK,CAAC;AAC3E,UAAM,KAAK,eAAe,aAAa;AACvC,UAAM,gBAAgB,oBAAI,IAA2C;AACrE,UAAM,QAAsB,CAAC;AAC7B,QAAI,YAAY;AAEhB,aAAS,aAAa,OAA8C;AAClE,UAAI,WAAW,cAAc,IAAI,KAAK;AACtC,UAAI,CAAC,UAAU;AACb,mBAAW,IAAI,MAAM,qBAAqB,EAAE,OAAO,WAAW,KAAK,WAAW,GAAG,aAAa,KAAK,CAAC;AACpG,sBAAc,IAAI,OAAO,QAAQ;AACjC,cAAM,KAAK,QAAQ;AAAA,MACrB;AACA,aAAO;AAAA,IACT;AAEA,aAAS,QAAQ,MAA6B,UAA4C;AACxF,YAAM,SAAS,KAAK;AACpB,YAAM,QAAQ,KAAK,IAAI,mBAAmB,KAAK,IAAI,mBAAmB,KAAK,MAAM,SAAS,CAAC,CAAC,CAAC;AAC7F,YAAM,WAAW,IAAI,MAAM,cAAc,GAAG,GAAG,OAAO,KAAK,EAAE,QAAQ,CAAC,KAAK,KAAK,CAAC;AACjF,YAAM,WAAW,SAAS,WAAW;AACrC,YAAMK,OAAM,KAAK,IAAI,KAAK,QAAQ;AAClC,YAAMC,OAAM,KAAK,IAAI,KAAK,QAAQ;AAClC,eAAS,QAAQ,GAAG,QAAQ,SAAS,OAAO,SAAS;AACnD,cAAM,SAAS,SAAS,KAAK,KAAK,IAAI;AACtC,cAAM,SAAS,SAAS,KAAK,KAAK,IAAI;AACtC,cAAM,SAAS,KAAK,IAAI,SAASD,OAAM,SAASC;AAChD,cAAM,SAAS,KAAK,IAAI,SAASA,OAAM,SAASD;AAChD,iBAAS,OAAO,OAAO,SAAS,QAAQ,QAAQ,SAAS,QAAQ,MAAM,KAAK,KAAK,KAAK,MAAM,MAAM;AAAA,MACpG;AACA,eAAS,qBAAqB;AAC9B,YAAM,OAAO,IAAI,MAAM,KAAK,UAAU,QAAyC;AAC/E,WAAK,gBAAgB;AACrB,aAAO;AAAA,IACT;AAEA,aAAS,QAAQ,MAA+B;AAC9C,YAAM,OAAO,IAAI,MAAM,KAAK,KAAK,QAAQ,QAAQ,gBAAgB,QAAQ,cAAc,aAAa,KAAK,KAAK,CAAC;AAC/G,WAAK,SAAS,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AACxC,WAAK,MAAM,IAAI,KAAK,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;AAC1D,WAAK,SAAS,IAAI,KAAK,SAAS,CAAC,GAAG,KAAK,SAAS,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC;AACtE,WAAK,aAAa;AAClB,WAAK,gBAAgB;AACrB,aAAO;AAAA,IACT;AAEA,aAAS,SAAS,MAAgC;AAChD,YAAM,OAAO,IAAI,MAAM,KAAK,eAAe,aAAa;AACxD,WAAK,SAAS,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AACxC,WAAK,MAAM,IAAI,KAAK,QAAQ,GAAG,KAAK,MAAM;AAC1C,WAAK,SAAS,IAAI,KAAK;AACvB,WAAK,gBAAgB;AACrB,WAAK,MAAM,eAAe,IAAI;AAC9B,YAAM,KAAK,EAAE,MAAM,QAAQ,KAAK,QAAQ,QAAQ,KAAK,QAAQ,KAAK,EAAE,CAAC;AACrE,aAAO;AAAA,IACT;AAEA,aAAS,MAAM,MAA2B;AACxC,UAAI,KAAK,SAAS,SAAU,QAAO,QAAQ,MAAM,gBAAgB,KAAK,OAAO,CAAE;AAC/E,UAAI,KAAK,SAAS,OAAQ,QAAO,QAAQ,MAAM,YAAY;AAC3D,UAAI,KAAK,SAAS,OAAQ,QAAO,QAAQ,IAAI;AAC7C,aAAO,SAAS,IAAI;AAAA,IACtB;AAEA,aAAS,cAAoB;AAC3B,iBAAW,SAAS,CAAC,GAAG,MAAM,QAAQ,GAAG;AACvC,cAAM,OAAO,KAAK;AAClB,cAAM,WAAY,MAAwB;AAC1C,YAAI,aAAa,QAAQ,gBAAgB,aAAa,QAAQ,iBAAiB,aAAa,cAAe,UAAS,QAAQ;AAAA,MAC9H;AACA,YAAM,SAAS;AACf,kBAAY;AAAA,IACd;AAEA,WAAO;AAAA,MACL;AAAA,MACA,OAAO,OAAO;AACZ,YAAI,MAAM,SAAS,SAAS;AAC1B,sBAAY;AACZ;AAAA,QACF;AACA,cAAM,IAAI,MAAM,MAAM,IAAI,CAAC;AAC3B;AAAA,MACF;AAAA,MACA,OAAO,IAAI;AACT,mBAAW,SAAS,OAAO;AACzB,cAAI,MAAM,MAAM,EAAG;AACnB,gBAAM,OAAO,KAAK;AAClB,gBAAME,QAAO,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,MAAM,GAAG,GAAG,GAAG;AACzD,gBAAM,KAAK,MAAM,IAAI,MAAM,SAAS,KAAK,IAAI,MAAMA,KAAI,GAAG,GAAG,MAAM,SAAS,KAAK,IAAI,MAAMA,KAAI,CAAC;AAAA,QAClG;AAAA,MACF;AAAA,MACA,OAAO,MAAM;AAAA,MACb,UAAU;AACR,oBAAY;AACZ,mBAAW,QAAQ,MAAO,MAAK,QAAQ;AAAA,MACzC;AAAA,IACF;AAAA,EACF;;;AC/IA,MAAMC,SAAQ,CAAC,OAAeC,MAAaC,SAAyB,QAAQD,OAAMA,OAAM,QAAQC,OAAMA,OAAM;AAE5G,WAAS,MAAM,WAAwB,MAAc,OAAgC;AACnF,UAAM,UAAU,UAAU,cAAc,cAAc,KAAK;AAC3D,YAAQ,QAAQ,aAAa;AAC7B,WAAO,OAAO,QAAQ,OAAO,EAAE,UAAU,YAAY,OAAO,KAAK,eAAe,QAAQ,SAAS,IAAI,CAAC;AACtG,QAAI,MAAO,SAAQ,MAAM,eAAe;AACxC,cAAU,YAAY,OAAO;AAC7B,WAAO;AAAA,EACT;AAMO,WAAS,oBAAoB,WAAuC;AACzE,UAAMC,SAAQ,MAAM,WAAW,SAAS,QAAQ;AAChD,IAAAA,OAAM,MAAM,aAAa;AACzB,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,UAAM,MAAM,MAAM,WAAW,KAAK;AAClC,UAAM,QAAQ,MAAM,WAAW,OAAO;AACtC,UAAM,MAAM,MAAM,WAAW,KAAK;AAClC,UAAM,WAAW,CAACA,QAAO,OAAO,KAAK,OAAO,GAAG;AAC/C,WAAO;AAAA,MACL,OAAO,OAAO;AACZ,QAAAA,OAAM,MAAM,UAAUH,OAAM,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,CAAC;AACxD,cAAM,MAAM,UAAU;AACtB,cAAM,MAAM,aAAa,oBAAoBA,OAAM,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;AAChF,YAAI,MAAM,UAAU;AACpB,YAAI,MAAM,aAAa,uEAAuEA,OAAM,MAAM,KAAK,GAAG,CAAC,IAAI,MAAM,QAAQ,CAAC,CAAC;AACvI,cAAM,MAAM,UAAU;AACtB,cAAM,MAAM,aAAa,0CAA0C,MAAM,gBAAgB,KAAK,QAAQ,CAAC,CAAC,2DAA2D,MAAM,iBAAiB,KAAK,QAAQ,CAAC,CAAC;AACzM,YAAI,MAAM,UAAU;AACpB,YAAI,MAAM,aAAa,MAAM,MAAM,OAAO,mBAAmB,MAAM,MAAM,MAAM,QAAQ,CAAC,CAAC,MAAM;AAAA,MACjG;AAAA,MACA,UAAU;AACR,mBAAW,WAAW,SAAU,SAAQ,OAAO;AAAA,MACjD;AAAA,IACF;AAAA,EACF;;;AC7CO,MAAM,eAAe;AAErB,MAAM,iBAAiB;AAAA;AAAA;AAAA;AAKvB,MAAM,cAAc;AAEpB,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACE7B,MAAM,cAAc;AASb,WAAS,iBAAiB,OAAiB,MAAsC;AACtF,UAAM,QAAQ,IAAI,MAAM,MAAM;AAC9B,UAAM,gBAAgB,IAAI,MAAM,eAAe,GAAG,IAAI,EAAE;AACxD,UAAM,eAAe,IAAI,MAAM,cAAc,GAAG,CAAC,EAAE,QAAQ,CAAC,KAAK,KAAK,CAAC;AACvE,UAAM,QAAgB,CAAC;AAEvB,aAAS,WAAiB;AACxB,YAAM,aAAa,EAAE,OAAO,EAAE;AAC9B,YAAM,YAAY,EAAE,OAAO,EAAE;AAC7B,YAAM,gBAAgB,IAAI,MAAM,eAAe,EAAE,aAAa,MAAM,YAAY,OAAO,UAAU,MAAM,kBAAkB,UAAU,EAAE,IAAI,WAAW,GAAG,cAAc,cAAc,gBAAgB,eAAe,CAAC;AACnN,YAAM,eAAe,IAAI,MAAM,eAAe;AAAA,QAC5C,aAAa;AAAA,QAAM,YAAY;AAAA,QAAO,UAAU,EAAE,IAAI,WAAW,IAAI,EAAE,OAAO,KAAK,GAAG,IAAI,EAAE,OAAO,IAAI,MAAM,MAAM,MAAM,KAAK,IAAI,EAAE,EAAE;AAAA,QAAG,cAAc;AAAA,QAAa,gBAAgB;AAAA,MACtL,CAAC;AACD,YAAM,QAAQ,IAAI,MAAM,KAAK,eAAe,aAAa;AACzD,YAAM,cAAc;AACpB,YAAMI,QAAO,IAAI,MAAM,KAAK,cAAc,YAAY;AACtD,MAAAA,MAAK,cAAc;AACnB,YAAM,IAAI,OAAOA,KAAI;AACrB,aAAO,EAAE,OAAO,MAAAA,OAAM,YAAY,UAAU;AAAA,IAC9C;AAEA,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AACL,cAAM,SAAS,KAAK;AACpB,iBAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS;AAClD,gBAAM,OAAQ,gCAAiB,SAAS;AACxC,gBAAM,QAAQ,OAAO,KAAK;AAC1B,eAAK,MAAM,UAAU,KAAK,KAAK,UAAU;AACzC,eAAK,MAAM,SAAS,IAAI,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AACjD,eAAK,MAAM,MAAM,UAAU,MAAM,UAAU;AAC3C,eAAK,WAAW,QAAQ,MAAM;AAC9B,eAAK,KAAK,SAAS,IAAI,MAAM,GAAG,aAAa,MAAM,CAAC;AACpD,eAAK,KAAK,MAAM,UAAU,MAAM,SAAS;AACzC,eAAK,UAAU,QAAQ,MAAM;AAAA,QAC/B;AACA,iBAAS,QAAQ,OAAO,QAAQ,QAAQ,MAAM,QAAQ,QAAS,OAAM,KAAK,EAAG,MAAM,UAAU,MAAM,KAAK,EAAG,KAAK,UAAU;AAC1H,eAAO,OAAO;AAAA,MAChB;AAAA,MACA,UAAU;AACR,mBAAW,QAAQ,OAAO;AACxB;AAAC,UAAC,KAAK,MAAM,SAA+B,QAAQ;AACnD,UAAC,KAAK,KAAK,SAA+B,QAAQ;AAAA,QACrD;AACA,sBAAc,QAAQ;AACtB,qBAAa,QAAQ;AAAA,MACvB;AAAA,IACF;AAAA,EACF;;;ACpEO,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAetB,MAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACG/B,WAAS,SAAS,OAAiB,MAAsB,UAAmB,YAA2B;AACrG,UAAM,WAAW,IAAI,MAAM,eAAe;AAC1C,UAAM,aAA+C,CAAC,CAAC,YAAY,KAAK,UAAU,CAAC,GAAG,CAAC,UAAU,KAAK,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC;AACjK,UAAM,UAAU,WAAW,IAAI,CAAC,CAAC,MAAM,OAAO,IAAI,MAAM;AACtD,YAAM,YAAY,IAAI,MAAM,gBAAgB,OAAO,IAAI,EAAE,SAAS,MAAM,gBAAgB;AACxF,eAAS,aAAa,MAAM,SAAS;AACrC,aAAO;AAAA,IACT,CAAC;AACD,aAAS,aAAa,GAAG,CAAC;AAC1B,UAAM,WAAW,IAAI,MAAM,eAAe;AAAA,MACxC,UAAU,EAAE,QAAQ,EAAE,OAAO,WAAW,EAAE;AAAA,MAC1C,cAAc;AAAA,MACd,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,UAAU,WAAW,MAAM,mBAAmB,MAAM;AAAA,IACtD,CAAC;AACD,UAAM,SAAS,IAAI,MAAM,OAAO,UAAU,QAAQ;AAClD,WAAO,gBAAgB;AACvB,WAAO,OAAO,WAAW,yBAAyB;AAClD,WAAO,cAAc,WAAW,KAAK;AACrC,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AACL,iBAAS,aAAa,GAAG,KAAK,SAAS;AACvC,mBAAW,UAAU,QAAS,QAAO,cAAc;AACnD,eAAO,KAAK;AAAA,MACd;AAAA,MACA,UAAU;AACR,iBAAS,QAAQ;AACjB,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAGO,WAAS,kBAAkB,OAAiB,QAA0B,YAAiC;AAC5G,UAAM,WAAW,SAAS,OAAO,OAAO,UAAU,MAAM,UAAU;AAClE,UAAM,SAAS,SAAS,OAAO,OAAO,QAAQ,OAAO,UAAU;AAC/D,WAAO;AAAA,MACL,UAAU,SAAS;AAAA,MACnB,QAAQ,OAAO;AAAA,MACf,MAAM,MAAM,SAAS,KAAK,IAAI,OAAO,KAAK;AAAA,MAC1C,UAAU;AACR,iBAAS,QAAQ;AACjB,eAAO,QAAQ;AAAA,MACjB;AAAA,IACF;AAAA,EACF;;;AClEO,MAAM,yBAAyB;AAAA;AAG/B,MAAM,2BAA2B;AAAA;;;ACCxC,MAAM,kBAAkB;AACxB,MAAM,iBAAiB;AACvB,MAAMC,iBAAgB;AACtB,MAAM,kBAAkB;AACxB,MAAMC,gBAAe;AACrB,MAAM,mBAAmB;AACzB,MAAM,sBAAsB;AAC5B,MAAM,iBAAiB;AACvB,MAAM,QAAQ;AACd,MAAM,eAAe;AACrB,MAAM,aAAa;AAenB,MAAMC,SAAQ,CAAC,GAAW,IAAY,OAAwB,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK;AAE1F,WAAS,YAAY,OAAiB,MAA6B,UAAmB,MAAc,OAAsB;AACxH,UAAM,WAAW,IAAI,MAAM,eAAe;AAC1C,UAAM,SAA2C,CAAC,CAAC,YAAY,KAAK,UAAU,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,GAAG,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC;AAC3J,UAAM,UAAU,OAAO,IAAI,CAAC,CAAC,MAAM,OAAO,IAAI,MAAM;AAClD,YAAM,YAAY,IAAI,MAAM,gBAAgB,OAAO,IAAI,EAAE,SAAS,MAAM,gBAAgB;AACxF,eAAS,aAAa,MAAM,SAAS;AACrC,aAAO;AAAA,IACT,CAAC;AACD,aAAS,aAAa,GAAG,CAAC;AAC1B,UAAM,WAAW,IAAI,MAAM,eAAe;AAAA,MACxC,UAAU,EAAE,QAAQ,EAAE,OAAO,MAAM,GAAG,OAAO,EAAE,OAAO,KAAK,EAAE;AAAA,MAC7D,cAAc;AAAA,MACd,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,UAAU,WAAW,MAAM,mBAAmB,MAAM;AAAA,IACtD,CAAC;AACD,UAAM,SAAS,IAAI,MAAM,OAAO,UAAU,QAAQ;AAClD,WAAO,gBAAgB;AACvB,WAAO,cAAc,WAAW,IAAI;AACpC,WAAO,OAAO,WAAW,iBAAiB;AAC1C,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AACL,iBAAS,aAAa,GAAG,KAAK,KAAK;AACnC,mBAAW,UAAU,QAAS,QAAO,cAAc;AACnD,eAAO,KAAK,QAAQ;AAAA,MACtB;AAAA,MACA,UAAU;AACR,iBAAS,QAAQ;AACjB,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,WAAS,YAAY,OAAiB,MAAwC;AAC5E,UAAM,WAAW,IAAI,MAAM,eAAe;AAC1C,UAAM,WAAW,IAAI,MAAM,gBAAgB,KAAK,SAAS,CAAC,EAAE,SAAS,MAAM,gBAAgB;AAC3F,UAAM,QAAQ,IAAI,MAAM,gBAAgB,KAAK,cAAc,CAAC,EAAE,SAAS,MAAM,gBAAgB;AAC7F,aAAS,aAAa,YAAY,QAAQ;AAC1C,aAAS,aAAa,SAAS,KAAK;AACpC,aAAS,aAAa,GAAG,CAAC;AAC1B,UAAM,WAAW,IAAI,MAAM,kBAAkB,EAAE,cAAc,MAAM,aAAa,MAAM,UAAU,MAAM,kBAAkB,YAAY,MAAM,CAAC;AAC3I,UAAM,QAAQ,IAAI,MAAM,aAAa,UAAU,QAAQ;AACvD,UAAM,gBAAgB;AACtB,UAAM,cAAc;AACpB,UAAM,OAAO;AACb,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AACL,iBAAS,aAAa,GAAG,KAAK,QAAQ,CAAC;AACvC,iBAAS,cAAc,MAAM,cAAc;AAC3C,eAAO,KAAK,QAAQ;AAAA,MACtB;AAAA,MACA,UAAU;AACR,iBAAS,QAAQ;AACjB,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,WAAS,YAAY,OAAiB,MAAuC;AAC3E,UAAM,WAAW,IAAI,MAAM,YAAY,GAAG,GAAG,CAAC;AAC9C,UAAM,WAAW,IAAI,MAAM,qBAAqB,EAAE,OAAO,UAAU,WAAW,MAAM,WAAW,MAAM,aAAa,KAAK,CAAC;AACxH,UAAM,OAAO,IAAI,MAAM,cAAc,UAAU,UAAU,eAAe;AACxE,SAAK,eAAe,SAAS,MAAM,gBAAgB;AACnD,SAAK,gBAAgB;AACrB,SAAK,OAAO;AACZ,UAAM,QAAQ,IAAI,MAAM,MAAM;AAC9B,UAAM,aAAa,IAAI,MAAM,WAAW;AACxC,UAAM,WAAW,IAAI,MAAM,QAAQ;AACnC,UAAM,QAAQ,IAAI,MAAM,QAAQ;AAChC,UAAM,SAAS,IAAI,MAAM,QAAQ;AACjC,UAAM,SAAS,IAAI,MAAM,MAAM;AAC/B,UAAM,SAAS,IAAI,MAAM,QAAQ,EAAE,UAAU,GAAG,GAAG,CAAC;AACpD,aAAS,QAAQ,GAAG,QAAQ,iBAAiB,QAAS,MAAK,YAAY,OAAO,MAAM;AACpF,SAAK,WAAW,GAAG,OAAO,OAAO,QAAQ,CAAC;AAC1C,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AACL,YAAI,QAAQ;AACZ,iBAAS,QAAQ,GAAG,QAAQ,iBAAiB,SAAS;AACpD,gBAAM,QAAQ,KAAK,OAAO,KAAK;AAC/B,cAAI,CAAC,MAAM,IAAI;AACb,iBAAK,YAAY,OAAO,MAAM;AAC9B;AAAA,UACF;AACA,kBAAQ;AACR,gBAAM,SAAS,KAAK,IAAI,GAAG,MAAM,OAAOD,aAAY;AACpD,gBAAM,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE;AACtC,qBAAW,aAAa,KAAK;AAC7B,iBAAO,QAAQ,SAAS,IAAI,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,YAAY,MAAM,IAAI,MAAM,KAAK,QAAQ,MAAM,KAAK,QAAQ,MAAM,KAAK,MAAM,CAAC;AACtI,eAAK,YAAY,OAAO,MAAM;AAC9B,eAAK,WAAW,OAAO,OAAO,OAAO,MAAM,KAAK,CAAC;AAAA,QACnD;AACA,aAAK,eAAe,cAAc;AAClC,YAAI,KAAK,cAAe,MAAK,cAAc,cAAc;AACzD,eAAO;AAAA,MACT;AAAA,MACA,UAAU;AACR,iBAAS,QAAQ;AACjB,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAGA,WAAS,UAAUE,QAAc,QAAwB,WAA2B,OAAuB,QAAwB,OAAkE;AACnM,UAAM,QAAQA,OAAM,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,GAAGA,OAAM,IAAIA,OAAM,IAAI,GAAG,GAAG,IAAI;AAC1F,QAAI,KAAKA,OAAM,KAAK;AACpB,QAAI,KAAKA,OAAM,KAAK;AACpB,WAAO,OAAOA,OAAM,KAAK;AACzB,QAAI,QAAQ;AACZ,UAAM,QAAQA,OAAM;AACpB,QAAI,OAAO;AACT,YAAM,QAAQ,UAAU,QAAQ,MAAM,UAAU,SAAS,MAAM,UAAU,SAAS,OAAO,UAAU,UAAU,MAAM;AACnH,YAAM,MAAMA,OAAM;AAClB,UAAIA,OAAM,UAAU,GAAG;AACrB,cAAM,IAAID,QAAO,MAAMC,OAAM,SAASA,OAAM,SAAS,GAAG,CAAC;AACzD,YAAIA,OAAM,YAAY,EAAG,WAAU,OAAOA,OAAM,QAAQ;AAAA,YACnD,WAAU,KAAK,MAAM,EAAE,eAAe,IAAI,EAAE,KAAK,OAAO,IAAI;AACjE,gBAAQ,IAAI;AACZ,cAAM,SAAS,QAAQ,IAAI,QAAQ,IAAI,SAAS,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC;AACrE,cAAM,QAAQ,SAAS,UAAU,IAAI,OAAO,KAAK,IAAI,MAAM,MAAM,KAAK;AACtE,cAAM,QAAQ,SAAS,UAAU,IAAI,OAAO,KAAK,IAAI,MAAM,MAAM,QAAQ,GAAG;AAC5E,eAAO,KAAK,WAAW,CAAC;AAAA,MAC1B,OAAO;AACL,cAAM,SAAS,IAAI,SAAS,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC;AACjD,cAAM,UAAU,IAAI,OAAO,KAAK,IAAI,MAAM,MAAM,KAAK;AACrD,cAAM,UAAU,IAAI,OAAO,KAAK,IAAI,MAAM,MAAM,QAAQ,GAAG;AAC3D,YAAI,UAAU,UAAU,UAAU,SAAS;AACzC,gBAAM,CAAC,MAAM,IAAI,IAAI,UAAU,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;AACxD,gBAAM,OAAOD,QAAO,MAAM,QAAQ,MAAM,GAAG,CAAC;AAC5C,gBAAM,IAAI,OAAO;AACjB,gBAAM,IAAI,OAAO;AACjB,iBAAO,KAAK,OAAO,OAAO,UAAU,SAAS,aAAa,YAAY,GAAG,OAAO,GAAG;AACnF,cAAI,QAAQ,EAAG,QAAO;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,IAAI,IAAI,MAAM;AAAA,EACzB;AAEA,WAAS,WAAW,OAAiB,MAAuC;AAC1E,UAAM,WAAW,IAAI,MAAM,eAAe,KAAK,eAAe;AAC9D,UAAM,YAAY,SAAS,aAAa,UAAU;AAElD,aAAS,QAAQ,GAAG,QAAQ,UAAU,OAAO,SAAS;AACpD,YAAM,IAAI,QAAU,QAAQ,eAAgB,KAAK,aAAc;AAC/D,gBAAU,MAAM,OAAO,UAAU,KAAK,KAAK,IAAI,GAAG,UAAU,KAAK,KAAK,IAAI,CAAC;AAAA,IAC7E;AACA,UAAM,MAAM,IAAI,MAAM,qBAAqB,EAAE,OAAO,UAAU,WAAW,KAAK,WAAW,KAAK,eAAe,MAAM,qBAAqB,IAAI,oBAAoB,GAAG,CAAC;AACpK,UAAM,MAAM,IAAI,MAAM,qBAAqB,EAAE,OAAO,UAAU,WAAW,GAAG,WAAW,GAAG,aAAa,MAAM,eAAe,MAAM,qBAAqB,IAAI,oBAAoB,GAAG,CAAC;AACnL,UAAM,UAAU,IAAI,MAAM,cAAc,UAAU,KAAK,cAAc;AACrE,UAAM,UAAU,IAAI,MAAM,cAAc,UAAU,KAAK,cAAc;AACrE,UAAM,QAAQ,IAAI,MAAM,MAAM;AAC9B,UAAM,OAAO;AACb,eAAW,QAAQ,CAAC,SAAS,OAAO,GAAG;AACrC,WAAK,gBAAgB;AACrB,WAAK,cAAc;AACnB,WAAK,eAAe,SAAS,MAAM,gBAAgB;AACnD,YAAM,IAAI,IAAI;AAAA,IAChB;AACA,UAAM,SAAS,IAAI,MAAM,QAAQ,EAAE,UAAU,GAAG,GAAG,CAAC;AACpD,UAAM,SAAS,IAAI,MAAM,MAAM;AAC/B,UAAM,YAAY,IAAI,MAAM,MAAM;AAClC,UAAM,QAAQ,IAAI,MAAM,MAAM,KAAK;AACnC,UAAM,SAAS,IAAI,MAAM,MAAM;AAC/B,UAAM,SAAS,IAAI,MAAM,QAAQ;AACjC,UAAM,UAAU,IAAI,MAAM,QAAQ,GAAG,GAAG,CAAC;AACzC,UAAM,OAAO,IAAI,MAAM,WAAW;AAClC,UAAM,aAAa,IAAI,MAAM,WAAW;AACxC,UAAM,WAAW,IAAI,MAAM,QAAQ;AACnC,UAAM,QAAQ,IAAI,MAAM,QAAQ;AAChC,UAAM,SAAS,IAAI,MAAM,QAAQ;AACjC,YAAQ,WAAW,GAAG,OAAO,OAAO,CAAC,CAAC;AACtC,YAAQ,WAAW,GAAG,OAAO,OAAO,CAAC,CAAC;AACtC,aAAS,QAAQ,GAAG,QAAQ,gBAAgB,SAAS;AACnD,cAAQ,YAAY,OAAO,MAAM;AACjC,cAAQ,YAAY,OAAO,MAAM;AAAA,IACnC;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AACL,YAAI,QAAQ;AACZ,iBAAS,QAAQ,GAAG,QAAQ,gBAAgB,SAAS;AACnD,gBAAMC,SAAQ,KAAK,OAAO,KAAK;AAC/B,kBAAQ,YAAY,OAAO,MAAM;AACjC,kBAAQ,YAAY,OAAO,MAAM;AACjC,cAAI,CAACA,OAAM,MAAMA,OAAM,IAAI,EAAG;AAC9B,gBAAM,OAAO,UAAUA,QAAO,QAAQ,WAAW,OAAO,QAAQ,KAAK;AACrE,cAAI,CAAC,KAAM;AACX,kBAAQ;AACR,iBAAO,IAAIA,OAAM,OAAO,CAAC,GAAGA,OAAM,OAAO,CAAC,GAAGA,OAAM,OAAO,CAAC,CAAC;AAC5D,qBAAW,mBAAmB,SAAS,MAAM;AAC7C,qBAAW,SAAS,KAAK,iBAAiB,SAAS,QAAQ,QAAQ,CAAC;AACpE,gBAAM,SAAS,OAAS,QAAQ,KAAM;AACtC,iBAAO,QAAQ,SAAS,IAAIA,OAAM,IAAI,OAAO,IAAI,QAAQA,OAAM,IAAI,OAAO,IAAI,QAAQA,OAAM,IAAI,OAAO,IAAI,MAAM,GAAG,YAAY,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;AAC9J,gBAAM,OAAO,KAAK,QAAQ,UAAU;AACpC,eAAK,YAAY,OAAO,MAAM;AAC9B,eAAK,WAAW,OAAO,MAAM;AAAA,QAC/B;AACA,mBAAW,QAAQ,CAAC,SAAS,OAAO,GAAG;AACrC,eAAK,eAAe,cAAc;AAClC,cAAI,KAAK,cAAe,MAAK,cAAc,cAAc;AAAA,QAC3D;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU;AACR,iBAAS,QAAQ;AACjB,YAAI,QAAQ;AACZ,YAAI,QAAQ;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAEA,WAAS,UAAU,OAAiB,MAAsC;AACxE,UAAM,WAAW,IAAI,MAAM,aAAa,MAAM,GAAG,EAAE;AACnD,UAAM,WAAW,IAAI,MAAM,kBAAkB,EAAE,OAAO,UAAU,aAAa,MAAM,UAAU,MAAM,kBAAkB,YAAY,OAAO,MAAM,MAAM,WAAW,CAAC;AAChK,UAAM,OAAO,IAAI,MAAM,cAAc,UAAU,UAAUH,cAAa;AACtE,SAAK,gBAAgB;AACrB,SAAK,eAAe,SAAS,MAAM,gBAAgB;AACnD,SAAK,OAAO;AACZ,UAAM,SAAS,IAAI,MAAM,QAAQ,EAAE,UAAU,GAAG,GAAG,CAAC;AACpD,UAAM,SAAS,IAAI,MAAM,MAAM;AAC/B,UAAM,SAAS,IAAI,MAAM,QAAQ;AACjC,UAAM,UAAU,IAAI,MAAM,QAAQ,GAAG,GAAG,CAAC;AACzC,UAAM,aAAa,IAAI,MAAM,WAAW;AACxC,UAAM,WAAW,IAAI,MAAM,QAAQ;AACnC,UAAM,QAAQ,IAAI,MAAM,QAAQ;AAChC,UAAM,SAAS,IAAI,MAAM,QAAQ;AACjC,SAAK,WAAW,GAAG,OAAO,OAAO,CAAC,CAAC;AACnC,aAAS,QAAQ,GAAG,QAAQA,gBAAe,QAAS,MAAK,YAAY,OAAO,MAAM;AAClF,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AACL,YAAI,QAAQ;AACZ,iBAAS,QAAQ,GAAG,QAAQA,gBAAe,SAAS;AAClD,gBAAMI,QAAO,KAAK,MAAM,KAAK;AAC7B,cAAI,CAACA,MAAK,IAAI;AACZ,iBAAK,YAAY,OAAO,MAAM;AAC9B;AAAA,UACF;AACA,kBAAQ;AACR,gBAAM,IAAI,KAAK,IAAI,GAAGA,MAAK,IAAIA,MAAK,QAAQ;AAC5C,gBAAM,SAASA,MAAK,QAAQA,MAAK,KAAKA,MAAK,SAAS,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC;AACzE,qBAAW,mBAAmB,SAAS,OAAO,IAAIA,MAAK,OAAO,CAAC,GAAGA,MAAK,OAAO,CAAC,GAAGA,MAAK,OAAO,CAAC,CAAC,CAAC;AACjG,iBAAO,QAAQ,SAAS,IAAIA,MAAK,MAAM,CAAC,GAAGA,MAAK,MAAM,CAAC,GAAGA,MAAK,MAAM,CAAC,CAAC,GAAG,YAAY,MAAM,IAAI,QAAQ,QAAQ,CAAC,CAAC;AAClH,eAAK,YAAY,OAAO,MAAM;AAC9B,eAAK,WAAW,OAAO,OAAO,OAAOA,MAAK,KAAK,EAAE,eAAeA,MAAK,OAAOA,MAAK,OAAO,IAAI,CAAC,CAAC;AAAA,QAChG;AACA,aAAK,eAAe,cAAc;AAClC,YAAI,KAAK,cAAe,MAAK,cAAc,cAAc;AACzD,eAAO;AAAA,MACT;AAAA,MACA,UAAU;AACR,iBAAS,QAAQ;AACjB,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAMO,WAAS,qBAAqB,OAAiB,QAAwB,YAAoB,YAAoC;AACpI,UAAM,QAAQ,IAAI,MAAM,MAAM;AAC9B,UAAM,OAAO;AACb,UAAM,SAAkB;AAAA,MACtB,YAAY,OAAO,OAAO,KAAK,MAAM,GAAG,UAAU;AAAA,MAClD,YAAY,OAAO,OAAO,QAAQ,OAAO,MAAM,UAAU;AAAA,MACzD,YAAY,OAAO,OAAO,OAAO;AAAA,MACjC,YAAY,OAAO,OAAO,MAAM;AAAA,MAChC,WAAW,OAAO,OAAO,MAAM;AAAA,MAC/B,UAAU,OAAO,OAAO,KAAK;AAAA,IAC/B;AACA,eAAWC,UAAS,OAAQ,OAAM,IAAIA,OAAM,MAAM;AAClD,UAAM,cAAc,OAAO,OAAO,OAAO,IAAI,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,EAAE,CAAC;AACxF,UAAM,aAAa,OAAO,OAAO,KAAK,IAAI,MAAM,IAAI,MAAM,WAAW,kBAAkB,GAAG,mBAAmB,CAAC;AAC9G,eAAW,SAAS,CAAC,GAAG,aAAa,GAAG,UAAU,EAAG,OAAM,IAAI,KAAK;AACpE,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AACL,YAAI,YAAY;AAChB,mBAAWA,UAAS,OAAQ,KAAIA,OAAM,KAAK,EAAG;AAC9C,eAAO,OAAO,OAAO,QAAQ,CAAC,QAAQ,UAAU;AAC9C,gBAAM,QAAQ,YAAY,KAAK;AAC/B,gBAAM,SAAS,IAAI,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAC/C,gBAAM,MAAM,OAAO,OAAO,KAAK;AAC/B,gBAAM,WAAW,OAAO;AACxB,gBAAM,YAAY,OAAO,YAAY;AAAA,QACvC,CAAC;AACD,eAAO,OAAO,KAAK,QAAQ,CAAC,QAAQ,UAAU;AAC5C,gBAAM,QAAQ,WAAW,KAAK;AAC9B,gBAAM,SAAS,IAAI,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAC/C,gBAAM,YAAY,OAAO,YAAY;AAAA,QACvC,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACA,UAAU;AACR,mBAAWA,UAAS,OAAQ,CAAAA,OAAM,QAAQ;AAC1C,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF;;;AClUA,MAAM,sBAAsB,CAAC,KAAK,IAAI,EAAE;AACxC,MAAM,YAAY;AAClB,MAAMC,gBAAe;AACrB,MAAM,YAAqD,EAAE,MAAM,MAAM,MAAM,GAAG,QAAQ,KAAK,KAAK,IAAI;AAExG,MAAM,iBAAmD,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,EAAE;AAE/E,MAAMC,cAAa,CAAC,SAAS,UAAU,SAAS,UAAU,SAAS,SAAS;AACnF,MAAM,eAAe;AACrB,MAAM,cAAc;AACpB,MAAM,cAAc;AAEpB,WAAS,QAAQ,OAAmC;AAClD,WAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,eAAe,SAAS,OAAQ,MAAmB,cAAc;AAAA,EACzH;AAGA,WAAS,aAAa,KAAkB,UAAgD;AACtF,QAAI,CAAC,SAAU,QAAO;AACtB,UAAM,SAAS,EAAE,GAAG,IAAI;AACxB,eAAW,OAAO,OAAO,KAAK,GAAG,EAA4B,QAAO,GAAG,IAAI,KAAK,IAAI,IAAI,GAAG,GAAG,SAAS,GAAG,CAAC;AAC3G,WAAO;AAAA,EACT;AAEA,WAAS,uBAAgC;AACvC,WAAO,OAAO,eAAe,cAAc,WAAW,kCAAkC,EAAE;AAAA,EAC5F;AAGO,WAAS,kBAAkB,OAAiB,SAA0C;AAC3F,UAAM,gBAAgB,QAAQ,iBAAiB,qBAAqB;AACpE,UAAM,YAAY,QAAQ;AAC1B,UAAM,QAAQ,QAAQ,SAAS,IAAI,YAAY,UAAU,EAAE,SAAS,QAAQ,WAAW,UAAU,eAAe,GAAG,UAAU,CAAC;AAC9H,UAAM,QAAQ,MAAM,MAAM;AAC1B,UAAM,OAAO,IAAI,MAAM,MAAM;AAC7B,YAAQ,MAAM,IAAI,IAAI;AAEtB,UAAM,YAAY,IAAI,MAAM,QAAQ,GAAI,QAAQ,kBAAkB,mBAAoB,EAAE,UAAU;AAClG,UAAM,MAAM,eAAe,SAAS;AACpC,UAAM,SAAS,eAAeD,aAAY;AAC1C,UAAM,WAAyB;AAAA,MAC7B,QAAQ,EAAE,OAAO,UAAU;AAAA,MAC3B,MAAM,EAAE,OAAO,IAAI,MAAM,QAAQ,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,IAAI,EAAE;AAAA,MAC9E,SAAS,EAAE,OAAO,IAAI,MAAM,QAAQ,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,GAAG,EAAE;AAAA,MACvF,UAAU,EAAE,OAAO,IAAI,MAAM,QAAQ,EAAE;AAAA,MACvC,UAAU,EAAE,OAAO,IAAI,MAAM,QAAQ,GAAG,KAAK,GAAG,EAAE;AAAA,MAClD,QAAQ,EAAE,OAAO,EAAE;AAAA,MACnB,OAAO,EAAE,OAAO,EAAE;AAAA,IACpB;AACA,UAAM,QAAQ,gBAAgB,OAAO,MAAM,OAAO,QAAQ;AAC1D,UAAM,SAAS,iBAAiB,OAAO,MAAM,MAAM;AACnD,UAAM,QAAQ,gBAAgB,OAAO,MAAM,KAAK;AAChD,UAAM,eAAe,IAAI,MAAM,qBAAqB,KAAK,CAAC;AAC1D,UAAM,gBAAgB,IAAI,MAAM,YAAY,GAAG,GAAG,CAAC;AACnD,UAAM,SAAS,iBAAiB,OAAO,MAAM,QAAQ,EAAE,MAAM,cAAc,OAAO,cAAc,GAAG,YAAY;AAC/G,UAAM,SAAS,iBAAiB,OAAO,MAAM,MAAM;AACnD,UAAM,UAAU,kBAAkB,OAAO,MAAM,QAAQ,GAAG,QAAQ,cAAc,GAAG;AACnF,UAAM,SAAS,iBAAiB,OAAO,MAAM,QAAQ,QAAQ,cAAc,KAAK,EAAE;AAClF,UAAM,QAAQ,gBAAgB,OAAO,EAAE,QAAQ,MAAM,QAAQ,cAAc,QAAQ,cAAc,cAAc,cAAc,CAAC;AAC9H,SAAK,IAAI,MAAM,MAAM,OAAO,MAAM,MAAM,MAAM,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,OAAO,OAAO,QAAQ,UAAU,QAAQ,QAAQ,MAAM,KAAK;AACpJ,UAAM,YAAY,MAAM,QAAQ,CAAC,UAAU,MAAM,OAAO,KAAK,CAAC;AAC9D,UAAM,UAAU,QAAQ,UAAU,oBAAoB,QAAQ,OAAO,IAAI;AACzE,QAAI,YAAY;AAChB,QAAI;AACJ,QAAI;AACJ,UAAM,UAAU,oBAAI,IAAqB;AACzC,UAAM,eAAe,OAA4C;AAAA,MAC/D,OAAO,CAAC,MAAM,IAAI;AAAA,MAClB,QAAQ,CAAC,OAAO,IAAI;AAAA,MACpB,OAAO,CAAC,MAAM,IAAI;AAAA,MAClB,QAAQ,CAAC,OAAO,OAAO,OAAO,MAAM;AAAA,MACpC,OAAO,CAAC,OAAO,KAAK;AAAA,MACpB,SAAS,CAAC,QAAQ,UAAU,QAAQ,QAAQ,GAAI,iBAAiB,CAAC,eAAe,KAAK,IAAI,CAAC,CAAE;AAAA,IAC/F;AACA,UAAM,cAAc,MAAY;AAC9B,iBAAW,CAAC,IAAI,OAAO,KAAK,OAAO,QAAQ,aAAa,CAAC,EAAG,YAAW,UAAU,QAAS,QAAO,UAAU,QAAQ,IAAI,EAAE,MAAM;AAAA,IACjI;AACA,UAAM,YAAY,MAAmB,aAAa,MAAM,OAAO,GAAG,MAAM,aAAa,GAAG,MAAM;AAC9F,QAAI,QAAQ;AACZ,UAAM,YAAY,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,EAAE;AAEpF,aAAS,eAAqB;AAC5B,YAAM,WAAW,QAAQ,OAAO;AAChC,YAAM,UAAU,CAAC,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC,CAAC;AAAA,IACtD;AAEA,aAAS,UAAgB;AACvB,gBAAU,QAAQ,MAAM,KAAK;AAC7B,gBAAU,SAAS,OAAO,KAAK;AAC/B,gBAAU,QAAQ,MAAM,KAAK;AAC7B,gBAAU,SAAS,OAAO,KAAK;AAC/B,gBAAU,SAAS,OAAO,KAAK;AAC/B,gBAAU,UAAU,QAAQ,KAAK;AACjC,aAAO,KAAK;AACZ,YAAM,SAAS,MAAM,aAAa;AAClC,UAAI,UAAU,WAAW,gBAAgB;AACvC,wBAAgB,QAAQ;AACxB,YAAI,eAAgB,MAAK,OAAO,eAAe,KAAK;AACpD,yBAAiB;AACjB,yBAAiB,qBAAqB,OAAO,QAAQ,QAAQ,cAAc,KAAK,CAAC;AACjF,aAAK,IAAI,eAAe,KAAK;AAC7B,oBAAY;AAAA,MACd;AACA,YAAM,gBAAgB,gBAAgB,KAAK,KAAK;AAChD,YAAM,OAAO,MAAM,OAAO;AAC1B,eAAS,SAAS,MAAM,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAClD,eAAS,SAAS,MAAM,IAAI,KAAK,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;AACvE,eAAS,OAAO,QAAQ,KAAK;AAC7B,kBAAY,OAAO,UAAU,QAAQ,CAAC,IAAI,OAAO,UAAU,SAAS,CAAC,IAAI,OAAO,UAAU,QAAQ,CAAC,IAAI,OAAO,OAAO,MAAM,QAAQ,CAAC,IAAI,OAAO,OAAO,OAAO,QAAQ,CAAC,IAAI,OAAO,QAAQ,SAAS,SAAS,UAAU,QAAQ,CAAC,IAAI,OAAO,QAAQ,OAAO,SAAS,UAAU,QAAQ,CAAC,IAAI,UAAU,SAAS,IAAI,MAAM,MAAM,IAAI;AAAA,IACjU;AAEA,WAAO;AAAA,MACL;AAAA,MACA,KAAK,SAAS;AACZ,qBAAa;AACb,cAAM,YAAY,MAAM,UAAU,QAAQ,QAAQ,QAAQ,OAAO;AAAA,UAC/D,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,UAC5D,GAAI,QAAQ,SAAS,SAAY,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,UAC3D,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,QAChE,CAAC;AACD,YAAI,cAAc,KAAM,QAAO;AAC/B,eAAO,MAAM,KAAK,QAAQ,QAAQ,QAAQ,OAAO;AAAA,UAC/C,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,UAC5D,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,UACnD,GAAI,QAAQ,SAAS,SAAY,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,UAC3D,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,QAChE,CAAC;AAAA,MACH;AAAA,MACA,MAAM,CAAC,WAAW,MAAM,KAAK,MAAM;AAAA,MACnC,UAAU,UAAkD;AAC1D,cAAM,OAAO,SAAS;AACtB,YAAI,OAAO,SAAS,YAAY,QAAQ,UAAW,OAAM,SAAS,UAAU,IAAI,KAAK,IAAI;AACzF,cAAM,UAAU,SAAS;AACzB,YAAI,OAAO,YAAY,YAAY,WAAW,eAAgB,OAAM,SAAS,EAAE,WAAW,eAAe,OAAO,KAAK,CAAC;AACtH,YAAI,gBAAgB;AACpB,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,cAAI,CAAC,IAAI,WAAW,YAAY,KAAK,OAAO,UAAU,UAAW;AACjE,kBAAQ,IAAI,IAAI,MAAM,aAAa,MAAM,GAAG,KAAK;AACjD,0BAAgB;AAAA,QAClB;AACA,YAAI,cAAe,aAAY;AAAA,MACjC;AAAA,MACA,SAAS,MAAM,CAAC,GAAG,MAAM,QAAQ,GAAG,GAAG,MAAM,UAAU,CAAC;AAAA,MACxD,OAAO,IAAI;AACT,iBAAS;AACT,iBAAS,MAAM,QAAQ;AACvB,qBAAa;AACb,cAAM,OAAO,EAAE;AACf,cAAM,OAAO,EAAE;AACf,gBAAQ;AACR,iBAAS,OAAO,UAAU,CAAC;AAAA,MAC7B;AAAA,MACA,cAAc;AACZ,cAAM,QAAQ,UAAU,EAAE;AAC1B,YAAI,iBAAiB,EAAE,QAAQ,aAAc,QAAO,MAAM;AAAA,QAAC;AAC3D,cAAME,UAAS,QAAQ;AACvB,cAAM,OAAOA,QAAO,SAAS,MAAM;AACnC,cAAM,QAAQ,QAAQ;AACtB,QAAAA,QAAO,SAAS,KAAK,KAAK,IAAI,QAAQ,EAAE,IAAI;AAC5C,QAAAA,QAAO,SAAS,KAAK,KAAK,IAAI,QAAQ,KAAK,CAAC,IAAI,QAAQ;AACxD,QAAAA,QAAO,SAAS,KAAK,KAAK,IAAI,QAAQ,KAAK,CAAC,IAAI;AAChD,eAAO,MAAMA,QAAO,SAAS,KAAK,IAAI;AAAA,MACxC;AAAA,MACA,QAAQ;AACN,cAAM,EAAE,WAAW,GAAG,SAAS,IAAI,MAAM,MAAM;AAC/C,eAAO,EAAE,GAAG,UAAU,YAAY,UAAU,OAAO,aAAa,UAAU,QAAQ,aAAa,UAAU,QAAQ,aAAa,UAAU,QAAQ,UAAU;AAAA,MAC5J;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AACR,kBAAU;AACV,iBAAS,QAAQ;AACjB,wBAAgB,QAAQ;AACxB,mBAAWC,UAAS,CAAC,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,OAAO,OAAO,EAAG,CAAAA,OAAM,QAAQ;AAClG,qBAAa,QAAQ;AACrB,sBAAc,QAAQ;AACtB,gBAAQ,MAAM,OAAO,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;;;ACrLO,MAAM,aAAkD;AAAA,IAC7D,IAAI;AAAA,MACF,QAAQ;AAAA,MACR,UAAU,EAAE,QAAQ,UAAU,SAAS,WAAW,QAAQ,UAAU,aAAa,eAAe,UAAU,YAAY,UAAU,YAAY,SAAS,UAAU;AAAA,MAC/J,KAAK,EAAE,MAAM,QAAQ,MAAM,QAAQ,QAAQ,UAAU,KAAK,MAAM;AAAA,MAChE,SAAS,EAAE,MAAM,QAAQ,QAAQ,UAAU,KAAK,MAAM;AAAA,MACtD,QAAQ,EAAE,OAAO,kBAAkB,QAAQ,UAAU,OAAO,SAAS,QAAQ,UAAU,OAAO,cAAc,SAAS,uBAAuB;AAAA,MAC5I,SAAS,EAAE,OAAO,SAAS,QAAQ,UAAU,QAAQ,UAAU,QAAQ,UAAU,kBAAkB,2BAA2B,KAAK,aAAa,OAAO,qBAAqB,YAAY,uBAAuB;AAAA,MAC/M,OAAO,EAAE,WAAW,aAAa,QAAQ,iBAAiB,QAAQ,iBAAiB,QAAQ,YAAY,WAAW,aAAa,WAAW,aAAa,OAAO,QAAQ;AAAA,MACtK,MAAM;AAAA,IACR;AAAA,IACA,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,UAAU,EAAE,QAAQ,UAAU,SAAS,YAAY,QAAQ,WAAW,aAAa,iCAAwB,UAAU,gBAAa,UAAU,gBAAgB,SAAS,YAAY;AAAA,MACjL,KAAK,EAAE,MAAM,iBAAc,MAAM,SAAS,QAAQ,QAAQ,KAAK,QAAQ;AAAA,MACvE,SAAS,EAAE,MAAM,QAAQ,QAAQ,YAAS,KAAK,QAAQ;AAAA,MACvD,QAAQ,EAAE,OAAO,oBAAiB,QAAQ,cAAW,OAAO,WAAW,QAAQ,gBAAa,OAAO,kBAAkB,SAAS,mBAAmB;AAAA,MACjJ,SAAS,EAAE,OAAO,UAAU,QAAQ,cAAW,QAAQ,gBAAa,QAAQ,SAAS,kBAAkB,2BAAwB,KAAK,iBAAiB,OAAO,iCAA2B,YAAY,4BAAyB;AAAA,MAC5N,OAAO,EAAE,WAAW,eAAY,QAAQ,cAAc,QAAQ,qBAAqB,QAAQ,gBAAgB,WAAW,iBAAiB,WAAW,iBAAc,OAAO,SAAS;AAAA,MAChL,MAAM;AAAA,IACR;AAAA,EACF;AAEO,MAAM,YAAY,CAAC,WAA8B,WAAW,MAAM,KAAK,WAAW;;;ACDzF,MAAM,iBAAiB;AAEvB,MAAM,qBAAqB;AAC3B,MAAM,aAAa;AACnB,MAAM,cAAiD,CAAC,GAAG,KAAK,CAAC;AACjE,MAAM,mBAAmB;AACzB,MAAM,yBAAyB;AAC/B,MAAM,eAAe,aAAa,cAAc,aAAa;AAC7D,MAAM,iBAAiB,CAAC,WAAW,WAAW,WAAW,SAAS;AAElE,MAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAM,WAAW;AAEjB,MAAM,WAAW,CAAC,OAAuB,GAAG,QAAQ,MAAM,GAAG;AAG7D,MAAM,SAAS,CAAC,aAA+C;AAAA,IAC7D,WAAW;AAAA,IACX,WAAW,OAAO;AAAA,IAClB,WAAW;AAAA,EACb;AAGA,WAAS,WACP,WACA,QACA,QACqC;AACrC,QAAI,WAAW;AACb,YAAMC,SAAQ,UAAU,MAAM,QAAQ;AACtC,YAAM,QAAQ,KAAK,IAAI,UAAU,MAAM,MAAM,CAAC;AAC9C,aAAO;AAAA,QACL,UAAU;AAAA,UACR,EAAE,MAAM,SAAS,OAAO,GAAG,KAAKA,QAAO,OAAO,eAAe,CAAC,EAAE;AAAA,UAChE;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK,KAAK,IAAI,OAAO,GAAG;AAAA,YACxB,OAAO,eAAe,CAAC;AAAA,UACzB;AAAA,UACA,EAAE,MAAM,SAAS,OAAO,KAAK,KAAK,OAAO,OAAO,eAAe,CAAC,EAAE;AAAA,QACpE;AAAA,QACA,OAAO,MAAM,KAAK,EAAE,QAAQ,KAAK,KAAK,KAAK,EAAE,GAAG,CAAC,GAAG,UAAU,QAAQ,CAAC;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AACA,UAAM,OAAO,QAAQ,QAAQ,OAAO,OAAO,IAAI,OAAO,OAAO;AAC7D,WAAO;AAAA,MACL,UAAU;AAAA,QACR,EAAE,MAAM,QAAQ,MAAM,IAAI,OAAO,GAAG,KAAK,MAAM,OAAO,eAAe,CAAC,EAAE;AAAA,MAC1E;AAAA,MACA,OAAO,MAAM,KAAK,EAAE,QAAQ,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,GAAG,UAAU,QAAQ,CAAC;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AAOO,WAAS,oBACd,UAAgC,CAAC,GACjB;AAChB,UAAM,SAAS,QAAQ,UAAU;AACjC,UAAM,UAAU,QAAQ,WAAW;AACnC,UAAM,aAAa,QAAQ,cAAc;AACzC,UAAM,OAAO,UAAU,MAAM;AAC7B,UAAM,UAAU,eAAe,MAAM;AAErC,UAAM,gBAAgB,MAAsB;AAAA,MAC1C,GAAG,OAAO,KAAK,UAAU,EACtB,OAAO,CAAC,OAAO,OAAO,kBAAkB,EACxC,IAAI,CAAC,QAAQ;AAAA,QACZ;AAAA,QACA,MAAM,SAAS,EAAE;AAAA,QACjB,OAAO,QAAQ,OAAO,cAAc,KAAK,MAAM;AAAA,MACjD,EAAE;AAAA;AAAA,MAEJ,GAAG,MAAM;AAAA,QAAQ,CAAC,SAChB,OAAO,OAAO,OAAO,EAClB,OAAO,CAAC,QAAQ,IAAI,SAAS,QAAQ,EAAE,IAAI,MAAM,WAAW,EAC5D,IAAI,CAAC,SAAS;AAAA,UACb,IAAI,IAAI;AAAA,UACR,MAAM,QAAQ,QAAQ,IAAI,EAAE,GAAG,QAAQ,SAAS,IAAI,EAAE;AAAA,UACtD,OAAO,QAAQ,OAAO,IAAI,IAAI,KAAK,IAAI;AAAA,QACzC,EAAE;AAAA,MACN;AAAA,IACF;AAEA,UAAM,WAAW,CAAC,OAA2B;AAC3C,YAAM,YAAY,WAAW,EAAE;AAC/B,UAAI,WAAW;AACb,eAAO;AAAA,UACL,QAAQ,QAAQ,OAAO,cAAc,KAAK,MAAM;AAAA,UAChD,OAAO,SAAS,EAAE;AAAA,UAClB,OAAO;AAAA,YACL,EAAE,OAAO,KAAK,MAAM,QAAQ,OAAO,GAAG,UAAU,MAAM,KAAK;AAAA,YAC3D,EAAE,OAAO,KAAK,MAAM,QAAQ,OAAO,GAAG,UAAU,MAAM,KAAK;AAAA,YAC3D,EAAE,OAAO,KAAK,MAAM,QAAQ,OAAO,GAAG,UAAU,YAAY,KAAK;AAAA,YACjE,EAAE,OAAO,KAAK,MAAM,WAAW,OAAO,OAAO,UAAU,SAAS,EAAE;AAAA,YAClE;AAAA,cACE,OAAO,KAAK,MAAM;AAAA,cAClB,OAAO,GAAG,aAAa,SAAS,CAAC,MAAM,aAAa,SAAS;AAAA,YAC/D;AAAA,UACF;AAAA,UACA,UAAU,WAAW,WAAW,QAAW,YAAY;AAAA,QACzD;AAAA,MACF;AACA,YAAM,SAAS,QAAQ,EAAE;AACzB,YAAM,QAAQ,QAAQ,QAAQ,EAAE;AAChC,YAAM,SAAS,QAAQ;AACvB,aAAO;AAAA,QACL,QAAQ,SAAU,QAAQ,OAAO,OAAO,IAAI,KAAK,OAAO,OAAQ;AAAA,QAChE,OAAO,OAAO,QAAQ,SAAS,EAAE;AAAA,QACjC,GAAI,QAAQ,EAAE,MAAM,MAAM,MAAM,IAAI,CAAC;AAAA,QACrC,OAAO,QACH,CAAC,EAAE,OAAO,OAAO,QAAQ,OAAO,GAAG,MAAM,IAAI,SAAM,MAAM,QAAQ,GAAG,CAAC,IACrE,CAAC;AAAA,QACL,OAAO,QACH;AAAA,UACE,EAAE,IAAI,OAAO,MAAM,MAAM,MAAM,KAAK;AAAA,UACpC,EAAE,IAAI,OAAO,MAAM,MAAM,MAAM,KAAK;AAAA,UACpC,EAAE,IAAI,OAAO,QAAQ,MAAM,MAAM,OAAO;AAAA,UACxC,EAAE,IAAI,OAAO,SAAS,MAAM,MAAM,QAAQ;AAAA,QAC5C,IACA,CAAC;AAAA,QACL,UAAU,WAAW,QAAW,QAAQ,OAAO;AAAA,MACjD;AAAA,IACF;AAEA,UAAM,WAAW,MAAuB;AAAA,MACtC;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,MAAM,KAAK,SAAS;AAAA,QACpB,SAAS,cAAc;AAAA,QACvB,SACE,kBAAkB,aAAa,iBAAiB,cAAc,EAAE,CAAC,EAAG;AAAA,MACxE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,MAAM,KAAK,SAAS;AAAA,QACpB,SAAS,CAAC,EAAE,IAAI,YAAY,MAAM,KAAK,KAAK,CAAC;AAAA,QAC7C,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,MACA,EAAE,MAAM,UAAU,IAAI,UAAU,MAAM,KAAK,SAAS,OAAO;AAAA,MAC3D;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,MAAM,KAAK,SAAS;AAAA,QACpB,SAAS;AAAA,MACX;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,MAAM,KAAK,SAAS;AAAA,QACpB,KAAK;AAAA,QACL,KAAK;AAAA,QACL,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,MAAM,KAAK,SAAS;AAAA,QACpB,SAAU,CAAC,QAAQ,QAAQ,UAAU,KAAK,EAAY,IAAI,CAAC,QAAQ;AAAA,UACjE;AAAA,UACA,MAAM,KAAK,IAAI,EAAE;AAAA,QACnB,EAAE;AAAA,QACF,SAAS;AAAA,MACX;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,MAAM,KAAK,SAAS;AAAA,QACpB,SAAU,CAAC,QAAQ,UAAU,KAAK,EAAY,IAAI,CAAC,QAAQ;AAAA,UACzD;AAAA,UACA,MAAM,KAAK,QAAQ,EAAE;AAAA,QACvB,EAAE;AAAA,QACF,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,SAAS,MACbC,YAAW,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,QAAQ,GAAG,EAAE,IAAI,MAAM,KAAK,OAAO,EAAE,EAAE,EAAE;AAG5E,QAAI,OAIA,OAAO,EAAE,OAAO,CAAC,GAAG,OAAO,GAAG,QAAQ,EAAE;AAE5C,UAAM,UAAU,MAAsB;AAAA,MACpC;AAAA,QACE,IAAI;AAAA,QACJ,MAAM,KAAK,QAAQ;AAAA,QACnB,QAAQ;AAAA,QACR,MAAM,MAAM,KAAK,EAAE,MAAM,SAAS;AAAA,MACpC;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM,KAAK,QAAQ;AAAA,QACnB,QAAQ;AAAA,QACR,MAAM,MAAM,KAAK,EAAE,MAAM,UAAU;AAAA,MACrC;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM,KAAK,QAAQ;AAAA,QACnB,QAAQ;AAAA,QACR,KAAK,aAAa;AAAA,QAClB,MAAM,MAAM,KAAK,EAAE,MAAM,UAAU;AAAA,MACrC;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM,KAAK,QAAQ;AAAA,QACnB,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,MAAM,OACH,KAAK,EAAE,MAAM,eAAe,MAAM,KAAK,EAAE,MAAM,cAAc;AAAA,MAClE;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM,KAAK,QAAQ;AAAA,QACnB,QAAQ;AAAA,QACR,KAAK,aAAa;AAAA,QAClB,MAAM,MAAM,KAAK,EAAE;AAAA,MACrB;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM,KAAK,QAAQ;AAAA,QACnB,QAAQ;AAAA,QACR,MAAM,MAAM,KAAK,EAAE,MAAM,OAAO;AAAA,MAClC;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM,KAAK,QAAQ;AAAA,QACnB,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,MAAM,MAAM,KAAK,EAAE;AAAA,MACrB;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,MAAM,KAAK,QAAQ;AAAA,QACnB,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,EAAE,MAAM,aAAa,CAAC;AAAA,MACrD;AAAA,IACF;AAEA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM,KAAK;AAAA,MACX,OAAO;AAAA,MACP,OAAO,MAAM,CAAC;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,MAAkB;AACvB,cAAM,QAAQ,KAAK;AACnB,YAAI;AACJ,YAAI,OAA+B,KAAK;AACxC,YAAI,CAAC,MAAM;AACT,gBAAM,kBAAkB,KAAK,OAAmB;AAAA,YAC9C,OAAO,KAAK;AAAA,YACZ,QAAQ,KAAK;AAAA,UACf,CAAC;AACD,iBAAO;AAAA,QACT;AACA,cAAM,UAAU;AAChB,YAAI,SAAS;AACb,YAAI,UAAU;AACd,YAAI,WAAW;AACf,YAAI,OAAO;AACX,YAAI,QAAQ;AACZ,YAAI,SAA8B;AAClC,YAAI,cAAc;AAElB,eAAO,MAAM;AACX,gBAAM,MAAM,WAAW,MAAM;AAC7B,gBAAM,SAAS,QAAQ,MAAM;AAC7B,gBAAM,SAAS,MACX,aAAa,GAAG,IACf,QAAQ,OAAO,aAAa;AACjC,iBAAO,EAAE,OAAO,QAAQ,QAAQ,KAAK,CAAC,GAAG,OAAO,OAAO;AAAA,QACzD;AAEA,iBAAS,SAAe;AACtB,cAAI,WAAW,KAAM,SAAQ,KAAK,MAAM;AACxC,kBAAQ;AACR,wBAAc;AACd,mBAAS,QAAQ,KAAK;AAAA,YACpB;AAAA,YACA,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC,GAAG,YAAY,CAAC,CAAC;AAAA,YACtD,WAAW,CAAC,GAAG,KAAK,GAAG;AAAA,YACvB,QAAQ,CAAC,GAAG,GAAG,CAAC;AAAA,YAChB,GAAI,YAAY,cAChB,QAAQ,MAAM,GAAG,QAAQ,QAAQ,SAAS,OAAO,IAC7C,EAAE,OAAO,QAAQ,IACjB,CAAC;AAAA,UACP,CAAC;AAAA,QACH;AAEA,iBAAS,OAAO,IAAkB;AAChC,mBAAS;AACT,gBAAM,SAAS,QAAQ,EAAE,GAAG;AAC5B,oBAAU,SACL,OAAO,QAAQ,OAAO,OAAO,KAAK,OAAO,QAAQ,CAAC,KAAK,aACxD;AACJ,iBAAO;AAAA,YACL;AAAA,YACA,SACI;AAAA,cACE,QAAQ;AAAA,cACR,SAAS,OAAO,QAAQ,IAAI,CAAC,YAAY;AAAA,gBACvC,IAAI;AAAA,gBACJ,MAAM;AAAA,cACR,EAAE;AAAA,cACF,OAAO;AAAA,YACT,IACA;AAAA,cACE,QAAQ;AAAA,cACR,SAAS,CAAC,EAAE,IAAI,YAAY,MAAM,KAAK,KAAK,CAAC;AAAA,cAC7C,OAAO;AAAA,YACT;AAAA,UACN;AACA,iBAAO,QAAQ,SAAS,EAAE,CAAC;AAC3B,iBAAO;AAAA,QACT;AAEA,iBAAS,OAAa;AACpB,gBAAM,MAAM,OAAO,QAAQ;AAC3B,iBAAO,KAAK,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;AAAA,QAC9B;AAEA,cAAM,QAAQ,CAAC,WAA8B;AAC3C,cAAI,OAAO,SAAS;AAClB,oBAAQ,YAAY;AAAA,cAClB,CAAC,SAAS,OAAO,GAAG,MAAM,SAAS,MAAM,CAAC,EAAE,GAAG,OAAO;AAAA,YACxD,CAAC;AAAA,mBACM,OAAO,SAAS,UAAU;AACjC,gBAAI,OAAO,OAAO,SAAU,QAAO;AAAA,UACrC,WAAW,OAAO,OAAO,YAAY,OAAO,OAAO,UAAU;AAC3D,mBAAO,OAAO,KAAK;AAAA,mBACZ,OAAO,OAAO,aAAa,OAAO,OAAO,UAAU,UAAU;AACpE,sBAAU,OAAO;AACjB,gBAAI,QAAQ,MAAM,GAAG,OAAQ,QAAO;AAAA,UACtC,WAAW,OAAO,OAAO,cAAe,QAAO,OAAO,UAAU;AAAA,mBACvD,OAAO,OAAO,cAAc,OAAO,OAAO,UAAU,UAAU;AACrE,uBAAW,OAAO;AAClB,iBAAK;AAAA,UACP,WAAW,OAAO,OAAO,cAAc,OAAO,OAAO;AACnD,oBAAQ,YAAY,EAAE,CAAC,OAAO,EAAE,GAAG,OAAO,MAAM,CAAC;AAAA,QACrD;AACA,cAAM,YAAY,OAAO,SAAS,KAAK;AACvC,cAAM,WAAW,KAAK,QAAQ,CAAC,OAAO;AACpC,mBAAS;AACT,yBAAe;AACf,eAAK,OAAO,EAAE;AACd,cACE,QACA,gBAAgB,QAAQ,iBAAiB;AAEzC,mBAAO;AAAA,QACX,CAAC;AACD,eAAO,MAAM;AACX,sBAAY;AACZ,mBAAS;AACT,cAAI,WAAW,KAAM,SAAQ,KAAK,MAAM;AACxC,iBAAO,QAAQ,IAAI;AACnB,eAAK,QAAQ;AACb,iBAAO,OAAO,EAAE,OAAO,CAAC,GAAG,OAAO,GAAG,QAAQ,EAAE;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;;;AChZA,MAAM,yBAAyB;AAGxB,WAAS,kBAAkB,OAAiB,SAA0C;AAC3F,UAAM,QAAQ,QAAQ;AACtB,UAAM,SAAS,QAAQ,iBAAiB;AACxC,UAAM,WAAW,IAAI,MAAM,cAAc,MAAM,MAAM,MAAM,MAAM,MAAM,UAAU,MAAM,QAAQ,EAAE,QAAQ,CAAC,KAAK,KAAK,CAAC;AACrH,UAAM,WAAW,SAAS,WAAW;AACrC,UAAM,KAAK,SAAS,WAAW;AAC/B,aAAS,QAAQ,GAAG,QAAQ,SAAS,OAAO,QAAS,IAAG,MAAM,OAAO,SAAS,KAAK,KAAK,IAAI,QAAQ,SAAS,KAAK,KAAK,IAAI,MAAM;AACjI,UAAM,WAAW,QAAQ,YAAY,IAAI,MAAM,qBAAqB,EAAE,OAAO,SAAU,WAAW,MAAM,aAAa,KAAK,CAAC;AAC3H,UAAM,OAAO,IAAI,MAAM,KAAK,UAAU,QAAQ;AAC9C,SAAK,gBAAgB;AACrB,QAAI,UAAU;AAEd,aAAS,OAAgB;AACvB,UAAI,MAAM,YAAY,QAAS,QAAO;AACtC,gBAAU,MAAM;AAChB,eAAS,QAAQ,GAAG,QAAQ,SAAS,OAAO,QAAS,UAAS,KAAK,OAAO,MAAM,QAAQ,KAAK,CAAE;AAC/F,eAAS,cAAc;AACvB,eAAS,sBAAsB;AAC/B,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU;AACR,iBAAS,QAAQ;AACjB,YAAI,CAAC,QAAQ,SAAU,UAAS,QAAQ;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;","names":["VFX_LAYERS","entry","DEFAULT_COLOR","min","puff","ageOrKeep","ring","floor","lerp","behavior","spawn","call","UP","FRESH_BLOOD","local","BLOOD","SPEED","FORWARD","BODY_Z","TIP","PORT","WALL_Z","FACING","CENTRE","FALL_SECONDS","BODIES","SPLINTER_DIRECTION","at","SCRAPE_DIRECTION","CAR_ORIGIN","CAR_ROTATION","SPARK_DIRECTION","HITS","HIT_X","HIT_Y","blow","min","max","ring","ORIGIN","OBJECT_ID_DRAWS","FLOOR","clamp","x","y","random","SPOT","QUARTER_TURN","lerp","vx","vy","vz","ease","axis","UP","FULL_TURN_DRAWN","behavior","local","param","screen","ORIGIN","positionOf","ageOrKeep","ring","puff","pick","flash","screen","vy","vx","vz","call","QUARTER_TURN","floor","clamp","lerp","at","rnd","UP","ring","GRAVITY","QUARTER_TURN","DEFAULT_COLOR","FULL_TURN_DRAWN","CAPACITY","DEFAULT_LIFE","decal","BYTE_MAX","FLOATS_PER_VECTOR","cos","sin","RING_CAPACITY","camera","layer","call","local","puff","cos","sin","ease","clamp","min","max","flash","ring","RING_CAPACITY","FADE_SECONDS","clamp","decal","ring","layer","GROUND_COLOR","VFX_LAYERS","camera","layer","flash","VFX_LAYERS"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../../game-vfx/src/area-cap.ts","../../game-vfx/src/budget.ts","../../game-vfx/src/data/explosion-aliases.json","../../game-vfx/src/data/explosions.json","../../game-vfx/src/catalog.ts","../../game-vfx/src/color.ts","../../game-vfx/src/constants.ts","../../game-vfx/src/pool.ts","../../game-vfx/src/pools/chunks.ts","../../game-vfx/src/vector.ts","../../game-vfx/src/pools/glows.ts","../../game-vfx/src/pools/puffs.ts","../../game-vfx/src/pools/sparks.ts","../../game-vfx/src/spawn.ts","../../game-vfx/src/emitters/fire.ts","../../game-vfx/src/effects/dsl.ts","../../game-vfx/src/effects/steps.ts","../../game-vfx/src/effects/creatures/bloater-cloud.ts","../../game-vfx/src/effects/creatures/blood-hit.ts","../../game-vfx/src/effects/creatures/corpse-decay.ts","../../game-vfx/src/effects/creatures/eyes-in-fog.ts","../../game-vfx/src/effects/creatures/dismember.ts","../../game-vfx/src/effects/creatures/headshot.ts","../../game-vfx/src/effects/creatures/reanimation.ts","../../game-vfx/src/effects/creatures/screamer-shriek.ts","../../game-vfx/src/effects/props.ts","../../game-vfx/src/effects/weapons/impact-by-material.ts","../../game-vfx/src/effects/weapons/penetration.ts","../../game-vfx/src/effects/weapons/casings-and-magazine.ts","../../game-vfx/src/effects/weapons/molotov.ts","../../game-vfx/src/effects/weapons/grenade.ts","../../game-vfx/src/effects/weapons/explosive-barrel.ts","../../game-vfx/src/effects/weapons/muzzle-flash.ts","../../game-vfx/src/effects/destruction/shopfront-glass.ts","../../game-vfx/src/effects/vector-math.ts","../../game-vfx/src/effects/destruction/door-stages.ts","../../game-vfx/src/effects/destruction/building-collapse.ts","../../game-vfx/src/effects/destruction/block-wall.ts","../../game-vfx/src/effects/destruction/spot.ts","../../game-vfx/src/effects/destruction/metal-door.ts","../../game-vfx/src/effects/destruction/iron-railing.ts","../../game-vfx/src/effects/destruction/wooden-fence.ts","../../game-vfx/src/effects/destruction/hit-point-breakage.ts","../../game-vfx/src/effects/destruction/pressure-cylinders.ts","../../game-vfx/src/effects/world/building-fire.ts","../../game-vfx/src/effects/world/fog-and-ash.ts","../../game-vfx/src/workshop/rain.ts","../../game-vfx/src/effects/world/rain.ts","../../game-vfx/src/effects/vehicles/car.ts","../../game-vfx/src/effects/vehicles/headlights.ts","../../game-vfx/src/effects/vehicles/scraping-sparks.ts","../../game-vfx/src/effects/vehicles/engine-smoke.ts","../../game-vfx/src/effects/vehicles/boom.ts","../../game-vfx/src/effects/vehicles/fuel-leak.ts","../../game-vfx/src/effects/vehicles/car-explosion.ts","../../game-vfx/src/effects/vehicles/windshield.ts","../../game-vfx/src/effects/screen/damage-and-bite.ts","../../game-vfx/src/effects/screen/infection-phases.ts","../../game-vfx/src/effects/screen/panic.ts","../../game-vfx/src/effects/screen/bloater-blindness.ts","../../game-vfx/src/effects/screen/campfire.ts","../../game-vfx/src/effects/screen/cough-and-breath.ts","../../game-vfx/src/effects/events.ts","../../game-vfx/src/effects/weapons/viewmodel.ts","../../game-vfx/src/effects/vehicles/game-effects.ts","../../game-vfx/src/effects/catalog.ts","../../game-vfx/src/random.ts","../../game-vfx/src/effects/builders/impact-table.ts","../../game-vfx/src/effects/builders/blood.ts","../../game-vfx/src/effects/behaviors/blocks.ts","../../game-vfx/src/effects/behaviors/car.ts","../../game-vfx/src/effects/behaviors/cracks.ts","../../game-vfx/src/effects/builders/shared.ts","../../game-vfx/src/effects/behaviors/cylinder.ts","../../game-vfx/src/effects/behaviors/plate.ts","../../game-vfx/src/effects/behaviors/rain.ts","../../game-vfx/src/effects/behaviors/walkers.ts","../../game-vfx/src/effects/behaviors.ts","../../game-vfx/src/schedule.ts","../../game-vfx/src/effects/expression.ts","../../game-vfx/src/effects/builders/fire.ts","../../game-vfx/src/effects/builders/weapon.ts","../../game-vfx/src/effects/macros.ts","../../game-vfx/src/effects/instance.ts","../../game-vfx/src/effects/player.ts","../../game-vfx/src/lights.ts","../../game-vfx/src/lod.ts","../../game-vfx/src/marks.ts","../../game-vfx/src/pools/rings.ts","../../game-vfx/src/pools/shocks.ts","../../game-vfx/src/explosion.ts","../../game-vfx/src/pools/chunk-motion.ts","../../game-vfx/src/screen.ts","../../game-vfx/src/sprites/kind-pool.ts","../../game-vfx/src/data/sprite-kinds.json","../../game-vfx/src/sprites/kinds.ts","../../game-vfx/src/sprites/system.ts","../../game-vfx/src/workshop/direction.ts","../../game-vfx/src/workshop/debris.ts","../../game-vfx/src/workshop/decals.ts","../../game-vfx/src/workshop/meshes.ts","../../game-vfx/src/workshop/sprites.ts","../../game-vfx/src/workshop/streaks.ts","../../game-vfx/src/workshop/waves.ts","../../game-vfx/src/workshop/engine.ts","../../game-vfx/src/types.ts","../../game-vfx/src/world.ts","../../game-vfx/src/data/event-effects.json","../../game-vfx/src/effects/event-map.ts","../../game-vfx/src/locales/en.ts","../../game-vfx/src/locales/pt-BR.ts","../../game-vfx/src/locale.ts","../../game-vfx/src/effects/camera.ts","../../game-vfx/src/effects/runner.ts","../../game-vfx/src/ground.ts","../src/shaders/glow.ts","../src/shaders/noise.ts","../src/shaders/puff.ts","../src/shaders/spark.ts","../src/instanced.ts","../src/lights.ts","../src/canvas.ts","../src/marks.ts","../src/screen-overlay.ts","../src/shaders/shock.ts","../src/shocks.ts","../src/shaders/sprite.ts","../src/sprites.ts","../src/mesh-layer.ts","../src/shaders/workshop-sprite.ts","../src/workshop-layers.ts","../src/renderer.ts","../src/bench/text.ts","../src/bench/module.ts","../src/ground-patch.ts"],"sourcesContent":["/**\n * @adatechnology/game-vfx-three: the three.js renderer of `@adatechnology/game-vfx`: the Explosion Lab's shaders, debris, shock, lights, marks and\n * screen overlay, plus a deformable ground patch and an `EffectSink` to lend to modules.\n */\nexport { createVfxRenderer, VFX_LAYERS } from './renderer'\nexport { createVfxTestModule } from './bench/module'\nexport type { VfxTestModuleOptions } from './bench/module'\nexport { benchText, benchTexts } from './bench/text'\nexport type { BenchText } from './bench/text'\nexport { createGroundPatch } from './ground-patch'\nexport type { GroundPatch, GroundPatchOptions } from './ground-patch'\nexport { createScreenOverlay } from './screen-overlay'\nexport type { ScreenOverlay } from './screen-overlay'\nexport { createSpriteLayer } from './sprites'\nexport type { SpriteLayer } from './sprites'\nexport { SPRITE_FRAGMENT, SPRITE_VERTEX } from './shaders/sprite'\nexport { createMarkLayer } from './marks'\nexport type { MarkLayer, MarkLayerOptions } from './marks'\nexport { PUFF_FRAGMENT, PUFF_VERTEX } from './shaders/puff'\nexport { SPARK_FRAGMENT, SPARK_VERTEX } from './shaders/spark'\nexport { GLOW_FRAGMENT, GLOW_VERTEX } from './shaders/glow'\nexport { RING_FRAGMENT, RING_VERTEX, SHELL_FRAGMENT, SHELL_VERTEX } from './shaders/shock'\nexport type { CanvasContextLike, CanvasLike, ThreeLib, VfxRenderer, VfxRendererOptions, VfxRendererStats } from './types'\n","import type { AreaCap } from './types'\n\n/** The game's cap (G68194-68202): from the 7th explosion within 40 m in 4 s, the extra ones are made at 0.3. */\nexport const AREA_CAP_GAME: AreaCap = { radius: 40, window: 4, count: 6, excessScale: 0.3 }\n\nexport interface AreaCapTracker {\n /** Registers an explosion at (`x`, `z`) at `time` seconds and answers the scale it gets: 1, or the cap's `excessScale` when `count` or more are already recent in the area. */\n register(time: number, x: number, z: number): number\n clear(): void\n}\n\ninterface Recent {\n time: number\n x: number\n z: number\n}\n\nexport function createAreaCap(cap: AreaCap): AreaCapTracker {\n const recent: Recent[] = []\n const spare: Recent[] = []\n const radiusSquared = cap.radius * cap.radius\n return {\n register(time, x, z) {\n let kept = 0\n for (const entry of recent) {\n if (time - entry.time < cap.window) recent[kept++] = entry\n else spare.push(entry)\n }\n recent.length = kept\n let near = 0\n for (const entry of recent) if ((entry.x - x) ** 2 + (entry.z - z) ** 2 < radiusSquared) near++\n const entry = spare.pop() ?? { time: 0, x: 0, z: 0 }\n entry.time = time\n entry.x = x\n entry.z = z\n recent.push(entry)\n return near >= cap.count ? cap.excessScale : 1\n },\n clear() {\n for (const entry of recent) spare.push(entry)\n recent.length = 0\n },\n }\n}\n","import type { ExplosionDef, VfxProfile, VfxProfileName } from './types'\n\n/**\n * The pool sizes of the three profiles. `high` is the bench and the goldens (the Lab's caps L131/240/295/367 and the Workshop's W221), `medium` the\n * game's default (G67747/67762), `low` close to the game's own budgets (G68074, G68108).\n */\nexport const PROFILES: Readonly<Record<VfxProfileName, VfxProfile>> = {\n high: { puffs: 2600, sparks: 3200, glows: 320, chunks: 300, sprites: { add: 9000, normal: 9000 }, streaks: 3000, debris: 500 },\n medium: { puffs: 1300, sparks: 1600, glows: 160, chunks: 150, sprites: { add: 1500, normal: 600 }, streaks: 1000, debris: 120 },\n low: { puffs: 260, sparks: 800, glows: 80, chunks: 120, sprites: { add: 600, normal: 300 }, streaks: 400, debris: 60 },\n}\n\n/** The Lab's per-event meters (L1043-1044): 400 GPU particles, 40 physics debris, and 4 + 2 lights. */\nexport const EVENT_BUDGET = { particles: 400, debris: 40, blastLights: 4, fireLights: 2 } as const\n\n/** Particles an explosion makes on the GPU, the number of the Lab's effect sheet (L1033): fireballs, smoke, dust, shrapnel, the mushroom and the embers. */\nexport function estimateCost(def: ExplosionDef): number {\n const mushroom = def.mushroom ? def.mushroom.count + def.mushroom.stem : 0\n return def.fireballs + def.smoke.count + def.dust.count + def.shrapnel.count + mushroom + (def.shrapnel.embers ?? 0)\n}\n","{\n \"carl_gustaf_84mm\": \"at4_84mm\",\n \"vog_25\": \"m79_40mm\"\n}\n","{\n \"m67\": {\n \"id\": \"m67\",\n \"lethal\": 5,\n \"injury\": 15,\n \"visualRadius\": 1.3,\n \"fireballs\": 16,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 18,\n \"life\": 5.5\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 30\n },\n \"shrapnel\": {\n \"count\": 150,\n \"kind\": 0,\n \"speed\": 34\n },\n \"chunks\": {\n \"count\": 14,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.25\n },\n \"mark\": {\n \"scorch\": 1.7,\n \"crater\": 0.9,\n \"dent\": 0.25\n },\n \"flash\": {\n \"light\": 45,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.1,\n \"push\": 9,\n \"sources\": [\n \"lab:L796\",\n \"lab:L793\"\n ]\n },\n \"molotov\": {\n \"id\": \"molotov\",\n \"lethal\": 0,\n \"injury\": 4,\n \"visualRadius\": 1.1,\n \"fireballs\": 24,\n \"fuel\": true,\n \"heat\": 0.95,\n \"heatLifeScale\": 1.5,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 3,\n \"life\": 3.5\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 0\n },\n \"shrapnel\": {\n \"count\": 0,\n \"kind\": 0,\n \"speed\": 28\n },\n \"chunks\": {\n \"count\": 0,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.3\n },\n \"mark\": {\n \"scorch\": 2.4\n },\n \"flash\": {\n \"light\": 22,\n \"life\": 1.2,\n \"color\": 16747066,\n \"intensity\": 6\n },\n \"shock\": false,\n \"shake\": 0.25,\n \"push\": 0,\n \"ignite\": 4.2,\n \"sources\": [\n \"lab:L797\",\n \"lab:L793\"\n ]\n },\n \"pipe_bomb\": {\n \"id\": \"pipe_bomb\",\n \"lethal\": 3,\n \"injury\": 10,\n \"visualRadius\": 1,\n \"fireballs\": 8,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 11841704,\n \"count\": 26,\n \"life\": 6,\n \"kind\": 3\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 22\n },\n \"shrapnel\": {\n \"count\": 220,\n \"kind\": 1,\n \"speed\": 30,\n \"width\": 0.03\n },\n \"chunks\": {\n \"count\": 8,\n \"colors\": [\n 5132886,\n 3816768\n ],\n \"plate\": true,\n \"hot\": 0.2\n },\n \"mark\": {\n \"scorch\": 1.3,\n \"crater\": 0.7,\n \"dent\": 0.18\n },\n \"flash\": {\n \"light\": 30,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1,\n \"push\": 7,\n \"sources\": [\n \"lab:L798\",\n \"lab:L793\"\n ]\n },\n \"propane_p13\": {\n \"id\": \"propane_p13\",\n \"lethal\": 5,\n \"injury\": 14,\n \"visualRadius\": 2.2,\n \"fireballs\": 34,\n \"fuel\": true,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 10,\n \"life\": 8\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 26\n },\n \"shrapnel\": {\n \"count\": 70,\n \"kind\": 0,\n \"speed\": 28,\n \"embers\": 30\n },\n \"chunks\": {\n \"count\": 8,\n \"colors\": [\n 3891098,\n 2835824\n ],\n \"plate\": true,\n \"hot\": 0.5\n },\n \"mark\": {\n \"scorch\": 2.6\n },\n \"flash\": {\n \"light\": 70,\n \"life\": 1.1,\n \"color\": 16751168,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.4,\n \"push\": 8,\n \"mushroom\": {\n \"height\": 7,\n \"radius\": 2.6,\n \"count\": 36,\n \"stem\": 16,\n \"life\": 8\n },\n \"residualFires\": [\n {\n \"radius\": 1.4,\n \"life\": 7,\n \"rate\": 20\n }\n ],\n \"ignite\": 5,\n \"hotParts\": true,\n \"sources\": [\n \"lab:L799\",\n \"lab:L793\"\n ]\n },\n \"dynamite\": {\n \"id\": \"dynamite\",\n \"lethal\": 4,\n \"injury\": 12,\n \"visualRadius\": 1.4,\n \"fireballs\": 12,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 8019006,\n \"count\": 24,\n \"life\": 7\n },\n \"dust\": {\n \"color\": 8019006,\n \"count\": 46\n },\n \"shrapnel\": {\n \"count\": 90,\n \"kind\": 0,\n \"speed\": 28\n },\n \"chunks\": {\n \"count\": 26,\n \"colors\": [\n 6965806,\n 8018490,\n 4863526\n ],\n \"hot\": 0.15,\n \"speed\": 1.2\n },\n \"mark\": {\n \"scorch\": 2.4,\n \"crater\": 1.8,\n \"dent\": 0.7\n },\n \"flash\": {\n \"light\": 55,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.5,\n \"push\": 10,\n \"sources\": [\n \"lab:L800\",\n \"lab:L793\"\n ]\n },\n \"c4\": {\n \"id\": \"c4\",\n \"lethal\": 6,\n \"injury\": 18,\n \"visualRadius\": 1.6,\n \"fireballs\": 20,\n \"heat\": 1.25,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 22,\n \"life\": 7\n },\n \"dust\": {\n \"color\": 9407106,\n \"count\": 50\n },\n \"shrapnel\": {\n \"count\": 200,\n \"kind\": 0,\n \"speed\": 42\n },\n \"chunks\": {\n \"count\": 32,\n \"colors\": [\n 9078140,\n 7301730,\n 3881528\n ],\n \"hot\": 0.3,\n \"speed\": 1.4\n },\n \"mark\": {\n \"scorch\": 3,\n \"crater\": 2.3,\n \"dent\": 0.9\n },\n \"flash\": {\n \"light\": 90,\n \"life\": 0.35,\n \"color\": 16773328,\n \"intensity\": 9\n },\n \"shock\": {\n \"duration\": 0.28\n },\n \"shake\": 2.2,\n \"push\": 13,\n \"sources\": [\n \"lab:L801\",\n \"lab:L793\"\n ]\n },\n \"claymore\": {\n \"id\": \"claymore\",\n \"lethal\": 15,\n \"injury\": 50,\n \"visualRadius\": 0.7,\n \"fireballs\": 6,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 8,\n \"life\": 4\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 34\n },\n \"shrapnel\": {\n \"count\": 700,\n \"kind\": 1,\n \"speed\": 55,\n \"width\": 0.025\n },\n \"chunks\": {\n \"count\": 6,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.3\n },\n \"mark\": {\n \"scorch\": 0.9\n },\n \"flash\": {\n \"light\": 28,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1,\n \"push\": 8,\n \"cone\": {\n \"angle\": 0,\n \"half\": 0.5235987755982988,\n \"length\": 50\n },\n \"directionBias\": 2,\n \"sources\": [\n \"lab:L802\",\n \"lab:L793\"\n ]\n },\n \"flashbang\": {\n \"id\": \"flashbang\",\n \"lethal\": 0,\n \"injury\": 10,\n \"visualRadius\": 0.5,\n \"fireballs\": 0,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 11841704,\n \"count\": 10,\n \"life\": 5,\n \"kind\": 3\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 0\n },\n \"shrapnel\": {\n \"count\": 60,\n \"kind\": 2,\n \"speed\": 12\n },\n \"chunks\": {\n \"count\": 0,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.3\n },\n \"mark\": {\n \"scorch\": 0.4\n },\n \"flash\": {\n \"light\": 160,\n \"life\": 0.2,\n \"color\": 16054015,\n \"intensity\": 14,\n \"blinding\": true\n },\n \"shock\": false,\n \"shake\": 0.4,\n \"push\": 0,\n \"sources\": [\n \"lab:L803\",\n \"lab:L793\"\n ]\n },\n \"m79_40mm\": {\n \"id\": \"m79_40mm\",\n \"lethal\": 4,\n \"injury\": 12,\n \"visualRadius\": 1.1,\n \"fireballs\": 14,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 14,\n \"life\": 5\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 24\n },\n \"shrapnel\": {\n \"count\": 130,\n \"kind\": 0,\n \"speed\": 28\n },\n \"chunks\": {\n \"count\": 12,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.3\n },\n \"mark\": {\n \"scorch\": 1.5,\n \"crater\": 0.8,\n \"dent\": 0.22\n },\n \"flash\": {\n \"light\": 40,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1,\n \"push\": 8,\n \"sources\": [\n \"lab:L804\",\n \"lab:L793\"\n ]\n },\n \"m72_66mm\": {\n \"id\": \"m72_66mm\",\n \"lethal\": 5,\n \"injury\": 15,\n \"visualRadius\": 1.5,\n \"fireballs\": 22,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 16,\n \"life\": 6\n },\n \"dust\": {\n \"color\": 9407106,\n \"count\": 30\n },\n \"shrapnel\": {\n \"count\": 180,\n \"kind\": 0,\n \"speed\": 40\n },\n \"chunks\": {\n \"count\": 24,\n \"colors\": [\n 9078140,\n 7301730\n ],\n \"hot\": 0.3\n },\n \"mark\": {\n \"scorch\": 2\n },\n \"flash\": {\n \"light\": 60,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.5,\n \"push\": 11,\n \"directionBias\": 1.4,\n \"sources\": [\n \"lab:L805\",\n \"lab:L793\"\n ]\n },\n \"at4_84mm\": {\n \"id\": \"at4_84mm\",\n \"lethal\": 5,\n \"injury\": 16,\n \"visualRadius\": 1.7,\n \"fireballs\": 26,\n \"heat\": 1.15,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 18,\n \"life\": 6.5\n },\n \"dust\": {\n \"color\": 9407106,\n \"count\": 34\n },\n \"shrapnel\": {\n \"count\": 220,\n \"kind\": 0,\n \"speed\": 46\n },\n \"chunks\": {\n \"count\": 30,\n \"colors\": [\n 9078140,\n 7301730\n ],\n \"hot\": 0.35\n },\n \"mark\": {\n \"scorch\": 2.2,\n \"crater\": 1.4,\n \"dent\": 0.5\n },\n \"flash\": {\n \"light\": 70,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.7,\n \"push\": 12,\n \"directionBias\": 1.6,\n \"sources\": [\n \"lab:L806\",\n \"lab:L793\"\n ]\n },\n \"pg7v\": {\n \"id\": \"pg7v\",\n \"lethal\": 5,\n \"injury\": 16,\n \"visualRadius\": 1.8,\n \"fireballs\": 28,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 18,\n \"life\": 7\n },\n \"dust\": {\n \"color\": 9407106,\n \"count\": 34\n },\n \"shrapnel\": {\n \"count\": 200,\n \"kind\": 0,\n \"speed\": 42,\n \"embers\": 20\n },\n \"chunks\": {\n \"count\": 28,\n \"colors\": [\n 9078140,\n 7301730\n ],\n \"hot\": 0.4\n },\n \"mark\": {\n \"scorch\": 2.2\n },\n \"flash\": {\n \"light\": 70,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.7,\n \"push\": 12,\n \"directionBias\": 1.2,\n \"sources\": [\n \"lab:L807\",\n \"lab:L793\"\n ]\n },\n \"fuel_barrel\": {\n \"id\": \"fuel_barrel\",\n \"lethal\": 4,\n \"injury\": 12,\n \"visualRadius\": 1.9,\n \"fireballs\": 28,\n \"fuel\": true,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 8,\n \"life\": 8\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 22\n },\n \"shrapnel\": {\n \"count\": 60,\n \"kind\": 0,\n \"speed\": 28,\n \"embers\": 24\n },\n \"chunks\": {\n \"count\": 10,\n \"colors\": [\n 10165272,\n 5902864\n ],\n \"plate\": true,\n \"hot\": 0.6\n },\n \"mark\": {\n \"scorch\": 2.4\n },\n \"flash\": {\n \"light\": 60,\n \"life\": 1,\n \"color\": 16748608,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.2,\n \"push\": 8,\n \"mushroom\": {\n \"height\": 6,\n \"radius\": 2.1,\n \"count\": 30,\n \"stem\": 14,\n \"life\": 8\n },\n \"residualFires\": [\n {\n \"dx\": 1.6,\n \"dz\": 0.4,\n \"radius\": 0.9,\n \"life\": 6\n },\n {\n \"dx\": -1.1,\n \"dz\": 1.2,\n \"radius\": 0.7,\n \"life\": 5.5\n },\n {\n \"dx\": -0.4,\n \"dz\": -1.5,\n \"radius\": 0.8,\n \"life\": 6.5\n }\n ],\n \"ignite\": 4,\n \"hotParts\": true,\n \"sources\": [\n \"lab:L808\",\n \"lab:L793\"\n ]\n },\n \"car_fuel_tank\": {\n \"id\": \"car_fuel_tank\",\n \"lethal\": 5,\n \"injury\": 14,\n \"visualRadius\": 2.3,\n \"fireballs\": 36,\n \"fuel\": true,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 12,\n \"life\": 9\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 30\n },\n \"shrapnel\": {\n \"count\": 90,\n \"kind\": 0,\n \"speed\": 28,\n \"embers\": 36\n },\n \"chunks\": {\n \"count\": 14,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"plate\": true,\n \"hot\": 0.5\n },\n \"mark\": {\n \"scorch\": 3.2\n },\n \"flash\": {\n \"light\": 80,\n \"life\": 1.2,\n \"color\": 16748608,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.8,\n \"push\": 9,\n \"mushroom\": {\n \"height\": 7.5,\n \"radius\": 2.8,\n \"count\": 40,\n \"stem\": 16,\n \"life\": 9\n },\n \"ignite\": 5,\n \"hotParts\": true,\n \"sources\": [\n \"lab:L809\",\n \"lab:L793\"\n ]\n },\n \"fuel_pump\": {\n \"id\": \"fuel_pump\",\n \"lethal\": 4,\n \"injury\": 12,\n \"visualRadius\": 1.7,\n \"fireballs\": 24,\n \"fuel\": true,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 6,\n \"life\": 7\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 16\n },\n \"shrapnel\": {\n \"count\": 60,\n \"kind\": 0,\n \"speed\": 28,\n \"embers\": 16\n },\n \"chunks\": {\n \"count\": 12,\n \"colors\": [\n 14209732,\n 2058810,\n 9407106\n ],\n \"plate\": true,\n \"hot\": 0.5\n },\n \"mark\": {\n \"scorch\": 2.4\n },\n \"flash\": {\n \"light\": 55,\n \"life\": 0.9,\n \"color\": 16748608,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.2,\n \"push\": 8,\n \"mushroom\": {\n \"height\": 5,\n \"radius\": 1.8,\n \"count\": 22,\n \"stem\": 10,\n \"life\": 7\n },\n \"residualFires\": [\n {\n \"radius\": 1.1,\n \"life\": 14,\n \"rate\": 22\n }\n ],\n \"ignite\": 4,\n \"hotParts\": true,\n \"sources\": [\n \"lab:L810\",\n \"lab:L793\"\n ]\n },\n \"fuel_station_tank\": {\n \"id\": \"fuel_station_tank\",\n \"lethal\": 12,\n \"injury\": 30,\n \"visualRadius\": 4.5,\n \"fireballs\": 44,\n \"fuel\": true,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 3814449,\n \"count\": 20,\n \"life\": 11\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 46\n },\n \"shrapnel\": {\n \"count\": 160,\n \"kind\": 0,\n \"speed\": 40,\n \"embers\": 60\n },\n \"chunks\": {\n \"count\": 30,\n \"colors\": [\n 9407106,\n 3881528,\n 2058810\n ],\n \"hot\": 0.5\n },\n \"mark\": {\n \"scorch\": 6,\n \"crater\": 4,\n \"dent\": 1.6\n },\n \"flash\": {\n \"light\": 140,\n \"life\": 1.8,\n \"color\": 16748608,\n \"intensity\": 8\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 3,\n \"push\": 14,\n \"mushroom\": {\n \"height\": 16,\n \"radius\": 5.5,\n \"count\": 60,\n \"stem\": 26,\n \"life\": 12,\n \"riseRate\": 0.42\n },\n \"residualFires\": [\n {\n \"radius\": 3.2,\n \"life\": 20,\n \"rate\": 26,\n \"smoke\": 1.4\n },\n {\n \"dx\": 4,\n \"dz\": 3,\n \"radius\": 1.4,\n \"life\": 16\n },\n {\n \"dx\": -4,\n \"dz\": 2,\n \"radius\": 1.2,\n \"life\": 15\n }\n ],\n \"ignite\": 12,\n \"hotParts\": true,\n \"sources\": [\n \"lab:L811\",\n \"lab:L793\"\n ]\n },\n \"generic\": {\n \"id\": \"generic\",\n \"lethal\": 5,\n \"injury\": 15,\n \"visualRadius\": 1.3,\n \"fireballs\": 16,\n \"heat\": 1,\n \"smoke\": {\n \"color\": 6972767,\n \"count\": 18,\n \"life\": 5.5\n },\n \"dust\": {\n \"color\": 8221544,\n \"count\": 30\n },\n \"shrapnel\": {\n \"count\": 150,\n \"kind\": 0,\n \"speed\": 34\n },\n \"chunks\": {\n \"count\": 14,\n \"colors\": [\n 3881528,\n 2894634,\n 4867650\n ],\n \"hot\": 0.25\n },\n \"mark\": {\n \"scorch\": 1.7,\n \"crater\": 0.9,\n \"dent\": 0.25\n },\n \"flash\": {\n \"light\": 45,\n \"life\": 0.45,\n \"color\": 16752720,\n \"intensity\": 6\n },\n \"shock\": {\n \"duration\": 0.32\n },\n \"shake\": 1.1,\n \"push\": 9,\n \"sources\": [\n \"lab:L796\",\n \"lab:L793\",\n \"derived: the M67 profile, for a part with no explosive id; the caller scales it by injury / 15\"\n ]\n }\n}\n","import aliasData from './data/explosion-aliases.json'\nimport explosionData from './data/explosions.json'\nimport type { ExplosionDef } from './types'\n\n/**\n * The 16 profiles of the Explosion Lab (`PROF`, L795-812) keyed by the id of the explosive in `game-weapons` (`m67`, `molotov`, `pipe_bomb`,\n * `propane_p13`, `dynamite`, `c4`, `claymore`, `flashbang`, `m79_40mm`, `m72_66mm`, `at4_84mm`, `pg7v`, `fuel_barrel`, `car_fuel_tank`, `fuel_pump`,\n * `fuel_station_tank`), plus `generic` (the M67 for a part with no explosive id: scale it by `injury / 15`). Each one lists the Lab lines it comes from.\n */\nexport const EXPLOSIONS = explosionData as unknown as Readonly<Record<string, ExplosionDef>>\n\n/** Explosives with no profile of their own: the Carl Gustaf blasts like the AT4, the VOG-25 like the M79. */\nexport const EXPLOSION_ALIASES: Readonly<Record<string, string>> = aliasData\n\n/** A copy of a catalogue with some profiles changed (a partial replaces the fields it names) or removed (`null`); a game adds, tunes or drops effects without touching the core. */\nexport function patchExplosions(base: Readonly<Record<string, ExplosionDef>>, changes: Readonly<Record<string, Partial<ExplosionDef> | ExplosionDef | null>>): Record<string, ExplosionDef> {\n const result: Record<string, ExplosionDef> = { ...base }\n for (const [id, change] of Object.entries(changes)) {\n if (change === null) delete result[id]\n else result[id] = { ...(base[id] ?? {}), ...change, id } as ExplosionDef\n }\n return result\n}\n","export type Rgb = readonly [number, number, number]\n\nconst BYTE_MAX = 255\nconst SRGB_LINEAR_SLOPE = 0.0773993808\nconst SRGB_THRESHOLD = 0.04045\n\n/** The channels of `0xRRGGBB` exactly as three.js r128 reads them (no colour-space conversion): the numbers the Lab's shaders and lights were tuned with. */\nexport function hexToRgb(hex: number): Rgb {\n const whole = Math.floor(hex)\n return [((whole >> 16) & BYTE_MAX) / BYTE_MAX, ((whole >> 8) & BYTE_MAX) / BYTE_MAX, (whole & BYTE_MAX) / BYTE_MAX]\n}\n\nexport function srgbChannelToLinear(channel: number): number {\n return channel < SRGB_THRESHOLD ? channel * SRGB_LINEAR_SLOPE : Math.pow(channel * 0.9478672986 + 0.0521327014, 2.4)\n}\n\n/** `new Color(hex).convertSRGBToLinear()` of r128: the smoke, dust and fire colours the puff shader multiplies the light with. Converted once, at spawn. */\nexport function hexToLinearRgb(hex: number): Rgb {\n const [red, green, blue] = hexToRgb(hex)\n return [srgbChannelToLinear(red), srgbChannelToLinear(green), srgbChannelToLinear(blue)]\n}\n\nexport function linearRgbFromRaw(color: Rgb): Rgb {\n return [srgbChannelToLinear(color[0]), srgbChannelToLinear(color[1]), srgbChannelToLinear(color[2])]\n}\n","import { hexToLinearRgb } from './color'\n\n/** The Lab's smoke colours (L211-214), converted to linear once. Colours of an explosion in data are `0xRRGGBB` and go through `hexToLinearRgb` the same way. */\nexport const SMOKE_COLORS = {\n grey: hexToLinearRgb(0x6a655f),\n dark: hexToLinearRgb(0x4a4440),\n black: hexToLinearRgb(0x3a3431),\n brown: hexToLinearRgb(0x7a5c3e),\n dust: hexToLinearRgb(0x7d7368),\n concrete: hexToLinearRgb(0x8f8a82),\n white: hexToLinearRgb(0xb4b0a8),\n blood: hexToLinearRgb(0x5a0b0b),\n bile: hexToLinearRgb(0x7a8a2a),\n gas: hexToLinearRgb(0xe8ecef),\n} as const\n\nexport const DEFAULT_GRAVITY = 9.8\nexport const DEFAULT_WIND = { x: 0.55, y: 0, z: 0.2 } as const\nexport const FRAME_STEP_LIMIT = 0.05\n","/**\n * A pool that keeps its live records in the order they were added, reuses dead records instead of allocating, and compacts in place. When it is full\n * the oldest record goes (the Lab's `P.shift()`); a pool may choose which one instead (the chunks drop a resting one first).\n */\nexport class OrderedPool<T extends object> {\n /** The live records, oldest first. */\n readonly items: T[] = []\n private readonly spare: T[] = []\n\n constructor(\n readonly capacity: number,\n private readonly create: () => T,\n private readonly release?: (item: T) => void,\n ) {}\n\n get count(): number {\n return this.items.length\n }\n\n /** A record to fill in. At capacity the record `victim` picks (default: the oldest) is dropped and reused. */\n acquire(victim?: (items: readonly T[]) => number): T {\n if (this.items.length >= this.capacity) this.removeAt(victim ? victim(this.items) : 0)\n const record = this.spare.pop() ?? this.create()\n this.items.push(record)\n return record\n }\n\n removeAt(index: number): void {\n const record = this.items[index]\n if (record === undefined) return\n for (let shifted = index; shifted < this.items.length - 1; shifted++) this.items[shifted] = this.items[shifted + 1]!\n this.items.length -= 1\n this.release?.(record)\n this.spare.push(record)\n }\n\n /** Keeps the records `keep` accepts, in the same order, without allocating. `context` goes to `keep` so no closure is needed per frame. */\n compact<TContext>(keep: (item: T, context: TContext) => boolean, context: TContext): void {\n let write = 0\n for (let read = 0; read < this.items.length; read++) {\n const record = this.items[read]!\n if (keep(record, context)) {\n this.items[write++] = record\n continue\n }\n this.release?.(record)\n this.spare.push(record)\n }\n this.items.length = write\n }\n\n clear(): void {\n for (const record of this.items) {\n this.release?.(record)\n this.spare.push(record)\n }\n this.items.length = 0\n }\n}\n","import type { Rgb } from '../color'\nimport { OrderedPool } from '../pool'\nimport type { RandomStream } from '../random'\nimport type { Glow } from './glows'\n\n/** Debris with embers (L366-400). The last block is what the renderer reads: the colour already blended towards the glow of a hot piece. */\nexport interface Chunk {\n x: number\n y: number\n z: number\n vx: number\n vy: number\n vz: number\n rx: number\n ry: number\n rz: number\n ax: number\n ay: number\n az: number\n sx: number\n sy: number\n sz: number\n color: Rgb\n plate: boolean\n hot: boolean\n rest: boolean\n blood: boolean\n splat: boolean\n t: number\n trail: number\n glow: Glow | null\n rng: RandomStream\n outColor: [number, number, number]\n}\n\nexport type ChunkInit = Partial<Pick<Chunk, 'x' | 'y' | 'z' | 'vx' | 'vy' | 'vz' | 'sx' | 'sy' | 'sz' | 'color' | 'plate' | 'hot' | 'blood'>>\n\nconst DEFAULT_COLOR: Rgb = [0x55 / 255, 0x55 / 255, 0x55 / 255]\n\n/** A glow that follows a chunk keeps the spot the chunk had when the chunk leaves the pool, as the Lab's does (the object stays where it was). */\nfunction freezeFollowingGlow(chunk: Chunk): void {\n const glow = chunk.glow\n chunk.glow = null\n if (!glow || glow.follow !== chunk) return\n glow.x = chunk.x + glow.fx\n glow.y = chunk.y + glow.fy\n glow.z = chunk.z + glow.fz\n glow.fx = glow.fy = glow.fz = 0\n glow.follow = null\n}\n\nexport function createChunkPool(capacity: number, placeholder: RandomStream): OrderedPool<Chunk> {\n return new OrderedPool<Chunk>(\n capacity,\n () => ({\n x: 0, y: 0, z: 0, vx: 0, vy: 0, vz: 0, rx: 0, ry: 0, rz: 0, ax: 0, ay: 0, az: 0, sx: 0.2, sy: 0.2, sz: 0.2, color: DEFAULT_COLOR, plate: false, hot: false, rest: false,\n blood: false, splat: false, t: 0, trail: 0, glow: null, rng: placeholder, outColor: [0, 0, 0],\n }),\n freezeFollowingGlow,\n )\n}\n\nfunction firstResting(chunks: readonly Chunk[]): number {\n const index = chunks.findIndex((chunk) => chunk.rest)\n return index >= 0 ? index : 0\n}\n\n/** `chunk()` (L368-376). Draws rotation and spin first (six numbers, always), then lets the caller add what it wants; a full pool drops a resting piece, else the oldest. */\nexport function spawnChunk(pool: OrderedPool<Chunk>, random: RandomStream, init: ChunkInit): Chunk {\n const chunk = pool.acquire(firstResting)\n chunk.x = init.x ?? 0\n chunk.y = init.y ?? 0\n chunk.z = init.z ?? 0\n chunk.vx = init.vx ?? 0\n chunk.vy = init.vy ?? 0\n chunk.vz = init.vz ?? 0\n chunk.rx = random.next() * 6\n chunk.ry = random.next() * 6\n chunk.rz = random.next() * 6\n chunk.ax = random.between(-12, 12)\n chunk.ay = random.between(-12, 12)\n chunk.az = random.between(-12, 12)\n chunk.sx = init.sx ?? 0.2\n chunk.sy = init.sy ?? 0.2\n chunk.sz = init.sz ?? 0.2\n chunk.color = init.color ?? DEFAULT_COLOR\n chunk.plate = init.plate ?? false\n chunk.hot = init.hot ?? false\n chunk.rest = false\n chunk.blood = init.blood ?? false\n chunk.splat = false\n chunk.t = 0\n chunk.trail = 0\n chunk.glow = null\n chunk.rng = random\n return chunk\n}\n\nexport const HOT_COLOR: Rgb = [1, 0.42, 0.1]\nexport const HOT_SECONDS = 1.6\nconst HOT_BLEND = 0.85\n\n/** `_hotCol` (L399-400): the colour of a hot piece, blended towards the glow while it is young. */\nexport function colorOfChunk(chunk: Chunk): readonly [number, number, number] {\n if (!chunk.hot || chunk.t >= HOT_SECONDS) {\n chunk.outColor[0] = chunk.color[0]\n chunk.outColor[1] = chunk.color[1]\n chunk.outColor[2] = chunk.color[2]\n return chunk.outColor\n }\n const amount = Math.max(0, 1 - chunk.t / HOT_SECONDS) * HOT_BLEND\n chunk.outColor[0] = chunk.color[0] + (HOT_COLOR[0] - chunk.color[0]) * amount\n chunk.outColor[1] = chunk.color[1] + (HOT_COLOR[1] - chunk.color[1]) * amount\n chunk.outColor[2] = chunk.color[2] + (HOT_COLOR[2] - chunk.color[2]) * amount\n return chunk.outColor\n}\n","import type { MutableVec3 } from './random'\n\n/** Operations on `{ x, y, z }` written the way three.js r128 does them (`normalize` multiplies by the reciprocal), so a port repeats the Lab's numbers bit for bit. */\n\nexport function createVec3(x = 0, y = 0, z = 0): MutableVec3 {\n return { x, y, z }\n}\n\nexport function addScaled(target: MutableVec3, direction: MutableVec3, scale: number): MutableVec3 {\n target.x += direction.x * scale\n target.y += direction.y * scale\n target.z += direction.z * scale\n return target\n}\n\nexport function normalize(target: MutableVec3): MutableVec3 {\n const length = Math.sqrt(target.x * target.x + target.y * target.y + target.z * target.z) || 1\n const inverse = 1 / length\n target.x *= inverse\n target.y *= inverse\n target.z *= inverse\n return target\n}\n\nexport function distanceBetween(ax: number, ay: number, az: number, bx: number, by: number, bz: number): number {\n const dx = ax - bx\n const dy = ay - by\n const dz = az - bz\n return Math.sqrt(dx * dx + dy * dy + dz * dz)\n}\n\nexport function lerp(from: number, to: number, amount: number): number {\n return from + (to - from) * amount\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return value < min ? min : value > max ? max : value\n}\n","import type { Rgb } from '../color'\nimport { lerp } from '../vector'\nimport { OrderedPool } from '../pool'\n\n/** The position a glow follows (a chunk, or anything with `x`, `y`, `z`). */\nexport interface FollowPoint {\n readonly x: number\n readonly y: number\n readonly z: number\n}\n\n/** An additive halo (L294-318). The last block is what the renderer reads after `update`: where it is, how big and how bright. */\nexport interface Glow {\n x: number\n y: number\n z: number\n s: number\n s1: number | null\n i: number\n t: number\n life: number\n color: Rgb\n curve: number\n flick: boolean\n follow: FollowPoint | null\n fx: number\n fy: number\n fz: number\n outX: number\n outY: number\n outZ: number\n outSize: number\n outIntensity: number\n}\n\nexport type GlowInit = Partial<Omit<Glow, 't' | 'outX' | 'outY' | 'outZ' | 'outSize' | 'outIntensity'>>\n\nconst DEFAULT_COLOR: Rgb = [1, 0.6, 0.25]\n\nexport function createGlowPool(capacity: number): OrderedPool<Glow> {\n return new OrderedPool<Glow>(capacity, () => ({\n x: 0, y: 0, z: 0, s: 1, s1: null, i: 1, t: 0, life: 0.3, color: DEFAULT_COLOR, curve: 2, flick: false, follow: null, fx: 0, fy: 0, fz: 0,\n outX: 0, outY: 0, outZ: 0, outSize: 0, outIntensity: 0,\n }))\n}\n\nexport function spawnGlow(pool: OrderedPool<Glow>, init: GlowInit): Glow {\n const glow = pool.acquire()\n glow.x = init.x ?? 0\n glow.y = init.y ?? 0\n glow.z = init.z ?? 0\n glow.s = init.s ?? 1\n glow.s1 = init.s1 ?? null\n glow.i = init.i ?? 1\n glow.t = 0\n glow.life = init.life ?? 0.3\n glow.color = init.color ?? DEFAULT_COLOR\n glow.curve = init.curve ?? 2\n glow.flick = init.flick ?? false\n glow.follow = init.follow ?? null\n glow.fx = init.fx ?? 0\n glow.fy = init.fy ?? 0\n glow.fz = init.fz ?? 0\n return glow\n}\n\nfunction ageOrKeep(glow: Glow, dt: number): boolean {\n glow.t += dt\n return glow.t < glow.life\n}\n\nconst FLICKER_RATE = 40\nconst FLICKER_SPREAD = 9\n\n/** `updateGlows` (L305-318). */\nexport function updateGlows(pool: OrderedPool<Glow>, dt: number): void {\n pool.compact(ageOrKeep, dt)\n for (const glow of pool.items) {\n const age = glow.t / glow.life\n let x = glow.x\n let y = glow.y\n let z = glow.z\n if (glow.follow) {\n x = glow.follow.x + glow.fx\n y = glow.follow.y + glow.fy\n z = glow.follow.z + glow.fz\n }\n glow.outX = x\n glow.outY = y\n glow.outZ = z\n glow.outSize = glow.s1 !== null ? lerp(glow.s, glow.s1, 1 - Math.pow(1 - age, 3)) : glow.s\n const flicker = glow.flick ? 0.75 + 0.25 * Math.sin(glow.t * FLICKER_RATE + glow.s * FLICKER_SPREAD) : 1\n glow.outIntensity = glow.i * Math.pow(1 - age, glow.curve) * flicker\n }\n}\n","import type { Rgb } from '../color'\nimport { SMOKE_COLORS } from '../constants'\nimport { OrderedPool } from '../pool'\nimport type { RandomStream } from '../random'\n\n/** The ring a mushroom cloud's puffs travel on (L722-735). */\nexport interface Ring {\n x: number\n z: number\n y0: number\n rise: number\n rk: number\n R0: number\n R1: number\n r: number\n roll: number\n t: number\n life: number\n}\n\n/**\n * Fire, smoke, dust, blood and gas (L193-238). `kind`: 0 fire that turns into smoke, 1 dust, 2 blood, 3 gas or white powder smoke, 4 bile.\n * The last block is what the renderer reads after `update`.\n */\nexport interface Puff {\n x: number\n y: number\n z: number\n vx: number\n vy: number\n vz: number\n s0: number\n s1: number\n sg: number\n gk: number\n life: number\n t: number\n h0: number\n hl: number\n drag: number\n buoy: number\n grav: number\n kind: number\n seed: number\n wind: number\n color: Rgb\n ring: Ring | null\n ph: number\n th: number\n rng: RandomStream\n age: number\n heat: number\n size: number\n}\n\nexport type PuffInit = Partial<Omit<Puff, 'seed' | 'age' | 'heat' | 'size' | 't' | 'rng'>>\n\nconst FLOOR_FRACTION = 0.4\nconst FLOOR_BOUNCE = -0.2\nconst ARRIVAL_FRAME = 30\nconst ARRIVAL_BASE = 0.3\nconst GROWTH_CAP_SECONDS = 3.5\n\nexport function createPuffPool(capacity: number): OrderedPool<Puff> {\n const placeholder: RandomStream = { next: () => 0, between: (min) => min, direction: (out) => out, state: 0 }\n return new OrderedPool<Puff>(capacity, () => ({\n x: 0, y: 0, z: 0, vx: 0, vy: 0, vz: 0, s0: 0.2, s1: 1, sg: 0.1, gk: 6, life: 3, t: 0, h0: 0, hl: 0.4, drag: 3, buoy: 0.5, grav: 0, kind: 0, seed: 0, wind: 1,\n color: SMOKE_COLORS.grey, ring: null, ph: 0, th: 0, rng: placeholder, age: 0, heat: 0, size: 0,\n }))\n}\n\n/** `puff()` of the Lab: draws `seed` first, always, even when the caller gives one (L196), and drops the oldest puff when the pool is full. */\nexport function spawnPuff(pool: OrderedPool<Puff>, random: RandomStream, init: PuffInit): Puff {\n const puff = pool.acquire()\n puff.x = init.x ?? 0\n puff.y = init.y ?? 0\n puff.z = init.z ?? 0\n puff.vx = init.vx ?? 0\n puff.vy = init.vy ?? 0\n puff.vz = init.vz ?? 0\n puff.s0 = init.s0 ?? 0.2\n puff.s1 = init.s1 ?? 1\n puff.sg = init.sg ?? 0.1\n puff.gk = init.gk ?? 6\n puff.life = init.life ?? 3\n puff.t = 0\n puff.h0 = init.h0 ?? 0\n puff.hl = init.hl ?? 0.4\n puff.drag = init.drag ?? 3\n puff.buoy = init.buoy ?? 0.5\n puff.grav = init.grav ?? 0\n puff.kind = init.kind ?? 0\n puff.seed = random.next()\n puff.wind = init.wind ?? 1\n puff.color = init.color ?? SMOKE_COLORS.grey\n puff.ring = init.ring ?? null\n puff.ph = init.ph ?? 0\n puff.th = init.th ?? 0\n puff.rng = random\n puff.age = 0\n puff.heat = 0\n puff.size = 0\n return puff\n}\n\nfunction ageOrKeep(puff: Puff, dt: number): boolean {\n puff.t += dt\n return puff.t < puff.life\n}\n\nfunction moveOnRing(puff: Puff, ring: Ring, wind: { x: number; z: number }): void {\n const ringTime = ring.t\n const centerY = ring.y0 + ring.rise * (1 - Math.exp(-ringTime * ring.rk))\n const majorRadius = ring.R0 + (ring.R1 - ring.R0) * (1 - Math.exp(-ringTime * 1.6))\n const theta = puff.th + ringTime * ring.roll\n const minorRadius = ring.r * (0.8 + 0.4 * Math.min(1, ringTime))\n const radius = majorRadius + minorRadius * Math.cos(theta)\n puff.x = ring.x + Math.cos(puff.ph) * radius + wind.x * ringTime * 0.6\n puff.z = ring.z + Math.sin(puff.ph) * radius + wind.z * ringTime * 0.6\n puff.y = centerY + minorRadius * Math.sin(theta)\n}\n\nfunction moveFree(puff: Puff, dt: number, age: number, heat: number, wind: { x: number; z: number }): void {\n const damping = Math.exp(-puff.drag * dt)\n puff.vx *= damping\n puff.vy *= damping\n puff.vz *= damping\n puff.vy += (puff.buoy * (heat > 0 ? 1.6 : 1) - puff.grav) * dt\n puff.x += (puff.vx + wind.x * puff.wind * age) * dt\n puff.y += puff.vy * dt\n puff.z += (puff.vz + wind.z * puff.wind * age) * dt\n if (puff.y < puff.s0 * FLOOR_FRACTION) {\n puff.y = puff.s0 * FLOOR_FRACTION\n if (puff.vy < 0) puff.vy *= FLOOR_BOUNCE\n }\n}\n\n/** `updatePuffs` (L205-238): ages, removes what ended, then moves the rest with the wind (or along their mushroom ring) and derives what the shader reads. */\nexport function updatePuffs(pool: OrderedPool<Puff>, dt: number, wind: { x: number; z: number }): void {\n pool.compact(ageOrKeep, dt)\n for (const puff of pool.items) {\n const age = puff.t / puff.life\n const heat = puff.h0 > 0 ? puff.h0 * Math.pow(Math.max(0, 1 - puff.t / puff.hl), 1.25) : 0\n if (puff.ring) moveOnRing(puff, puff.ring, wind)\n else moveFree(puff, dt, age, heat, wind)\n const size = puff.s0 + (puff.s1 - puff.s0) * (1 - Math.exp(-puff.t * puff.gk)) + puff.sg * Math.min(puff.t, GROWTH_CAP_SECONDS)\n puff.size = size * Math.min(1, puff.t * ARRIVAL_FRAME + ARRIVAL_BASE)\n puff.age = age\n puff.heat = heat\n }\n}\n","import { OrderedPool } from '../pool'\n\n/** Shrapnel, sparks and embers, stretched along their velocity by the shader (L239-293). `kind`: 0 hot fragment, 1 steel ball, 2 white spark, 3 glass, 4 slow ember. */\nexport interface Spark {\n x: number\n y: number\n z: number\n vx: number\n vy: number\n vz: number\n t: number\n life: number\n w: number\n st: number\n kind: number\n drag: number\n g: number\n bounce: number\n age: number\n}\n\nexport type SparkInit = Partial<Omit<Spark, 't' | 'age'>>\n\nconst GROUND_LIFT = 0.02\nconst BOUNCE_SLIDE = 0.55\n\nexport function createSparkPool(capacity: number): OrderedPool<Spark> {\n return new OrderedPool<Spark>(capacity, () => ({ x: 0, y: 0, z: 0, vx: 0, vy: 0, vz: 0, t: 0, life: 0.8, w: 0.04, st: 0.035, kind: 0, drag: 0.6, g: 9.8, bounce: 0.35, age: 0 }))\n}\n\nexport function spawnSpark(pool: OrderedPool<Spark>, init: SparkInit): Spark {\n const spark = pool.acquire()\n spark.x = init.x ?? 0\n spark.y = init.y ?? 0\n spark.z = init.z ?? 0\n spark.vx = init.vx ?? 0\n spark.vy = init.vy ?? 0\n spark.vz = init.vz ?? 0\n spark.t = 0\n spark.life = init.life ?? 0.8\n spark.w = init.w ?? 0.04\n spark.st = init.st ?? 0.035\n spark.kind = init.kind ?? 0\n spark.drag = init.drag ?? 0.6\n spark.g = init.g ?? 9.8\n spark.bounce = init.bounce ?? 0.35\n spark.age = 0\n return spark\n}\n\nfunction ageOrKeep(spark: Spark, dt: number): boolean {\n spark.t += dt\n return spark.t < spark.life\n}\n\nexport interface SparkStep {\n readonly dt: number\n readonly groundAt: (x: number, z: number) => number\n}\n\n/** `updateSparks` (L277-293): drag, gravity, a bounce that kills some speed on the ground. */\nexport function updateSparks(pool: OrderedPool<Spark>, step: SparkStep): void {\n pool.compact(ageOrKeep, step.dt)\n for (const spark of pool.items) {\n const damping = Math.exp(-spark.drag * step.dt)\n spark.vx *= damping\n spark.vy *= damping\n spark.vz *= damping\n spark.vy -= spark.g * step.dt\n spark.x += spark.vx * step.dt\n spark.y += spark.vy * step.dt\n spark.z += spark.vz * step.dt\n const floor = step.groundAt(spark.x, spark.z) + GROUND_LIFT\n if (spark.y < floor) {\n spark.y = floor\n if (spark.vy < 0) {\n spark.vy *= -spark.bounce\n spark.vx *= BOUNCE_SLIDE\n spark.vz *= BOUNCE_SLIDE\n }\n }\n spark.age = spark.t / spark.life\n }\n}\n","import type { VfxCore } from './core'\nimport { spawnChunk } from './pools/chunks'\nimport type { Chunk, ChunkInit } from './pools/chunks'\nimport { spawnGlow } from './pools/glows'\nimport type { Glow, GlowInit } from './pools/glows'\nimport { spawnPuff } from './pools/puffs'\nimport type { Puff, PuffInit } from './pools/puffs'\nimport { spawnSpark } from './pools/sparks'\nimport type { Spark, SparkInit } from './pools/sparks'\nimport type { RandomStream } from './random'\n\nconst HOT_GLOW_COLOR = [1, 0.45, 0.12] as const\n\n/** The spawners count what an explosion makes (the Lab's `evCount`) on top of the pools, and a hot chunk carries a halo, as in the Lab (L371-376). */\nexport function addPuff(core: VfxCore, random: RandomStream, init: PuffInit): Puff {\n core.spawned.puffs++\n const puff = spawnPuff(core.puffs, random, init)\n core.trace?.puff?.(puff)\n return puff\n}\n\nexport function addSpark(core: VfxCore, init: SparkInit): Spark {\n core.spawned.sparks++\n const spark = spawnSpark(core.sparks, init)\n core.trace?.spark?.(spark)\n return spark\n}\n\nexport function addGlow(core: VfxCore, init: GlowInit): Glow {\n const glow = spawnGlow(core.glows, init)\n core.trace?.glow?.(glow)\n return glow\n}\n\nexport function addChunk(core: VfxCore, random: RandomStream, init: ChunkInit): Chunk {\n const chunk = spawnChunk(core.chunks, random, init)\n core.spawned.chunks++\n if (chunk.hot && core.layers.shrapnel) {\n chunk.glow = addGlow(core, { follow: chunk, s: 0.35 + chunk.sx, i: 2.2, life: random.between(1, 2.2), color: HOT_GLOW_COLOR, curve: 1.5 })\n }\n core.trace?.chunk?.(chunk)\n return chunk\n}\n","import type { Rgb } from '../color'\nimport { SMOKE_COLORS } from '../constants'\nimport type { VfxCore } from '../core'\nimport { OrderedPool } from '../pool'\nimport type { RandomStream } from '../random'\nimport { addPuff, addSpark } from '../spawn'\nimport type { Follow } from '../types'\nimport { lerp } from '../vector'\n\n/** A lingering fire (L424-442): it grows, gives flames that cool into smoke, and fades out. */\nexport interface Fire {\n x: number\n y: number\n z: number\n r: number\n r0: number\n grow: number\n life: number\n t: number\n rate: number\n acc: number\n smoke: number\n smokeAcc: number\n fade: number\n follow: Follow | null\n fx: number\n fy: number\n fz: number\n color: Rgb\n rng: RandomStream\n handle: number\n}\n\nexport type FireInit = Partial<Pick<Fire, 'x' | 'y' | 'z' | 'r' | 'grow' | 'life' | 'rate' | 'smoke' | 'follow' | 'fx' | 'fy' | 'fz' | 'color'>> & { startRadius?: number }\n\nexport function createFirePool(capacity: number, placeholder: RandomStream): OrderedPool<Fire> {\n return new OrderedPool<Fire>(capacity, () => ({\n x: 0, y: 0, z: 0, r: 0.6, r0: 0.6, grow: 0, life: 6, t: 0, rate: 22, acc: 0, smoke: 0.6, smokeAcc: 0, fade: 1, follow: null, fx: 0, fy: 0, fz: 0, color: SMOKE_COLORS.black,\n rng: placeholder, handle: 0,\n }))\n}\n\nexport function spawnFire(pool: OrderedPool<Fire>, random: RandomStream, init: FireInit, handle: number): Fire {\n const fire = pool.acquire()\n fire.x = init.x ?? 0\n fire.y = init.y ?? 0\n fire.z = init.z ?? 0\n fire.r = init.r ?? 0.6\n fire.r0 = init.startRadius ?? fire.r\n fire.grow = init.grow ?? 0\n fire.life = init.life ?? 6\n fire.t = 0\n fire.rate = init.rate ?? 22\n fire.acc = 0\n fire.smoke = init.smoke ?? 0.6\n fire.smokeAcc = 0\n fire.fade = 1\n fire.follow = init.follow ?? null\n fire.fx = init.fx ?? 0\n fire.fy = init.fy ?? 0\n fire.fz = init.fz ?? 0\n fire.color = init.color ?? SMOKE_COLORS.black\n fire.rng = random\n fire.handle = handle\n return fire\n}\n\nexport function addFire(core: VfxCore, random: RandomStream, init: FireInit, handle: number): Fire {\n const fire = spawnFire(core.fires, random, init, handle)\n core.trace?.fire?.(fire)\n return fire\n}\n\nfunction positionOf(follow: Follow): { x: number; y: number; z: number } {\n return 'position' in follow ? follow.position : follow\n}\n\nfunction emitFlames(core: VfxCore, fire: Fire, radius: number, dt: number): void {\n const random = fire.rng\n fire.acc += dt * fire.rate * (0.5 + radius * 0.9) * fire.fade * core.clock.lod\n while (fire.acc >= 1) {\n fire.acc -= 1\n const angle = random.next() * Math.PI * 2\n const distance = Math.sqrt(random.next()) * radius\n addPuff(core, random, {\n x: fire.x + Math.cos(angle) * distance, y: fire.y + 0.05, z: fire.z + Math.sin(angle) * distance,\n vx: random.between(-0.2, 0.2), vy: random.between(0.6, 1.4), vz: random.between(-0.2, 0.2),\n s0: 0.1, s1: random.between(0.28, 0.46) * (0.8 + Math.min(radius, 3) * 0.22), sg: -0.08,\n life: random.between(0.45, 0.85), h0: random.between(1, 1.25), hl: random.between(0.35, 0.6),\n drag: 1.5, buoy: 3.2, color: fire.color, kind: 0, wind: 0.4,\n })\n }\n}\n\nfunction emitSmoke(core: VfxCore, fire: Fire, radius: number, dt: number): void {\n const random = fire.rng\n fire.smokeAcc += dt * fire.smoke * (1 + radius * 0.8) * fire.fade * core.clock.lod\n while (fire.smokeAcc >= 1 && core.layers.smoke) {\n fire.smokeAcc -= 1\n addPuff(core, random, {\n x: fire.x + random.between(-radius, radius) * 0.5, y: fire.y + 0.6 + radius * 0.3, z: fire.z + random.between(-radius, radius) * 0.5,\n vy: random.between(0.8, 1.5), s0: 0.25, s1: 0.6 + Math.min(radius, 2) * 0.3, sg: 0.3, life: random.between(4, 6.5),\n h0: 0.25, hl: 0.25, drag: 0.6, buoy: 0.55, color: fire.color, kind: 0,\n })\n }\n}\n\nfunction emitEmber(core: VfxCore, fire: Fire, radius: number, dt: number): void {\n const random = fire.rng\n if (!(random.next() < dt * 6 * fire.fade && core.layers.shrapnel)) return\n addSpark(core, {\n x: fire.x + random.between(-radius, radius) * 0.6, y: fire.y + 0.4, z: fire.z + random.between(-radius, radius) * 0.6,\n vx: random.between(-0.4, 0.4), vy: random.between(1.5, 3.2), vz: random.between(-0.4, 0.4),\n life: random.between(0.8, 1.6), w: 0.025, st: 0.02, kind: 4, g: -0.6, drag: 1.2,\n })\n}\n\n/** `updateFires` (L430-442), walking the list backwards like the Lab. */\nexport function updateFires(core: VfxCore, dt: number): void {\n const pool = core.fires\n for (let index = pool.items.length - 1; index >= 0; index--) {\n const fire = pool.items[index]!\n fire.t += dt\n if (fire.follow) {\n const point = positionOf(fire.follow)\n fire.x = point.x + fire.fx\n fire.y = point.y + fire.fy\n fire.z = point.z + fire.fz\n }\n const radius = fire.grow ? lerp(fire.r0, fire.r, Math.min(1, fire.t / fire.grow)) : fire.r\n fire.fade = fire.t < fire.life - 1.5 ? Math.min(1, fire.t * 3) : Math.max(0, (fire.life - fire.t) / 1.5)\n if (fire.t >= fire.life) {\n pool.removeAt(index)\n continue\n }\n if (!core.layers.fire) continue\n emitFlames(core, fire, radius, dt)\n emitSmoke(core, fire, radius, dt)\n emitEmber(core, fire, radius, dt)\n }\n}\n","import type { Expr } from './expression'\n\n/** Constructors for the computed fields of a recipe. They only build data (`{ $, a }`); `expression.ts` runs it. */\nconst call =\n (name: string) =>\n (...args: readonly unknown[]): Expr => ({ $: name, a: args })\n\nexport const rnd = call('rnd')\nexport const rand = call('rand')\nexport const add = call('add')\nexport const concat = call('concat')\nexport const sub = call('sub')\nexport const mul = call('mul')\nexport const div = call('div')\nexport const mod = call('mod')\nexport const neg = call('neg')\nexport const abs = call('abs')\nexport const sqrt = call('sqrt')\nexport const exp = call('exp')\nexport const sin = call('sin')\nexport const cos = call('cos')\nexport const atan2 = call('atan2')\nexport const min = call('min')\nexport const max = call('max')\nexport const floor = call('floor')\nexport const ceil = call('ceil')\nexport const round = call('round')\nexport const clamp = call('clamp')\nexport const lerp = call('lerp')\nexport const ease = call('ease')\nexport const lt = call('lt')\nexport const gt = call('gt')\nexport const le = call('le')\nexport const ge = call('ge')\nexport const eq = call('eq')\nexport const ne = call('ne')\nexport const not = call('not')\nexport const and = call('and')\nexport const or = call('or')\nexport const ite = call('ite')\nexport const vadd = call('vadd')\nexport const vsub = call('vsub')\nexport const vscale = call('vscale')\nexport const vnorm = call('vnorm')\nexport const vneg = call('vneg')\nexport const vlerp = call('vlerp')\nexport const vx = call('vx')\nexport const vy = call('vy')\nexport const vz = call('vz')\nexport const vdist = call('vdist')\nexport const vwith = call('with')\nexport const pick = call('at')\nexport const scaled = call('scaled')\nexport const param = (...values: readonly unknown[]): Expr => ({ $: 'param', a: [values] })\n/** Binds `name` to `value` while `body` resolves: the page's `const a = ...` inside a spawn callback. */\nexport const local = (name: string, value: unknown, body: unknown): Expr => ({ $: 'let', a: [name, value, body] })\nexport const query = (behavior: string, name: string, ...args: readonly unknown[]): Expr => ({ $: 'query', a: [behavior, name, ...args] })\nexport const variable = (name: string): Expr => ({ $: 'var', a: [name] })\nexport const cameraForward = call('cameraForward')\nexport const TIME: Expr = { $: 't' }\nexport const PARAM: Expr = { $: 'paramIndex' }\nexport const DELTA: Expr = { $: 'dt' }\nexport const INDEX: Expr = { $: 'index' }\nexport const QUALITY: Expr = { $: 'quality' }\nexport const FRESH: Expr = { $: 'fresh' }\nexport const DIRECTION: Expr = { $: 'direction' }\nexport const NORMAL: Expr = { $: 'normal' }\nexport const CAMERA_POSITION: Expr = { $: 'cameraPosition' }\nexport const UP = [0, 1, 0] as const\n","import type { Computed, EffectStep, ScreenKey } from './types'\n\ntype System = 'add' | 'normal' | 'streak'\n\n/** Constructors for the steps of a recipe (they only build data). */\nexport const burst = (system: System, count: Computed, spawn: Computed): EffectStep => ({ op: 'burst', system, count, spawn })\nexport const spawn = (system: System, options: Computed): EffectStep => ({ op: 'spawn', system, spawn: options })\nexport const emit = (key: string, system: System, rate: Computed, options: Computed): EffectStep => ({ op: 'emit', key, system, rate, spawn: options })\n/** A solid particle (`MeshSpawn`): a cone, a sphere, an icosahedron. */\nexport const mesh = (options: Computed): EffectStep => ({ op: 'mesh', spawn: options })\nexport const debris = (options: Computed): EffectStep => ({ op: 'debris', spawn: options })\nexport const decal = (...args: readonly Computed[]): EffectStep => ({ op: 'decal', args })\nexport const ring = (...args: readonly Computed[]): EffectStep => ({ op: 'ring', args })\nexport const flash = (...args: readonly Computed[]): EffectStep => ({ op: 'flash', args })\nexport const lens = (...args: readonly Computed[]): EffectStep => ({ op: 'lens', args })\nexport const screen = (change: { add?: Partial<Record<ScreenKey, Computed>>; set?: Partial<Record<ScreenKey, Computed>>; max?: Partial<Record<ScreenKey, Computed>> }): EffectStep => ({ op: 'screen', ...change })\nexport const fireLight = (slot: 0 | 1, point: Computed, intensity: Computed, time: Computed): EffectStep => ({ op: 'fire_light', slot, point, intensity, time })\nexport const fireLightOff = (slot: 0 | 1): EffectStep => ({ op: 'fire_light_off', slot })\nexport const cue = (name: string, args?: Computed, draws?: number): EffectStep => ({ op: 'cue', cue: name, ...(args !== undefined ? { args } : {}), ...(draws !== undefined ? { draws } : {}) })\nexport const call = (macro: string, ...args: readonly Computed[]): EffectStep => ({ op: 'call', macro, args })\nexport const after = (time: Computed, ...steps: readonly EffectStep[]): EffectStep => ({ op: 'at', time, steps })\nexport const when = (condition: Computed, steps: readonly EffectStep[], otherwise?: readonly EffectStep[]): EffectStep => ({ op: 'when', if: condition, steps, ...(otherwise ? { otherwise } : {}) })\nexport const repeat = (count: Computed, ...steps: readonly EffectStep[]): EffectStep => ({ op: 'repeat', count, steps })\nexport const set = (name: string, value: Computed): EffectStep => ({ op: 'set', name, value })\nexport const behavior = (id: string, action: string, args?: Computed): EffectStep => ({ op: 'behavior', id, action, ...(args !== undefined ? { args } : {}) })\nexport const append = (name: string, value: Computed): EffectStep => ({ op: 'append', name, value })\nexport const camera = (eye: Computed, target: Computed, instant?: boolean): EffectStep => ({ op: 'camera', eye, target, ...(instant ? { instant } : {}) })\nexport const post = (values: Readonly<Record<string, Computed>>): EffectStep => ({ op: 'post', values })\n","import { gt, lt, and, INDEX, ite, mod, scaled, TIME } from '../dsl'\nimport { after, burst, debris, decal, emit, repeat, ring, screen, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst CENTRE: readonly [number, number, number] = [0, 1.1, 0]\nconst UP: readonly [number, number, number] = [0, 1, 0]\n\n/** W501-520: the belly bursts after a second and leaves a green cloud near the ground for eight. */\nexport const BLOATER_CLOUD: EffectDef = {\n id: 'bloater_cloud',\n pageId: 'inchado',\n team: 'creatures',\n budget: { particles: 180 },\n loop: 9,\n view: { eye: [5.5, 3.2, 6], target: [0, 1, 0] },\n timeline: [\n after(\n 1,\n burst('normal', 40, { p: CENTRE, r: 0.4, sp: [1.5, 4], drag: 2.2, life: [4, 6], size: [1, 2.2], grow: 2, c0: 0x6f8a3c, c1: 0x3b4a26, a: 0.32, fi: 0.08, g: 0.05 }),\n burst('normal', 30, { p: CENTRE, dir: UP, cone: 1.3, sp: [2, 4], life: 1.4, size: [0.04, 0.08], c0: 0x4a5a1c, g: 9.8, fi: 0, gnd: 3, ds: [0.1, 0.2] }),\n repeat(scaled(10), debris({ p: CENTRE, dir: UP, cone: 1.2, sp: [2, 5], size: [0.07, 0.05, 0.07], k: [0.6, 1.4], c: ite(mod(INDEX, 2), 0x6b7a52, 0x4a1a12), life: 9 })),\n decal(0, 0, 0, 1.6, 0x6a7a24, { grow: 0.6, life: 60, fluid: 'bile' }),\n ring([0, 0.02, 0], 4, 4, 8, 0x3a5a20, UP, 0.35),\n screen({ add: { shake: 0.15 } }),\n ),\n ],\n tick: [\n when(and(gt(TIME, 1), lt(TIME, 8)), [\n emit('gas', 'normal', 7, { p: [0, 0.4, 0], r: 3.4, flat: true, dir: UP, cone: 1.3, sp: [0.1, 0.35], drag: 0.4, life: [3, 5], size: [1.2, 2.2], grow: 1.5, c0: 0x6f8a3c, c1: 0x3b4a26, a: 0.22, fi: 0.3 }),\n emit('mote', 'add', 10, { p: [0, 0.6, 0], r: 3.6, flat: true, dir: UP, cone: 0.6, sp: [0.05, 0.25], life: [1.5, 2.5], size: [0.04, 0.07], c0: 0x5fe08a, a: 0.7, fi: 0.4 }),\n ]),\n ],\n}\n","import { add, and, gt, lt, mul, param, PARAM, pick, TIME, vnorm } from '../dsl'\nimport { after, call, decal, emit, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst BLOOD = param(0x8a0a0a, 0x5a0c10, 0x3a1c12, 0x1d1914)\nconst BLEED = [1, 0.7, 0.35]\n\n/** W449-473: blood by infection age: a mist at the entry, a jet at the exit, a pool that grows and darkens. */\nexport const BLOOD_HIT: EffectDef = {\n id: 'blood_hit',\n pageId: 'sangue',\n team: 'creatures',\n params: { id: 'age', options: ['fresh', 'recent', 'old', 'decrepit'], default: 0 },\n budget: { particles: 70, decals: 1 },\n loop: 3.2,\n view: { eye: [2.6, 1.9, 3.4], target: [0, 1, -0.6] },\n timeline: [\n after(0.3, call('blood_hit', [0, 1.3, 0.1], vnorm([0.15, 0.1, -1]), PARAM)),\n after(1.5, call('blood_hit', [0.1, 1.05, 0.1], vnorm([-0.2, 0.05, -1]), PARAM, 0.8)),\n when(lt(PARAM, 3), [after(0.7, decal(0, 0, -0.2, add(0.5, mul(0.7, pick(BLEED, PARAM))), BLOOD, { grow: add(2, mul(2, pick(BLEED, PARAM))), dark: 60, dry: 0x3b1d14 }))]),\n ],\n tick: [\n when(and(lt(PARAM, 2), gt(TIME, 0.3)), [\n emit('drip', 'normal', param(7, 3), {\n p: [0.05, 1.15, 0.17], box: [0.08, 0.05, 0], dir: [0, 1, 0], cone: 0.2, sp: [0, 0.2], life: 1.2, size: 0.03, c0: BLOOD, g: 9.8, fi: 0, gnd: 3, ds: [0.04, 0.08],\n }),\n ]),\n ],\n}\n","import { and, gt, lt, TIME } from '../dsl'\nimport { after, decal, emit, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst UP: readonly [number, number, number] = [0, 1, 0]\n\n/** W540-553: fifteen minutes in eight seconds: the pool dries, flies appear from the minute five and the body turns to dust. */\nexport const CORPSE_DECAY: EffectDef = {\n id: 'corpse_decay',\n pageId: 'corpo',\n team: 'creatures',\n budget: { particles: 40 },\n loop: 8.5,\n view: { eye: [2.4, 1.6, 2.6], target: [0, 0.3, -0.6] },\n timeline: [after(0.8, decal(0, 0, -0.9, 1.1, 0x5a0c10, { grow: 1.5, dark: 5, dry: 0x3b1d14 }))],\n tick: [\n when(and(gt(TIME, 2.5), lt(TIME, 7)), [\n emit('fly', 'normal', 6, { p: [0, 0.35, -0.8], r: 0.5, sp: [0.3, 0.8], life: [0.6, 1.2], size: 0.02, c0: 0x050505, a: 1, fi: 0.2 }),\n ]),\n when(and(gt(TIME, 6.8), lt(TIME, 7.6)), [\n emit('dust', 'normal', 40, { p: [0, 0.15, -0.8], box: [0.25, 0.05, 0.8], dir: UP, cone: 0.6, sp: [0.2, 0.6], drag: 1, life: [1, 1.8], size: [0.12, 0.22], grow: 3, c0: 0x2b2722, a: 0.5 }),\n ]),\n ],\n}\n","import { and, INDEX, ite, lt, not, pick, query, QUALITY, rnd, variable } from '../dsl'\nimport { behavior, repeat, set, spawn, when } from '../steps'\nimport type { EffectDef } from '../types'\n\n/** Which of the ten walkers run: the ones with red eyes (W192). */\nconst RUNNERS = [false, true, false, false, false, true, false, false, false, true]\nconst RUN_SPEED = 3.8\nconst WALK_SPEED = 0.7\nconst SPEED = ite(pick(RUNNERS, INDEX), RUN_SPEED, WALK_SPEED)\nconst walkTo = behavior('walkers', 'walk', { index: INDEX, to: [-12, 0, query('walkers', 'z', INDEX)], speed: SPEED })\n\n/** W562-571 (the page's `olhos`): ten zombies walk through fog from the east; the runners leave a short red trail behind their eyes. */\nexport const EYES_IN_FOG: EffectDef = {\n id: 'eyes_in_fog',\n pageId: 'olhos',\n team: 'creatures',\n budget: { particles: 20 },\n loop: 0,\n view: { eye: [-9, 1.7, 2], target: [6, 1.3, 2] },\n setup: [\n repeat(10, set('placeX', rnd(4, 34)), set('placeZ', rnd(-1.5, 5.5)), behavior('walkers', 'place', { index: INDEX, x: variable('placeX'), z: variable('placeZ'), facing: -Math.PI / 2 }), walkTo),\n ],\n timeline: [],\n tick: [\n repeat(\n 10,\n when(lt(query('walkers', 'x', INDEX), -8), [behavior('walkers', 'move_x', { index: INDEX, x: rnd(28, 36) }), walkTo], [when(not(query('walkers', 'is_walking', INDEX)), [walkTo])]),\n when(and(pick(RUNNERS, INDEX), lt(QUALITY, 2)), [\n spawn('streak', { p: query('walkers', 'point', INDEX, [0, 1.74, 0.2]), dir: [1, 0, 0], cone: 0, sp: RUN_SPEED, v: [-RUN_SPEED, 0, 0], life: 0.25, len: 0.06, c0: 0xe5392b, c1: 0x400000, a: 0.8 }),\n ]),\n ),\n ],\n}\n","import { ite, gt, lt, and, mul, sin, sub, vnorm, TIME } from '../dsl'\nimport { after, burst, debris, emit, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst SHOULDER: readonly [number, number, number] = [0.36, 1.46, 0.05]\nconst FRESH_BLOOD = 0x8a0a0a\n\n/** W487-500: the arm leaves as a loose piece and the shoulder spurts in pulses for half a second. */\nexport const DISMEMBER: EffectDef = {\n id: 'dismember',\n pageId: 'membro',\n team: 'creatures',\n budget: { particles: 60, debris: 1, decals: 4 },\n loop: 3.6,\n view: { eye: [3, 1.8, 2.2], target: [0.4, 1.1, 0] },\n timeline: [\n after(\n 0.4,\n debris({ p: SHOULDER, v: [2.2, 2.5, -0.6], sp: 0, size: [0.12, 0.12, 0.66], c: 0x6d7a5a, spin: 9, life: 12, bounce: 0.25 }),\n burst('normal', 12, { p: SHOULDER, r: 0.05, sp: [0.3, 1.2], drag: 3, life: [0.3, 0.6], size: [0.1, 0.16], grow: 3, c0: FRESH_BLOOD, a: 0.6 }),\n ),\n ],\n tick: [\n when(and(gt(TIME, 0.4), lt(TIME, 1.1)), [\n emit('jet', 'normal', mul(90, ite(gt(sin(mul(sub(TIME, 0.4), 28)), 0), 1, 0.2)), { p: SHOULDER, dir: vnorm([1, 0.35, 0.1]), cone: 0.25, sp: [1.5, 3], life: 1.4, size: [0.03, 0.055], c0: FRESH_BLOOD, g: 9.8, fi: 0, gnd: 3, ds: [0.05, 0.12] }),\n ]),\n ],\n}\n","import { ite, mod, INDEX, scaled, vnorm } from '../dsl'\nimport { after, burst, debris, decal, flash, repeat } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst FRESH_BLOOD = 0x8a0a0a\n\n/** W474-486: the head bursts, the eyes go out in the same frame and the body falls. */\nexport const HEADSHOT: EffectDef = {\n id: 'headshot',\n pageId: 'headshot',\n team: 'creatures',\n budget: { particles: 70, debris: 8, decals: 1 },\n loop: 3.2,\n view: { eye: [2.2, 1.8, 3], target: [0, 1.2, -0.5] },\n timeline: [\n after(\n 0.45,\n burst('normal', 20, { p: [0, 1.7, 0], r: 0.1, sp: [0.4, 1.8], drag: 3, life: [0.4, 0.75], size: [0.12, 0.2], grow: 3, c0: FRESH_BLOOD, a: 0.7 }),\n burst('normal', 35, { p: [0, 1.7, 0], dir: vnorm([0, 0.45, -1]), cone: 0.8, sp: [2, 5], life: 1.5, size: [0.035, 0.065], c0: FRESH_BLOOD, g: 9.8, fi: 0, gnd: 3, ds: [0.06, 0.14] }),\n repeat(scaled(8), debris({ p: [0, 1.7, 0], dir: vnorm([0, 0.6, -1]), cone: 0.9, sp: [1.5, 4], size: [0.06, 0.05, 0.06], k: [0.5, 1.2], c: ite(mod(INDEX, 2), 0xd9cfbf, 0x6d7a5a), life: 8 })),\n flash([0, 1.7, 0], 0xff3020, 1.2, 0.08, 4),\n ),\n after(1.4, decal(0, 0, -1.5, 0.9, FRESH_BLOOD, { grow: 2.4, dark: 60, dry: 0x3b1d14 })),\n ],\n}\n","import { and, gt, lt, TIME, vnorm } from '../dsl'\nimport { cue, emit, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst UP: readonly [number, number, number] = [0, 1, 0]\n\n/** W554-561: green motes while the body twitches (two random draws a frame for the arms), the eyes light up and a breath of steam on the first scream. */\nexport const REANIMATION: EffectDef = {\n id: 'reanimation',\n pageId: 'reanima',\n team: 'creatures',\n budget: { particles: 30 },\n loop: 6.5,\n view: { eye: [2.4, 1.4, 2.4], target: [0, 0.6, -0.4] },\n timeline: [],\n tick: [\n when(lt(TIME, 3.4), [\n when(gt(TIME, 1), [cue('zombie_arm_twitch', undefined, 2)]),\n when(gt(TIME, 0.6), [\n emit('mote', 'add', 8, { p: [0, 0.2, -0.8], box: [0.25, 0.05, 0.6], dir: UP, cone: 0.4, sp: [0.2, 0.5], life: [0.6, 1], size: [0.03, 0.05], c0: 0x9fc25a, a: 0.7, fi: 0.3 }),\n ]),\n ]),\n when(and(gt(TIME, 5), lt(TIME, 5.6)), [\n emit('br', 'normal', 20, { p: [0, 1.68, 0.2], dir: vnorm([0, 0.3, 1]), cone: 0.3, sp: [0.6, 1.1], drag: 1.5, life: 1.2, size: [0.05, 0.1], grow: 5, c0: 0xd8dde2, a: 0.2 }),\n ]),\n ],\n}\n","import { add, cos, div, INDEX, local, lt, mul, rand, sin, sub, TIME, variable, vnorm } from '../dsl'\nimport { after, emit, repeat, ring, screen, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst WHITE_RING = 0xe8e2d0\nconst PREPARATION_END = 1.7\nconst SHRIEK_END = 2.6\n\n/** W521-539: a steam of breath while the screamer prepares, then three pressure rings, a ring of dust and a burst of chromatic aberration. */\nexport const SCREAMER_SHRIEK: EffectDef = {\n id: 'screamer_shriek',\n pageId: 'grito',\n team: 'creatures',\n budget: { particles: 150 },\n loop: 5,\n view: { eye: [6, 3, 7], target: [0, 1, -1] },\n timeline: [\n after(\n PREPARATION_END,\n repeat(3, after(add(PREPARATION_END, mul(INDEX, 0.18)), ring([0, 0.03, 0], 0.3, 9, 0.9, WHITE_RING))),\n screen({ add: { chroma: 7, shake: 0.25 } }),\n ),\n ],\n tick: [\n when(lt(TIME, PREPARATION_END), [\n emit('vap', 'normal', 18, { p: [0, 1.68, 0.2], dir: vnorm([0, 0.5, 1]), cone: 0.3, sp: [0.6, 1.2], drag: 1.5, life: [0.8, 1.3], size: [0.05, 0.1], grow: 5, c0: 0xd8dde2, a: 0.2 }),\n ], [\n when(lt(TIME, SHRIEK_END), [\n set('shriekRadius', mul(div(sub(TIME, PREPARATION_END), 0.9), 8)),\n emit(\n 'dust', 'normal', 140,\n local('angle', mul(rand(), 6.283), {\n p: [mul(cos(variable('angle')), variable('shriekRadius')), 0.05, mul(sin(variable('angle')), variable('shriekRadius'))],\n dir: vnorm([cos(variable('angle')), 0.6, sin(variable('angle'))]),\n cone: 0.3, sp: [0.6, 1.6], drag: 2, life: [0.8, 1.4], size: [0.2, 0.35], grow: 3, c0: 0x5d574d, a: 0.35,\n }),\n ),\n ]),\n ]),\n ],\n}\n","import type { Vec3Tuple } from '../workshop/types'\n\n/**\n * A point of a prop's own space in the world, for a prop placed at `translation` and turned by `rotation` (x, y, z radians, applied in the order x, y,\n * z) as three.js composes it: how the page's `carW` and `tbW` find the bumper or a table leg.\n */\nexport function localToWorld(translation: Vec3Tuple, rotation: Vec3Tuple, local: Vec3Tuple): Vec3Tuple {\n const [x, y, z] = local\n const [a, c, e] = [Math.cos(rotation[0]), Math.cos(rotation[1]), Math.cos(rotation[2])]\n const [b, d, f] = [Math.sin(rotation[0]), Math.sin(rotation[1]), Math.sin(rotation[2])]\n const [ae, af, be, bf] = [a * e, a * f, b * e, b * f]\n return [\n c * e * x + -c * f * y + d * z + translation[0],\n (af + be * d) * x + (ae - bf * d) * y + -b * c * z + translation[1],\n (bf - ae * d) * x + (be + af * d) * y + a * c * z + translation[2],\n ]\n}\n","import { add, eq, FRESH, INDEX, ite, PARAM, pick, rnd, variable, vadd } from '../dsl'\nimport { localToWorld } from '../props'\nimport { after, behavior, call, camera, decal, repeat, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst MATERIALS = ['concrete', 'metal', 'wood', 'glass', 'flesh', 'water']\nconst CAR_ORIGIN = [5.6, 0, 0.8] as const\nconst CAR_ROTATION = [0, -0.4, 0] as const\nconst FACING_WALL = [0, 0, 1] as const\nconst UP = [0, 1, 0] as const\nconst GLASS = 3\nconst FLESH = 4\nconst WATER = 5\nconst SHOT_TIMES = [0, 0.55, 1.1]\nconst LAST_SHOT = 2\nconst BUMPER = localToWorld(CAR_ORIGIN, CAR_ROTATION, [0.96, 0.7, 0.4])\nconst CAR_SIDE = [Math.cos(CAR_ROTATION[1]), 0, -Math.sin(CAR_ROTATION[1])] as const\n/** Where each material is hit and the way the surface faces (W752-756). */\nconst POINTS = [[-2, 1.6, -4.45], BUMPER, [2, 1.3, -4.36], [-5, 1.9, -4.45], [0, 1.25, 0.16], [-1.5, 0.012, 2.2]]\nconst NORMALS = [FACING_WALL, CAR_SIDE, FACING_WALL, FACING_WALL, FACING_WALL, UP]\n/** The eye the page glides to for each material on the first run (W773-774); the car's is found from the car. */\nconst EYES = [[-2, 1.6, -1.8], localToWorld(CAR_ORIGIN, CAR_ROTATION, [3, 1.4, 1.5]), [2, 1.3, -1.6], [-5, 1.9, -1.8], [0, 1.2, 2.6], [-1.5, 0.8, 4.6]]\n/** The shop window as the glass texture sees it (`crackAt` takes pixels): 2.6 x 1.8 m on 256 x 180. */\nconst WINDOW = { centreX: -5, centreY: 1.9, width: 2.6, height: 1.8, pixelsX: 256, pixelsY: 180 }\n\nconst scatter = ite(eq(PARAM, WATER), [rnd(-0.6, 0.6), 0, rnd(-0.3, 0.3)], ite(eq(PARAM, FLESH), [rnd(-0.1, 0.1), rnd(-0.15, 0.15), 0], [rnd(-0.4, 0.4), rnd(-0.3, 0.3), 0]))\nconst hitX = { $: 'vx', a: [variable('hit')] }\nconst hitY = { $: 'vy', a: [variable('hit')] }\nconst pixelX = { $: 'mul', a: [{ $: 'add', a: [{ $: 'div', a: [{ $: 'sub', a: [hitX, WINDOW.centreX] }, WINDOW.width] }, 0.5] }, WINDOW.pixelsX] }\nconst pixelY = { $: 'mul', a: [{ $: 'sub', a: [1, { $: 'add', a: [{ $: 'div', a: [{ $: 'sub', a: [hitY, WINDOW.centreY] }, WINDOW.height] }, 0.5] }] }, WINDOW.pixelsY] }\n\n/** W762-775: three hits, 0.55 s apart, on the material the parameter names; the window keeps its cracks and the puddle takes a dark patch. */\nexport const IMPACT_BY_MATERIAL: EffectDef = {\n id: 'impact',\n pageId: 'impacto',\n team: 'weapons',\n params: { id: 'material', options: MATERIALS, default: 0 },\n budget: { particles: 40, decals: 1 },\n loop: 2.6,\n view: { eye: [0, 1.8, 4.5], target: [0, 1.2, -2] },\n props: ['cracks'],\n timeline: [\n when({ $: 'eq', a: [PARAM, WATER] }, [decal(-1.5, 0, 2.2, 3.2, 0x0d1218, { grow: 0, life: 60, ar: 0.55 })]),\n repeat(\n SHOT_TIMES.length,\n after(\n add(0.2, pick(SHOT_TIMES, INDEX)),\n set('hit', vadd(pick(POINTS, PARAM), scatter)),\n call('impact', pick(MATERIALS, PARAM), variable('hit'), pick(NORMALS, PARAM), 1, 0),\n when(eq(PARAM, GLASS), [behavior('cracks', 'crack', { x: pixelX, y: pixelY, big: eq(INDEX, LAST_SHOT) })]),\n ),\n ),\n when(FRESH, [camera(pick(EYES, PARAM), pick(POINTS, PARAM))]),\n ],\n}\n","import { and, DELTA, gt, INDEX, le, lt, mod, mul, add, pick, rnd, sub, TIME, variable } from '../dsl'\nimport { after, append, call, cue, decal, repeat, set, spawn, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst BLOOD = [0x8a0a0a, 0x5a0c10, 0x3a1c12, 0x1d1914]\n/** Where the five bodies stand along the line of the shot (W786). */\nconst BODY_Z = [2.2, 1, -0.2, -1.4, -2.6]\nconst MUZZLE_Z = 8.5\nconst SPEED = 12\nconst WALL_Z = -4.4\nconst FORWARD = [0, 0, -1] as const\nconst bulletAt = [0, 1.45, variable('bulletZ')]\n\n/** W776-785: a tracer of the Barrett crosses five bodies, each bleeding the colour of its age, then hits the wall. */\nexport const PENETRATION: EffectDef = {\n id: 'penetration',\n pageId: 'penetra',\n team: 'weapons',\n budget: { particles: 250 },\n loop: 4.2,\n view: { eye: [4.2, 2.2, 6.5], target: [0, 1.2, -0.5] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n repeat(\n BODY_Z.length,\n set('bodyX', rnd(-0.05, 0.05)),\n set('bodyTurn', rnd(-0.3, 0.3)),\n append('bodiesX', variable('bodyX')),\n cue('zombie_place', { index: INDEX, x: variable('bodyX'), z: pick(BODY_Z, INDEX), turn: variable('bodyTurn') }),\n ),\n ],\n timeline: [set('bulletZ', MUZZLE_Z), set('bulletOn', true), call('muzzle', 'barrett', [0, 1.45, MUZZLE_Z], FORWARD)],\n tick: [\n when(variable('bulletOn'), [\n set('previousZ', variable('bulletZ')),\n set('bulletZ', sub(variable('bulletZ'), mul(SPEED, DELTA))),\n spawn('streak', { p: bulletAt, dir: FORWARD, cone: 0, sp: 12, life: 0.04, len: 0.07, c0: 0xffd090 }),\n spawn('add', { p: bulletAt, size: 0.09, life: 0.05, c0: 0xffc070, fi: 0 }),\n spawn('normal', { p: bulletAt, r: 0.02, sp: [0, 0.05], life: [1.2, 2], size: 0.05, grow: 3, c0: 0xc8ccd2, a: 0.12, fi: 0.1 }),\n repeat(\n BODY_Z.length,\n when(and(gt(variable('previousZ'), pick(BODY_Z, INDEX)), le(variable('bulletZ'), pick(BODY_Z, INDEX))), [\n call('blood_hit', [0, 1.45, sub(pick(BODY_Z, INDEX), 0.1)], [0, 0.05, -1], mod(INDEX, 4), 0.8),\n cue('zombie_fall', { index: INDEX, delay: 0.05, duration: 0.6 }),\n after(\n add(TIME, 0.6),\n decal(pick(variable('bodiesX'), INDEX), 0, sub(pick(BODY_Z, INDEX), 1.2), 0.6, pick(BLOOD, mod(INDEX, 4)), { grow: 2, dark: 60, dry: 0x3b1d14 }),\n ),\n ]),\n ),\n when(lt(variable('bulletZ'), WALL_Z), [set('bulletOn', false), call('impact', 'concrete', [0, 1.45, -4.45], [0, 0, 1], 2.2)]),\n ]),\n ],\n}\n","import { add, gt, INDEX, lt, and, mul, TIME } from '../dsl'\nimport { after, call, cue, debris, emit, repeat, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst TIP = [-0.8, 1.38, 3.4 - 0.78] as const\nconst PORT = [-0.76, 1.4, 3.32] as const\nconst FORWARD = [0, 0, -1] as const\nconst UP = [0, 1, 0] as const\nconst BURST_SHOTS = 12\n\n/** W787-797: twelve rounds of an AK with their brass, the empty magazine falling at 1.8 s and a thread of smoke from the hot barrel. */\nexport const CASINGS_AND_MAGAZINE: EffectDef = {\n id: 'casings_and_magazine',\n pageId: 'capsulas',\n team: 'weapons',\n budget: { particles: 200, debris: 13 },\n loop: 4.6,\n view: { eye: [0.9, 1.3, 4.6], target: [-0.6, 0.6, 3.1] },\n setup: [cue('gun_visible', { visible: true }), cue('zombie_visible', { index: -1, visible: false })],\n timeline: [\n repeat(\n BURST_SHOTS,\n after(add(0.2, mul(INDEX, 0.1)), call('muzzle', 'ak', TIP, FORWARD), call('casing', PORT, ''), cue('gun_recoil', { kick: 0.05 })),\n ),\n after(1.8, debris({ p: [-0.8, 1.15, 3.3], v: [0.1, -0.5, 0.1], sp: 0, size: [0.05, 0.2, 0.09], c: 0x2a2a2a, spin: 3, life: 20, bounce: 0.2 })),\n ],\n tick: [\n when(and(gt(TIME, 1.4), lt(TIME, 3.6)), [\n emit('hot', 'normal', 10, { p: TIP, dir: UP, cone: 0.25, sp: [0.2, 0.5], life: [1.4, 2.2], size: [0.03, 0.06], grow: 5, c0: 0x9a9a96, a: 0.18, g: -0.2, fi: 0.2 }),\n ]),\n ],\n}\n","import { add, and, div, DELTA, FRESH, ge, gt, ite, lerp, lt, max, min, mul, not, scaled, sin, sub, TIME, variable, vadd, vlerp, vwith } from '../dsl'\nimport { call, cue, debris, burst, decal, emit, fireLight, fireLightOff, flash, repeat, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst FROM = [-4, 1.6, 5] as const\nconst TARGET = [0, 0, -0.5] as const\nconst UP = [0, 1, 0] as const\nconst FLIGHT = 1\nconst ARC_HEIGHT = 2.2\nconst GLASS_GREEN = 0x3a6a3a\nconst OBJECT_ID_DRAWS = 12\nconst at = (offset: readonly [number, number, number]) => vadd(TARGET, offset)\n\n/** W798-818 (`lab: 1`): a bottle in an arc with a wick burning, glass and a splash of fire on landing, and a pool of fire that spreads for 6 s. */\nexport const MOLOTOV: EffectDef = {\n id: 'molotov',\n pageId: 'molotov',\n team: 'weapons',\n lab: 'molotov',\n budget: { particles: 300, lights: 1 },\n loop: 9.5,\n view: { eye: [5, 3, 6.5], target: [0, 0.6, -0.5] },\n // three.js draws 12 random numbers (the object ids of the bottle's geometry, material and mesh) the first time the page builds the bottle\n setup: [cue('zombie_visible', { index: -1, visible: false }), when(FRESH, [cue('prop_created', { prop: 'bottle' }, OBJECT_ID_DRAWS)])],\n timeline: [set('landed', false), cue('bottle_visible', { visible: true })],\n tick: [\n when(lt(TIME, FLIGHT), [\n set('bottle', vwith(vlerp(FROM, TARGET, TIME), 1, add(lerp(FROM[1], TARGET[1], TIME), mul(sin(mul(TIME, Math.PI)), ARC_HEIGHT)))),\n cue('bottle_move', { position: variable('bottle'), spin: mul(10, DELTA) }),\n emit('wick', 'add', 40, { p: vadd(variable('bottle'), [0, 0.12, 0]), r: 0.03, sp: [0.1, 0.3], life: [0.15, 0.3], size: [0.08, 0.14], grow: 0.5, c0: 0xffd27a, c1: 0xff5010, fi: 0, g: -1 }),\n emit('wsm', 'normal', 14, { p: variable('bottle'), size: [0.06, 0.1], grow: 4, life: [0.8, 1.2], c0: 0x3a3530, a: 0.3, sp: [0, 0.2] }),\n ], [\n when(not(variable('landed')), [\n set('landed', true),\n cue('bottle_visible', { visible: false }),\n repeat(scaled(12), debris({ p: at([0, 0.1, 0]), dir: UP, cone: 1.3, sp: [1, 3], size: [0.04, 0.01, 0.04], c: GLASS_GREEN, life: 12 })),\n burst('add', 45, { p: at([0, 0.15, 0]), dir: UP, cone: 1.35, sp: [2, 4], drag: 2, life: [0.3, 0.6], size: [0.3, 0.5], c0: 0xffd27a, c1: 0xa02008, fi: 0.05 }),\n flash(at([0, 0.6, 0]), 0xff8a30, 6, 0.3, 12, true),\n decal(TARGET[0], 0, TARGET[2], 4.2, 0x0d0b09, { grow: 0.8, life: 60 }),\n ]),\n ]),\n when(and(gt(TIME, FLIGHT), lt(TIME, 8.2)), [\n set('poolRadius', min(2.2, add(0.5, mul(sub(TIME, 1), 2.1)))),\n set('poolFade', ite(gt(TIME, 7), max(0.1, sub(1, div(sub(TIME, 7), 1.2))), 1)),\n call('fire_emit', 'mol', at([0, 0.05, 0]), variable('poolRadius'), mul(1.6, variable('poolFade')), { smoke: 16 }),\n fireLight(0, at([0, 1, 0]), mul(3.2, variable('poolFade')), TIME),\n ], [\n when(ge(TIME, 8.2), [\n fireLightOff(0),\n emit('emb', 'add', 6, { p: TARGET, r: 2, flat: true, size: [0.04, 0.07], life: [0.6, 1.2], c0: 0xff6a20, a: 0.8, fi: 0.3 }),\n ]),\n ]),\n ],\n}\n","import { add, atan2, DELTA, FRESH, INDEX, lt, mul, neg, not, pick, sub, TIME, variable } from '../dsl'\nimport { call, cue, repeat, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\n/** The five bodies the blast reaches (W826), where they stand and the way each faces (`atan2(-x, -z)`, toward the origin). */\nconst BODIES = [[1.6, 0.8], [-1.8, 1.2], [0.6, -2], [-1, -1.8], [2.4, -1.2]] as const\nconst BODY_X = BODIES.map(([x]) => x)\nconst BODY_Z = BODIES.map(([, z]) => z)\nconst FACING = BODIES.map(([x, z]) => Math.atan2(-x, -z))\nconst FUSE = 1.8\nconst GRAVITY = 9.8\nconst FLOOR = 0.07\nconst BOUNCE = -0.4\nconst SIDE_LOSS = 0.5\n\n/** W819-830 (`lab: 1`): a grenade thrown in an arc, bouncing on the asphalt, then the Workshop's blast and the five bodies turning away to fall. */\nexport const GRENADE: EffectDef = {\n id: 'grenade',\n pageId: 'granada',\n team: 'weapons',\n lab: 'm67',\n budget: { particles: 400, debris: 16, decals: 1 },\n loop: 6.5,\n view: { eye: [7, 3.4, 7.5], target: [0, 0.8, -0.2] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n // three.js draws 12 random numbers (the object ids of the grenade's geometry, material and mesh) the first time the page builds it\n when(FRESH, [cue('prop_created', { prop: 'grenade' }, 12)]),\n repeat(BODIES.length, cue('zombie_place', { index: INDEX, x: pick(BODY_X, INDEX), z: pick(BODY_Z, INDEX), turn: pick(FACING, INDEX) })),\n ],\n timeline: [\n set('px', -4), set('py', 1.4), set('pz', 4.5),\n set('vx', 3.2), set('vy', 2.4), set('vz', -3.6),\n set('boom', false),\n cue('grenade_visible', { visible: true }),\n ],\n tick: [\n when(lt(TIME, FUSE), [\n set('vy', sub(variable('vy'), mul(GRAVITY, DELTA))),\n set('px', add(variable('px'), mul(variable('vx'), DELTA))),\n set('py', add(variable('py'), mul(variable('vy'), DELTA))),\n set('pz', add(variable('pz'), mul(variable('vz'), DELTA))),\n when(lt(variable('py'), FLOOR), [\n set('py', FLOOR),\n set('vy', mul(variable('vy'), BOUNCE)),\n set('vx', mul(variable('vx'), SIDE_LOSS)),\n set('vz', mul(variable('vz'), SIDE_LOSS)),\n ]),\n cue('grenade_move', { position: [variable('px'), variable('py'), variable('pz')] }),\n ], [\n when(not(variable('boom')), [\n set('boom', true),\n cue('grenade_visible', { visible: false }),\n call('explode', [variable('px'), 0, variable('pz')], 1),\n repeat(\n BODIES.length,\n cue('zombie_turn_and_fall', {\n index: INDEX,\n turn: atan2(neg(sub(pick(BODY_X, INDEX), variable('px'))), neg(sub(pick(BODY_Z, INDEX), variable('pz')))),\n delay: 0.02,\n duration: 0.45,\n }),\n ),\n ]),\n ]),\n ],\n}\n","import { add, and, cos, gt, ge, INDEX, ite, lt, mod, mul, rnd, scaled, sin, sub, TIME, variable, vadd, concat } from '../dsl'\nimport { after, append, burst, call, cue, debris, emit, fireLight, fireLightOff, repeat, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst BARREL = [-4.4, 0, 1.4] as const\nconst UP = [0, 1, 0] as const\nconst RED = 0x9b1c18\nconst YELLOW = 0xd8b02a\nconst POOLS = 3\nconst above = (height: number) => vadd(BARREL, [0, height, 0])\n\n/** W831-845 (`lab: 1`): the barrel goes up in a mushroom, its lid and red scraps fly, three pools of petrol burn for 5 s and a black column marks it from afar. */\nexport const EXPLOSIVE_BARREL: EffectDef = {\n id: 'explosive_barrel',\n pageId: 'barril',\n team: 'weapons',\n lab: 'barrel',\n budget: { particles: 450, lights: 1 },\n loop: 9,\n view: { eye: [2.4, 3, 7.5], target: [-4.4, 1.6, 1.4] },\n setup: [cue('zombie_visible', { index: -1, visible: false })],\n timeline: [\n set('pools', []),\n after(\n 0.4,\n cue('barrel_visible', { visible: false }),\n call('explode', BARREL, 1.3, RED),\n burst('add', 30, { p: above(0.8), r: 0.4, dir: UP, cone: 0.25, sp: [3, 5], drag: 1.2, life: [1, 1.6], size: [0.9, 1.4], grow: 1.4, c0: 0xffb050, c1: 0x3a0d05, g: -1, fi: 0.05 }),\n debris({ p: above(1), v: [0.6, 9, 0.3], sp: 0, size: [0.7, 0.05, 0.7], c: RED, spin: 8, life: 12 }),\n repeat(scaled(8), debris({ p: BARREL, dir: UP, cone: 1, sp: [3, 7], size: [0.25, 0.04, 0.18], c: ite(mod(INDEX, 2), RED, YELLOW), life: 12 })),\n repeat(\n POOLS,\n set('poolAngle', add(mul(INDEX, 2.1), rnd(0, 0.6))),\n append('pools', vadd(BARREL, [mul(cos(variable('poolAngle')), 1.4), 0.05, mul(sin(variable('poolAngle')), 1.4)])),\n ),\n ),\n ],\n tick: [\n when(and(variable('pools'), gt(TIME, 0.5), lt(TIME, 6)), [\n set('poolFade', ite(gt(TIME, 5), sub(1, sub(TIME, 5)), 1)),\n repeat(POOLS, call('fire_emit', concat('bp', INDEX), { $: 'at', a: [variable('pools'), INDEX] }, 0.45, mul(0.6, variable('poolFade')), { smoke: 6 })),\n fireLight(0, above(1), mul(2.6, variable('poolFade')), TIME),\n ]),\n when(and(gt(TIME, 0.6), lt(TIME, 8)), [\n emit('col', 'normal', 6, { p: above(1.5), r: 0.6, dir: UP, cone: 0.2, sp: [1.5, 2.5], v: [0.4, 0, 0], drag: 0.05, life: [4, 6], size: [1.2, 1.8], grow: 3, c0: 0x1a1817, c1: 0x0c0d10, a: 0.5, fi: 0.2 }),\n ]),\n when(ge(TIME, 6), [fireLightOff(0)]),\n ],\n}\n","import { add, and, eq, INDEX, ite, mod, mul, ne, param, PARAM, pick, rnd, round, variable } from '../dsl'\nimport { after, call, repeat, set, spawn, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst WEAPONS = ['glock', 'ak', 'r870', 'barrett']\nconst TIP = [-0.8, 1.38, 3.4 - 0.78] as const\nconst PORT = [-0.76, 1.4, 3.32] as const\nconst FORWARD = [0, 0, -1] as const\nconst NORMAL = [0, 0, 1] as const\nconst WALL_Z = -4.45\nconst SHOTS = [[0, 0.45, 0.9], [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6], [0], [0]]\nconst SHOT_TIME = pick(pick(SHOTS, PARAM), INDEX)\nconst AK = 1\nconst SHOTGUN = 2\nconst BARRETT = 3\n\n/** W745-761: core, petals and smoke scaled by weapon (the Barrett also vents sideways and lifts dust), with the shot's casing and hit on the wall. */\nexport const MUZZLE_FLASH: EffectDef = {\n id: 'muzzle_flash',\n pageId: 'muzzle',\n team: 'weapons',\n params: { id: 'weapon', options: ['glock', 'ak', 'r870', 'barrett'], default: 1 },\n budget: { particles: 60, lights: 1 },\n loop: 2.4,\n view: { eye: [1.8, 1.8, 5.2], target: [-0.8, 1.3, 1.4] },\n timeline: [\n repeat(\n param(3, 7, 1, 1),\n after(\n add(0.2, SHOT_TIME),\n call('muzzle', pick(WEAPONS, PARAM), TIP, FORWARD),\n when(ne(PARAM, SHOTGUN), [call('casing', PORT, ite(eq(PARAM, BARRETT), '50', ''))]),\n set('target', [add(-0.8, rnd(-0.4, 0.4)), add(1.4, rnd(-0.3, 0.3)), WALL_Z]),\n when(\n eq(PARAM, SHOTGUN),\n [repeat(8, call('impact', 'concrete', [add(-0.8, rnd(-0.5, 0.5)), add(1.4, rnd(-0.4, 0.4)), WALL_Z], NORMAL, 0.35))],\n [call('impact', 'concrete', variable('target'), NORMAL, ite(eq(PARAM, BARRETT), 2, 1))],\n ),\n when(and(eq(PARAM, AK), eq(mod(round(mul(SHOT_TIME, 10)), 3), 0)), [spawn('streak', { p: TIP, dir: FORWARD, cone: 0, sp: 90, life: 0.09, len: 0.025, c0: 0xffa040, a: 1 })]),\n ),\n ),\n when(eq(PARAM, SHOTGUN), [after(0.75, call('casing', PORT, 'shell'))]),\n ],\n}\n","import { rnd, scaled } from '../dsl'\nimport { after, behavior, burst, call, cue, debris, repeat, screen } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst FACING = [0, 0, 1] as const\n\n/** W846-855 (`vidro`): two cracks open in the shop window, then the whole pane comes down as 60 to 80 shards that stay on the pavement. */\nexport const SHOPFRONT_GLASS: EffectDef = {\n id: 'shopfront_glass',\n pageId: 'vidro',\n team: 'destruction',\n budget: { debris: 80, decals: 1 },\n loop: 5,\n view: { eye: [-2.4, 1.8, 1.2], target: [-5, 1.4, -4] },\n timeline: [\n after(0.3, call('impact', 'glass', [-5.4, 2.2, -4.45], FACING), behavior('cracks', 'crack', { x: 97, y: 59, big: false })),\n after(1, call('impact', 'glass', [-4.5, 1.6, -4.45], FACING), behavior('cracks', 'crack', { x: 177, y: 108, big: true })),\n after(\n 1.8,\n cue('glass_pane_gone'),\n screen({ add: { shake: 0.08 } }),\n repeat(\n scaled(75),\n debris({ p: [-5, 1.9, -4.42], box: [1.25, 0.85, 0.02], v: [rnd(-0.4, 0.4), rnd(-0.5, 0.8), rnd(0.6, 2)], sp: 0, size: [rnd(0.05, 0.18), 0.006, rnd(0.05, 0.18)], c: 0xa8c8d8, spin: 14, life: 30, bounce: 0.15 }),\n ),\n burst('add', 30, { p: [-5, 1.9, -4.3], box: [1.2, 0.8, 0.05], size: [0.02, 0.05], life: [0.2, 0.6], c0: 0xffffff, a: 0.9, fi: 0.3 }),\n burst('normal', 20, { p: [-5, 1.3, -4.2], box: [1.2, 0.5, 0.1], sp: [0.2, 0.6], drag: 2, life: [0.8, 1.4], size: [0.12, 0.2], grow: 3, c0: 0xbfd6e2, a: 0.2 }),\n ),\n ],\n}\n","import type { Vec3Tuple } from '../workshop/types'\n\n/** Vector helpers written as three.js r128 does them, so a recipe's numbers match the page's. */\nexport function normalized(vector: Vec3Tuple): Vec3Tuple {\n const length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]) || 1\n const inverse = 1 / length\n return [vector[0] * inverse, vector[1] * inverse, vector[2] * inverse]\n}\n\nexport function plus(vector: Vec3Tuple, x: number, y: number, z: number): Vec3Tuple {\n return [vector[0] + x, vector[1] + y, vector[2] + z]\n}\n\nexport function scaledBy(vector: Vec3Tuple, factor: number): Vec3Tuple {\n return [vector[0] * factor, vector[1] * factor, vector[2] * factor]\n}\n\nexport function plusScaled(vector: Vec3Tuple, direction: Vec3Tuple, factor: number): Vec3Tuple {\n return [vector[0] + direction[0] * factor, vector[1] + direction[1] * factor, vector[2] + direction[2] * factor]\n}\n\nexport function negated(vector: Vec3Tuple): Vec3Tuple {\n return [-vector[0], -vector[1], -vector[2]]\n}\n","import { add, and, div, DELTA, ge, INDEX, min, mul, not, rnd, scaled, sub, variable } from '../dsl'\nimport { after, behavior, burst, cue, debris, repeat, screen, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef, EffectStep } from '../types'\n\nconst FRAME_DUST = normalized([0, -0.3, 1])\nconst SPLINTER_DIRECTION = normalized([0, 0.3, 1])\nconst FALL_SECONDS = 0.4\n\n/** One blow on the door (`hit`, W779): the frame sheds dust and splinters; a heavy blow sheds twice as much. */\nconst blow = (heavy: boolean): EffectStep[] => [\n cue('door_shake', { strength: 0.25 }),\n burst('normal', heavy ? 24 : 12, { p: [2, 2.3, -4.38], box: [0.6, 0.05, 0.02], dir: FRAME_DUST, cone: 0.6, sp: [0.2, 0.8], drag: 1.5, life: [0.8, 1.4], size: [0.08, 0.16], grow: 3, c0: 0x7a7366, a: 0.45, g: 0.4 }),\n repeat(scaled(heavy ? 5 : 2), debris({ p: [add(2, rnd(-0.5, 0.5)), rnd(0.4, 2), -4.36], dir: SPLINTER_DIRECTION, cone: 0.6, sp: [1, 2.5], size: [0.015, 0.015, 0.1], c: 0x7a5530, life: 12 })),\n]\n\n/** W856-871 (`porta`): blows loosen dust from the frame, a plank cracks at 66 %, falls at 33 % and the door drops at the third stage. */\nexport const DOOR_STAGES: EffectDef = {\n id: 'door_stages',\n pageId: 'porta',\n team: 'destruction',\n budget: { particles: 120, debris: 6 },\n loop: 7.5,\n view: { eye: [4.2, 1.7, 1.4], target: [2, 1.1, -4] },\n setup: [behavior('walkers', 'place', { index: 0, x: 2, z: -5.4, facing: 0 })],\n timeline: [\n after(0.5, ...blow(false)),\n after(1.2, ...blow(false)),\n after(1.9, ...blow(true), cue('door_plank_crack', { stage: 1 })),\n after(2.7, ...blow(false)),\n after(\n 3.3,\n ...blow(true),\n cue('door_plank_fall', { stage: 2 }),\n repeat(3, debris({ p: [add(2, mul(sub(INDEX, 1), 0.4)), 1.1, -4.3], v: [rnd(-0.3, 0.3), 0.5, 1.2], sp: 0, size: [0.38, 0.68, 0.07], c: 0x5a3c22, spin: 4, life: 20, bounce: 0.15 })),\n ),\n after(4.4, set('fall', 0), set('falling', true), cue('door_fall', { stage: 3 })),\n after(4.6, behavior('walkers', 'walk', { index: 0, to: [2, 0, -2.2], speed: 0.9 })),\n ],\n tick: [\n when(variable('falling'), [\n set('fall', add(variable('fall'), DELTA)),\n set('progress', min(1, div(variable('fall'), FALL_SECONDS))),\n when(and(ge(variable('progress'), 1), not(variable('landed'))), [\n set('landed', true),\n screen({ add: { shake: 0.2 } }),\n burst('normal', 45, { p: [2, 0.15, -3.4], box: [0.7, 0.05, 1], dir: [0, 1, 0], cone: 1.4, sp: [0.6, 2], drag: 1.8, life: [1.5, 2.8], size: [0.25, 0.5], grow: 3, c0: 0x6a645a, a: 0.45 }),\n ]),\n ]),\n ],\n}\n","import { abs, add, and, cos, DELTA, gt, local, lt, mul, rand, rnd, scaled, sin, TIME, variable, vnorm } from '../dsl'\nimport { after, cue, debris, emit, repeat, screen, spawn, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst CENTRE = [-1.4, 3.35, -3.75] as const\n\n/** W872-886 (`desaba`): dust trickles from the awning for a second as a warning, then the slab drops in blocks and a cloud rolls along the street. */\nexport const BUILDING_COLLAPSE: EffectDef = {\n id: 'building_collapse',\n pageId: 'desaba',\n team: 'destruction',\n budget: { particles: 350, debris: 26 },\n loop: 8,\n view: { eye: [4, 2.4, 5], target: [-1.4, 1.4, -2.8] },\n setup: [cue('zombie_visible', { index: -1, visible: false })],\n timeline: [\n after(\n 1.5,\n cue('slab_gone'),\n screen({ add: { shake: 0.3 } }),\n repeat(6, debris({ p: CENTRE, box: [2, 0.05, 0.6], v: [rnd(-0.5, 0.5), rnd(-0.5, 0), rnd(0, 0.8)], sp: 0, size: [rnd(0.5, 1.1), 0.25, rnd(0.4, 0.8)], c: 0x6e6a63, spin: 3, life: 30, bounce: 0.1 })),\n repeat(scaled(20), debris({ p: CENTRE, box: [2.1, 0.1, 0.7], v: [rnd(-1, 1), rnd(-1, 1), rnd(0, 1.5)], sp: 0, size: [0.12, 0.1, 0.12], k: [0.5, 1.5], c: 0x5e5a54, life: 30 })),\n ),\n after(\n 2.15,\n screen({ add: { shake: 0.45 } }),\n repeat(\n scaled(70),\n spawn('normal', local('angle', rnd(-0.4, 3.5), {\n p: [add(-1.4, rnd(-2, 2)), 0.2, add(-3.4, rnd(-0.5, 0.5))],\n dir: vnorm([mul(cos(variable('angle')), 0.6), 0.25, abs(sin(variable('angle')))]),\n cone: 0.5, sp: [1, 3.2], drag: 1.1, life: [3, 6], size: [0.7, 1.2], grow: 3, c0: 0x7a7268, c1: 0x4a4640, a: 0.5, fi: 0.12,\n })),\n ),\n ),\n ],\n tick: [\n when(and(gt(TIME, 0.3), lt(TIME, 1.5)), [\n emit('trk', 'normal', 30, { p: [add(-1.4, rnd(-2, 2)), 3.2, -3.05], dir: [0, -1, 0], cone: 0.1, sp: [0.2, 0.5], life: [1, 1.6], size: [0.04, 0.08], grow: 2.5, c0: 0x8a8478, a: 0.5, g: 1 }),\n when(lt(rand(), mul(DELTA, 6)), [debris({ p: [add(-1.4, rnd(-2, 2)), 3.2, -3.05], sp: 0.2, size: [0.04, 0.04, 0.04], c: 0x6e6a63, life: 10 })]),\n ]),\n ],\n}\n","import { add, cos, INDEX, local, mul, rnd, scaled, sin, variable, vnorm } from '../dsl'\nimport { after, behavior, burst, call, cue, debris, repeat, screen, spawn } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\n\nconst FIRING_FROM = [0.6, 1.3, 7] as const\nconst FIRING_DIRECTION = normalized([-2.8, -0.4, -4.4])\nconst WALL_CENTRE = [-2.2, 1, 2.6] as const\n\n/** W1039-1053 (`parede`): a burst of AK fire leaves holes that are stuck to the blocks, then the wall gives way and the holes fall with them. */\nexport const BLOCK_WALL: EffectDef = {\n id: 'block_wall',\n pageId: 'parede',\n team: 'destruction',\n budget: { particles: 300, debris: 16 },\n loop: 8,\n view: { eye: [0.4, 1.7, 6.6], target: [-2.2, 0.9, 2.4] },\n props: ['blocks'],\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('work_light', { intensity: 2.2 })],\n timeline: [\n repeat(\n 14,\n after(\n add(0.3, mul(INDEX, 0.11)),\n call('muzzle', 'ak', FIRING_FROM, FIRING_DIRECTION),\n behavior('blocks', 'hit', { x: rnd(-1.3, 1.3), y: rnd(0.4, 1.9), scale: 1 }),\n ),\n ),\n after(2.2, behavior('blocks', 'hit', { x: -0.2, y: 1.1, scale: 2.2 })),\n after(\n 3,\n screen({ add: { shake: 0.4 } }),\n behavior('blocks', 'collapse', { x: -0.2, y: 1.1 }),\n burst('normal', 30, { p: WALL_CENTRE, box: [1.4, 0.8, 0.2], sp: [0.3, 1.2], drag: 1.5, life: [1.5, 2.6], size: [0.4, 0.7], grow: 3, c0: 0x8a857a, c1: 0x4a4640, a: 0.45 }),\n repeat(scaled(16), debris({ p: WALL_CENTRE, box: [1.3, 0.8, 0.1], sp: [1, 3], size: [0.08, 0.07, 0.08], k: [0.5, 1.5], c: 0x6e6a63, life: 20 })),\n ),\n after(\n 3.6,\n screen({ add: { shake: 0.25 } }),\n repeat(\n scaled(60),\n spawn('normal', local('angle', rnd(0, 6.283), {\n p: [add(-2.2, rnd(-1.4, 1.4)), 0.2, add(2.4, rnd(-0.6, 0.4))],\n dir: vnorm([cos(variable('angle')), 0.3, sin(variable('angle'))]),\n cone: 0.4, sp: [0.8, 2.4], drag: 1.3, life: [2.5, 4.5], size: [0.6, 1], grow: 3, c0: 0x7a7268, c1: 0x4a4640, a: 0.45, fi: 0.12,\n })),\n ),\n ),\n ],\n}\n","import type { Vec3Tuple } from '../../workshop/types'\n\n/** The free spot of the Workshop's set where the wall, door, railing, fence, table and cylinders are put one at a time (W937, `SPOT`). */\nexport const SPOT: Vec3Tuple = [-2.2, 0, 2.6]\nexport const UP: Vec3Tuple = [0, 1, 0]\n","import { add, and, DELTA, div, floor, ge, INDEX, ite, min, mod, mul, not, pick, scaled, variable } from '../dsl'\nimport { after, behavior, burst, call, cue, debris, repeat, screen, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\nimport { SPOT, UP } from './spot'\n\nconst HITS = [[0.4, 1.4], [0.75, 1.0], [0.3, 0.7], [0.6, 1.7], [0.5, 1.2]]\nconst HIT_X = HITS.map(([x]) => x)\nconst HIT_Y = HITS.map(([, y]) => y)\nconst SPARK_DIRECTION = normalized([0, 0.3, 1])\nconst CHIP_DIRECTION = normalized([0, 0.2, 1])\nconst HINGE_DIRECTION = normalized([1, 0.3, 1])\nconst SCRAPE_DIRECTION = normalized([0, 0.4, 1])\nconst FALL_SECONDS = 0.45\nconst SCRAPES = 5\n\n/** W960-985 (`portametal`): each blow dents the plate where it lands and throws sparks, paint chips and rust; the top hinge bursts and the door scrapes down. */\nexport const METAL_DOOR_EFFECT: EffectDef = {\n id: 'metal_door',\n pageId: 'portametal',\n team: 'destruction',\n budget: { particles: 160, debris: 20 },\n loop: 7.5,\n view: { eye: [0.6, 1.6, 6.2], target: [-2.2, 1.1, 2.6] },\n props: ['plate'],\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n cue('work_light', { intensity: 2.2 }),\n behavior('walkers', 'place', { index: 3, x: SPOT[0] + 0.1, z: SPOT[2] - 0.7, facing: 0 }),\n ],\n timeline: [\n repeat(\n HITS.length,\n after(\n add(0.5, mul(INDEX, 0.75)),\n cue('zombie_swing', { index: 3, side: mod(INDEX, 2) }),\n after(\n add(0.5, mul(INDEX, 0.75), 0.15),\n behavior('plate', 'dent', { x: pick(HIT_X, INDEX), y: pick(HIT_Y, INDEX), radius: 0.42, depth: add(0.09, mul(INDEX, 0.025)) }),\n set('spot', [add(SPOT[0] - 0.56, pick(HIT_X, INDEX)), pick(HIT_Y, INDEX), SPOT[2] + 0.06]),\n call('spark_at', variable('spot'), SPARK_DIRECTION, 8),\n repeat(scaled(5), debris({ p: variable('spot'), dir: CHIP_DIRECTION, cone: 0.9, sp: [0.8, 2.2], size: [0.035, 0.004, 0.03], k: [0.6, 1.4], c: ite(mod(INDEX, 2), 0x51625a, 0x8a8f86), life: 20, spin: 16 })),\n call('rust_at', variable('spot'), 6),\n cue('door_dent', { level: min(3, add(1, floor(div(INDEX, 1.7)))) }),\n ),\n ),\n ),\n after(4.4, call('spark_at', [SPOT[0] - 0.6, 2.05, SPOT[2] + 0.05], HINGE_DIRECTION, 30, 1.2), screen({ add: { shake: 0.15 } }), set('fall', 0), set('falling', true), cue('door_hinge_burst')),\n after(5.2, behavior('walkers', 'walk', { index: 3, to: [SPOT[0], 0, SPOT[2] + 2.4], speed: 0.8 })),\n ],\n tick: [\n when(variable('falling'), [\n set('fall', add(variable('fall'), DELTA)),\n set('progress', min(1, div(variable('fall'), FALL_SECONDS))),\n when(and(ge(variable('progress'), 1), not(variable('landed'))), [\n set('landed', true),\n screen({ add: { shake: 0.3 } }),\n repeat(SCRAPES, call('spark_at', [add(SPOT[0] - 0.5, mul(INDEX, 0.27)), 0.03, SPOT[2] + 2.1], SCRAPE_DIRECTION, 8, 1)),\n burst('normal', 40, { p: [SPOT[0], 0.15, SPOT[2] + 1.2], box: [0.6, 0.05, 1], dir: UP, cone: 1.4, sp: [0.6, 2], drag: 1.8, life: [1.4, 2.4], size: [0.25, 0.5], grow: 3, c0: 0x6a645a, a: 0.45 }),\n ]),\n ]),\n ],\n}\n","import { add, and, DELTA, div, ge, gt, INDEX, lt, min, mul, not, pick, rnd, sub, TIME, variable } from '../dsl'\nimport { after, behavior, burst, call, cue, emit, repeat, screen, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\nimport { SPOT, UP } from './spot'\n\n/** Where the four pushing bodies stand, relative to the railing (W987). */\nconst PUSHERS = [[-0.6, 0.45], [0.1, 0.5], [0.6, 0.42], [-0.1, 1]]\nconst BEND_LIMIT = 0.42\nconst BEND_STEP = 0.004\nconst FALL_SECONDS = 0.55\nconst WELD = normalized([0, 0.3, 1])\n\n/** W986-1003 (`grade`): the horde pushes, the bars bend and rust falls in a thread; the weld bursts in sparks twice and the railing topples. */\nexport const IRON_RAILING: EffectDef = {\n id: 'iron_railing',\n pageId: 'grade',\n team: 'destruction',\n budget: { particles: 200 },\n loop: 7.5,\n view: { eye: [1.4, 1.8, 6.4], target: [-2.2, 0.7, 2.4] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n cue('work_light', { intensity: 2.2 }),\n set('bend', 0),\n ...PUSHERS.map(([x, dz], index) => behavior('walkers', 'place', { index, x: SPOT[0] + x!, z: SPOT[2] - dz!, facing: 0 })),\n ],\n timeline: [\n after(1.6, call('spark_at', [SPOT[0], 0.75, SPOT[2] + 0.05], WELD, 20, 1), screen({ add: { shake: 0.08 } }), cue('weld_burst')),\n after(3.2, call('spark_at', [SPOT[0] + 0.02, 1.2, SPOT[2] + 0.1], WELD, 20, 1), screen({ add: { shake: 0.1 } })),\n after(\n 4.3,\n set('fall', 0),\n set('falling', true),\n call('spark_at', [SPOT[0] - 1.5, 0.25, SPOT[2]], normalized([-0.3, 0.5, 1]), 14, 1),\n call('spark_at', [SPOT[0] + 1.5, 0.25, SPOT[2]], normalized([0.3, 0.5, 1]), 14, 1),\n cue('railing_gave_way'),\n ),\n after(\n 4.9,\n repeat(PUSHERS.length, behavior('walkers', 'walk', { index: INDEX, to: [add(SPOT[0], pick(PUSHERS.map(([x]) => x), INDEX)), 0, add(SPOT[2], 2.6, mul(INDEX, 0.3))], speed: 0.7 })),\n ),\n ],\n tick: [\n when(lt(TIME, 4.3), [\n set('target', min(BEND_LIMIT, mul(TIME, 0.1))),\n when(gt(sub(variable('target'), variable('bend')), BEND_STEP), [set('bend', variable('target')), cue('railing_bend', { amount: variable('bend') })]),\n emit('rust', 'normal', 10, { p: [add(SPOT[0], rnd(-0.6, 0.6)), rnd(0.3, 1.2), add(SPOT[2], mul(variable('bend'), 0.8))], sp: [0, 0.2], life: [0.8, 1.2], size: [0.015, 0.03], c0: 0x7a4a2a, a: 0.9, g: 6, fi: 0, gnd: 1 }),\n ]),\n when(variable('falling'), [\n set('fall', add(variable('fall'), DELTA)),\n set('progress', min(1, div(variable('fall'), FALL_SECONDS))),\n when(and(ge(variable('progress'), 1), not(variable('landed'))), [\n set('landed', true),\n screen({ add: { shake: 0.25 } }),\n repeat(4, call('spark_at', [add(SPOT[0] - 1.2, mul(INDEX, 0.8)), 0.04, SPOT[2] + 1.2], normalized([0, 0.5, 1]), 6, 1)),\n burst('normal', 30, { p: [SPOT[0], 0.12, SPOT[2] + 0.8], box: [1.4, 0.05, 0.5], dir: UP, cone: 1.4, sp: [0.5, 1.6], drag: 1.8, life: [1.2, 2.2], size: [0.2, 0.4], grow: 3, c0: 0x6a645a, a: 0.4 }),\n ]),\n ]),\n ],\n}\n","import { add, and, DELTA, div, ge, INDEX, min, mul, not, pick, rnd, scaled, sub, variable, vadd, mod } from '../dsl'\nimport { after, behavior, burst, cue, debris, repeat, screen, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\nimport { SPOT, UP } from './spot'\n\n/** The order the planks break in and where each stands along the fence (W1005-1006). */\nconst ORDER = [3, 4, 8, 5, 9, 2, 7]\nconst PLANK_X = Array.from({ length: 12 }, (_, index) => -1.43 + index * 0.26)\nconst BODIES = [[-0.8, 0.6], [0.5, 0.7], [0, 1.2]]\nconst SPLINTER_DIRECTION = normalized([0, 0.4, 1])\nconst FALL_SECONDS = 0.5\nconst PLANK_HEIGHT = 1.3\n\n/** W1004-1020 (`cerca`): the planks snap one by one at a random height, the stump stays on the rail and the rest flies; the section finally tips over. */\nexport const WOODEN_FENCE: EffectDef = {\n id: 'wooden_fence',\n pageId: 'cerca',\n team: 'destruction',\n budget: { particles: 150, debris: 12 },\n loop: 7.5,\n view: { eye: [1, 1.6, 6], target: [-2.2, 0.7, 2.4] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n cue('work_light', { intensity: 2.2 }),\n ...BODIES.map(([x, dz], index) => behavior('walkers', 'place', { index, x: SPOT[0] + x!, z: SPOT[2] - dz!, facing: 0 })),\n ],\n timeline: [\n repeat(\n ORDER.length,\n after(\n add(0.4, mul(INDEX, 0.5)),\n set('cut', rnd(0.32, 0.6)),\n set('top', sub(PLANK_HEIGHT, variable('cut'))),\n set('break', [add(SPOT[0], pick(PLANK_X, pick(ORDER, INDEX))), variable('cut'), SPOT[2]]),\n cue('zombie_swing', { index: mod(INDEX, 3), side: mod(INDEX, 2) }),\n cue('plank_snap', { plank: pick(ORDER, INDEX), cut: variable('cut') }),\n debris({ p: vadd(variable('break'), [0, div(variable('top'), 2), 0]), v: [rnd(-0.8, 0.8), rnd(1.5, 3), rnd(1.5, 3)], sp: 0, size: [0.17, variable('top'), 0.035], c: 0x8a6a44, spin: 7, life: 20, bounce: 0.2 }),\n repeat(scaled(6), debris({ p: variable('break'), dir: SPLINTER_DIRECTION, cone: 0.9, sp: [1, 3], size: [0.012, 0.012, 0.1], k: [0.6, 1.4], c: 0xb08a5a, life: 20 })),\n burst('normal', 8, { p: variable('break'), dir: [0, 0, 1], cone: 0.8, sp: [0.4, 1.4], drag: 2, life: [0.8, 1.4], size: [0.1, 0.18], grow: 3, c0: 0x7a6048, a: 0.4 }),\n ),\n ),\n after(\n 4.2,\n set('fall', 0),\n set('falling', true),\n repeat(scaled(10), debris({ p: [add(SPOT[0], rnd(-1.4, 1.4)), 1, SPOT[2]], dir: SPLINTER_DIRECTION, cone: 0.9, sp: [1, 3], size: [0.012, 0.012, 0.1], c: 0xb08a5a, life: 20 })),\n cue('fence_rail_cracked'),\n ),\n after(4.8, repeat(BODIES.length, behavior('walkers', 'walk', { index: INDEX, to: [add(SPOT[0], pick(BODIES.map(([x]) => x), INDEX)), 0, SPOT[2] + 2.5], speed: 0.75 }))),\n ],\n tick: [\n when(variable('falling'), [\n set('fall', add(variable('fall'), DELTA)),\n set('progress', min(1, div(variable('fall'), FALL_SECONDS))),\n when(and(ge(variable('progress'), 1), not(variable('landed'))), [\n set('landed', true),\n screen({ add: { shake: 0.2 } }),\n burst('normal', 35, { p: [SPOT[0], 0.12, SPOT[2] + 0.8], box: [1.5, 0.05, 0.5], dir: UP, cone: 1.4, sp: [0.5, 1.6], drag: 1.8, life: [1.2, 2.2], size: [0.25, 0.45], grow: 3, c0: 0x6a5a48, a: 0.4 }),\n ]),\n ]),\n ],\n}\n","import { add, INDEX, mul, rnd, variable, vadd } from '../dsl'\nimport { after, call, cue, debris, burst, repeat, screen, set } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\nimport { SPOT, UP } from './spot'\n\nconst at = (x: number, y: number, z: number): readonly [number, number, number] => [SPOT[0] + x, SPOT[1] + y, SPOT[2] + z]\n/**\n * Where each part of the table is in the world. The page asks its scene graph for it (`tbW`), and the capture does not render, so the table's tilt never\n * reaches the world matrix it reads: the parts are always where the table stands level (W1009, recorded at 2.2 s, 3.8 s and 5.3 s).\n */\nconst FRONT_LEG = at(-0.52, 0.2, 0.32)\nconst TOP_CORNER = at(0.3, 0.78, 0.2)\nconst TOP_PIECE = at(-0.3, 0.78, -0.2)\nconst FAR_CORNER = at(0.3, 0.78, -0.2)\nconst HOLE_OBJECT_ID_DRAWS = 12\nconst HOLES = 9\nconst GLOCK_FROM = [-0.4, 1, 6] as const\nconst SHOTGUN_FROM = [0.2, 1.1, 4.6] as const\nconst toward = (target: readonly [number, number, number], from: readonly [number, number, number]) => normalized([target[0] - from[0], target[1] - from[1], target[2] - from[2]])\n\n/** W1008-1020 (`pontos`): a 9 mm in the leg, a machete on a corner, a bat on the top and a 12-gauge up close: each breaks only the part it hit. */\nexport const HIT_POINT_BREAKAGE: EffectDef = {\n id: 'hit_point_breakage',\n pageId: 'pontos',\n team: 'destruction',\n budget: { particles: 120, debris: 20 },\n loop: 7.5,\n view: { eye: [0.2, 1.6, 5.4], target: [-2.2, 0.6, 2.6] },\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('work_light', { intensity: 2.2 })],\n timeline: [\n after(\n 0.6,\n call('muzzle', 'glock', GLOCK_FROM, toward(FRONT_LEG, GLOCK_FROM)),\n call('chips', FRONT_LEG, normalized([0, 0.2, 1]), 6),\n cue('table_part_detached', { part: 'front_leg' }),\n debris({ p: FRONT_LEG, v: [0.4, 0.6, 1.4], sp: 0, size: [0.07, 0.4, 0.07], c: 0x7a5530, spin: 6, life: 20, bounce: 0.25 }),\n cue('table_tilt'),\n ),\n after(\n 2.2,\n repeat(8, call('chips', vadd(TOP_CORNER, [add(-0.3, mul(INDEX, 0.08)), 0.03, 0]), normalized([0, 0.6, 1]), 1, 0.4)),\n cue('table_part_detached', { part: 'top_corner' }),\n debris({ p: TOP_CORNER, v: [1.2, 1.5, 1], sp: 0, size: [0.6, 0.06, 0.4], c: 0x7a5530, spin: 6, life: 20, bounce: 0.25 }),\n ),\n after(\n 3.8,\n screen({ add: { shake: 0.12 } }),\n call('chips', TOP_PIECE, UP, 10, 1.3),\n cue('table_part_gone', { part: 'top_piece' }),\n repeat(4, debris({ p: [add(TOP_PIECE[0], rnd(-0.2, 0.2)), TOP_PIECE[1], add(TOP_PIECE[2], rnd(-0.1, 0.1))], dir: UP, cone: 1.2, sp: [1, 2.5], size: [rnd(0.15, 0.3), 0.06, rnd(0.12, 0.25)], c: 0x6b4a2a, spin: 8, life: 20, bounce: 0.2 })),\n burst('normal', 20, { p: TOP_PIECE, r: 0.2, sp: [0.3, 1], drag: 2, life: [1, 1.8], size: [0.2, 0.35], grow: 3, c0: 0x7a6048, a: 0.4 }),\n ),\n after(\n 5.3,\n call('muzzle', 'r870', SHOTGUN_FROM, toward(FAR_CORNER, SHOTGUN_FROM)),\n repeat(HOLES, set('holeX', rnd(-0.15, 0.15)), set('holeZ', rnd(-0.1, 0.1)), cue('table_hole', { x: variable('holeX'), z: variable('holeZ') }, HOLE_OBJECT_ID_DRAWS)),\n call('chips', FAR_CORNER, UP, 10, 1),\n ),\n ],\n}\n","import { abs, clamp, DELTA, div, eq, gt, lt, min, mul, not, PARAM, query, sub, TIME, variable, vx, vz } from '../dsl'\nimport { after, behavior, call, cue, emit, set, screen, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\nimport { SPOT, UP } from './spot'\n\nconst OXYGEN = 1\nconst PUNCTURE_AT = 0.6\nconst JET_SECONDS = 3.4\nconst CLOUD_UNTIL = 7\nconst SHOT_FROM = [0.4, 1.2, 6.4] as const\nconst SHOT_DIRECTION = normalized([-0.5, -0.15, -1])\nconst SCRAPE_DIRECTION = normalized([1, 0.4, 0])\nconst jetStrength = variable('jet')\nconst isOxygen = eq(PARAM, OXYGEN)\n\n/** W1021-1038 (`pressao`): a shot into an extinguisher (a white cloud and a spin) or into an oxygen bottle (the valve breaks and it flies off as a rocket). */\nexport const PRESSURE_CYLINDERS: EffectDef = {\n id: 'pressure_cylinders',\n pageId: 'pressao',\n team: 'destruction',\n params: { id: 'cylinder', options: ['extinguisher', 'oxygen'], default: 0 },\n budget: { particles: 250 },\n loop: 7,\n view: { eye: [1.6, 1.5, 6.4], target: [-1.6, 0.4, 2.4] },\n props: ['cylinder'],\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('work_light', { intensity: 2.2 }), behavior('cylinder', 'choose', { oxygen: isOxygen }), cue('cylinder_visible', { oxygen: isOxygen })],\n timeline: [\n after(\n PUNCTURE_AT,\n call('muzzle', 'glock', SHOT_FROM, SHOT_DIRECTION),\n screen({ add: { shake: 0.1 } }),\n behavior('cylinder', 'puncture'),\n when(isOxygen, [call('spark_at', [SPOT[0], 1.3, SPOT[2]], UP, 20, 1.2)]),\n ),\n ],\n tick: [\n when(query('cylinder', 'live'), [\n set('jet', clamp(sub(1, div(sub(TIME, PUNCTURE_AT), JET_SECONDS)), 0, 1)),\n behavior('cylinder', 'step', { dt: DELTA, t: TIME }),\n when(not(isOxygen), [\n when(gt(jetStrength, 0), [\n emit('jet', 'normal', 60, { p: query('cylinder', 'tip'), dir: query('cylinder', 'direction'), cone: 0.3, sp: [3, 6], drag: 2.5, life: [2, 3.5], size: [0.15, 0.3], grow: 6, c0: 0xeeeeea, c1: 0xbfc3c8, a: 0.45, g: -0.05, fi: 0.05 }),\n ]),\n when(lt(TIME, CLOUD_UNTIL), [\n emit('cloud', 'normal', 4, { p: [SPOT[0], 0.6, SPOT[2]], r: 2.5, flat: true, sp: [0.05, 0.2], life: [3, 5], size: [1.5, 2.5], grow: 1.3, c0: 0xe2e2de, a: mul(0.18, min(1, sub(TIME, PUNCTURE_AT))), fi: 0.3 }),\n ]),\n ], [\n when(gt(jetStrength, 0), [\n emit('jet', 'normal', 50, { p: query('cylinder', 'back'), dir: [1, 0, 0], cone: 0.25, sp: [2, 4], drag: 3, life: [0.5, 0.9], size: [0.1, 0.2], grow: 4, c0: 0xdde6ee, a: 0.2 }),\n ]),\n when(gt(abs(query('cylinder', 'speed_x')), 0.5), [\n emit('scr', 'streak', 120, { p: [vx(query('cylinder', 'position')), 0.03, vz(query('cylinder', 'position'))], dir: SCRAPE_DIRECTION, cone: 0.6, sp: [2, 6], v: [mul(query('cylinder', 'speed_x'), 0.5), 0, 0], life: [0.2, 0.45], len: 0.02, c0: 0xfff0c0, c1: 0xff5010, g: 9.8, gnd: 2 }),\n ]),\n ]),\n ]),\n ],\n}\n","import { add, concat, eq, INDEX, pick, TIME, vadd } from '../dsl'\nimport { call, cue, fireLight, repeat, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\n\n/** The two burning windows of the shop front (W73). */\nconst WINDOWS = [[4.6, 5, -4.48], [-1.6, 5, -4.48]]\n\n/** W1054-1068 (`incendio`): fire out of the top of each window, licking up the facade, embers and smoke carried by the wind, and a light that paints the street. */\nexport const BUILDING_FIRE: EffectDef = {\n id: 'building_fire',\n pageId: 'incendio',\n team: 'world',\n budget: { particles: 600, lights: 2 },\n loop: 0,\n view: { eye: [3, 2.4, 6.5], target: [1.5, 4, -4] },\n setup: [cue('zombie_visible', { index: -1, visible: false })],\n timeline: [],\n tick: [\n repeat(\n WINDOWS.length,\n call('fire_emit', concat('w', INDEX), vadd(pick(WINDOWS, INDEX), [0, 0.55, 0.12]), 0.55, 1.1, { dir: normalized([0, 1, 0.35]), wind: [0.9, 0, 0], smoke: 22, smokeAlpha: 0.5 }),\n when(eq(INDEX, 0), [fireLight(0, vadd(pick(WINDOWS, INDEX), [0, 0, 1.4]), 3, add(TIME, INDEX))], [fireLight(1, vadd(pick(WINDOWS, INDEX), [0, 0, 1.4]), 3, add(TIME, INDEX))]),\n ),\n ],\n}\n","import { INDEX, pick, rnd, variable } from '../dsl'\nimport { behavior, cue, emit, repeat, set } from '../steps'\nimport type { EffectDef } from '../types'\n\n/** Where the three zombies stand in the fog (W1084). */\nconst SPOTS_X = [-3, 1, 5]\nconst SPOTS_Z = [-1, -2.4, 0.4]\n\n/**\n * W1073-1080 (the page's `neblina`): a low layer of mist that drifts slowly, fine ash falling in a spiral and the lamp's cone of light, with three\n * zombies standing in the fog (each turned at random). The fog density (0.075) and the cone are cues for whoever owns the scene.\n */\nexport const FOG_AND_ASH: EffectDef = {\n id: 'fog_and_ash',\n pageId: 'neblina',\n team: 'world',\n budget: { particles: 120, lights: 1 },\n loop: 0,\n view: { eye: [3, 1.8, 7.5], target: [-3, 1.2, -1] },\n setup: [\n cue('fog', { density: 0.075 }),\n cue('lamp_cone', { visible: true }),\n cue('zombie_visible', { index: -1, visible: false }),\n repeat(\n SPOTS_X.length,\n set('turn', rnd(-0.6, 0.6)),\n behavior('walkers', 'place', { index: INDEX, x: pick(SPOTS_X, INDEX), z: pick(SPOTS_Z, INDEX), facing: variable('turn') }),\n ),\n ],\n timeline: [],\n tick: [\n emit('fog', 'normal', 5, { p: [rnd(-14, 10), rnd(0.2, 1.1), rnd(-3, 8)], v: [rnd(0.15, 0.35), 0, rnd(-0.05, 0.05)], sp: 0, life: [9, 13], size: [3, 5], grow: 1.4, c0: 0x7d8aa0, a: 0.13, fi: 0.35 }),\n emit('ash', 'normal', 14, { p: [rnd(-10, 8), rnd(4, 6), rnd(-3, 7)], v: [rnd(0.1, 0.4), -0.35, rnd(-0.1, 0.1)], sp: [0.05, 0.15], life: [8, 12], size: [0.025, 0.04], c0: 0xa09a90, a: 0.75, fi: 0.1, gnd: 1 }),\n ],\n}\n","import type { WorkshopEngine } from './engine'\nimport type { Vec3Tuple } from './types'\n\n/** The most drops the field keeps (`RAINMAX`, W312). */\nexport const RAIN_CAPACITY = 4000\n/** Metres per second a drop falls (W322: `15 * dt`). */\nconst FALL_SPEED = 15\n/** How far the wind slants a drop per metre it falls (W322: `.07`), and the slant of the streak itself (W321: `.04`). */\nconst WIND_PER_FALL = 0.07\nconst STREAK_SLANT = 0.04\nconst STREAK_LENGTH = 0.6\n/** Where a drop starts, in a box of the field's own: x -15..15, z -6..16, height 0..16 at first and 14..17 when it comes back (W321, W328). */\nconst BOX_X: readonly [number, number] = [-15, 15]\nconst BOX_Z: readonly [number, number] = [-6, 16]\nconst START_HEIGHT: readonly [number, number] = [0, 16]\nconst REENTRY_HEIGHT: readonly [number, number] = [14, 17]\n/** A drop that lands makes a splash 35% of the time, within `12 / (1 + quality)` metres of the camera (W324). */\nconst SPLASH_CHANCE = 0.35\nconst SPLASH_RANGE = 12\nconst SPRITE_CHANCE = 0.5\nconst UP: Vec3Tuple = [0, 1, 0]\n\n/** An ellipse of the ground a puddle covers: centre x, centre z and the two half-axes (W332 `PUD`). */\nexport type Puddle = readonly [x: number, z: number, radiusX: number, radiusZ: number]\n\n/** The Workshop's four puddles (W332): the rings of the rain show only in them. */\nexport const WORKSHOP_PUDDLES: readonly Puddle[] = [\n [-1.5, 2.2, 1.6, 0.9],\n [3.0, 3.6, 1.1, 0.7],\n [-6, 3.2, 1.3, 0.8],\n [1.4, -2.2, 0.9, 0.5],\n]\n\nexport const inPuddle = (puddles: readonly Puddle[], x: number, z: number): boolean => puddles.some((p) => ((x - p[0]) / p[2]) ** 2 + ((z - p[1]) / p[3]) ** 2 < 1)\n\n/**\n * The Workshop's rain (W313-331): up to 4000 streaks (two points each, in a Float32Array as the page keeps them) that fall in a box, slanted by the\n * wind. A streak that reaches the ground may leave a splash (a sprite of the `normal` pool, and a ring where there is a puddle) when it is near the\n * camera, and comes back at the top. It draws its random numbers in the page's order, so the weather and the Workshop see the same rain.\n */\nexport class RainField {\n /** Two points per streak: x, y, z of the top and x, y, z of the bottom. */\n readonly positions = new Float32Array(RAIN_CAPACITY * 6)\n /** Streaks alive. */\n count = 0\n /** The slant (the wind along x in the Workshop's units). */\n wind = 1\n on = false\n /** Where the box is centred (the Workshop leaves it at the origin; a game follows the camera). */\n centerX = 0\n centerZ = 0\n puddles: readonly Puddle[] = WORKSHOP_PUDDLES\n /** Replaces the puddle test (a game knows its own wet spots). */\n puddleAt: ((x: number, z: number) => boolean) | undefined\n\n constructor(private readonly engine: WorkshopEngine) {}\n\n /** `initRain` (W321): `count` streaks (thinned by the quality), each drawn at a random place in the box. */\n init(count: number, wind: number): void {\n const { random } = this.engine\n this.count = Math.min(RAIN_CAPACITY, Math.round(count * this.engine.context.quality.mult))\n this.wind = wind\n this.on = true\n for (let index = 0; index < this.count; index++) {\n const offset = index * 6\n const x = random.between(BOX_X[0], BOX_X[1])\n const y = random.between(START_HEIGHT[0], START_HEIGHT[1])\n const z = random.between(BOX_Z[0], BOX_Z[1])\n this.set(offset, x, y, z)\n }\n }\n\n /**\n * What a game does with the field every frame: the box follows the camera (`centerX`, `centerZ`), the streaks thin or thicken to `count` (a new streak\n * starts at a random place of the box, as `init` draws it) and the wind slants them. The golden never calls it.\n */\n drive(count: number, wind: number, centerX: number, centerZ: number): void {\n const { random } = this.engine\n const target = Math.max(0, Math.min(RAIN_CAPACITY, Math.round(count * this.engine.context.quality.mult)))\n this.wind = wind\n this.centerX = centerX\n this.centerZ = centerZ\n this.on = target > 0\n for (let index = this.count; index < target; index++) {\n this.set(index * 6, random.between(BOX_X[0], BOX_X[1]) + centerX, random.between(START_HEIGHT[0], START_HEIGHT[1]), random.between(BOX_Z[0], BOX_Z[1]) + centerZ)\n }\n this.count = target\n }\n\n /** `updateRain` (W322-329). `camera` is where the eye is; `splash` lets the drops that land leave a splash. */\n update(dt: number, splash: boolean, camera: Vec3Tuple): void {\n if (!this.on) return\n const { random, context } = this.engine\n const positions = this.positions\n const fall = FALL_SPEED * dt\n const slant = this.wind * fall * WIND_PER_FALL\n const reach = SPLASH_RANGE / (1 + context.quality.level)\n for (let index = 0; index < this.count; index++) {\n const o = index * 6\n positions[o]! += slant\n positions[o + 3]! += slant\n positions[o + 1]! -= fall\n positions[o + 4]! -= fall\n const ground = context.groundAt(positions[o]!, positions[o + 2]!)\n if (positions[o + 4]! < ground) {\n const x = positions[o]!\n const z = positions[o + 2]!\n if (splash && random.next() < SPLASH_CHANCE) {\n const distance = Math.hypot(x - camera[0], z - camera[2])\n if (distance < reach) {\n if (random.next() < SPRITE_CHANCE) {\n this.engine.spawn('normal', { p: [x, ground + 0.01, z], dir: UP, cone: 0.6, sp: [0.6, 1.3], life: [0.18, 0.3], size: 0.035, c0: 0xb8c8dc, a: 0.6, g: 9.8, fi: 0 })\n }\n if (this.puddleAt ? this.puddleAt(x, z) : inPuddle(this.puddles, x, z)) {\n this.engine.ring([[x, ground + 0.012, z], 0.01, random.between(0.12, 0.25), random.between(0.4, 0.6), 0x6a7a90])\n }\n }\n }\n const nx = random.between(BOX_X[0], BOX_X[1]) + this.centerX\n const ny = random.between(REENTRY_HEIGHT[0], REENTRY_HEIGHT[1])\n const nz = random.between(BOX_Z[0], BOX_Z[1]) + this.centerZ\n this.set(o, nx, ny, nz)\n }\n }\n }\n\n /** `rain.visible = false; RN.on = false` (W440): the field stops; the streaks stay where they were. */\n clear(): void {\n this.on = false\n }\n\n private set(offset: number, x: number, y: number, z: number): void {\n const positions = this.positions\n positions[offset] = x\n positions[offset + 1] = y\n positions[offset + 2] = z\n positions[offset + 3] = x + this.wind * STREAK_SLANT\n positions[offset + 4] = y - STREAK_LENGTH\n positions[offset + 5] = z\n }\n}\n","import { add, DELTA, eq, ge, gt, ite, lt, mul, PARAM, rnd, TIME, variable } from '../dsl'\nimport { behavior, cue, decal, emit, screen, set, when } from '../steps'\nimport type { EffectDef } from '../types'\nimport { WORKSHOP_PUDDLES } from '../../workshop/rain'\n\n/** How many streaks, and how much the wind slants them, for the garoa, the chuva and the temporal (W1070). */\nconst DROPS = [900, 2200, 4000]\nconst SLANT = [0.3, 1.2, 4.5]\nconst STORM = 2\n/** The double flash (W1072): at full for 0.08 s, 0.2 for 0.08 s, 0.8 for 0.1 s, then dark; it ends at 0.4 s. */\nconst FLASH_STEPS = ite(lt(variable('flash'), 0.08), 1, ite(lt(variable('flash'), 0.16), 0.2, ite(lt(variable('flash'), 0.26), 0.8, 0)))\n\n/**\n * W1063-1072 (the page's `chuva`): up to 4000 streaks in a box by the camera, slanted by the wind; splashes and rings only within 12 m and only on the\n * four dark puddles; in the storm, sheets of water pass and a double flash lights the scene for 0.2 s every 3.5 to 6 s. The flash is a cue (`lightning`) for\n * whoever owns the lights; the screen goes white by itself.\n */\nexport const RAIN_AND_PUDDLES: EffectDef = {\n id: 'rain_and_puddles',\n pageId: 'chuva',\n team: 'world',\n params: { id: 'intensity', options: ['drizzle', 'rain', 'storm'], default: 1 },\n budget: { particles: 4000, decals: 4 },\n loop: 0,\n view: { eye: [2, 2, 7], target: [-1, 0.6, 1] },\n setup: [\n cue('lamp_cone', { visible: true }),\n ...WORKSHOP_PUDDLES.map(([x, z, radiusX, radiusZ]) => decal(x, 0, z, radiusX * 2, 0x0c1016, { grow: 0, life: 1e6, ar: radiusZ / radiusX })),\n ],\n timeline: [\n behavior('rain', 'init', { count: ite(eq(PARAM, 0), DROPS[0], ite(eq(PARAM, 1), DROPS[1], DROPS[2])), wind: ite(eq(PARAM, 0), SLANT[0], ite(eq(PARAM, 1), SLANT[1], SLANT[2])) }),\n set('nextStrike', rnd(2, 4)),\n set('flash', -1),\n ],\n tick: [\n behavior('rain', 'update', { dt: DELTA, splash: gt(PARAM, 0) }),\n when(eq(PARAM, STORM), [\n when(gt(TIME, variable('nextStrike')), [set('nextStrike', add(TIME, rnd(3.5, 6))), set('flash', 0)]),\n when(ge(variable('flash'), 0), [\n set('flash', add(variable('flash'), DELTA)),\n set('light', FLASH_STEPS),\n cue('lightning', { intensity: variable('light') }),\n screen({ max: { white: mul(variable('light'), 0.12) } }),\n when(gt(variable('flash'), 0.4), [set('flash', -1), cue('lightning', { intensity: 0 })]),\n ]),\n emit('sheet', 'normal', 2.5, { p: [-12, 2.5, rnd(-1, 8)], box: [0, 2, 0], v: [7, -0.5, 0], sp: 0, life: [3, 4], size: [3, 5], grow: 1.3, c0: 0x8a9ab0, a: 0.06, fi: 0.3 }),\n ]),\n ],\n}\n","import { localToWorld } from '../props'\nimport type { Vec3Tuple } from '../../workshop/types'\nimport { normalized } from '../vector-math'\n\n/** The car of the Workshop's set as the page leaves it between effects (`CAR0`, W104): at (5.6, 0, 0.8), turned -0.4 rad. */\nexport const CAR_ORIGIN: Vec3Tuple = [5.6, 0, 0.8]\nexport const CAR_ROTATION: Vec3Tuple = [0, -0.4, 0]\n/** A point of the car's own space in the world (`carW`). */\nexport const carPoint = (x: number, y: number, z: number): Vec3Tuple => localToWorld(CAR_ORIGIN, CAR_ROTATION, [x, y, z])\nexport const carDirection = (from: Vec3Tuple, to: Vec3Tuple): Vec3Tuple => normalized([to[0] - from[0], to[1] - from[1], to[2] - from[2]])\n","import { add, cos, DELTA, INDEX, local, mul, not, pick, query, rand, rnd, sin, sqrt, variable, vadd, vscale, vwith, vy } from '../dsl'\nimport { behavior, cue, emit, repeat, set, when } from '../steps'\nimport type { EffectDef } from '../types'\nimport { carDirection, carPoint } from './car'\n\n/** Where the beam starts (between the two lamps, W1176) and which way it points: the car's own +z. */\nconst BEAM_FROM = carPoint(0, 0.74, 2.15)\nconst BEAM_DIRECTION = carDirection(BEAM_FROM, carPoint(0, 0.74, 3.15))\nconst BEAM_SIDE = [BEAM_DIRECTION[2], 0, -BEAM_DIRECTION[0]] as const\n/** The six zombies that come into the light walk toward a point 2.6 m in front of the car (W1168). */\nconst WALKERS = 6\nconst WALK_SPEED = 0.7\nconst DROPS = 1800\nconst SLANT = 0.8\n\nconst startWalking = [\n set('spot', query('car', 'point', rnd(-2, 2), 0, rnd(8, 18))),\n set('goal', query('car', 'point', rnd(-0.6, 0.6), 0, 2.6)),\n behavior('walkers', 'place', { index: INDEX, x: pick(variable('spot'), 0), z: pick(variable('spot'), 2), facing: 0 }),\n behavior('walkers', 'walk', { index: INDEX, to: variable('goal'), speed: WALK_SPEED }),\n]\n\n/**\n * W1161-1170 (the page's `farol`): two beams in the air, rain that glows only inside the cone (up to 600 lit drops a second, thrown into the beam and\n * falling), and zombies that walk into the light. The lamps, the cones and the fog (0.05) are cues for whoever owns the scene.\n */\nexport const HEADLIGHTS_IN_RAIN: EffectDef = {\n id: 'headlights_in_rain',\n pageId: 'farol',\n team: 'vehicles',\n budget: { particles: 600, lights: 2 },\n loop: 0,\n view: { eye: [-2.5, 2, 5.5], target: [4, 1, 6] },\n setup: [\n cue('fog', { density: 0.05 }),\n cue('headlights', { on: true, intensity: 2.4, color: 0xfff1d0 }),\n behavior('rain', 'init', { count: DROPS, wind: SLANT }),\n repeat(WALKERS, ...startWalking),\n ],\n timeline: [],\n tick: [\n behavior('rain', 'update', { dt: DELTA, splash: true }),\n emit(\n 'lit',\n 'streak',\n 600,\n local(\n 'depth',\n rnd(1, 13),\n local(\n 'spread',\n mul(variable('depth'), 0.33, sqrt(rand())),\n local(\n 'turn',\n rnd(0, 6.283),\n local('base', vadd(BEAM_FROM, vscale(BEAM_DIRECTION, variable('depth')), vscale(BEAM_SIDE, mul(cos(variable('turn')), variable('spread')))), {\n p: vwith(variable('base'), 1, add(vy(variable('base')), mul(sin(variable('turn')), variable('spread'), 0.6))),\n v: [0.8, -14, 0],\n sp: 0,\n life: 0.06,\n len: 0.035,\n c0: 0xcfdcf0,\n a: 0.9,\n }),\n ),\n ),\n ),\n ),\n repeat(WALKERS, when(not(query('walkers', 'is_walking', INDEX)), startWalking)),\n ],\n}\n","import { add, DELTA, lt, mul, rand, rnd, sub, TIME, variable, vx, vz } from '../dsl'\nimport { cue, decal, emit, fireLight, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef } from '../types'\n\nconst YAW = -Math.PI / 2\nconst COS = Math.cos(YAW)\nconst SIN = Math.sin(YAW)\nconst START_X = 10\nconst SPEED = 2.4\n/** `carW(0.6, 0.06, 2.15)` for a car turned by `YAW`, as the matrix multiplies it (the y component is replaced by 0.04). */\nconst contactX = (carX: number | object) => add(COS * 0.6, 0 * 0.06, SIN * 2.15, carX)\nconst contactZ = add(-SIN * 0.6, 0 * 0.06, COS * 2.15, 1.5)\nconst BACKWARD = normalized([1, 0.35, 0])\n\n/** W1090-1100 (`faisca`): a bumper dragging on the asphalt throws a river of sparks that bounce and go from white to orange, with a short light and dark scratches. */\nexport const SCRAPING_SPARKS: EffectDef = {\n id: 'scraping_sparks',\n pageId: 'faisca',\n team: 'vehicles',\n budget: { particles: 200, lights: 1 },\n loop: 4.4,\n view: { eye: [2, 1.6, 5.5], target: [3, 0.3, 1.5] },\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('car_pose', { x: START_X, z: 1.5, yaw: YAW })],\n timeline: [],\n tick: [\n set('carX', sub(START_X, mul(TIME, SPEED))),\n set('contact', [contactX(variable('carX')), 0.04, contactZ]),\n cue('car_pose', { x: variable('carX'), z: 1.5, yaw: YAW }),\n emit('sp', 'streak', 200, { p: variable('contact'), dir: BACKWARD, cone: 0.55, sp: [3, 8], v: [-2.4, 0, 0], life: [0.2, 0.5], len: 0.02, c0: 0xfff0c0, c1: 0xff5010, g: 9.8, gnd: 2 }),\n emit('gl', 'add', 40, { p: variable('contact'), r: 0.05, size: [0.08, 0.16], life: 0.05, c0: 0xffd8a0, fi: 0 }),\n when(lt(rand(), mul(DELTA, 14)), [decal(vx(variable('contact')), 0, add(vz(variable('contact')), rnd(-0.05, 0.05)), 0.12, 0x0a0a0a, { grow: 0, life: 60, ar: 0.25 })]),\n fireLight(0, [vx(variable('contact')), 0.34, vz(variable('contact'))], 1.6, mul(TIME, 3)),\n ],\n}\n","import { DELTA, eq, gt, ite, lt, mul, PARAM, rand, TIME } from '../dsl'\nimport { burst, call, emit, fireLight, fireLightOff, when } from '../steps'\nimport type { EffectDef } from '../types'\nimport { carDirection, carPoint } from './car'\n\nconst HOOD = carPoint(0, 1.02, 1.4)\nconst EXHAUST = carPoint(0.5, 0.3, -2.2)\nconst EXHAUST_DIRECTION = carDirection(EXHAUST, carPoint(0.5, 0.3, -3))\nconst SPARK_FROM = carPoint(0, 0.7, 2.1)\nconst SPARK_DIRECTION = carDirection(SPARK_FROM, carPoint(0, 0.9, 3))\nconst WORN = 1\nconst BAD = 2\nconst CRITICAL = 3\n\n/** W1101-1112 (`motor`): exhaust only at 100, a thread of white steam at 60, steady grey smoke and the odd spark at 30, thick black smoke with fire at 10. */\nexport const ENGINE_SMOKE: EffectDef = {\n id: 'engine_smoke',\n pageId: 'motor',\n team: 'vehicles',\n params: { id: 'condition', options: ['100', '60', '30', '10'], default: 2 },\n budget: { particles: 120, lights: 1 },\n loop: 0,\n view: { eye: [9.5, 2.6, 5.2], target: [5.2, 0.9, 1.5] },\n timeline: [],\n tick: [\n emit('ex', 'normal', ite(eq(PARAM, CRITICAL), 6, 3), { p: EXHAUST, dir: EXHAUST_DIRECTION, cone: 0.3, sp: [0.6, 1.2], drag: 1.2, life: [1, 1.8], size: [0.06, 0.12], grow: 5, c0: ite(gt(PARAM, 1), 0x55524e, 0x9a9a96), a: 0.18, g: -0.2 }),\n when(eq(PARAM, WORN), [\n emit('st', 'normal', 14, { p: HOOD, box: [0.4, 0, 0.3], dir: [0, 1, 0], cone: 0.35, sp: [0.5, 1], drag: 0.8, life: [1.4, 2.4], size: [0.15, 0.25], grow: 4, c0: 0xc8ccd0, a: 0.22, g: -0.3 }),\n ]),\n when(eq(PARAM, BAD), [\n emit('st', 'normal', 22, { p: HOOD, box: [0.4, 0, 0.3], dir: [0, 1, 0], cone: 0.35, sp: [0.6, 1.2], drag: 0.6, life: [2, 3], size: [0.2, 0.35], grow: 4, c0: 0x6a6a68, c1: 0x3a3a3c, a: 0.4, g: -0.35 }),\n when(lt(rand(), mul(DELTA, 0.8)), [burst('streak', 8, { p: SPARK_FROM, dir: SPARK_DIRECTION, cone: 0.6, sp: [2, 4], life: 0.3, len: 0.02, c0: 0xffd080, c1: 0xff4000, g: 9.8 })]),\n ]),\n when(eq(PARAM, CRITICAL), [\n emit('st', 'normal', 34, { p: HOOD, box: [0.5, 0, 0.4], dir: [0, 1, 0], cone: 0.3, sp: [0.8, 1.6], drag: 0.4, life: [2.5, 3.8], size: [0.3, 0.5], grow: 4.5, c0: 0x1c1b1b, c1: 0x0e0e10, a: 0.6, g: -0.4 }),\n call('fire_emit', 'hood', carPoint(0, 0.8, 2.0), 0.3, 0.45, { noSmoke: true }),\n fireLight(0, carPoint(0, 1.2, 2.6), 2.2, TIME),\n ], [fireLightOff(0)]),\n ],\n}\n","import { rnd, scaled, query, vadd } from '../dsl'\nimport { behavior, call, cue, debris, repeat } from '../steps'\nimport type { EffectStep } from '../types'\nimport { carPoint } from './car'\n\nconst UP = [0, 1, 0] as const\n\n/** The velocity the page gives a door: the car's own space pushed outward by `s * 4`, minus the centre, with the height set to 3 (W1124). */\nconst doorVelocity = (side: number): readonly [number, number, number] => {\n const out = carPoint(side * 4, 3, 0.3)\n const centre = carPoint(0, 0, 0.3)\n return [out[0] - centre[0], 3, out[2] - centre[2]]\n}\n\n/** `vehicleBoom` (W1118-1128): the blast at the car, the car jumping, glass in the air, then the bonnet, both doors and a wheel flying off. */\nexport const VEHICLE_BOOM: readonly EffectStep[] = [\n call('explode', vadd(query('car', 'position'), [0, 0.6, 0]), 1.8, 0x2a1a14),\n cue('car_burnt'),\n behavior('car', 'launch', { rise: 4.5, spin: 0.9 }),\n repeat(scaled(30), debris({ p: vadd(query('car', 'position'), [0, 1.3, 0]), dir: UP, cone: 1.3, sp: [2, 6], size: [0.06, 0.006, 0.06], c: 0xa8c8d8, life: 20 })),\n debris({ p: carPoint(0, 1, 1.4), v: [rnd(-1, 1), 9, rnd(-1, 1)], sp: 0, size: [1.6, 0.06, 1.2], c: 0x3a1d18, spin: 6, life: 20, bounce: 0.2 }),\n ...[-1, 1].map((side) => debris({ p: carPoint(side * 0.95, 0.7, 0.3), v: doorVelocity(side), sp: 0, size: [0.06, 0.7, 1.1], c: 0x3a1d18, spin: 5, life: 20, bounce: 0.2 })),\n debris({ p: carPoint(0.95, 0.38, 1.35), v: [3, 4, 2], sp: 0, size: [0.3, 0.76, 0.76], c: 0x111111, spin: 8, life: 20, bounce: 0.4 }),\n]\n","import { add, and, clamp, DELTA, div, ge, gt, lt, mul, query, sub, TIME, variable, vadd, vlerp } from '../dsl'\nimport { after, behavior, burst, call, cue, decal, emit, fireLight, set, when } from '../steps'\nimport type { EffectDef } from '../types'\nimport { VEHICLE_BOOM } from './boom'\nimport { carDirection, carPoint } from './car'\n\nconst TANK = carPoint(-0.6, 0.25, -1.3)\nconst TANK_FLOOR = [TANK[0], 0, TANK[2]] as const\nconst POOL = [TANK_FLOOR[0] - 1.2, 0, TANK_FLOOR[2] - 0.6] as const\nconst BOOM_AT = 7.2\nconst HOLE = carPoint(-0.96, 0.6, -1.2)\n\n/** W1113-1132 (`vazamento`): petrol drips into a pool, a shot into the metal throws a spark, the fire runs along the pool to the tank and the car blows up. */\nexport const FUEL_LEAK: EffectDef = {\n id: 'fuel_leak',\n pageId: 'vazamento',\n team: 'vehicles',\n budget: { particles: 400, lights: 1 },\n loop: 11,\n view: { eye: [10, 2.4, 4.2], target: [5.6, 0.4, 0] },\n setup: [cue('zombie_visible', { index: -1, visible: false })],\n timeline: [\n decal(POOL[0], 0, POOL[2], 2.2, 0x1f2230, { grow: 3, life: 60, ar: 0.6, fluid: 'oil' }),\n after(\n 3.4,\n call('impact', 'metal', HOLE, carDirection(HOLE, carPoint(-2, 0.6, -1.2)), 1.5),\n burst('streak', 14, { p: [POOL[0], 0.05, POOL[2]], cone: 1.4, sp: [1, 3], life: 0.3, len: 0.02, c0: 0xffd080, c1: 0xff4000, g: 9.8 }),\n ),\n after(BOOM_AT, ...VEHICLE_BOOM),\n ],\n tick: [\n when(lt(TIME, BOOM_AT), [\n emit('drip', 'normal', 12, { p: TANK, box: [0.05, 0, 0.05], sp: 0, life: 1, size: 0.03, c0: 0x5a5a7a, a: 0.9, g: 9.8, fi: 0, gnd: 1 }),\n ]),\n when(and(gt(TIME, 3.5), lt(TIME, BOOM_AT)), [\n set('spread', clamp(div(sub(TIME, 3.5), 2.5), 0, 1)),\n set('front', vlerp(POOL, TANK_FLOOR, mul(variable('spread'), 0.8))),\n call('fire_emit', 'vz', variable('front'), add(0.6, mul(variable('spread'), 0.4)), 1.1, { smoke: 14 }),\n call('fire_emit', 'vz2', POOL, 0.7, 0.8, { smoke: 6 }),\n fireLight(0, vadd(variable('front'), [0, 1, 0]), 3, TIME),\n ]),\n when(ge(TIME, BOOM_AT), [\n call('fire_emit', 'wr', vadd(query('car', 'position'), [0, 0.9, 0]), 0.8, 1.4, { smoke: 18, smokeAlpha: 0.55 }),\n fireLight(0, vadd(query('car', 'position'), [0, 1.6, 0]), 3.4, TIME),\n behavior('car', 'step', { dt: DELTA }),\n ]),\n ],\n}\n","import { DELTA, gt, query, TIME, vadd } from '../dsl'\nimport { after, behavior, call, cue, fireLight, when } from '../steps'\nimport type { EffectDef } from '../types'\nimport { VEHICLE_BOOM } from './boom'\n\n/** W1133-1139 (`explosao`, `lab: 1`): a big blast (scale 1.8 of the grenade), the car jumps and lands crooked, bonnet, doors and a wheel fly, and the wreck burns. */\nexport const CAR_EXPLOSION: EffectDef = {\n id: 'car_explosion',\n pageId: 'explosao',\n team: 'vehicles',\n lab: 'car_fuel_tank',\n budget: { particles: 600, debris: 34, lights: 1 },\n loop: 10,\n view: { eye: [12, 4.2, 8], target: [5.6, 1, 0.8] },\n props: ['car'],\n setup: [cue('zombie_visible', { index: -1, visible: false })],\n timeline: [after(0.4, ...VEHICLE_BOOM)],\n tick: [\n when(gt(TIME, 0.5), [\n call('fire_emit', 'wr', vadd(query('car', 'position'), [0, 0.9, 0]), 0.8, 1.4, { smoke: 18, smokeAlpha: 0.55 }),\n fireLight(0, vadd(query('car', 'position'), [0, 1.6, 0]), 3.4, TIME),\n ]),\n behavior('car', 'step', { dt: DELTA }),\n ],\n}\n","import { add, eq, gt, INDEX, mod, mul, or, pick } from '../dsl'\nimport { after, behavior, burst, camera, cue, screen, repeat, when } from '../steps'\nimport type { EffectDef } from '../types'\nimport { carPoint } from './car'\n\nconst HITS = [[90, 40], [170, 60], [120, 75], [60, 50]]\nconst HIT_X = HITS.map(([x]) => x)\nconst HIT_Y = HITS.map(([, y]) => y)\nconst ZOMBIE = carPoint(0, 0, 3.1)\nconst CAR_YAW = -0.4\n\n/** W1140-1152 (`parabrisa`): from inside the car, blows shake the camera and add a star crack; at the second and fourth a smear of blood with a handprint runs down. */\nexport const WINDSHIELD: EffectDef = {\n id: 'windshield',\n pageId: 'parabrisa',\n team: 'vehicles',\n budget: { particles: 6, decals: 1 },\n loop: 5.8,\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n behavior('walkers', 'place', { index: 0, x: ZOMBIE[0], z: ZOMBIE[2], facing: CAR_YAW + Math.PI }),\n camera(carPoint(-0.3, 1.35, -0.2), carPoint(0, 1.2, 2.2), true),\n ],\n timeline: [\n repeat(\n HITS.length,\n after(\n add(0.6, mul(INDEX, 0.85)),\n cue('zombie_swing', { index: 0, side: mod(INDEX, 2) }),\n after(\n add(0.6, mul(INDEX, 0.85), 0.15),\n behavior('cracks', 'crack', { x: pick(HIT_X, INDEX), y: pick(HIT_Y, INDEX), big: gt(INDEX, 1) }),\n when(or(eq(INDEX, 1), eq(INDEX, 3)), [behavior('cracks', 'blood_streaks', { x: pick(HIT_X, INDEX), y: pick(HIT_Y, INDEX) })]),\n screen({ add: { shake: 0.18 } }),\n burst('add', 6, { p: carPoint(-0.1, 1.25, 0.75), box: [0.4, 0.1, 0.05], size: [0.01, 0.03], life: [0.2, 0.5], c0: 0xffffff, a: 0.8, fi: 0.2 }),\n cue('windshield_stage', { stage: add(INDEX, 1) }),\n ),\n ),\n ),\n ],\n}\n","import { add, and, DELTA, gt, lt, mod, mul, rnd, TIME } from '../dsl'\nimport { after, burst, cue, lens, repeat, screen, when } from '../steps'\nimport type { EffectDef, EffectStep } from '../types'\n\nconst FRESH_BLOOD = 0x8a0a0a\nconst BEAT_RATE = 1.9\n\n/** A blow from one side (`swing`, W1178): a red edge on that side, a shake and splashes on the lens, 0.18 s after the swing starts. */\nconst blow = (side: 0 | 1): EffectStep[] => [\n cue('zombie_swing', { index: -1, side }),\n after(\n add(TIME, 0.18),\n screen({ set: side === 0 ? { dirL: 1 } : { dirR: 1 }, add: { shake: 0.3 } }),\n repeat(4, lens(side === 0 ? rnd(0.05, 0.3) : rnd(0.7, 0.95), rnd(0.3, 0.8), rnd(0.02, 0.05), '110,8,8', 0.8)),\n burst('normal', 12, { p: [0, 1.4, 0.9], dir: [0, 0.2, 1], cone: 0.6, sp: [1, 2], life: 1, size: [0.03, 0.05], c0: FRESH_BLOOD, g: 9.8, fi: 0, gnd: 3, ds: [0.05, 0.1] }),\n ),\n]\n\n/** W1169-1185 (`dano`): two blows, from the left and from the right, then the bite: a red flash, the colour drains, the heartbeat pulses and big blood runs down the lens. */\nexport const DAMAGE_AND_BITE: EffectDef = {\n id: 'damage_and_bite',\n pageId: 'dano',\n team: 'screen',\n budget: {},\n loop: 5.6,\n view: { eye: [0, 1.6, 1.7], target: [0, 1.5, 0] },\n timeline: [\n after(0.3, ...blow(0)),\n after(1.6, ...blow(1)),\n after(3, cue('zombie_lunge', { z: 0.45 })),\n after(\n 3.15,\n screen({ set: { red: 1, desat: 0.9 }, add: { shake: 0.6 } }),\n cue('bite', { infection: 1 }),\n repeat(7, lens(rnd(0.2, 0.8), rnd(0.2, 0.7), rnd(0.04, 0.1), '100,6,6', 1)),\n ),\n ],\n tick: [\n when(and(gt(TIME, 3.2), lt(TIME, 5.4)), [when(lt(mod(mul(TIME, BEAT_RATE), 1), mul(DELTA, BEAT_RATE)), [screen({ set: { beat: 1 } })])]),\n ],\n}\n","import { add, CAMERA_POSITION, cameraForward, DELTA, eq, gt, INDEX, lt, max, mod, mul, PARAM, rand, rnd, sin, TIME, variable, vadd } from '../dsl'\nimport { burst, cue, post, repeat, screen, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst MALAISE = 0\nconst FEVER = 1\nconst DELIRIUM = 2\nconst LAST_HOURS = 3\nconst GHOSTS = [[-3, -1.8], [3.5, -2.4], [-6, 1.5]]\n\n/** W1186-1205 (`infeccao`): malaise (washed colour, a breathing vignette), fever (cold edge, waves of blur, a cough that shakes the camera), delirium, the last hours. */\nexport const INFECTION_PHASES: EffectDef = {\n id: 'infection_phases',\n pageId: 'infeccao',\n team: 'screen',\n params: { id: 'phase', options: ['malaise', 'fever', 'delirium', 'last_hours'], default: 1 },\n budget: { particles: 10 },\n loop: 0,\n view: { eye: [2, 1.7, 7], target: [0, 1.2, -1] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n ...GHOSTS.map(([x, z], index) => cue('ghost_place', { index, x, z, turn: rnd(-0.4, 0.4) })),\n ],\n timeline: [set('nextCough', 2)],\n tick: [\n when(eq(PARAM, MALAISE), [post({ desat: 0.25, tunnel: add(0.15, mul(0.12, sin(mul(TIME, 1.2)))), blur: mul(0.3, max(0, sin(mul(TIME, 0.7)))) })]),\n when(eq(PARAM, FEVER), [\n post({ cold: add(0.8, mul(0.15, sin(mul(TIME, 2)))), blur: add(0.6, mul(0.6, sin(mul(TIME, 1.6)))), desat: 0.3 }),\n when(gt(TIME, variable('nextCough')), [\n set('nextCough', add(TIME, rnd(3, 5))),\n screen({ add: { shake: 0.25 } }),\n burst('normal', 10, { p: vadd(CAMERA_POSITION, cameraForward([0, -0.15, -0.6])), dir: cameraForward([0, 0, -1]), cone: 0.4, sp: [0.6, 1.2], drag: 1.5, life: 1.2, size: [0.05, 0.1], grow: 5, c0: 0xdfe6ee, a: 0.2 }),\n ]),\n ]),\n when(eq(PARAM, DELIRIUM), [\n post({ chroma: add(2, mul(3, add(0.5, mul(0.5, sin(mul(TIME, 1.7)))))), hue: mul(22, sin(mul(TIME, 0.6))), tunnel: 0.3, desat: 0.15 }),\n repeat(GHOSTS.length, cue('ghost_visible', { index: INDEX, visible: gt(sin(add(mul(TIME, add(1.3, mul(INDEX, 0.7))), mul(INDEX, 2))), 0.6) })),\n when(lt(rand(), mul(DELTA, 0.3)), [screen({ set: { white: 0.12 } })]),\n ]),\n when(eq(PARAM, LAST_HOURS), [\n post({ desat: 0.85, tintAlpha: 0.22, tintColor: '70,110,40', tunnel: 0.55, blur: 1.2 }),\n when(lt(mod(mul(TIME, 2.2), 1), mul(DELTA, 2.2)), [screen({ set: { beat: 1 }, add: { shake: 0.05 } })]),\n ]),\n ],\n}\n","import { add, CAMERA_POSITION, clamp, DELTA, div, eq, INDEX, ite, lt, min, mod, mul, query, rnd, sub, TIME, variable, vdist } from '../dsl'\nimport { behavior, cue, post, repeat, screen, set, when } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst WALKERS = 6\nconst NEAR = 9\nconst RANGE = 7\nconst RESTING_BPM = 70\nconst BPM_RISE = 80\nconst walkerPoint = [query('walkers', 'x', INDEX), 0, query('walkers', 'z', INDEX)]\n\n/** W1206-1217 (`panico`): the aim trembles, the tunnel closes as the nearest zombie arrives and the heartbeat quickens from 70 to 150 bpm. */\nexport const PANIC: EffectDef = {\n id: 'panic',\n pageId: 'panico',\n team: 'screen',\n budget: {},\n loop: 8,\n view: { eye: [0, 1.65, 6], target: [0, 1.3, -2] },\n setup: [\n cue('zombie_visible', { index: -1, visible: false }),\n repeat(\n WALKERS,\n set('startX', rnd(-4, 4)),\n set('startZ', sub(rnd(-4, -2), mul(INDEX, 0.6))),\n behavior('walkers', 'place', { index: INDEX, x: variable('startX'), z: variable('startZ'), facing: 0 }),\n behavior('walkers', 'walk', { index: INDEX, to: [rnd(-1.2, 1.2), 0, 5], speed: ite(eq(mod(INDEX, 3), 1), 1.6, 0.7) }),\n ),\n ],\n timeline: [],\n tick: [\n set('nearest', 99),\n repeat(WALKERS, set('nearest', min(variable('nearest'), vdist(walkerPoint, CAMERA_POSITION)))),\n set('fear', clamp(div(sub(NEAR, variable('nearest')), RANGE), 0, 1)),\n set('bpm', add(RESTING_BPM, mul(BPM_RISE, variable('fear')))),\n when(lt(mod(div(mul(TIME, variable('bpm')), 60), 1), div(mul(DELTA, variable('bpm')), 60)), [screen({ set: { beat: add(0.4, mul(0.6, variable('fear'))) } })]),\n post({ tunnel: add(0.1, mul(0.65, variable('fear'))), desat: mul(0.45, variable('fear')) }),\n set('tremor', add(0.012, mul(0.035, variable('fear')))),\n ],\n}\n","import { rnd } from '../dsl'\nimport { after, burst, cue, lens, repeat, screen } from '../steps'\nimport type { EffectDef } from '../types'\n\n/** W1218-1226 (`cegueira`): a green cloud bursts between the bloater and the camera, the screen goes green and blurred and clears in 5 s; two coughs shake the camera. */\nexport const BLOATER_BLINDNESS: EffectDef = {\n id: 'bloater_blindness',\n pageId: 'cegueira',\n team: 'screen',\n budget: { particles: 30 },\n loop: 7.5,\n view: { eye: [0, 1.6, 2.6], target: [0, 1.3, 0] },\n setup: [cue('bloater_pose', { eyes: 0x5fe08a, skin: 0x6b7a52, belly: [1.4, 1.25, 1.6] })],\n timeline: [\n after(\n 0.7,\n cue('zombie_visible', { index: -1, visible: false }),\n screen({ set: { gas: 1 }, add: { shake: 0.3 } }),\n burst('normal', 30, { p: [0, 1.3, 0.8], r: 0.6, sp: [0.5, 2], drag: 2, life: [3, 5], size: [0.8, 1.6], grow: 1.6, c0: 0x6f8a3c, c1: 0x3b4a26, a: 0.3, fi: 0.05 }),\n repeat(8, lens(rnd(0.15, 0.85), rnd(0.15, 0.7), rnd(0.03, 0.08), '110,150,50', 0.9)),\n ),\n after(2, screen({ add: { shake: 0.2 } })),\n after(3.4, screen({ add: { shake: 0.2 } })),\n ],\n}\n","import { TIME } from '../dsl'\nimport { call, cue, fireLight } from '../steps'\nimport type { EffectDef } from '../types'\n\nconst FIRE = [-1.4, 0.1, 3.0] as const\n\n/** W1227-1233 (`fogueira`): a low flame, embers that spiral up, thin smoke and a warm light that trembles and paints the survivor. */\nexport const CAMPFIRE: EffectDef = {\n id: 'campfire',\n pageId: 'fogueira',\n team: 'screen',\n budget: { particles: 120, lights: 1 },\n loop: 0,\n view: { eye: [1.4, 1.6, 6.4], target: [-1.4, 0.6, 3] },\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('survivor_pose', { x: -2.6, z: 3.6, turn: 2.2 })],\n timeline: [],\n tick: [\n call('fire_emit', 'camp', FIRE, 0.25, 0.55, { smoke: 8, smokeColor: 0x4a4642, smokeAlpha: 0.25 }),\n fireLight(0, [FIRE[0], FIRE[1] + 0.8, FIRE[2]], 2.4, TIME),\n ],\n}\n","import { add, gt, TIME, variable } from '../dsl'\nimport { after, burst, cue, set, when } from '../steps'\nimport { normalized } from '../vector-math'\nimport type { EffectDef, EffectStep } from '../types'\n\nconst FACING = 0.5\n/** The survivor's mouth and the way it breathes out, with the survivor at (-1.6, 0, 1.8) turned by `FACING` (W1236-1238). */\nconst MOUTH = [Math.sin(FACING) * 0.2 + -1.6, 1.68, Math.cos(FACING) * 0.2 + 1.8] as const\nconst BREATH = normalized([Math.sin(FACING), -0.15, Math.cos(FACING)])\nconst BREATH_EVERY = 2.4\nconst COUGH_EVERY = 6.5\n\n/** A puff of breath (`puff`, W1239): `strength` scales how many and how fast. */\nconst puff = (strength: number): EffectStep =>\n burst('normal', 8 * strength, { p: MOUTH, dir: BREATH, cone: 0.35, sp: [0.5, 1.1 * strength], drag: 1.6, life: [1.2, 1.8], size: [0.05, 0.09], grow: 6, c0: 0xdfe6ee, a: 0.22, g: -0.1 })\n\n/** W1234-1243 (`tosse`): a short breath every 2.4 s; in a cough, three quick bigger ones and a jolt of the body; the torch shows its beam in the fog. */\nexport const COUGH_AND_BREATH: EffectDef = {\n id: 'cough_and_breath',\n pageId: 'tosse',\n team: 'screen',\n budget: { particles: 40, lights: 1 },\n loop: 0,\n view: { eye: [2.4, 1.8, 6.5], target: [-1.4, 1.3, 1.6] },\n setup: [cue('zombie_visible', { index: -1, visible: false }), cue('survivor_pose', { x: -1.6, z: 1.8, turn: FACING }), cue('torch', { on: true })],\n timeline: [set('nextBreath', 0.5), set('nextCough', 3)],\n tick: [\n when(gt(TIME, variable('nextBreath')), [set('nextBreath', add(TIME, BREATH_EVERY)), puff(1)]),\n when(gt(TIME, variable('nextCough')), [\n set('nextCough', add(TIME, COUGH_EVERY)),\n ...[0, 0.25, 0.5].map((delay) => after(add(TIME, delay), puff(1.6), cue('survivor_jolt', { tilt: 0.25 }))),\n ]),\n ],\n}\n","import { cos, local, mul, rnd, scaled, sin, variable, vnorm } from './dsl'\nimport { burst, call, debris, repeat, screen, spawn } from './steps'\nimport type { EffectDef } from './types'\n\nconst FACING = [0, 0, 1] as const\nconst UP = [0, 1, 0] as const\nconst ORIGIN = [0, 0, 0] as const\nconst FORWARD = [0, 0, -1] as const\nconst IMPACT_MATERIALS = ['concrete', 'metal', 'wood', 'glass', 'flesh', 'water'] as const\n\n/** What a hit leaves on one material, the way the Workshop's `impact` helper does (W374-391), played once at the hit. */\nconst impactEffect = (material: (typeof IMPACT_MATERIALS)[number]): EffectDef => ({\n id: `impact_${material}`,\n pageId: `event:impact_${material}`,\n team: 'weapons',\n budget: { particles: 40, decals: 1 },\n loop: 2,\n timeline: [call('impact', material, ORIGIN, FACING, 1, 0)],\n})\n\n/** The flash of one weapon at its muzzle (W417 `muzzle`), played once: the recipe's own per-weapon sizes, petals, light and smoke. */\nconst muzzleEffect = (weapon: 'glock' | 'ak' | 'r870' | 'barrett'): EffectDef => ({\n id: `muzzle_${weapon}`,\n pageId: `event:muzzle_${weapon}`,\n team: 'weapons',\n budget: { particles: 60, lights: 1 },\n loop: 2.4,\n timeline: [call('muzzle', weapon, ORIGIN, FORWARD)],\n})\n\n/** A case thrown out of the port (W430 `casing`): brass, a red shell or a .50 case. */\nconst casingEffect = (id: string, type: '' | 'shell' | '50'): EffectDef => ({\n id,\n pageId: `event:${id}`,\n team: 'weapons',\n budget: { debris: 1 },\n loop: 2,\n timeline: [call('casing', ORIGIN, type)],\n})\n\n/**\n * The effects the destruction events play, as slices of the Workshop's recipes: the same bursts, with the recipe's own numbers, centred on the point the event\n * happens (`data/event-effects.json` says which event plays which). They are not Workshop pages, so they have no golden of their own; each cites the lines it was cut from.\n */\nexport const EVENT_EFFECTS: readonly EffectDef[] = [\n ...IMPACT_MATERIALS.map(impactEffect),\n ...(['glock', 'ak', 'r870', 'barrett'] as const).map(muzzleEffect),\n casingEffect('casing_brass', ''),\n casingEffect('casing_shell', 'shell'),\n casingEffect('casing_50', '50'),\n {\n // door_stages (W856-871): the dust a blow shakes loose from the frame and the splinters.\n id: 'stage_crack',\n pageId: 'event:stage_crack',\n team: 'destruction',\n budget: { particles: 12, debris: 5 },\n loop: 2,\n timeline: [\n burst('normal', 12, { p: ORIGIN, box: [0.6, 0.05, 0.02], dir: [0, -0.287, 0.958], cone: 0.6, sp: [0.2, 0.8], drag: 1.5, life: [0.8, 1.4], size: [0.08, 0.16], grow: 3, c0: 0x7a7366, a: 0.45, g: 0.4 }),\n repeat(scaled(2), debris({ p: [rnd(-0.5, 0.5), rnd(0, 1.6), 0], dir: [0, 0.287, 0.958], cone: 0.6, sp: [1, 2.5], size: [0.015, 0.015, 0.1], c: 0x7a5530, life: 12 })),\n ],\n },\n {\n // block_wall (W872-886, 3.6 s): the ring of dust that rolls out when the wall gives way.\n id: 'breach_dust',\n pageId: 'event:breach_dust',\n team: 'destruction',\n budget: { particles: 90, debris: 16 },\n loop: 5,\n timeline: [\n screen({ add: { shake: 0.25 } }),\n burst('normal', 30, { p: ORIGIN, box: [1.4, 0.8, 0.2], sp: [0.3, 1.2], drag: 1.5, life: [1.5, 2.6], size: [0.4, 0.7], grow: 3, c0: 0x8a857a, c1: 0x4a4640, a: 0.45 }),\n repeat(scaled(16), debris({ p: ORIGIN, box: [1.3, 0.8, 0.1], sp: [1, 3], size: [0.08, 0.07, 0.08], k: [0.5, 1.5], c: 0x6e6a63, life: 20 })),\n repeat(\n scaled(60),\n spawn('normal', local('angle', rnd(0, 6.283), {\n p: [rnd(-1.4, 1.4), 0.2, rnd(-0.6, 0.4)],\n dir: vnorm([cos(variable('angle')), 0.3, sin(variable('angle'))]),\n cone: 0.4, sp: [0.8, 2.4], drag: 1.3, life: [2.5, 4.5], size: [0.6, 1], grow: 3, c0: 0x7a7268, c1: 0x4a4640, a: 0.45, fi: 0.12,\n })),\n ),\n ],\n },\n {\n // building_collapse (W872-886): the slab dropping in blocks and the cloud that rolls along the street.\n id: 'collapse_dust',\n pageId: 'event:collapse_dust',\n team: 'destruction',\n budget: { particles: 350, debris: 26 },\n loop: 8,\n timeline: [\n screen({ add: { shake: 0.45 } }),\n repeat(6, debris({ p: ORIGIN, box: [2, 0.05, 0.6], v: [rnd(-0.5, 0.5), rnd(-0.5, 0), rnd(0, 0.8)], sp: 0, size: [rnd(0.5, 1.1), 0.25, rnd(0.4, 0.8)], c: 0x6e6a63, spin: 3, life: 30, bounce: 0.1 })),\n repeat(scaled(20), debris({ p: ORIGIN, box: [2.1, 0.1, 0.7], v: [rnd(-1, 1), rnd(-1, 1), rnd(0, 1.5)], sp: 0, size: [0.12, 0.1, 0.12], k: [0.5, 1.5], c: 0x5e5a54, life: 30 })),\n repeat(\n scaled(70),\n spawn('normal', local('angle', rnd(-0.4, 3.5), {\n p: [rnd(-2, 2), 0.2, rnd(-0.5, 0.5)],\n dir: vnorm([mul(cos(variable('angle')), 0.6), 0.25, sin(variable('angle'))]),\n cone: 0.5, sp: [1, 3.2], drag: 1.1, life: [3, 6], size: [0.7, 1.2], grow: 3, c0: 0x7a7268, c1: 0x4a4640, a: 0.5, fi: 0.12,\n })),\n ),\n ],\n },\n {\n // shopfront_glass (W846-855): the pane coming down as shards, the flash of the glints and the pale dust.\n id: 'glass_burst',\n pageId: 'event:glass_burst',\n team: 'destruction',\n budget: { debris: 80, particles: 50 },\n loop: 5,\n timeline: [\n screen({ add: { shake: 0.08 } }),\n repeat(\n scaled(75),\n debris({ p: ORIGIN, box: [1.25, 0.85, 0.02], v: [rnd(-0.4, 0.4), rnd(-0.5, 0.8), rnd(0.6, 2)], sp: 0, size: [rnd(0.05, 0.18), 0.006, rnd(0.05, 0.18)], c: 0xa8c8d8, spin: 14, life: 30, bounce: 0.15 }),\n ),\n burst('add', 30, { p: ORIGIN, box: [1.2, 0.8, 0.05], size: [0.02, 0.05], life: [0.2, 0.6], c0: 0xffffff, a: 0.9, fi: 0.3 }),\n burst('normal', 20, { p: [0, -0.6, 0.1], box: [1.2, 0.5, 0.1], sp: [0.2, 0.6], drag: 2, life: [0.8, 1.4], size: [0.12, 0.2], grow: 3, c0: 0xbfd6e2, a: 0.2 }),\n ],\n },\n {\n // The chips macro the page uses on wood (W849) plus rust (`rustAt`), for rebar laid bare in concrete.\n id: 'rebar_expose',\n pageId: 'event:rebar_expose',\n team: 'destruction',\n budget: { particles: 20, debris: 8 },\n loop: 2,\n timeline: [call('chips', ORIGIN, UP, 8, 0.9), call('rust_at', ORIGIN, 6)],\n },\n]\n","import { add, cos, DIRECTION, div, eq, floor, INDEX, lt, min, mul, neg, pick, rand, sin, sub, variable, vx, vz } from '../dsl'\nimport { append, flash, mesh, repeat, set, when } from '../steps'\nimport type { EffectDef, EffectStep } from '../types'\n\n/**\n * The weapon in the player's hands (the Arsenal gallery's first-person effects: the muzzle flash and smoke of `createEffects`, the backblast of a launched rocket, the rocket's\n * trail and the flame jet of a flamethrower) as recipes of the Workshop engine, drawn as the gallery draws them: as solids (cones, spheres, icosahedra) with the gallery's sizes,\n * segment counts, materials, timing and growth, not as sprites. They are written in the weapon's own axes, the gallery's: x along the barrel, y up, z to the right. A player\n * says how big (`values`), where the weapon points (`direction`, the barrel in the world) and how it is turned (`orientation`, the quaternion, pitch and roll included), and\n * seeds the numbers the effect draws, which it draws in the order the gallery drew them.\n */\nconst PI = Math.PI\n/** The gallery's `smoke`: a sphere of 10 by 8 segments, a grey that rises, slows and grows by 2.1 a second while it fades. */\nconst SMOKE = { color: 0x8a8a86, width: 10, height: 8, gravity: -0.08, drag: 2.2, growth: 2.1 }\n/** The flash lasts 55 ms and its group grows from 0.6 to 1.5 times its size (`0.6 + min(1, age / 0.055) * 0.9`). */\nconst FLASH_SECONDS = 0.055\nconst FLASH_RAMP = [0.6, 0.9] as const\nconst FLASH_OPACITY = 0.95\n/** The gallery's palette for flame bits: orange, yellow and dark red, and a pale additive core. */\nconst FLAME_COLORS = [0xff7a22, 0xffc040, 0xc8361a, 0xfff0b0]\nconst FLAME_ADDITIVE = 3\nconst ORIGIN = [0, 0, 0] as const\n\nconst SIZE = variable('size')\nconst wide = (width: number): unknown => mul(sub(rand(), 0.5), width)\n\n/** The gallery's `smoke(position, velocity, size, life, opacity)`; the keys are in the order the gallery drew its numbers. `world` is a velocity that is not turned with the weapon. */\nconst puff = (point: unknown, velocity: unknown, world: unknown, radius: unknown, life: unknown, opacity: unknown): EffectStep =>\n mesh({\n shape: 'sphere',\n p: point,\n v: velocity,\n wv: world,\n r: radius,\n seg: SMOKE.width,\n seg2: SMOKE.height,\n life,\n c0: SMOKE.color,\n a: opacity,\n fade: true,\n lit: true,\n g: SMOKE.gravity,\n drag: SMOKE.drag,\n grow: SMOKE.growth,\n })\n\n/** The gallery's `flameBit`: an icosahedron of one of four colours, tumbling, thrown, rising, growing and slowing. The numbers are drawn in the gallery's order, the colour after the life. */\nconst flameBit = (point: unknown, velocity: unknown, world: unknown, radius: unknown, life: unknown): EffectStep[] => [\n set('bitPoint', point),\n set('bitVelocity', velocity),\n set('bitWorld', world),\n set('bitRadius', radius),\n set('bitLife', life),\n set('bitColour', floor(mul(rand(), FLAME_COLORS.length))),\n mesh({\n shape: 'icosahedron',\n p: variable('bitPoint'),\n v: variable('bitVelocity'),\n wv: variable('bitWorld'),\n r: variable('bitRadius'),\n seg: 1,\n rot: [mul(rand(), 3), mul(rand(), 3), 0],\n spin: [3, 4, 2],\n life: variable('bitLife'),\n c0: pick(FLAME_COLORS, variable('bitColour')),\n add: eq(variable('bitColour'), FLAME_ADDITIVE),\n a: 0.9,\n fade: true,\n g: -1.4,\n drag: 1.4,\n grow: 2.2,\n }),\n]\n\n/** One piece of the flash: additive, 55 ms, in the group that grows and is rolled by `roll`. */\nconst flashPiece = (shape: 'cone' | 'cone_open' | 'sphere', radius: unknown, height: unknown, width: number, at: unknown, rot: unknown, color: number): EffectStep =>\n mesh({ shape, r: radius, ...(height === undefined ? {} : { h: height }), seg: width, seg2: shape === 'sphere' ? 8 : 1, p: ORIGIN, at, rot, roll: variable('roll'), ramp: FLASH_RAMP, life: FLASH_SECONDS, c0: color, a: FLASH_OPACITY, add: true })\n\n/**\n * `muzzleFlash` of the gallery (size `k`): an open cone, four small cones and a sphere, additive for 55 ms and growing, a short orange light that holds its strength, and six\n * puffs of smoke. It draws the four angles of the small cones, the roll of the group, then the velocity and life of each puff.\n */\nconst MUZZLE_FLASH: EffectDef = {\n id: 'viewmodel_muzzle_flash',\n pageId: 'event:viewmodel_muzzle_flash',\n team: 'weapons',\n budget: { particles: 12, lights: 1 },\n loop: 0.1,\n timeline: [\n set('angles', []),\n repeat(4, append('angles', add(div(mul(INDEX, PI), 2), mul(rand(), 0.6)))),\n set('roll', mul(rand(), PI)),\n flash(ORIGIN, 0xffb060, mul(4, SIZE), FLASH_SECONDS, mul(2, SIZE), true, true),\n flashPiece('cone_open', mul(0.013, SIZE), mul(0.085, SIZE), 10, [mul(0.042, SIZE), 0, 0], [0, 0, -PI / 2], 0xffb347),\n repeat(\n 4,\n set('angle', pick(variable('angles'), INDEX)),\n flashPiece(\n 'cone',\n mul(0.005, SIZE),\n mul(0.04, SIZE),\n 6,\n [mul(0.012, SIZE), mul(cos(variable('angle')), 0.016, SIZE), mul(sin(variable('angle')), 0.016, SIZE)],\n [variable('angle'), 0, -PI / 2],\n 0xffb347,\n ),\n ),\n flashPiece('sphere', mul(0.016, SIZE), undefined, 12, [mul(0.008, SIZE), 0, 0], [0, 0, 0], 0xfff1c0),\n repeat(\n 6,\n puff(\n ORIGIN,\n [add(0.15, mul(rand(), 0.35)), add(0.03, mul(rand(), 0.12)), mul(sub(rand(), 0.5), 0.14)],\n [0, 0, 0],\n mul(0.013, SIZE),\n add(1.3, mul(rand(), 0.6)),\n 0.45,\n ),\n ),\n ],\n}\n\n/**\n * One puff of smoke the gallery's `smoke(position, velocity, size, life, opacity)` throws: a hot barrel's, a rocket's trail, the smoke of a flame on the ground. The numbers come as\n * `values` (`vx`, `vy`, `vz` in the world, `radius`, `life`, `opacity`), so the weapon keeps its own random draws.\n */\nconst SMOKE_PUFF: EffectDef = {\n id: 'weapon_smoke_puff',\n pageId: 'event:weapon_smoke_puff',\n team: 'weapons',\n budget: { particles: 1 },\n loop: 0.1,\n timeline: [puff(ORIGIN, undefined, [variable('vx'), variable('vy'), variable('vz')], variable('radius'), variable('life'), variable('opacity'))],\n}\n\n/** A rocket leaving the tube, from the rear of it: 26 puffs thrown back (-x) and 14 bits of fire. */\nconst BACKBLAST: EffectDef = {\n id: 'launcher_backblast',\n pageId: 'event:launcher_backblast',\n team: 'weapons',\n budget: { particles: 40 },\n loop: 0.1,\n timeline: [\n repeat(26, puff(ORIGIN, [neg(add(1.5, mul(rand(), 3))), 0, 0], [wide(1.4), wide(0.8), wide(1.4)], add(0.03, mul(rand(), 0.03)), add(1.8, mul(rand(), 1.4)), 0.5)),\n repeat(14, ...flameBit(ORIGIN, [neg(add(2, mul(rand(), 2))), 0, 0], [wide(1), wide(0.6), wide(1)], 0.02, 0.25)),\n ],\n}\n\n/**\n * A frame of a flamethrower's jet: `floor(420 dt scale)` bits of fire thrown along the barrel and up (`dt` and `scale` are the values), and a puff of smoke downwind half the time.\n * It is played every frame the nozzle burns. It needs the `direction` of the barrel for the wind of the smoke.\n */\nconst FLAME_JET: EffectDef = {\n id: 'flame_jet',\n pageId: 'event:flame_jet',\n team: 'weapons',\n budget: { particles: 30 },\n loop: 0.1,\n timeline: [\n repeat(\n floor(mul(420, variable('dt'), variable('scale'))),\n set('speed', mul(add(2.2, mul(rand(), 1.1)), variable('scale'))),\n ...flameBit(\n [mul(rand(), variable('speed'), min(variable('dt'), 0.3)), 0, 0],\n [variable('speed'), 0, 0],\n [wide(0.35), mul(sub(rand(), 0.3), 0.3), wide(0.35)],\n add(0.02, mul(rand(), 0.022)),\n add(0.4, mul(rand(), 0.35)),\n ),\n ),\n when(lt(rand(), 0.5), [\n puff([add(mul(1.1, variable('scale')), mul(rand(), 0.4)), 0, 0], undefined, [mul(vx(DIRECTION), 0.6), 0.35, mul(vz(DIRECTION), 0.6)], 0.03, 1.6, 0.4),\n ]),\n ],\n}\n\nexport const VIEWMODEL_EFFECTS: readonly EffectDef[] = [MUZZLE_FLASH, SMOKE_PUFF, BACKBLAST, FLAME_JET]\n","import { CAR_ORIGIN } from './car'\nimport { ENGINE_SMOKE } from './engine-smoke'\nimport { FUEL_LEAK } from './fuel-leak'\nimport type { EffectDef } from '../types'\n\n/**\n * The Garagem's recipes written around a car, to be played at a vehicle: the Workshop's `engine_smoke` and `fuel_leak` keep the car where the page stood\n * it (`CAR_ORIGIN`), so each alias names that spot as its `anchor` and the effect lands on the point it is played at. The values are the recipes' own;\n * only the id, the condition they start in and (for the exhaust) how long one play lasts change. Ids a vehicle module asks for: `vehicle_fire`, `vehicle_leak`, `vehicle_exhaust`.\n * The other vehicle requests use point-based entries that already exist: the explosion catalogue's `car_fuel_tank`, `glass_burst` and `impact_metal`.\n */\nconst aliasOf = (base: EffectDef, id: string, changes: Partial<EffectDef>): EffectDef => ({ ...base, id, pageId: `vehicle:${id}`, anchor: CAR_ORIGIN, ...changes })\n\nexport const VEHICLE_EFFECTS: readonly EffectDef[] = [\n /** The engine on fire: `engine_smoke` at its worst condition (black smoke, flames in the hood, a light). */\n aliasOf(ENGINE_SMOKE, 'vehicle_fire', { params: { id: 'condition', options: ['100', '60', '30', '10'], default: 3 }, loop: 12 }),\n /** The exhaust of a car under way: `engine_smoke` in the best condition, for half a second so a moving car asks again. */\n aliasOf(ENGINE_SMOKE, 'vehicle_exhaust', { params: { id: 'condition', options: ['100', '60', '30', '10'], default: 0 }, loop: 0.5 }),\n /** A hole in the tank: the page's own petrol leak (drips, pool, sparks, fire running to the tank). */\n aliasOf(FUEL_LEAK, 'vehicle_leak', {}),\n]\n","import { BLOATER_CLOUD } from './creatures/bloater-cloud'\nimport { BLOOD_HIT } from './creatures/blood-hit'\nimport { CORPSE_DECAY } from './creatures/corpse-decay'\nimport { EYES_IN_FOG } from './creatures/eyes-in-fog'\nimport { DISMEMBER } from './creatures/dismember'\nimport { HEADSHOT } from './creatures/headshot'\nimport { REANIMATION } from './creatures/reanimation'\nimport { SCREAMER_SHRIEK } from './creatures/screamer-shriek'\nimport { IMPACT_BY_MATERIAL } from './weapons/impact-by-material'\nimport { PENETRATION } from './weapons/penetration'\nimport { CASINGS_AND_MAGAZINE } from './weapons/casings-and-magazine'\nimport { MOLOTOV } from './weapons/molotov'\nimport { GRENADE } from './weapons/grenade'\nimport { EXPLOSIVE_BARREL } from './weapons/explosive-barrel'\nimport { MUZZLE_FLASH } from './weapons/muzzle-flash'\nimport { SHOPFRONT_GLASS } from './destruction/shopfront-glass'\nimport { DOOR_STAGES } from './destruction/door-stages'\nimport { BUILDING_COLLAPSE } from './destruction/building-collapse'\nimport { BLOCK_WALL } from './destruction/block-wall'\nimport { METAL_DOOR_EFFECT } from './destruction/metal-door'\nimport { IRON_RAILING } from './destruction/iron-railing'\nimport { WOODEN_FENCE } from './destruction/wooden-fence'\nimport { HIT_POINT_BREAKAGE } from './destruction/hit-point-breakage'\nimport { PRESSURE_CYLINDERS } from './destruction/pressure-cylinders'\nimport { BUILDING_FIRE } from './world/building-fire'\nimport { FOG_AND_ASH } from './world/fog-and-ash'\nimport { RAIN_AND_PUDDLES } from './world/rain'\nimport { HEADLIGHTS_IN_RAIN } from './vehicles/headlights'\nimport { SCRAPING_SPARKS } from './vehicles/scraping-sparks'\nimport { ENGINE_SMOKE } from './vehicles/engine-smoke'\nimport { FUEL_LEAK } from './vehicles/fuel-leak'\nimport { CAR_EXPLOSION } from './vehicles/car-explosion'\nimport { WINDSHIELD } from './vehicles/windshield'\nimport { DAMAGE_AND_BITE } from './screen/damage-and-bite'\nimport { INFECTION_PHASES } from './screen/infection-phases'\nimport { PANIC } from './screen/panic'\nimport { BLOATER_BLINDNESS } from './screen/bloater-blindness'\nimport { CAMPFIRE } from './screen/campfire'\nimport { COUGH_AND_BREATH } from './screen/cough-and-breath'\nimport { EVENT_EFFECTS } from './events'\nimport { VIEWMODEL_EFFECTS } from './weapons/viewmodel'\nimport { VEHICLE_EFFECTS } from './vehicles/game-effects'\nimport type { EffectDef } from './types'\n\nconst ALL_EFFECTS: readonly EffectDef[] = [BLOOD_HIT, HEADSHOT, DISMEMBER, BLOATER_CLOUD, SCREAMER_SHRIEK, CORPSE_DECAY, REANIMATION, EYES_IN_FOG, MUZZLE_FLASH, IMPACT_BY_MATERIAL, PENETRATION, CASINGS_AND_MAGAZINE, MOLOTOV, GRENADE, EXPLOSIVE_BARREL, SHOPFRONT_GLASS, DOOR_STAGES, BUILDING_COLLAPSE, BLOCK_WALL, METAL_DOOR_EFFECT, IRON_RAILING, WOODEN_FENCE, HIT_POINT_BREAKAGE, PRESSURE_CYLINDERS, BUILDING_FIRE, RAIN_AND_PUDDLES, FOG_AND_ASH, SCRAPING_SPARKS, ENGINE_SMOKE, FUEL_LEAK, CAR_EXPLOSION, WINDSHIELD, HEADLIGHTS_IN_RAIN, DAMAGE_AND_BITE, INFECTION_PHASES, PANIC, BLOATER_BLINDNESS, CAMPFIRE, COUGH_AND_BREATH]\n\n/** Every effect of the Workshop by id. A game adds, changes or removes entries with `patchEffects`. */\nexport const WORKSHOP_EFFECTS: Readonly<Record<string, EffectDef>> = Object.fromEntries(ALL_EFFECTS.map((effect) => [effect.id, effect]))\n\n/** The Workshop's recipes plus the one-shot effects the destruction events play (`event-effects.json`) and the ones of the weapon in the player's hands and the vehicle ones (`vehicle_fire`, `vehicle_exhaust`, `vehicle_leak`, written around a car): what a world plays by default. */\nexport const GAME_EFFECTS: Readonly<Record<string, EffectDef>> = { ...WORKSHOP_EFFECTS, ...Object.fromEntries([...EVENT_EFFECTS, ...VIEWMODEL_EFFECTS, ...VEHICLE_EFFECTS].map((effect) => [effect.id, effect])) }\n\n/** A copy of the recipes with some changed (a partial replaces the fields it names), added or removed (`null`); a game tunes the Workshop's effects without touching the core. */\nexport function patchEffects(base: Readonly<Record<string, EffectDef>>, changes: Readonly<Record<string, Partial<EffectDef> | EffectDef | null>>): Record<string, EffectDef> {\n const result: Record<string, EffectDef> = { ...base }\n for (const [id, change] of Object.entries(changes)) {\n if (change === null) delete result[id]\n else result[id] = { ...(base[id] ?? {}), ...change, id } as EffectDef\n }\n return result\n}\n","const LEHMER_MULTIPLIER = 16807\nconst LEHMER_MODULUS = 2147483647\nconst LCG_MULTIPLIER = 1664525\nconst LCG_INCREMENT = 1013904223\nconst LCG_RANGE = 4294967296\nconst HASH_MIX = 0x9e3779b1\n\nexport interface MutableVec3 {\n x: number\n y: number\n z: number\n}\n\n/** A seeded stream of numbers in [0, 1). The Lab's generator and the Fluid Standard's are both here, behind the same three calls. */\nexport interface RandomStream {\n /** The next number (the Lab's `rnd`). */\n next(): number\n /** The Lab's `rr(min, max)`: one draw, scaled. */\n between(min: number, max: number): number\n /** The Lab's `rdir`: a random unit vector, two draws (`u`, then the angle), written into `out`. */\n direction(out: MutableVec3): MutableVec3\n readonly state: number\n}\n\nfunction normalizeLehmerSeed(seed: number): number {\n const whole = Math.floor(Math.abs(seed)) % (LEHMER_MODULUS - 1)\n return whole === 0 ? 1 : whole\n}\n\n/** Park-Miller 16807 (the Lab's L16-18). A seed in 1..2147483646 is used as is, so a stream replays the page's. */\nexport function lehmer(seed: number): RandomStream {\n let state = normalizeLehmerSeed(seed)\n const next = (): number => {\n state = (state * LEHMER_MULTIPLIER) % LEHMER_MODULUS\n return (state - 1) / (LEHMER_MODULUS - 1)\n }\n return {\n next,\n between: (min, max) => min + (max - min) * next(),\n direction(out) {\n const up = next() * 2 - 1\n const angle = next() * Math.PI * 2\n const ring = Math.sqrt(1 - up * up)\n out.x = ring * Math.cos(angle)\n out.y = up\n out.z = ring * Math.sin(angle)\n return out\n },\n get state() {\n return state\n },\n }\n}\n\n/** The Fluid Standard's generator (F17-18): a 32-bit linear congruential one. */\nexport function lcg(seed: number): RandomStream {\n let state = seed >>> 0\n const next = (): number => {\n state = (Math.imul(state, LCG_MULTIPLIER) + LCG_INCREMENT) >>> 0\n return state / LCG_RANGE\n }\n return {\n next,\n between: (min, max) => min + (max - min) * next(),\n direction(out) {\n const up = next() * 2 - 1\n const angle = next() * Math.PI * 2\n const ring = Math.sqrt(1 - up * up)\n out.x = ring * Math.cos(angle)\n out.y = up\n out.z = ring * Math.sin(angle)\n return out\n },\n get state() {\n return state\n },\n }\n}\n\nfunction mixEventSeed(eventSeed: number): number {\n let mixed = Math.imul((eventSeed | 0) ^ HASH_MIX, 0x85ebca6b)\n mixed ^= mixed >>> 13\n mixed = Math.imul(mixed, 0xc2b2ae35)\n mixed ^= mixed >>> 16\n return (mixed >>> 0) % (LEHMER_MODULUS - 1) + 1\n}\n\n/** The stream of one event: the same event seed draws the same effect on every machine, whatever else is playing (`randomMode: 'per_event'`). */\nexport function streamFor(eventSeed: number): RandomStream {\n return lehmer(mixEventSeed(eventSeed))\n}\n","import type { ImpactMaterial } from './blood'\n\n/** What each material raises when hit: dust colour, chip colour and the number of sparks (W374-381). Zero means none. */\nconst TABLE: Readonly<Record<ImpactMaterial, { readonly dust: number; readonly chip: number; readonly spark: number }>> = {\n concrete: { dust: 0x8a857a, chip: 0x6e6a63, spark: 2 },\n metal: { dust: 0, chip: 0, spark: 18 },\n wood: { dust: 0x6a5038, chip: 0x7a5530, spark: 0 },\n glass: { dust: 0xbfd6e2, chip: 0xa8c8d8, spark: 0 },\n flesh: { dust: 0, chip: 0, spark: 0 },\n water: { dust: 0, chip: 0, spark: 0 },\n}\n\nexport function sparkSpec(material: ImpactMaterial): { readonly dust: number; readonly chip: number; readonly spark: number } {\n return TABLE[material]\n}\n","import type { WorkshopEngine } from '../../workshop/engine'\nimport type { Vec3Tuple } from '../../workshop/types'\nimport { negated, plus, plusScaled } from '../vector-math'\nimport { sparkSpec } from './impact-table'\n\n/** The blood colour of each infection age (W116) and how much each bleeds (W392). */\nexport const BLOOD_COLORS = [0x8a0a0a, 0x5a0c10, 0x3a1c12, 0x1d1914] as const\nconst BLEED_BY_AGE = [1, 0.7, 0.35, 0.1] as const\n\n/** The dust and dry flakes a decrepit body gives instead of blood. */\nfunction drySplash(engine: WorkshopEngine, point: Vec3Tuple, exitDirection: Vec3Tuple, scale: number): void {\n engine.burst('normal', 16 * scale, { p: point, dir: exitDirection, cone: 1, sp: [0.5, 1.6], drag: 2, life: [0.9, 1.6], size: [0.1, 0.2], grow: 4, c0: 0x2e2822, c1: 0x15130f, a: 0.6, g: -0.15 })\n for (let index = 0; index < engine.scaled(5); index++) engine.debrisPiece({ p: point, dir: exitDirection, cone: 1, sp: [0.5, 2], size: [0.03, 0.008, 0.03], c: 0x1c1916, life: 6 })\n engine.decal([point[0], 0, point[2] + exitDirection[2] * 0.6, 0.25, 0x1a1714, { grow: 0.4, ar: 0.7 }])\n}\n\n/** `bloodHit` (W392-398): a mist at the entry, a jet out of the exit and a cloud, by infection age. */\nexport function bloodHit(engine: WorkshopEngine, point: Vec3Tuple, exitDirection: Vec3Tuple, age: number, scale = 1): void {\n if (age === 3) return drySplash(engine, point, exitDirection, scale)\n const amount = BLEED_BY_AGE[age]!\n const color = BLOOD_COLORS[age]!\n engine.burst('normal', 10 * amount * scale, { p: point, dir: negated(exitDirection), cone: 0.9, sp: [0.2, 0.9], drag: 3, life: [0.25, 0.5], size: [0.08, 0.14], grow: 3, c0: color, a: 0.65 })\n engine.burst('normal', 45 * amount * scale, { p: point, dir: exitDirection, cone: 0.45, sp: [2.5, 6], life: [1, 1.6], size: [0.035, 0.07], c0: color, a: 0.95, g: 9.8, fi: 0, gnd: 3, ds: [0.06, 0.16] })\n engine.burst('normal', 14 * amount * scale, { p: point, dir: exitDirection, cone: 0.5, sp: [1, 2.5], drag: 2.5, life: [0.4, 0.8], size: [0.1, 0.18], grow: 3, c0: color, a: 0.45 })\n}\n\nconst MATERIAL_NAMES = ['concrete', 'metal', 'wood', 'glass', 'flesh', 'water'] as const\nexport type ImpactMaterial = (typeof MATERIAL_NAMES)[number]\n\nfunction waterImpact(engine: WorkshopEngine, point: Vec3Tuple, scale: number): void {\n engine.burst('normal', 22 * scale, { p: point, dir: [0, 1, 0], cone: 0.5, sp: [1.5, 3.5], life: [0.4, 0.7], size: [0.03, 0.06], c0: 0xc8d6e6, a: 0.7, g: 9.8, fi: 0, gnd: 1 })\n engine.ring([plus(point, 0, 0.012, 0), 0.02, 0.6, 0.7, 0x8090a8])\n engine.ring([plus(point, 0, 0.013, 0), 0.02, 0.35, 0.5, 0x8090a8])\n}\n\n/** `impact` (W374-391): what a bullet raises on each material. */\nexport function impact(engine: WorkshopEngine, material: ImpactMaterial, point: Vec3Tuple, normal: Vec3Tuple, scale = 1, age = 0): void {\n if (material === 'flesh') return bloodHit(engine, point, negated(normal), age, scale)\n if (material === 'water') return waterImpact(engine, point, scale)\n const spec = sparkSpec(material)\n if (spec.dust) engine.burst('normal', 14 * scale, { p: point, dir: normal, cone: 0.6, sp: [0.6, 2.4], drag: 2.5, life: [0.6, 1.2], size: [0.08, 0.16], grow: 4, c0: spec.dust, c1: 0x3a3936, a: 0.55, g: -0.1 })\n if (spec.chip) {\n const size = material === 'wood' ? ([0.015, 0.015, 0.09] as const) : material === 'glass' ? ([0.03, 0.004, 0.03] as const) : ([0.03, 0.03, 0.03] as const)\n for (let index = 0; index < engine.scaled(material === 'wood' ? 8 : 6) * scale; index++) {\n engine.debrisPiece({ p: point, dir: normal, cone: 0.8, sp: [1.5, 4], size, k: [0.6, 1.4], c: spec.chip, life: 6 })\n }\n }\n if (spec.spark && engine.quality < 2) {\n engine.burst('streak', spec.spark * scale, { p: point, dir: normal, cone: material === 'metal' ? 0.9 : 0.5, sp: [3, 9], life: [0.15, 0.45], len: 0.025, c0: 0xfff0c0, c1: 0xff5a10, g: 9.8, gnd: 2 })\n engine.burst('add', material === 'metal' ? 3 : 1, { p: point, size: [0.12, 0.2], life: 0.06, c0: 0xffe0a0, fi: 0 })\n if (material === 'metal') engine.flash([plusScaled(point, normal, 0.2), 0xffb060, 2, 0.06, 5])\n }\n if (material === 'glass') engine.burst('add', 5, { p: point, r: 0.15, size: [0.02, 0.05], life: [0.2, 0.5], c0: 0xffffff, a: 0.9, fi: 0.3 })\n if (engine.quality < 2) {\n const size = material === 'glass' ? 0.07 : material === 'metal' ? 0.05 : 0.06\n engine.decal([point[0], point[1], point[2], size, material === 'metal' ? 0x2a2522 : 0x0e0d0c, { n: normal, grow: 0, life: 60 }])\n }\n}\n\nexport function impactMaterialAt(index: number): ImpactMaterial {\n return MATERIAL_NAMES[index]!\n}\n","import { impact } from '../builders/blood'\nimport type { Behavior } from '../behavior'\n\nconst COLUMNS = 6\nconst ROWS = 5\nconst ORIGIN = [-2.2, 0, 2.6] as const\nconst BLOCK_SIZE = [0.5, 0.44, 0.25] as const\nconst OBJECT_ID_DRAWS = 4\nconst FLOOR = 0.13\nconst QUARTER_TURN = 1.5708\n\ninterface Motion {\n vx: number\n vy: number\n vz: number\n wx: number\n wy: number\n wz: number\n rest: boolean\n}\n\nexport interface WallBlock {\n readonly home: readonly [number, number]\n x: number\n y: number\n rotation: [number, number, number]\n /** Bullet holes stuck to this block (local to the block). */\n holes: { x: number; y: number; scale: number; chipTurn: number; chipScale: number }[]\n motion: Motion | undefined\n}\n\nconst clamp = (value: number, low: number, high: number): number => (value < low ? low : value > high ? high : value)\n\nfunction createBlocks(): WallBlock[] {\n const blocks: WallBlock[] = []\n for (let row = 0; row < ROWS; row++) {\n for (let column = 0; column < COLUMNS; column++) {\n const home = [(column - 2.5) * BLOCK_SIZE[0] + (row % 2 ? 0.12 : 0), 0.22 + row * BLOCK_SIZE[1]] as const\n blocks.push({ home, x: home[0], y: home[1], rotation: [0, 0, 0], holes: [], motion: undefined })\n }\n }\n return blocks\n}\n\n/**\n * The free-standing wall of 30 blocks of the page (W926-935, W1039-1046): a bullet leaves a hole and a chip stuck to the nearest block (`bwHit`, which\n * also costs the page the ids three.js gives each new mesh), and when it gives way the blocks fall with the velocities the page draws for them and\n * rest on their sides. The holes travel with the blocks, which is the point of the effect.\n */\nexport function createBlocksBehavior(): Behavior {\n let blocks = createBlocks()\n return {\n reset() {\n blocks = createBlocks()\n },\n act(host, action, args) {\n const random = host.engine.random\n if (action === 'hit') {\n const { x, y, scale } = args as { readonly x: number; readonly y: number; readonly scale: number }\n let best: WallBlock | undefined\n let bestDistance = 9\n for (const block of blocks) {\n const distance = Math.hypot(block.x - x, block.y - y)\n if (distance < bestDistance) {\n bestDistance = distance\n best = block\n }\n }\n if (!best) return\n const offsetX = clamp(x - best.x, -0.2, 0.2)\n const offsetY = clamp(y - best.y, -0.17, 0.17)\n for (let draw = 0; draw < OBJECT_ID_DRAWS; draw++) random.next()\n const chipTurn = random.between(0, 6)\n const chipScale = random.between(0.8, 1.3) * scale\n for (let draw = 0; draw < OBJECT_ID_DRAWS; draw++) random.next()\n best.holes.push({ x: offsetX, y: offsetY, scale, chipTurn, chipScale })\n impact(host.engine, 'concrete', [ORIGIN[0] + x, y, ORIGIN[2] + 0.13], [0, 0, 1], 0.8)\n } else if (action === 'collapse') {\n const { x, y } = args as { readonly x: number; readonly y: number }\n for (const block of blocks) {\n const dx = block.x - x\n const dy = block.y - y\n block.motion = {\n vx: dx * random.between(0.8, 2),\n vy: random.between(0.5, 2.5) + dy * 0.5,\n vz: random.between(-2.2, -0.4),\n wx: random.between(-4, 4),\n wy: random.between(-3, 3),\n wz: random.between(-4, 4),\n rest: false,\n }\n }\n }\n },\n query(_host, name) {\n if (name === 'blocks') return blocks\n throw new Error(`blocks: unknown query ${name}`)\n },\n update(_host, dt) {\n for (const block of blocks) {\n const motion = block.motion\n if (!motion || motion.rest) continue\n motion.vy -= 9.8 * dt\n block.x += motion.vx * dt\n block.y += motion.vy * dt\n block.rotation[0] += motion.wx * dt\n block.rotation[1] += motion.wy * dt\n block.rotation[2] += motion.wz * dt\n if (block.y < FLOOR) {\n block.y = FLOOR\n motion.vy *= -0.25\n motion.vx *= 0.5\n motion.vz *= 0.5\n motion.wx *= 0.5\n motion.wy *= 0.5\n motion.wz *= 0.5\n if (Math.abs(motion.vy) < 0.4 && Math.hypot(motion.vx, motion.vz) < 0.3) {\n motion.rest = true\n block.rotation[0] = Math.round(block.rotation[0] / QUARTER_TURN) * QUARTER_TURN\n block.rotation[2] = Math.round(block.rotation[2] / QUARTER_TURN) * QUARTER_TURN\n }\n }\n }\n },\n }\n}\n","import type { Behavior } from '../behavior'\nimport { carPoint } from '../vehicles/car'\nimport type { Vec3Tuple } from '../../workshop/types'\n\nconst ORIGIN: Vec3Tuple = [5.6, 0, 0.8]\nconst MAX_TILT = 0.25\n\n/**\n * The car of the page after it blew up (`carTick`, W1131): it leaps, spins and lands crooked. Its height is what the burning wreck's fire is emitted\n * from, so the model keeps it; the body is drawn by whoever owns the car.\n */\nexport function createCarBehavior(): Behavior {\n let y = 0\n let rise: number | undefined\n let spin = 0\n let roll = 0\n return {\n reset() {\n y = 0\n rise = undefined\n spin = 0\n roll = 0\n },\n act(_host, action, args) {\n if (action === 'launch') {\n const launch = args as { readonly rise: number; readonly spin: number }\n rise = launch.rise\n spin = launch.spin\n } else if (action === 'step') {\n if (rise === undefined) return\n const dt = (args as { readonly dt: number }).dt\n rise -= 9.8 * dt\n y = Math.max(0, y + rise * dt)\n roll += spin * dt\n spin *= Math.exp(-dt * 2)\n if (y === 0 && rise < 0) {\n rise = undefined\n roll = Math.min(MAX_TILT, Math.max(-MAX_TILT, roll))\n }\n }\n },\n query(_host, name, args) {\n if (name === 'position') return [ORIGIN[0], y, ORIGIN[2]]\n // `carW(x, y, z)` (W104): a point of the car's own space in the world, with the car where it is now\n if (name === 'point') {\n const [x, py, z] = args as readonly [number, number, number]\n const point = carPoint(x, py, z)\n return [point[0], point[1] + y, point[2]]\n }\n if (name === 'roll') return roll\n throw new Error(`car: unknown query ${name}`)\n },\n update() {},\n }\n}\n","import type { Behavior } from '../behavior'\n\n/** A smear of blood that runs down the windshield from a hit (`wsMarks`, W1156). */\nexport interface BloodStreak {\n readonly x: number\n readonly y: number\n readonly dx: number\n readonly dy: number\n readonly width: number\n}\n\nexport interface Crack {\n readonly x: number\n readonly y: number\n /** Each ray is a list of `[dx, dy]` segments that start at the impact. */\n readonly rays: readonly (readonly (readonly [number, number])[])[]\n readonly rings: readonly number[]\n}\n\nconst FULL_TURN_ROUNDED = 6.28\nconst SHORT_RAYS = 7\nconst LONG_RAYS = 12\nconst STREAKS_PER_HIT = 5\n\n/** `crackAt` (W62-63): the star of cracks a hit leaves in glass. Its draws depend on the lengths it draws, so the model keeps the same loop. */\nexport function createCracksBehavior(): Behavior {\n let cracks: Crack[] = []\n let streaks: BloodStreak[][] = []\n return {\n reset() {\n cracks = []\n streaks = []\n },\n act(host, action, args) {\n if (action === 'blood_streaks') {\n const { x, y } = args as { readonly x: number; readonly y: number }\n const random = host.engine.random\n const group: BloodStreak[] = []\n for (let index = 0; index < STREAKS_PER_HIT; index++) {\n group.push({ x: x - 18 + index * 8, y: y - 10, dx: random.between(-3, 3), dy: random.between(18, 40), width: random.between(5, 9) })\n }\n streaks.push(group)\n return\n }\n if (action !== 'crack') return\n const { x, y, big } = args as { readonly x: number; readonly y: number; readonly big: boolean }\n const random = host.engine.random\n const count = big ? LONG_RAYS : SHORT_RAYS\n const rays: [number, number][][] = []\n for (let ray = 0; ray < count; ray++) {\n let angle = (ray / count) * FULL_TURN_ROUNDED + random.between(-0.3, 0.3)\n const segments: [number, number][] = []\n let remaining = big ? random.between(40, 110) : random.between(15, 45)\n while (remaining > 0) {\n const length = random.between(6, 14)\n angle += random.between(-0.35, 0.35)\n segments.push([Math.cos(angle) * length, Math.sin(angle) * length])\n remaining -= length\n }\n rays.push(segments)\n }\n cracks.push({ x, y, rays, rings: big ? [12, 26] : [8] })\n },\n query(_host, name) {\n if (name === 'cracks') return cracks\n if (name === 'streaks') return streaks\n throw new Error(`cracks: unknown query ${name}`)\n },\n update() {},\n }\n}\n","import type { WorkshopEngine } from '../../workshop/engine'\nimport type { Vec3Tuple } from '../../workshop/types'\n\n/** Wood chips and a puff of dust (`chips`, W849). */\nexport function chips(engine: WorkshopEngine, point: Vec3Tuple, direction: Vec3Tuple, count: number, spread?: number): void {\n for (let index = 0; index < engine.scaled(count); index++) {\n engine.debrisPiece({ p: point, dir: direction, cone: spread || 0.9, sp: [1, 3], size: [0.012, 0.012, 0.09], k: [0.6, 1.4], c: 0xb08a5a, life: 20 })\n }\n engine.burst('normal', count, { p: point, dir: direction, cone: 0.8, sp: [0.3, 1.2], drag: 2, life: [0.8, 1.4], size: [0.08, 0.15], grow: 3, c0: 0x7a6048, a: 0.4 })\n}\n\n/** Sparks off metal (`sparkAt`, W899). */\nexport function sparkAt(engine: WorkshopEngine, point: Vec3Tuple, direction: Vec3Tuple, count: number, spread?: number): void {\n engine.burst('streak', count, { p: point, dir: direction, cone: spread || 0.8, sp: [2.5, 7], life: [0.2, 0.5], len: 0.025, c0: 0xfff0c0, c1: 0xff5010, g: 9.8, gnd: 2 })\n engine.burst('add', 2, { p: point, size: [0.1, 0.18], life: 0.06, c0: 0xffd8a0, fi: 0 })\n}\n\n/** Rust flakes and a little dust (`rustAt`, W900). */\nexport function rustAt(engine: WorkshopEngine, point: Vec3Tuple, count: number): void {\n engine.burst('normal', count, { p: point, r: 0.1, sp: [0.1, 0.5], life: [1, 1.6], size: [0.02, 0.035], c0: 0x7a4a2a, a: 0.9, g: 6, fi: 0, gnd: 1 })\n engine.burst('normal', Math.ceil(count / 2), { p: point, r: 0.08, sp: [0.2, 0.5], drag: 2, life: [0.8, 1.3], size: [0.08, 0.14], grow: 3, c0: 0x6a4a34, a: 0.3 })\n}\n","import type { Behavior, BehaviorHost } from '../behavior'\nimport { sparkAt } from '../builders/shared'\nimport { normalized } from '../vector-math'\nimport type { Vec3Tuple } from '../../workshop/types'\n\nconst SPOT: Vec3Tuple = [-2.2, 0, 2.6]\nconst WALL_X = -8.2\nconst QUARTER_TURN = Math.PI / 2\n\nconst lerp = (from: number, to: number, amount: number): number => from + (to - from) * amount\nconst clamp = (value: number, low: number, high: number): number => (value < low ? low : value > high ? high : value)\n\n/**\n * The pressure cylinder of the page (W1021-1038): an extinguisher that spins on the floor pushed by its own jet, or an oxygen bottle that becomes a\n * rocket and hits the wall. `step` moves it the way the page's tick does, drawing the sparks of the wall hit; the recipe then asks where the jet comes\n * out (`tip`, `back`, `direction`) to emit it.\n */\nexport function createCylinderBehavior(): Behavior {\n let position: Vec3Tuple = SPOT\n let velocity: Vec3Tuple = [0, 0, 0]\n let rotationZ = 0\n let angle = 0\n let spin = 0\n let live = false\n let oxygen = false\n let direction: Vec3Tuple = [1, 0, 0]\n\n const clear = (): void => {\n position = SPOT\n velocity = [0, 0, 0]\n rotationZ = 0\n angle = 0\n spin = 0\n live = false\n direction = [1, 0, 0]\n }\n\n return {\n reset: clear,\n act(host: BehaviorHost, action: string, args: unknown) {\n if (action === 'choose') {\n clear()\n oxygen = (args as { readonly oxygen: boolean }).oxygen\n } else if (action === 'puncture') {\n live = true\n if (oxygen) velocity = [-5, 0, -0.3]\n else spin = 9\n } else if (action === 'step') {\n if (!live) return\n const { dt, t } = args as { readonly dt: number; readonly t: number }\n const k = clamp(1 - (t - 0.6) / 3.4, 0, 1)\n if (!oxygen) {\n rotationZ = lerp(rotationZ, QUARTER_TURN, dt * 8)\n const y = lerp(position[1], 0.09, dt * 8)\n angle += spin * k * dt\n direction = [Math.cos(angle), 0, -Math.sin(angle)]\n position = [position[0] + direction[0] * (-0.6 * k * dt), y + direction[1] * (-0.6 * k * dt), position[2] + direction[2] * (-0.6 * k * dt)]\n return\n }\n let [vx, vy, vz] = velocity\n if (k > 0) vx -= 4 * k * dt\n const damping = Math.exp(-dt * (k > 0 ? 0.3 : 3))\n vx *= damping\n vy *= damping\n vz *= damping\n velocity = [vx, vy, vz]\n rotationZ = lerp(rotationZ, -QUARTER_TURN, dt * 10)\n position = [position[0] + vx * dt, lerp(position[1], 0.12, dt * 10) + vy * dt, position[2] + vz * dt]\n if (position[0] < WALL_X) {\n position = [WALL_X, position[1], position[2]]\n velocity = [velocity[0] * -0.3, velocity[1], velocity[2]]\n host.engine.screen.shake += 0.08\n sparkAt(host.engine, position, normalized([1, 0.5, 0]), 16, 1)\n }\n }\n },\n query(_host, name) {\n switch (name) {\n case 'live': return live\n case 'oxygen': return oxygen\n case 'position': return position\n case 'direction': return direction\n case 'speed_x': return velocity[0]\n case 'rotation_z': return rotationZ\n case 'tip': return [position[0] + direction[0] * 0.3, 0.1, position[2] + direction[2] * 0.3]\n case 'back': return [position[0] + 1.1, position[1], position[2]]\n default: throw new Error(`cylinder: unknown query ${name}`)\n }\n },\n update() {},\n }\n}\n","import type { Behavior } from '../behavior'\n\n/** The geometry of a box plate as three.js lays out its vertices: `BoxGeometry(width, height, depth, columns, rows, 1)` moved by `(shiftX, shiftY)`. */\nexport interface PlateGeometry {\n readonly width: number\n readonly height: number\n readonly columns: number\n readonly rows: number\n readonly shiftX: number\n readonly shiftY: number\n}\n\n/** The metal door of the page: 1.1 x 2.2 m, 14 x 24 segments, hinged at its left edge (W960). */\nexport const METAL_DOOR: PlateGeometry = { width: 1.1, height: 2.2, columns: 14, rows: 24, shiftX: 0.56, shiftY: 1.1 }\n\n/** Every vertex of the plate seen from the front (x, y), the front and back faces and the four thin edges, each vertex once per face it belongs to. */\nexport function plateVertices(geometry: PlateGeometry): readonly (readonly [number, number])[] {\n const { width, height, columns, rows, shiftX, shiftY } = geometry\n const xs = Array.from({ length: columns + 1 }, (_, column) => (column * width) / columns - width / 2)\n const ys = Array.from({ length: rows + 1 }, (_, row) => (row * height) / rows - height / 2)\n const vertices: [number, number][] = []\n // the sides (px, nx): two vertices, front and back, for each row; then top and bottom (py, ny): the same for each column; then the two big faces\n for (const x of [width / 2, -width / 2]) for (const y of ys) for (let depth = 0; depth < 2; depth++) vertices.push([x, y])\n for (const y of [height / 2, -height / 2]) for (const x of xs) for (let depth = 0; depth < 2; depth++) vertices.push([x, y])\n for (let face = 0; face < 2; face++) for (const y of ys) for (const x of xs) vertices.push([x, y])\n return vertices.map(([x, y]) => [x + shiftX, y + shiftY] as const)\n}\n\ninterface DentArgs {\n readonly x: number\n readonly y: number\n readonly radius: number\n readonly depth: number\n}\n\n/**\n * `dentAt` (W1002): pushes the vertices within `radius` of a hit in and draws one random number for each, so how many it draws depends on how the plate\n * is cut. The model counts them; the deformed mesh belongs to whoever draws the door.\n */\nlet doorVertices: ReturnType<typeof plateVertices> | undefined\n\nexport function createPlateBehavior(geometry: PlateGeometry = METAL_DOOR): Behavior {\n const vertices = geometry === METAL_DOOR ? (doorVertices ??= plateVertices(geometry)) : plateVertices(geometry)\n let dents: { x: number; y: number; radius: number; depth: number; vertices: number }[] = []\n return {\n reset() {\n dents = []\n },\n act(host, action, args) {\n if (action !== 'dent') return\n const { x, y, radius, depth } = args as DentArgs\n let touched = 0\n for (const [vertexX, vertexY] of vertices) {\n if (Math.hypot(vertexX - x, vertexY - y) < radius) {\n host.engine.random.next()\n touched++\n }\n }\n dents.push({ x, y, radius, depth, vertices: touched })\n },\n query(_host, name) {\n if (name === 'dents') return dents\n throw new Error(`plate: unknown query ${name}`)\n },\n update() {},\n }\n}\n","import type { Behavior, BehaviorHost } from '../behavior'\n\ninterface InitArgs { readonly count: number; readonly wind: number }\ninterface UpdateArgs { readonly dt: number; readonly splash: boolean }\n\n/**\n * The page's rain (`initRain` and `updateRain`, W321-331) as a prop an effect starts and ticks: `init` fills the box with streaks, `update` moves them and\n * leaves the splashes. The field itself lives in the engine (`engine.rain`), where the renderer reads it; the weather package drives the same field.\n */\nexport function createRainBehavior(): Behavior {\n return {\n reset() {},\n act(host: BehaviorHost, action: string, args: unknown) {\n const { engine, camera } = host\n if (action === 'init') {\n const { count, wind } = args as InitArgs\n engine.rain.init(count, wind)\n } else if (action === 'update') {\n const { dt, splash } = args as UpdateArgs\n engine.rain.update(dt, splash, camera.position)\n }\n },\n query(host, name) {\n if (name === 'count') return host.engine.rain.count\n if (name === 'on') return host.engine.rain.on\n throw new Error(`rain: unknown query ${name}`)\n },\n update() {},\n }\n}\n","import type { Behavior } from '../behavior'\n\nconst WALKER_COUNT = 10\nconst ARRIVAL_DISTANCE = 0.05\nconst SWAY_AMPLITUDE = 0.04\nconst BOB_AMPLITUDE = 0.04\nconst STRIDE_FACTOR = 4.5\n\n/**\n * The `ph` of each walker, the offset of its sway and stride. The page drew them at load (`Math.random() * 6`) after three.js had drawn a few hundred\n * numbers for object ids, so they cannot be replayed; the three that matter (the runners with red eyes, whose trails start at the eyes) were fitted to\n * the recording until every position matched to four decimals. The others only turn a zombie nobody reads.\n */\nconst PHASES = [0, 0, 3.59629, 0, 0, 0, 2.946505, 0, 0, 0, 2.44693] as const\n\ninterface Walker {\n x: number\n z: number\n facing: number\n bob: number\n sway: number\n walk: { toX: number; toZ: number; speed: number } | undefined\n}\n\nfunction createWalkers(): Walker[] {\n return Array.from({ length: WALKER_COUNT }, () => ({ x: 0, z: 0, facing: 0, bob: 0, sway: 0, walk: undefined }))\n}\n\ninterface PlaceArgs { readonly index: number; readonly x: number; readonly z: number; readonly facing: number }\ninterface WalkArgs { readonly index: number; readonly to: readonly [number, number, number]; readonly speed: number }\ninterface MoveArgs { readonly index: number; readonly x: number }\n\n/**\n * The ten walking zombies of the page (W151, W190-197): they walk to a point at a speed, face where they go, bob with each stride and sway. An effect\n * reads where their eyes are (`point`) to start a trail from them. Phases are the page's, so the sway and bob repeat to the last digit.\n */\nexport function createWalkersBehavior(phases: readonly number[] = PHASES): Behavior {\n let walkers = createWalkers()\n return {\n reset() {\n walkers = createWalkers()\n },\n act(_host, action, args) {\n if (action === 'place') {\n const { index, x, z, facing } = args as PlaceArgs\n Object.assign(walkers[index]!, { x, z, facing })\n } else if (action === 'walk') {\n const { index, to, speed } = args as WalkArgs\n walkers[index]!.walk = { toX: to[0], toZ: to[2], speed }\n } else if (action === 'move_x') {\n const { index, x } = args as MoveArgs\n walkers[index]!.x = x\n }\n },\n query(_host, name, args) {\n const walker = walkers[args[0] as number]!\n if (name === 'x') return walker.x\n if (name === 'z') return walker.z\n if (name === 'is_walking') return walker.walk !== undefined\n if (name !== 'point') throw new Error(`walkers: unknown query ${name}`)\n const [localX, localY, localZ] = args[1] as readonly [number, number, number]\n const swayedX = Math.cos(walker.sway) * localX - Math.sin(walker.sway) * localY\n const swayedY = Math.sin(walker.sway) * localX + Math.cos(walker.sway) * localY + walker.bob\n return [Math.cos(walker.facing) * swayedX + Math.sin(walker.facing) * localZ + walker.x, swayedY, -Math.sin(walker.facing) * swayedX + Math.cos(walker.facing) * localZ + walker.z]\n },\n update(_host, dt, elapsed) {\n walkers.forEach((walker, index) => {\n walker.sway = Math.sin(elapsed * 1.3 + phases[index + 1]!) * SWAY_AMPLITUDE\n const walk = walker.walk\n if (!walk) return\n const dx = walk.toX - walker.x\n const dz = walk.toZ - walker.z\n const distance = Math.hypot(dx, dz)\n if (distance <= ARRIVAL_DISTANCE) {\n walker.walk = undefined\n return\n }\n const step = Math.min(distance, walk.speed * dt)\n walker.x += (dx / distance) * step\n walker.z += (dz / distance) * step\n walker.facing = Math.atan2(dx, dz)\n walker.bob = Math.abs(Math.cos(elapsed * walk.speed * STRIDE_FACTOR + phases[index + 1]!)) * BOB_AMPLITUDE\n })\n },\n}\n}\n","import type { Behavior } from './behavior'\nimport { createBlocksBehavior } from './behaviors/blocks'\nimport { createCarBehavior } from './behaviors/car'\nimport { createCracksBehavior } from './behaviors/cracks'\nimport { createCylinderBehavior } from './behaviors/cylinder'\nimport { createPlateBehavior } from './behaviors/plate'\nimport { createRainBehavior } from './behaviors/rain'\nimport { createWalkersBehavior } from './behaviors/walkers'\n\n/** How to build each prop the Workshop animates by hand, by id (see `Behavior`). A game adds its own the same way. */\nexport const WORKSHOP_BEHAVIORS: Readonly<Record<string, () => Behavior>> = {\n walkers: () => createWalkersBehavior(),\n cracks: () => createCracksBehavior(),\n blocks: () => createBlocksBehavior(),\n plate: () => createPlateBehavior(),\n cylinder: () => createCylinderBehavior(),\n car: () => createCarBehavior(),\n rain: () => createRainBehavior(),\n}\n\n/** A fresh set of the props the Workshop animates by hand, by id; one per runner, since they keep state. */\nexport function createWorkshopBehaviors(factories: Readonly<Record<string, () => Behavior>> = WORKSHOP_BEHAVIORS): Record<string, Behavior> {\n return Object.fromEntries(Object.entries(factories).map(([id, make]) => [id, make()]))\n}\n","export interface Schedule {\n /** Runs `action` once `now` reaches `time`. */\n at(time: number, action: () => void): void\n /** Runs what is due at `now`, from the last one added to the first (the Lab's L1085 and the Workshop's W1280 walk the list backwards, and so does this). */\n update(now: number): void\n clear(): void\n readonly pending: number\n}\n\ninterface Entry {\n time: number\n action: () => void\n}\n\nconst NOOP = (): void => {}\n\nexport function createSchedule(): Schedule {\n const entries: Entry[] = []\n const spare: Entry[] = []\n return {\n at(time, action) {\n const entry = spare.pop() ?? { time: 0, action: NOOP }\n entry.time = time\n entry.action = action\n entries.push(entry)\n },\n update(now) {\n for (let index = entries.length - 1; index >= 0; index--) {\n const entry = entries[index]\n if (!entry || entry.time > now) continue\n const action = entry.action\n entries.splice(index, 1)\n entry.action = NOOP\n spare.push(entry)\n action()\n }\n },\n clear() {\n for (const entry of entries) {\n entry.action = NOOP\n spare.push(entry)\n }\n entries.length = 0\n },\n get pending() {\n return entries.length\n },\n }\n}\n","import type { RandomStream } from '../random'\nimport { normalized } from './vector-math'\n\n/** A value an effect computes: a number, a flag, a name or a vector. */\nexport type EffectValue = number | boolean | string | readonly number[]\n\n/** A computed field of a recipe. Plain data: `{ $: 'add', a: [1, { $: 't' }] }`. Built with the helpers in `dsl.ts`. */\nexport interface Expr {\n readonly $: string\n readonly a?: readonly unknown[]\n}\n\nexport interface ExprContext {\n readonly random: RandomStream\n readonly param: number\n readonly time: number\n readonly dt: number\n readonly index: number\n readonly variables: ReadonlyMap<string, unknown>\n readonly scaled: (count: number) => number\n readonly quality: number\n /** True on the first run after the effect was chosen, false on its repeats (the page's `fresh`). */\n readonly fresh: boolean\n /** Which way the played effect points and which surface it hit, in the world (`play`'s `direction` and `normal`). */\n readonly direction: readonly number[]\n readonly normal: readonly number[]\n readonly query: (behavior: string, name: string, args: readonly unknown[]) => unknown\n readonly camera: { readonly position: readonly number[]; readonly forward: (local: readonly number[]) => readonly number[] }\n}\n\nexport function isExpr(value: unknown): value is Expr {\n return typeof value === 'object' && value !== null && !Array.isArray(value) && '$' in value\n}\n\ntype Vector = readonly number[]\nconst asNumber = (value: unknown): number => value as number\nconst asVector = (value: unknown): Vector => value as Vector\nconst EASE_LIMIT = 1\n\nfunction ease(value: number): number {\n return value < 0 ? 0 : value > EASE_LIMIT ? EASE_LIMIT : value * value * (3 - 2 * value)\n}\n\nfunction reduceVectors(operands: readonly unknown[], combine: (accumulated: number, next: number) => number): Vector {\n const [first, ...rest] = operands.map(asVector)\n return rest.reduce<Vector>((total, next) => [combine(total[0]!, next[0]!), combine(total[1]!, next[1]!), combine(total[2]!, next[2]!)], first!)\n}\n\nfunction evaluateCall(name: string, args: readonly unknown[]): unknown {\n const [first, second, third] = args\n switch (name) {\n case 'concat': return args.map(String).join('')\n case 'add': return args.reduce<number>((total, next) => total + asNumber(next), 0)\n case 'sub': return asNumber(first) - asNumber(second)\n case 'mul': return args.reduce<number>((total, next) => total * asNumber(next), 1)\n case 'div': return asNumber(first) / asNumber(second)\n case 'mod': return asNumber(first) % asNumber(second)\n case 'neg': return -asNumber(first)\n case 'abs': return Math.abs(asNumber(first))\n case 'sqrt': return Math.sqrt(asNumber(first))\n case 'exp': return Math.exp(asNumber(first))\n case 'sin': return Math.sin(asNumber(first))\n case 'cos': return Math.cos(asNumber(first))\n case 'atan2': return Math.atan2(asNumber(first), asNumber(second))\n case 'min': return Math.min(...args.map(asNumber))\n case 'max': return Math.max(...args.map(asNumber))\n case 'floor': return Math.floor(asNumber(first))\n case 'ceil': return Math.ceil(asNumber(first))\n case 'round': return Math.round(asNumber(first))\n case 'clamp': return asNumber(first) < asNumber(second) ? asNumber(second) : asNumber(first) > asNumber(third) ? asNumber(third) : asNumber(first)\n case 'lerp': return asNumber(first) + (asNumber(second) - asNumber(first)) * asNumber(third)\n case 'ease': return ease(asNumber(first))\n case 'lt': return asNumber(first) < asNumber(second)\n case 'gt': return asNumber(first) > asNumber(second)\n case 'le': return asNumber(first) <= asNumber(second)\n case 'ge': return asNumber(first) >= asNumber(second)\n case 'eq': return first === second\n case 'ne': return first !== second\n case 'not': return !first\n case 'vadd': return reduceVectors(args, (total, next) => total + next)\n case 'vsub': return reduceVectors(args, (total, next) => total - next)\n case 'vscale': return asVector(first).map((component) => component * asNumber(second))\n case 'vnorm': return normalized(asVector(first) as readonly [number, number, number])\n case 'vneg': return asVector(first).map((component) => -component)\n case 'vlerp': return asVector(first).map((component, axis) => component + (asVector(second)[axis]! - component) * asNumber(third))\n case 'vx': return asVector(first)[0]\n case 'vy': return asVector(first)[1]\n case 'vz': return asVector(first)[2]\n case 'vdist': {\n const dx = asVector(first)[0]! - asVector(second)[0]!\n const dy = asVector(first)[1]! - asVector(second)[1]!\n const dz = asVector(first)[2]! - asVector(second)[2]!\n return Math.sqrt(dx * dx + dy * dy + dz * dz)\n }\n case 'with': return asVector(first).map((component, axis) => (axis === asNumber(second) ? asNumber(third) : component))\n default: throw new Error(`unknown expression: ${name}`)\n }\n}\n\n/** Resolves every `Expr` inside `value` (arrays and plain objects are walked in order, so the draws follow the order the page wrote its fields). */\nexport function resolve(value: unknown, context: ExprContext): unknown {\n if (Array.isArray(value)) return value.map((entry) => resolve(entry, context))\n if (typeof value !== 'object' || value === null) return value\n if (!isExpr(value)) return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, resolve(entry, context)]))\n const args = value.a ?? []\n switch (value.$) {\n case 'rnd': return context.random.between(asNumber(resolve(args[0], context)), asNumber(resolve(args[1], context)))\n case 'rand': return context.random.next()\n case 'param': return (args[0] as readonly unknown[])[context.param]\n case 'paramIndex': return context.param\n case 't': return context.time\n case 'dt': return context.dt\n case 'index': return context.index\n case 'quality': return context.quality\n case 'fresh': return context.fresh\n case 'direction': return context.direction\n case 'normal': return context.normal\n case 'scaled': return context.scaled(asNumber(resolve(args[0], context)))\n case 'var': return context.variables.get(args[0] as string)\n case 'at': return (resolve(args[0], context) as readonly unknown[])[asNumber(resolve(args[1], context))]\n case 'query': return context.query(args[0] as string, args[1] as string, args.slice(2).map((entry) => resolve(entry, context)))\n case 'cameraPosition': return context.camera.position\n case 'cameraForward': return context.camera.forward(asVector(resolve(args[0], context)))\n case 'let': return resolve(args[2], { ...context, variables: new Map([...context.variables, [args[0] as string, resolve(args[1], context)]]) })\n case 'ite': return resolve(resolve(args[0], context) ? args[1] : args[2], context)\n case 'and': return args.reduce<unknown>((result, next) => (result ? resolve(next, context) : result), true)\n case 'or': return args.reduce<unknown>((result, next) => (result ? result : resolve(next, context)), false)\n default: return evaluateCall(value.$, args.map((entry) => resolve(entry, context)))\n }\n}\n","import type { WorkshopEngine } from '../../workshop/engine'\nimport type { SpriteSpawn, Vec3Tuple } from '../../workshop/types'\nimport { normalized, plus } from '../vector-math'\n\nconst UP: Vec3Tuple = [0, 1, 0]\nconst ZERO: Vec3Tuple = [0, 0, 0]\nconst FULL_TURN_DRAWN = 6.283\n\nexport interface FireEmitOptions {\n readonly wind?: Vec3Tuple\n readonly dir?: Vec3Tuple\n readonly smoke?: number\n readonly smokeColor?: number\n readonly smokeAlpha?: number\n readonly noSmoke?: boolean\n}\n\nfunction scaledSizes(range: readonly [number, number], factor: number): readonly [number, number] {\n return [range[0] * Math.sqrt(factor), range[1] * Math.sqrt(factor)]\n}\n\n/** `fireEmit` (W399-405): flames, a hot core, embers and smoke for one frame, from a point and a radius, scaled by `factor`. */\nexport function fireEmit(engine: WorkshopEngine, key: string, dt: number, centre: Vec3Tuple, radius: number, factor: number, options: FireEmitOptions = {}): void {\n const wind = options.wind ?? ZERO\n const sqrtFactor = Math.sqrt(factor)\n engine.emit(`${key}f`, 'add', 90 * factor, dt, () => ({\n p: centre, r: radius, flat: true, dir: options.dir ?? UP, cone: 0.35, sp: [0.4, 1.4], v: wind, life: [0.35, 0.85], size: scaledSizes([0.22, 0.5], factor), grow: 0.35, c0: 0xffd27a, c1: 0x8a1a05, a: 0.85, fi: 0.15, g: -2.2,\n }))\n engine.emit(`${key}c`, 'add', 30 * factor, dt, () => ({\n p: centre, r: radius * 0.6, flat: true, dir: UP, cone: 0.3, sp: [0.3, 0.8], life: [0.2, 0.4], size: scaledSizes([0.25, 0.4], factor), grow: 0.6, c0: 0xfff2c0, c1: 0xff8a20, a: 0.8, fi: 0.1, g: -1,\n }))\n if (engine.quality < 2) {\n engine.emit(`${key}e`, 'streak', 10 * factor, dt, () => {\n const jitter = plus(wind, engine.random.between(-0.4, 0.4), 0, engine.random.between(-0.4, 0.4))\n return { p: centre, box: [radius, 0, radius], dir: UP, cone: 0.5, sp: [1.5, 3.5], v: jitter, life: [0.8, 1.8], len: 0.03, c0: 0xffb050, c1: 0x601000, g: -0.6, drag: 0.4 }\n })\n }\n if (options.noSmoke) return\n engine.emit(`${key}s`, 'normal', (options.smoke || 14) * factor, dt, () => ({\n p: plus(centre, 0, 0.8 * sqrtFactor, 0), r: radius * 0.7, dir: UP, cone: 0.35, sp: [0.6, 1.4], v: wind, drag: 0.15, life: [2.5, 4.5], size: scaledSizes([0.4, 0.8], factor), grow: 4, c0: options.smokeColor || 0x2a2522, c1: 0x121318, a: options.smokeAlpha || 0.42, fi: 0.2, g: -0.25,\n }))\n}\n\nfunction ringOfDust(engine: WorkshopEngine, point: Vec3Tuple, scale: number): void {\n for (let index = 0; index < engine.scaled(44); index++) {\n const angle = engine.random.next() * FULL_TURN_DRAWN\n const spec: SpriteSpawn = {\n p: plus(point, Math.cos(angle) * 0.5, 0.15, Math.sin(angle) * 0.5), dir: [Math.cos(angle), 0.08, Math.sin(angle)], cone: 0.15, sp: [4, 9 * scale], drag: 2.4, life: [1.4, 2.6], size: [0.5, 0.9], grow: 4, c0: 0x5d574d, c1: 0x2a2724, a: 0.5, fi: 0.1,\n }\n engine.spawn('normal', spec)\n }\n}\n\n/** `explode` (W406-416): the Workshop's blast, scaled by `scale`, that the Lab's profiles later replaced. `cameraPosition` turns the second ring to face the viewer. */\nexport function explode(engine: WorkshopEngine, point: Vec3Tuple, scale: number, cameraPosition: Vec3Tuple, chipColor?: number): void {\n engine.flash([plus(point, 0, 1, 0), 0xffa040, 14 * scale, 0.5, 30, 'boom'])\n engine.screen.shake += 0.7 * scale\n engine.screen.white += 0.18 * scale\n engine.burst('add', 55 * scale, { p: point, r: 0.3 * scale, sp: [2, 7 * scale], drag: 4, life: [0.25, 0.6], size: [0.7 * scale, 1.4 * scale], grow: 1.7, c0: 0xfff0b0, c1: 0x9a2a08, fi: 0.04 })\n engine.burst('add', 28 * scale, { p: plus(point, 0, 0.3, 0), r: 0.3, dir: UP, cone: 0.7, sp: [2, 5 * scale], drag: 1.5, life: [0.6, 1.1], size: [0.6 * scale, 1 * scale], grow: 1.3, c0: 0xffc060, c1: 0x5a1205, g: -2, fi: 0.05 })\n engine.ring([plus(point, 0, 0.05, 0), 0.3, 7 * scale, 0.55, 0xffd8a0])\n const toCamera = normalized([cameraPosition[0] - point[0], cameraPosition[1] - point[1], cameraPosition[2] - point[2]])\n engine.ring([plus(point, 0, 1, 0), 0.3, 5 * scale, 0.35, 0xfff0d0, toCamera])\n engine.burst('normal', 32 * scale, { p: plus(point, 0, 0.6, 0), r: 0.8 * scale, dir: UP, cone: 1.1, sp: [1, 3], drag: 1.2, life: [3, 6], size: [1 * scale, 1.8 * scale], grow: 2.6, c0: 0x2b2724, c1: 0x0f1013, a: 0.6, fi: 0.18, g: -0.35 })\n ringOfDust(engine, point, scale)\n if (engine.quality < 2) engine.burst('streak', 44 * scale, { p: point, dir: UP, cone: 1.45, sp: [10, 26], life: [0.3, 0.7], len: 0.03, c0: 0xffc070, c1: 0x802000, g: 9.8, gnd: 2 })\n for (let index = 0; index < engine.scaled(16 * scale); index++) {\n engine.debrisPiece({ p: point, dir: UP, cone: 1.2, sp: [3, 9], size: [0.12, 0.06, 0.1], k: [0.6, 1.6], c: chipColor || 0x2a2622, life: 9 })\n }\n engine.decal([point[0], engine.context.groundAt(point[0], point[2]), point[2], 3 * scale, 0x0a0a0a, { grow: 0.15, life: 60 }])\n}\n","import type { WorkshopEngine } from '../../workshop/engine'\nimport type { Vec3Tuple } from '../../workshop/types'\nimport { normalized, plus, plusScaled, scaledBy } from '../vector-math'\n\nconst FULL_TURN_DRAWN = 6.283\n\nexport const WEAPON_NAMES = ['glock', 'ak', 'r870', 'barrett'] as const\nexport type WeaponName = (typeof WEAPON_NAMES)[number]\n\n/** Per weapon: flash size, petals, light, smoke puffs and length of the petals (W417). */\nconst WEAPON_SIZES: Readonly<Record<WeaponName, readonly [number, number, number, number, number]>> = {\n glock: [0.35, 4, 3, 3, 0.25],\n ak: [0.6, 5, 5, 5, 0.45],\n r870: [0.95, 8, 7, 10, 0.6],\n barrett: [1.45, 6, 11, 14, 0.5],\n}\n\nfunction barrettBrake(engine: WorkshopEngine, tip: Vec3Tuple, direction: Vec3Tuple): void {\n const side = normalized([direction[2], 0, -direction[0]])\n for (const sign of [-1, 1]) {\n const sideways = scaledBy(side, sign)\n for (let index = 0; index < engine.scaled(8); index++) {\n engine.spawn('add', { p: plusScaled(tip, side, sign * 0.06), dir: sideways, cone: 0.25, sp: [2, 5], drag: 6, life: 0.09, size: [0.25, 0.4], c0: 0xffc070, c1: 0xff6010, fi: 0 })\n }\n engine.burst('normal', 10, { p: tip, dir: normalized(plus(sideways, 0, 0.2, 0)), cone: 0.3, sp: [1.5, 3], drag: 2, life: [1.2, 2], size: [0.15, 0.25], grow: 5, c0: 0x8a8a86, a: 0.3, g: -0.2 })\n }\n for (let index = 0; index < engine.scaled(26); index++) {\n const angle = engine.random.next() * FULL_TURN_DRAWN\n engine.spawn('normal', { p: [tip[0] + Math.cos(angle) * 0.3, 0.05, tip[2] + Math.sin(angle) * 0.3], dir: [Math.cos(angle), 0.15, Math.sin(angle)], cone: 0.2, sp: [1.5, 3.5], drag: 2, life: [1, 1.8], size: [0.2, 0.35], grow: 3, c0: 0x5a554b, a: 0.4 })\n }\n}\n\n/** `muzzle` (W417-429): flash core, petals along the barrel and smoke, scaled by weapon; the Barrett also vents sideways and lifts the dust. */\nexport function muzzle(engine: WorkshopEngine, weapon: WeaponName, tip: Vec3Tuple, direction: Vec3Tuple): void {\n const [flashSize, petals, light, smoke, length] = WEAPON_SIZES[weapon]\n engine.burst('add', 3, { p: tip, size: [flashSize * 0.45, flashSize * 0.75], life: 0.055, c0: 0xfff4d0, fi: 0 })\n for (let index = 0; index < engine.scaled(petals * 2); index++) {\n engine.spawn('add', { p: plusScaled(tip, direction, engine.random.between(0, length)), r: 0.03, size: [flashSize * 0.22, flashSize * 0.38], life: 0.06, c0: 0xffb050, c1: 0xff7020, fi: 0 })\n }\n engine.burst('streak', petals, { p: tip, dir: direction, cone: 0.55, sp: [6, 12], life: 0.05, len: 0.025, c0: 0xffd080 })\n if (weapon === 'barrett') barrettBrake(engine, tip, direction)\n engine.burst('normal', smoke, { p: tip, dir: direction, cone: 0.45, sp: [0.4, 1.6], drag: 2.2, life: [1, 2.2], size: [0.06, 0.14], grow: 6, c0: 0x8a8a86, c1: 0x55565a, a: 0.22, g: -0.25, fi: 0.05 })\n engine.flash([tip, 0xffc070, light, 0.05, 10])\n}\n\nexport type CasingType = 'shell' | '50' | ''\n\n/** `casing` (W430): a brass case, or a red shell, thrown out of the port. */\nexport function casing(engine: WorkshopEngine, port: Vec3Tuple, type: CasingType): void {\n const size = type === 'shell' ? ([0.03, 0.03, 0.07] as const) : type === '50' ? ([0.024, 0.024, 0.13] as const) : ([0.014, 0.014, 0.05] as const)\n engine.debrisPiece({ p: port, dir: normalized([0.8, 0.6, 0.2]), cone: 0.3, sp: [1.6, 2.6], size, c: type === 'shell' ? 0xb5281e : 0xc9a24a, spin: 20, bounce: 0.45, life: 20 })\n}\n","import type { WorkshopEngine } from '../workshop/engine'\nimport type { Vec3Tuple } from '../workshop/types'\nimport { bloodHit, impact } from './builders/blood'\nimport type { ImpactMaterial } from './builders/blood'\nimport { explode, fireEmit } from './builders/fire'\nimport type { FireEmitOptions } from './builders/fire'\nimport { chips, rustAt, sparkAt } from './builders/shared'\nimport { casing, muzzle } from './builders/weapon'\nimport type { CasingType, WeaponName } from './builders/weapon'\n\nexport interface MacroContext {\n readonly engine: WorkshopEngine\n readonly cameraPosition: Vec3Tuple\n readonly dt: number\n}\n\ntype MacroArgs = readonly unknown[]\n\n/** The helpers the page's recipes share (`bloodHit`, `impact`, `fireEmit`, `explode`, `muzzle`, `casing`, `chips`, `sparkAt`, `rustAt`), called by name from a step. */\nexport const MACROS: Readonly<Record<string, (context: MacroContext, args: MacroArgs) => void>> = {\n blood_hit: ({ engine }, [point, direction, age, scale]) => bloodHit(engine, point as Vec3Tuple, direction as Vec3Tuple, age as number, scale as number | undefined),\n impact: ({ engine }, [material, point, normal, scale, age]) => impact(engine, material as ImpactMaterial, point as Vec3Tuple, normal as Vec3Tuple, scale as number | undefined, age as number | undefined),\n fire_emit: ({ engine, dt }, [key, centre, radius, factor, options]) => fireEmit(engine, key as string, dt, centre as Vec3Tuple, radius as number, factor as number, options as FireEmitOptions | undefined),\n explode: ({ engine, cameraPosition }, [point, scale, chipColor]) => explode(engine, point as Vec3Tuple, scale as number, cameraPosition, chipColor as number | undefined),\n muzzle: ({ engine }, [weapon, tip, direction]) => muzzle(engine, weapon as WeaponName, tip as Vec3Tuple, direction as Vec3Tuple),\n casing: ({ engine }, [port, type]) => casing(engine, port as Vec3Tuple, type as CasingType),\n chips: ({ engine }, [point, direction, count, spread]) => chips(engine, point as Vec3Tuple, direction as Vec3Tuple, count as number, spread as number | undefined),\n spark_at: ({ engine }, [point, direction, count, spread]) => sparkAt(engine, point as Vec3Tuple, direction as Vec3Tuple, count as number, spread as number | undefined),\n rust_at: ({ engine }, [point, count]) => rustAt(engine, point as Vec3Tuple, count as number),\n}\n","import { createSchedule } from '../schedule'\nimport type { ScreenState } from '../types'\nimport type { Placement, WorkshopEngine } from '../workshop/engine'\nimport type { DebrisSpawn, MeshSpawn, SpriteSpawn, Vec3Tuple } from '../workshop/types'\nimport type { Behavior, BehaviorHost } from './behavior'\nimport type { ExprContext } from './expression'\nimport { resolve } from './expression'\nimport { MACROS } from './macros'\nimport type { CueRequest, EffectDef, EffectStep, ScreenKey } from './types'\n\nconst DEFAULT_DIRECTION: Vec3Tuple = [0, 0, -1]\nconst DEFAULT_NORMAL: Vec3Tuple = [0, 1, 0]\nconst SCREEN_FIELDS: Readonly<Record<ScreenKey, keyof ScreenState>> = {\n shake: 'shake', white: 'white', red: 'red', dirL: 'directionLeft', dirR: 'directionRight', chroma: 'chroma', desat: 'desat', gas: 'gas', beat: 'beat',\n}\n\n/** What an effect reads off the view: where it is and which way the camera's own axes point. The Workshop's bench also moves it (`camera` steps). */\nexport interface EffectView {\n readonly position: Vec3Tuple\n forward(local: readonly number[]): Vec3Tuple\n goTo?(eye: Vec3Tuple, target: Vec3Tuple): void\n place?(eye: Vec3Tuple, target: Vec3Tuple): void\n}\n\nexport interface InstanceDeps {\n readonly engine: WorkshopEngine\n readonly view: EffectView\n /** The prop models the recipe can call, by id (see `Behavior`). */\n readonly behavior: (id: string) => Behavior\n /** Every behaviour made so far, to age them every frame. */\n readonly behaviors: () => Iterable<Behavior>\n readonly onCue?: (cue: CueRequest) => void\n}\n\n/** Where and how a played effect sits in the world. */\nexport interface InstanceSetup {\n readonly placement?: Placement\n /** Which way the effect points in the world (`direction` in a recipe). */\n readonly direction?: Vec3Tuple\n /** The surface it hit (`normal` in a recipe). */\n readonly normal?: Vec3Tuple\n /** Named numbers the recipe reads with `variable(name)`; they are in place before its first step. */\n readonly values?: Readonly<Record<string, number>>\n}\n\n/**\n * One run of one effect (W1259-1295): `begin` runs the recipe's `setup` and `timeline`, `step` runs the timers that came due (from the last added to the\n * first) and the `tick`, once per frame. Step by step it draws random numbers where the page did and in the same order.\n */\nexport class EffectInstance {\n readonly variables = new Map<string, unknown>()\n def: EffectDef | undefined\n param = 0\n /** True until the first run of a chosen effect is over: a repeat of the loop is not fresh (`f.fresh`). */\n fresh = false\n time = 0\n /** Seconds since the effect was chosen: unlike `time`, a restart of the loop does not reset it (`el`). */\n elapsed = 0\n setup: InstanceSetup = {}\n private dt = 0\n private index = 0\n private readonly schedule = createSchedule()\n private readonly host: BehaviorHost\n private readonly context: ExprContext\n\n constructor(private readonly deps: InstanceDeps) {\n const instance = (): EffectInstance => this\n this.host = {\n engine: deps.engine,\n camera: deps.view,\n variables: this.variables,\n get param() { return instance().param },\n get time() { return instance().time },\n after: (seconds, action) => this.schedule.at(seconds, action),\n }\n this.context = {\n get random() { return deps.engine.random },\n get param() { return instance().param },\n get time() { return instance().time },\n get dt() { return instance().dt },\n get index() { return instance().index },\n variables: this.variables,\n scaled: (count) => deps.engine.scaled(count),\n query: (behavior, name, args) => deps.behavior(behavior).query(this.host, name, args),\n get quality() { return deps.engine.quality },\n get fresh() { return instance().fresh },\n get direction() { return instance().setup.direction ?? DEFAULT_DIRECTION },\n get normal() { return instance().setup.normal ?? DEFAULT_NORMAL },\n camera: { get position() { return deps.view.position }, forward: (local) => deps.view.forward(local) },\n }\n }\n\n /** The effect starts (`select` + `startLoop`): the recipe's `setup` and `timeline` run now. */\n begin(def: EffectDef, param: number | undefined, setup: InstanceSetup = {}): void {\n this.def = def\n this.param = param ?? def.params?.default ?? 0\n this.elapsed = 0\n this.fresh = true\n this.setup = setup\n this.restart()\n }\n\n /** The loop starts over (`startLoop`): timers, variables and props go back to the start. */\n restart(): void {\n const def = this.def\n if (!def) return\n this.schedule.clear()\n this.variables.clear()\n for (const [name, value] of Object.entries(this.setup.values ?? {})) this.variables.set(name, value)\n for (const behavior of this.deps.behaviors()) behavior.reset(this.host)\n this.time = 0\n this.within(() => {\n this.execute(def.setup ?? [])\n this.execute(def.timeline)\n })\n this.fresh = false\n }\n\n /** The effect's part of one frame: the timers due, then the tick, then the props. The pools are aged by whoever owns the engine. */\n step(dt: number): void {\n const def = this.def\n this.dt = dt\n if (def) {\n this.time += dt\n this.elapsed += dt\n this.within(() => {\n this.schedule.update(this.time)\n this.execute(def.tick ?? [])\n })\n }\n for (const behavior of this.deps.behaviors()) behavior.update(this.host, dt, this.elapsed)\n }\n\n /** True once a looping effect has run its seconds, or a one-shot has nothing left to fire. */\n get finished(): boolean {\n const def = this.def\n if (!def) return true\n if (def.loop && def.loop > 0) return this.time >= def.loop\n return false\n }\n\n /** The recipe's own camera shake on top of the screen's (`panico` trembles the aim). */\n get tremor(): number {\n return (this.variables.get('tremor') as number | undefined) ?? 0\n }\n\n private within(action: () => void): void {\n const engine = this.deps.engine\n const previous = engine.placement\n engine.placement = this.setup.placement\n try {\n action()\n } finally {\n engine.placement = previous\n }\n }\n\n private value(expression: unknown): unknown {\n return resolve(expression, this.context)\n }\n\n execute(steps: readonly EffectStep[]): void {\n for (const step of steps) this.run(step)\n }\n\n private run(step: EffectStep): void {\n const engine = this.deps.engine\n switch (step.op) {\n case 'burst': return engine.burst(step.system, this.value(step.count) as number, this.value(step.spawn) as SpriteSpawn)\n case 'spawn': return engine.spawn(step.system, this.value(step.spawn) as SpriteSpawn)\n case 'emit': return engine.emit(step.key, step.system, this.value(step.rate) as number, this.dt, () => this.value(step.spawn) as SpriteSpawn)\n case 'mesh': { engine.mesh(this.value(step.spawn) as MeshSpawn); return }\n case 'debris': return engine.debrisPiece(this.value(step.spawn) as DebrisSpawn)\n case 'decal': return engine.decal(this.value(step.args) as Parameters<WorkshopEngine['decal']>[0])\n case 'ring': return engine.ring(this.value(step.args) as Parameters<WorkshopEngine['ring']>[0])\n case 'flash': return engine.flash(this.value(step.args) as Parameters<WorkshopEngine['flash']>[0])\n case 'lens': return engine.lensBlob(...(this.value(step.args) as [number, number, number, string, number]))\n case 'screen': return this.changeScreen(step)\n case 'fire_light': return engine.fireLight(step.slot, this.value(step.point) as Vec3Tuple, this.value(step.intensity) as number, this.value(step.time) as number)\n case 'fire_light_off': engine.lights.fire[step.slot]!.intensity = 0; return\n case 'cue': return this.cue(step)\n case 'call': return MACROS[step.macro]!({ engine, cameraPosition: this.deps.view.position, dt: this.dt }, this.value(step.args) as readonly unknown[])\n case 'at': return this.scheduleSteps(step)\n case 'when': return this.execute(this.value(step.if) ? step.steps : (step.otherwise ?? []))\n case 'repeat': return this.repeat(step)\n case 'set': { this.variables.set(step.name, this.value(step.value)); return }\n case 'append': { this.variables.set(step.name, [...((this.variables.get(step.name) as unknown[] | undefined) ?? []), this.value(step.value)]); return }\n case 'camera': return this.moveView(step)\n case 'post': { Object.assign(engine.post, this.value(step.values)); return }\n case 'behavior': return this.deps.behavior(step.id).act(this.host, step.action, this.value(step.args))\n }\n }\n\n private moveView(step: Extract<EffectStep, { op: 'camera' }>): void {\n const eye = this.value(step.eye) as Vec3Tuple\n const target = this.value(step.target) as Vec3Tuple\n if (step.instant) this.deps.view.place?.(eye, target)\n else this.deps.view.goTo?.(eye, target)\n }\n\n private changeScreen(step: Extract<EffectStep, { op: 'screen' }>): void {\n const screen = this.deps.engine.screen\n for (const [key, expression] of Object.entries(step.add ?? {})) screen[SCREEN_FIELDS[key as ScreenKey]] += this.value(expression) as number\n for (const [key, expression] of Object.entries(step.set ?? {})) screen[SCREEN_FIELDS[key as ScreenKey]] = this.value(expression) as number\n for (const [key, expression] of Object.entries(step.max ?? {})) screen[SCREEN_FIELDS[key as ScreenKey]] = Math.max(screen[SCREEN_FIELDS[key as ScreenKey]], this.value(expression) as number)\n }\n\n private cue(step: Extract<EffectStep, { op: 'cue' }>): void {\n const args = this.value(step.args)\n for (let draw = 0; draw < (step.draws ?? 0); draw++) this.deps.engine.random.next()\n this.deps.onCue?.({ cue: step.cue, args, time: this.time })\n }\n\n private scheduleSteps(step: Extract<EffectStep, { op: 'at' }>): void {\n const captured = this.index\n this.schedule.at(this.value(step.time) as number, () => {\n const previous = this.index\n this.index = captured\n this.execute(step.steps)\n this.index = previous\n })\n }\n\n private repeat(step: Extract<EffectStep, { op: 'repeat' }>): void {\n const previous = this.index\n const count = this.value(step.count) as number\n for (let index = 0; index < count; index++) {\n this.index = index\n this.execute(step.steps)\n }\n this.index = previous\n }\n}\n","import { lehmer } from '../random'\nimport type { RandomStream } from '../random'\nimport type { Follow } from '../types'\nimport type { Placement, WorkshopEngine } from '../workshop/engine'\nimport type { Vec3Tuple } from '../workshop/types'\nimport type { Behavior } from './behavior'\nimport { WORKSHOP_BEHAVIORS } from './behaviors'\nimport { EffectInstance } from './instance'\nimport type { EffectView } from './instance'\nimport type { CueRequest, EffectDef } from './types'\n\nconst ORIGIN: Vec3Tuple = [0, 0, 0]\nconst DEFAULT_HEADING: Vec3Tuple = [0, 0, -1]\nconst DEFAULT_MAX_INSTANCES = 48\n/** A recipe with no end of its own (`loop: 0`: a campfire, a fire in a building) plays this long unless it is stopped. */\nconst ENDLESS_SECONDS = 60\n\nexport interface PlayOptions {\n /** Which way the effect points in the world (the muzzle's barrel, the spray of a jet). */\n readonly direction?: Vec3Tuple\n /** Which way the thing it belongs to is turned, as a unit quaternion `[x, y, z, w]`: the effect is placed with this turn, pitch and roll included, in place of the turn about the vertical axis `direction` gives. */\n readonly orientation?: readonly [number, number, number, number]\n /** The surface it hit. */\n readonly normal?: Vec3Tuple\n /** Repeats the same visual: a LAN client draws the same numbers from the same seed. */\n readonly seed?: number\n /** The recipe's parameter (age, material, weapon...). */\n readonly param?: number | string\n /** Named numbers the recipe reads with `variable(name)` (a size, a length of time): set before its `setup` runs, and again whenever its loop starts over. */\n readonly values?: Readonly<Record<string, number>>\n /** Moves with a thing: the effect sits at its position plus the point it was played at. */\n readonly follow?: Follow\n /** Stops after this many seconds (default: the recipe's loop). */\n readonly seconds?: number\n}\n\nexport interface EffectPlayerOptions {\n readonly engine: WorkshopEngine\n readonly effects: Readonly<Record<string, EffectDef>>\n readonly behaviors?: Readonly<Record<string, () => Behavior>>\n /** Where the viewer is, for the recipes that read it. */\n readonly view: EffectView\n /** A stream for a seed (default `lehmer`). */\n readonly streamFor?: (seed: number) => RandomStream\n readonly maxInstances?: number\n readonly onCue?: (cue: CueRequest) => void\n}\n\nexport interface EffectPlayer {\n /** Plays `id` at `point`; `null` when no recipe has that id or the cap of live effects is reached. Returns a handle for `stop`. */\n play(id: string, point: Vec3Tuple, options?: PlayOptions): number | null\n stop(handle: number): void\n /** Runs the timers and ticks of every live effect (the engine's pools are aged by its owner). */\n update(dt: number): void\n clear(): void\n readonly active: number\n has(id: string): boolean\n ids(): readonly string[]\n}\n\ninterface Playing {\n readonly handle: number\n readonly instance: EffectInstance\n readonly random: RandomStream | undefined\n readonly follow: Follow | undefined\n readonly origin: Vec3Tuple\n readonly anchor: Vec3Tuple\n readonly yaw: number\n readonly orientation: readonly [number, number, number, number] | undefined\n readonly seconds: number\n}\n\nconst positionOf = (follow: Follow): Vec3Tuple => {\n const source = 'position' in follow ? follow.position : follow\n return [source.x, source.y, source.z]\n}\n\n/** A parameter given by its option id (`'ak'`, `'concrete'`) as the index of the option; a number is taken as it is. */\nfunction paramIndex(def: EffectDef, param: number | string | undefined): number | undefined {\n if (typeof param !== 'string') return param\n const index = def.params?.options.indexOf(param) ?? -1\n return index >= 0 ? index : undefined\n}\n\n/** The turn about the vertical axis that takes the recipe's `heading` onto `direction` (three.js turns by `x' = cos x + sin z`). */\nfunction yawOf(heading: Vec3Tuple, direction: Vec3Tuple | undefined): number {\n if (!direction || (direction[0] === 0 && direction[2] === 0)) return 0\n return Math.atan2(direction[0], direction[2]) - Math.atan2(heading[0], heading[2])\n}\n\n/**\n * Plays the Workshop's recipes anywhere in the world, many at once, each with its own clock, variables and props, a place and a way it faces. They all\n * spawn into the one engine, so the pools stay shared and bounded. This is what `VfxWorld.play` and the host's `EffectSink` use.\n */\nexport function createEffectPlayer(options: EffectPlayerOptions): EffectPlayer {\n const { engine, view } = options\n const factories = options.behaviors ?? WORKSHOP_BEHAVIORS\n const streamOf = options.streamFor ?? ((seed: number) => lehmer(seed))\n const limit = options.maxInstances ?? DEFAULT_MAX_INSTANCES\n const playing: Playing[] = []\n let next = 0\n\n function makeInstance(): EffectInstance {\n const made = new Map<string, Behavior>()\n return new EffectInstance({\n engine,\n view,\n behavior: (id) => {\n let behavior = made.get(id)\n if (!behavior) {\n const make = factories[id]\n if (!make) throw new Error(`no behaviour ${id}`)\n behavior = make()\n made.set(id, behavior)\n }\n return behavior\n },\n behaviors: () => made.values(),\n ...(options.onCue ? { onCue: options.onCue } : {}),\n })\n }\n\n function placementOf(entry: Playing): Placement {\n const origin = entry.follow ? [entry.origin[0] + positionOf(entry.follow)[0], entry.origin[1] + positionOf(entry.follow)[1], entry.origin[2] + positionOf(entry.follow)[2]] as const : entry.origin\n return { origin, anchor: entry.anchor, yaw: entry.yaw, ...(entry.orientation ? { orientation: entry.orientation } : {}) }\n }\n\n /** Runs `action` drawing from the effect's own stream, if it has one. */\n function drawing(entry: Playing, action: () => void): void {\n const context = engine.context\n const shared = context.random\n if (entry.random) context.random = entry.random\n try {\n action()\n } finally {\n context.random = shared\n }\n }\n\n return {\n play(id, point, playOptions = {}) {\n const def = options.effects[id]\n if (!def || playing.length >= limit) return null\n const heading = def.heading ?? DEFAULT_HEADING\n const instance = makeInstance()\n const entry: Playing = {\n handle: ++next,\n instance,\n random: playOptions.seed !== undefined ? streamOf(playOptions.seed) : undefined,\n follow: playOptions.follow,\n origin: point,\n anchor: def.anchor ?? ORIGIN,\n yaw: yawOf(heading, playOptions.direction),\n orientation: playOptions.orientation,\n seconds: playOptions.seconds ?? (def.loop && def.loop > 0 ? def.loop : ENDLESS_SECONDS),\n }\n playing.push(entry)\n drawing(entry, () =>\n instance.begin(def, paramIndex(def, playOptions.param), {\n placement: placementOf(entry),\n ...(playOptions.direction ? { direction: playOptions.direction } : {}),\n ...(playOptions.normal ? { normal: playOptions.normal } : {}),\n ...(playOptions.values ? { values: playOptions.values } : {}),\n }),\n )\n return entry.handle\n },\n stop(handle) {\n const index = playing.findIndex((entry) => entry.handle === handle)\n if (index >= 0) playing.splice(index, 1)\n },\n update(dt) {\n for (let index = playing.length - 1; index >= 0; index--) {\n const entry = playing[index]!\n const instance = entry.instance\n instance.setup = { ...instance.setup, placement: placementOf(entry) }\n drawing(entry, () => instance.step(dt))\n if (instance.time >= entry.seconds) playing.splice(index, 1)\n }\n },\n clear() {\n playing.length = 0\n },\n get active() {\n return playing.length\n },\n has: (id) => id in options.effects,\n ids: () => Object.keys(options.effects),\n }\n}\n","import type { Rgb } from './color'\nimport { hexToRgb, srgbChannelToLinear } from './color'\n\n/** One of the 4 blast lights (L349-365). */\nexport interface BlastLight {\n x: number\n y: number\n z: number\n distance: number\n peak: number\n life: number\n t: number\n color: Rgb\n /** The level before the flash layer is applied. */\n level: number\n intensity: number\n}\n\n/** One of the 2 fire lights: they go to the two largest fires. */\nexport interface FireLight {\n x: number\n y: number\n z: number\n distance: number\n intensity: number\n}\n\n/** The glow the puff shader reads (`uGlowPos`, `uGlowCol`, `uGlowI`): where the brightest light is, in linear colour. */\nexport interface LightGlow {\n x: number\n y: number\n z: number\n color: [number, number, number]\n intensity: number\n}\n\nexport interface LightPool {\n readonly blast: BlastLight[]\n readonly fire: FireLight[]\n readonly glow: LightGlow\n /** Which blast light the next explosion takes (the Lab's `xlIdx`). */\n cursor: number\n}\n\nexport const BLAST_LIGHTS = 4\nexport const FIRE_LIGHTS = 2\nconst DEFAULT_BLAST_COLOR = 0xffa050\nconst FIRE_GLOW_COLOR: Rgb = [1, 0.42, 0.12]\nconst PEAK_HOLD = 0.05\n\nexport function createLightPool(): LightPool {\n return {\n blast: Array.from({ length: BLAST_LIGHTS }, () => ({ x: 0, y: -50, z: 0, distance: 30, peak: 0, life: 1, t: 9, color: hexToRgb(DEFAULT_BLAST_COLOR), level: 0, intensity: 0 })),\n fire: Array.from({ length: FIRE_LIGHTS }, () => ({ x: 0, y: -50, z: 0, distance: 16, intensity: 0 })),\n glow: { x: 0, y: 0, z: 0, color: [1, 0.5, 0.2], intensity: 0 },\n cursor: 0,\n }\n}\n\nexport function resetLightPool(pool: LightPool): void {\n for (const light of pool.blast) {\n light.t = 9\n light.level = 0\n light.intensity = 0\n }\n pool.cursor = 0\n}\n\nexport interface BlastLightSpec {\n readonly x: number\n readonly y: number\n readonly z: number\n readonly peak: number\n readonly distance: number\n readonly life: number\n readonly color: number\n}\n\n/** `boomLight` (L357-358): the next blast light, round robin. */\nexport function lightBlast(pool: LightPool, spec: BlastLightSpec): void {\n const light = pool.blast[pool.cursor++ % pool.blast.length]!\n light.x = spec.x\n light.y = spec.y\n light.z = spec.z\n light.distance = spec.distance\n light.peak = spec.peak\n light.life = spec.life\n light.t = 0\n light.color = hexToRgb(spec.color)\n}\n\nexport interface FireForLight {\n readonly x: number\n readonly y: number\n readonly z: number\n readonly r: number\n readonly fade: number\n}\n\nexport interface LightStep {\n readonly dt: number\n /** 1 while the flash layer is on, 0 while it is off (the Lab multiplies by it). */\n readonly flashLayer: number\n readonly clock: number\n readonly fires: readonly FireForLight[]\n}\n\nfunction largestFire(fires: readonly FireForLight[], skip: FireForLight | null): FireForLight | null {\n let best: FireForLight | null = null\n for (const fire of fires) {\n if (fire === skip) continue\n if (best === null || fire.r > best.r) best = fire\n }\n return best\n}\n\nfunction updateBlastLights(pool: LightPool, step: LightStep): BlastLight | null {\n let brightest: BlastLight | null = null\n for (const light of pool.blast) {\n light.t += step.dt\n const age = light.t / light.life\n const level = age < 1 ? light.peak * (light.t < PEAK_HOLD ? 1 : Math.pow(1 - age, 2.2)) * (0.85 + 0.15 * Math.sin(light.t * 60)) : 0\n light.level = level\n light.intensity = level * step.flashLayer\n if (level > (brightest?.level ?? 0)) brightest = light\n }\n return brightest\n}\n\n/** `updateLights` (L350-364): blast lights fade by their curve, the two fire lights follow the two largest fires, and the glow follows the brightest light. */\nexport function updateLights(pool: LightPool, step: LightStep): void {\n const brightest = updateBlastLights(pool, step)\n const brightness = brightest?.level ?? 0\n const first = largestFire(step.fires, null)\n const second = largestFire(step.fires, first)\n const largest = [first, second]\n for (let index = 0; index < FIRE_LIGHTS; index++) {\n const fire = largest[index]\n const light = pool.fire[index]!\n if (!fire) {\n light.intensity = 0\n continue\n }\n light.x = fire.x\n light.y = fire.y + Math.max(0.8, fire.r * 0.6)\n light.z = fire.z\n light.intensity = (1.4 + fire.r * 0.6) * (0.75 + 0.25 * Math.sin(step.clock * 17 + index * 3) + 0.1 * Math.sin(step.clock * 41)) * fire.fade\n light.distance = 10 + fire.r * 4\n }\n if (brightest && brightness > 0.05) {\n pool.glow.x = brightest.x\n pool.glow.y = brightest.y\n pool.glow.z = brightest.z\n pool.glow.color[0] = srgbChannelToLinear(brightest.color[0])\n pool.glow.color[1] = srgbChannelToLinear(brightest.color[1])\n pool.glow.color[2] = srgbChannelToLinear(brightest.color[2])\n pool.glow.intensity = brightness * 0.06 * step.flashLayer\n } else if (first) {\n pool.glow.x = first.x\n pool.glow.y = first.y + 0.5\n pool.glow.z = first.z\n pool.glow.color[0] = FIRE_GLOW_COLOR[0]\n pool.glow.color[1] = FIRE_GLOW_COLOR[1]\n pool.glow.color[2] = FIRE_GLOW_COLOR[2]\n pool.glow.intensity = (0.35 + first.r * 0.12) * first.fade\n } else pool.glow.intensity = 0\n}\n","import type { LodBands } from './types'\n\n/** The game's bands: distance minus the visual radius, 15 / 40 / 80 m, scales 1 / .5 / .2 / .1 (G68203, the Workshop's quality bands). The default. */\nexport const LOD_GAME: LodBands = { edges: [15, 40, 80], scales: [1, 0.5, 0.2, 0.1], radiusFactor: 1 }\n\n/** The Lab's own bands (L481): distance minus three visual radii, 20 / 45 / 85 m, scales 1 / .5 / .2 / .08. Used on the bench and in the goldens. */\nexport const LOD_LAB: LodBands = { edges: [20, 45, 85], scales: [1, 0.5, 0.2, 0.08], radiusFactor: 3 }\n\n/** The scale of an effect `distance` metres from the camera, for an effect whose fireball has `visualRadius`. */\nexport function lodScale(bands: LodBands, distance: number, visualRadius: number): number {\n const effective = distance - visualRadius * bands.radiusFactor\n if (effective < bands.edges[0]) return bands.scales[0]\n if (effective < bands.edges[1]) return bands.scales[1]\n if (effective < bands.edges[2]) return bands.scales[2]\n return bands.scales[3]\n}\n","import type { GroundField } from './ground'\nimport type { RandomStream } from './random'\n\n/** What an explosion leaves on the ground, as data: the renderer builds the meshes (L443-476). */\nexport interface ScorchMark {\n readonly kind: 'scorch'\n readonly x: number\n readonly z: number\n readonly radius: number\n /** Which of the three scorch textures. */\n readonly variant: number\n readonly lift: number\n readonly rotation: number\n}\n\nexport interface DirtMark {\n readonly kind: 'dirt'\n readonly x: number\n readonly z: number\n readonly radius: number\n readonly lift: number\n readonly rotation: number\n}\n\n/** A piece of broken asphalt on the rim of a crater. */\nexport interface RockMark {\n readonly kind: 'rock'\n readonly x: number\n readonly y: number\n readonly z: number\n readonly scale: readonly [number, number, number]\n readonly rotation: readonly [number, number, number]\n readonly plate: boolean\n readonly color: number\n}\n\nexport interface BloodMark {\n readonly kind: 'blood'\n readonly x: number\n readonly y: number\n readonly z: number\n readonly scaleX: number\n readonly scaleZ: number\n readonly rotation: number\n}\n\nexport type Mark = ScorchMark | DirtMark | RockMark | BloodMark\n\nexport type MarkEvent = { readonly type: 'add'; readonly mark: Mark } | { readonly type: 'clear' }\n\nexport interface MarkStore {\n readonly entries: Mark[]\n /** Goes up on every mark added or cleared. */\n readonly version: number\n readonly bloodCount: number\n /** The counter that lifts each decal a hair higher than the last (the Lab's `decalY`). */\n lift: number\n add(mark: Mark): void\n clear(): void\n /** Tells a renderer the moment a mark is made (the ground it conforms to is the ground of that moment) or taken away. */\n subscribe(listener: (event: MarkEvent) => void): () => void\n}\n\nconst BLOOD_LIMIT = 450\nconst SCORCH_VARIANTS = 3\nconst RIM_COLORS = [0x2b2c2f, 0x3a3836] as const\n\nexport function createMarkStore(): MarkStore {\n const entries: Mark[] = []\n let version = 0\n let bloodCount = 0\n const listeners = new Set<(event: MarkEvent) => void>()\n return {\n entries,\n get version() {\n return version\n },\n get bloodCount() {\n return bloodCount\n },\n lift: 0,\n add(mark) {\n entries.push(mark)\n if (mark.kind === 'blood') bloodCount++\n version++\n for (const listener of listeners) listener({ type: 'add', mark })\n },\n clear() {\n entries.length = 0\n bloodCount = 0\n this.lift = 0\n version++\n for (const listener of listeners) listener({ type: 'clear' })\n },\n subscribe(listener) {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n }\n}\n\nfunction nextLift(store: MarkStore): number {\n return store.lift++ % 20\n}\n\n/** `scorch` (L458): a burn mark; the texture and the turn are drawn in that order. */\nexport function addScorch(store: MarkStore, random: RandomStream, x: number, z: number, radius: number): void {\n const variant = Math.floor(random.next() * SCORCH_VARIANTS)\n const lift = 0.03 + nextLift(store) * 0.001\n const rotation = random.next() * 6\n store.add({ kind: 'scorch', x, z, radius, variant, lift, rotation })\n}\n\nfunction addRimRocks(store: MarkStore, ground: GroundField | undefined, random: RandomStream, x: number, z: number, radius: number): void {\n const count = Math.round(6 + radius * 7)\n for (let index = 0; index < count; index++) {\n const angle = (index / count) * Math.PI * 2 + random.between(-0.15, 0.15)\n const distance = radius * random.between(0.95, 1.3)\n const size = random.between(0.12, 0.26) * Math.min(1.6, 0.6 + radius * 0.4)\n const px = x + Math.cos(angle) * distance\n const pz = z + Math.sin(angle) * distance\n const plate = random.next() < 0.6\n const color = RIM_COLORS[random.next() < 0.5 ? 0 : 1]\n const tiltX = random.between(-0.5, 0.5)\n const tiltZ = random.between(-0.6, 0.2)\n store.add({\n kind: 'rock',\n x: px,\n y: (ground?.heightAt(px, pz) ?? 0) + size * 0.12,\n z: pz,\n scale: [size * 2, size * 0.35, size * 1.4],\n rotation: [tiltX, angle, tiltZ],\n plate,\n color,\n })\n }\n}\n\n/** `crater` (L460-468): digs the ground (always), then, when marks are on, lays the dirt, and broken asphalt around the rim. */\nexport function addCrater(store: MarkStore, ground: GroundField | undefined, random: RandomStream, spec: { x: number; z: number; radius: number; depth: number; marks: boolean }): void {\n ground?.dent(random, spec.x, spec.z, spec.radius, spec.depth)\n if (!spec.marks) return\n const rotation = random.next() * 6\n store.add({ kind: 'dirt', x: spec.x, z: spec.z, radius: spec.radius * 1.02, lift: 0.045, rotation })\n addRimRocks(store, ground, random, spec.x, spec.z, spec.radius)\n}\n\n/** `bloodSplat` (L471-475). */\nexport function addBloodSplat(store: MarkStore, ground: GroundField | undefined, random: RandomStream, spec: { x: number; z: number; radius: number }): void {\n if (store.bloodCount > BLOOD_LIMIT) return\n const y = (ground?.heightAt(spec.x, spec.z) ?? 0) + 0.03 + nextLift(store) * 0.0008\n const scaleX = spec.radius * random.between(1.6, 2.4)\n const scaleZ = spec.radius * random.between(1.2, 2)\n store.add({ kind: 'blood', x: spec.x, y, z: spec.z, scaleX, scaleZ, rotation: random.next() * 6 })\n}\n","import { OrderedPool } from '../pool'\nimport type { Ring } from './puffs'\n\nexport function createRingPool(capacity: number): OrderedPool<Ring> {\n return new OrderedPool<Ring>(capacity, () => ({ x: 0, z: 0, y0: 0, rise: 0, rk: 0, R0: 0, R1: 0, r: 0, roll: 0, t: 0, life: 0 }))\n}\n\nfunction ageOrKeep(ring: Ring, dt: number): boolean {\n ring.t += dt\n return ring.t <= ring.life + 1\n}\n\n/** `updateRings` (L736): a ring is kept one second past the life of its puffs. */\nexport function updateRings(pool: OrderedPool<Ring>, dt: number): void {\n pool.compact(ageOrKeep, dt)\n}\n\nexport function spawnRing(pool: OrderedPool<Ring>, spec: Omit<Ring, 't'>): Ring {\n const ring = pool.acquire()\n ring.x = spec.x\n ring.z = spec.z\n ring.y0 = spec.y0\n ring.rise = spec.rise\n ring.rk = spec.rk\n ring.R0 = spec.R0\n ring.R1 = spec.R1\n ring.r = spec.r\n ring.roll = spec.roll\n ring.t = 0\n ring.life = spec.life\n return ring\n}\n","import { OrderedPool } from '../pool'\nimport type { Puff } from './puffs'\n\n/** A shock wave: an air shell that grows to the lethal radius in 120 ms, and a dust ring on the ground (L319-348). The last block is what the renderer reads. */\nexport interface Shock {\n x: number\n y: number\n z: number\n Rs: number\n Rg: number\n t: number\n dur: number\n shellScale: number\n shellAlpha: number\n ringScale: number\n ringAlpha: number\n}\n\nconst DEFAULT_DURATION = 0.3\nconst SHELL_GROWTH_SECONDS = 0.12\nconst SHELL_FADE_SECONDS = 0.16\nconst PUSH_BAND = 0.8\nconst PUSH_CEILING = 3\nconst PUSH_AGE_LIMIT = 2\n\nexport function createShockPool(capacity: number): OrderedPool<Shock> {\n return new OrderedPool<Shock>(capacity, () => ({ x: 0, y: 0, z: 0, Rs: 0, Rg: 0, t: 0, dur: DEFAULT_DURATION, shellScale: 0, shellAlpha: 0, ringScale: 0, ringAlpha: 0 }))\n}\n\nexport function spawnShock(pool: OrderedPool<Shock>, spec: { x: number; y: number; z: number; shellRadius: number; groundRadius: number; duration: number }): Shock {\n const shock = pool.acquire()\n shock.x = spec.x\n shock.y = spec.y\n shock.z = spec.z\n shock.Rs = spec.shellRadius\n shock.Rg = spec.groundRadius\n shock.t = 0\n shock.dur = spec.duration || DEFAULT_DURATION\n shock.shellScale = 0\n shock.shellAlpha = 0\n shock.ringScale = 0\n shock.ringAlpha = 0\n return shock\n}\n\nfunction pushPuffs(puffs: readonly Puff[], shock: Shock, reach: number, dt: number, age: number): void {\n for (const puff of puffs) {\n if (puff.ring || puff.t > PUSH_AGE_LIMIT) continue\n const dx = puff.x - shock.x\n const dz = puff.z - shock.z\n const distance = Math.hypot(dx, dz) + 0.001\n if (Math.abs(distance - reach) < PUSH_BAND && puff.y < PUSH_CEILING) {\n const strength = 4 * dt * (1 - age)\n puff.vx += (dx / distance) * strength * 6\n puff.vz += (dz / distance) * strength * 6\n }\n }\n}\n\n/** `updateShocks` (L335-348), walking the list backwards like the Lab: the fronts push the smoke and dust they meet. */\nexport function updateShocks(pool: OrderedPool<Shock>, puffs: readonly Puff[], dt: number): void {\n for (let index = pool.items.length - 1; index >= 0; index--) {\n const shock = pool.items[index]!\n shock.t += dt\n const age = shock.t / shock.dur\n const shellEase = 1 - Math.pow(1 - Math.min(1, shock.t / SHELL_GROWTH_SECONDS), 3)\n shock.shellScale = Math.max(0.01, shock.Rs * shellEase)\n shock.shellAlpha = Math.max(0, 1 - shock.t / SHELL_FADE_SECONDS) * 0.9\n const ringEase = 1 - Math.pow(1 - Math.min(1, age), 2.2)\n shock.ringScale = Math.max(0.01, shock.Rg * ringEase)\n shock.ringAlpha = Math.max(0, 1 - age) * 0.85\n pushPuffs(puffs, shock, shock.Rg * ringEase, dt, age)\n if (age >= 1) pool.removeAt(index)\n }\n}\n","import { hexToLinearRgb, hexToRgb } from './color'\nimport { SMOKE_COLORS } from './constants'\nimport type { VfxCore } from './core'\nimport { lightBlast } from './lights'\nimport { lodScale } from './lod'\nimport { addCrater, addScorch } from './marks'\nimport { spawnRing } from './pools/rings'\nimport { spawnShock } from './pools/shocks'\nimport type { RandomStream, MutableVec3 } from './random'\nimport { addFire } from './emitters/fire'\nimport { addChunk, addGlow, addPuff, addSpark } from './spawn'\nimport type { ExplosionDef, MushroomSpec } from './types'\nimport { addScaled, createVec3, distanceBetween, normalize } from './vector'\n\n/** Where and how one explosion goes off. */\nexport interface ExplosionCall {\n readonly x: number\n readonly y: number\n readonly z: number\n /** Where it is aimed (a rocket's direction, a charge's face). */\n readonly direction?: MutableVec3\n /** The stream the whole effect draws from: the world's in `shared` mode, the event's own in `per_event`. */\n readonly random: RandomStream\n readonly handle: number\n}\n\ninterface Context {\n readonly core: VfxCore\n readonly def: ExplosionDef\n readonly call: ExplosionCall\n readonly random: RandomStream\n readonly x: number\n readonly y: number\n readonly z: number\n /** Fireball radius. */\n readonly size: number\n /** LOD scale of this explosion. */\n readonly scale: number\n readonly direction: MutableVec3 | undefined\n readonly smokeColor: readonly [number, number, number]\n /** Where the camera is (for the screen flash), distance to the blast. */\n readonly cameraDistance: number\n}\n\nconst DEFAULT_LIGHT = 40\nconst DEFAULT_LIGHT_LIFE = 0.45\nconst DEFAULT_LIGHT_COLOR = 0xffa050\nconst DEFAULT_FLASH_INTENSITY = 6\nconst DEFAULT_SHOCK_DURATION = 0.32\nconst DEFAULT_CHUNK_COLOR = 0x47423d\nconst ROCK_COLORS = [0x2b2c2f, 0x4a3a2c] as const\nconst SCRATCH = createVec3()\n\nfunction pick<T>(random: RandomStream, items: readonly T[]): T {\n return items[Math.floor(random.next() * items.length)]!\n}\n\nfunction composeFlash(context: Context): void {\n const { core, def, x, y, z, size } = context\n if (!core.layers.flash) return\n const flash = def.flash\n const light = { x, y: y + size * 0.6, z, peak: (flash.light || DEFAULT_LIGHT) * 0.7, distance: (def.injury || 10) * 2.4, life: flash.life || DEFAULT_LIGHT_LIFE, color: flash.color || DEFAULT_LIGHT_COLOR }\n core.trace?.light?.(light)\n lightBlast(core.lights, light)\n core.spawned.lights++\n const blinding = flash.blinding === true\n addGlow(core, { x, y: y + size * 0.4, z, s: size * 1.4, s1: size * 3.2, i: flash.intensity || DEFAULT_FLASH_INTENSITY, life: 0.22, color: [1, 0.92, 0.75], curve: 2.5 })\n if (!blinding) addGlow(core, { x, y: y + size * 0.5, z, s: size * 2.2, s1: size * 3.6, i: 2.2, life: def.fuel ? 1.4 : 0.6, color: [1, 0.45, 0.15], curve: 1.6 })\n if (core.reducedMotion) return\n const distance = context.cameraDistance\n const screen = core.screen\n if (distance < 15) {\n screen.flash = Math.max(screen.flash, (blinding ? 1 : 0.32) * (1 - distance / 15))\n screen.flashDecay = blinding ? 0.55 : 7\n }\n if (blinding && distance < 40) {\n screen.flash = Math.max(screen.flash, 1)\n screen.flashDecay = 0.5\n }\n}\n\nfunction composeFireballs(context: Context): void {\n const { core, def, random, x, y, z, size, scale, direction } = context\n if (!core.layers.fire || !def.fireballs) return\n const count = Math.round(def.fireballs * Math.max(scale, 0.35))\n const fuel = def.fuel === true\n const heat = def.heat ?? 1\n for (let index = 0; index < count; index++) {\n const d = random.direction(SCRATCH)\n d.y = fuel ? Math.abs(d.y) * 0.5 + 0.05 : Math.abs(d.y) * 0.8 + 0.1\n if (direction) normalize(addScaled(d, direction, def.directionBias ?? 1.2))\n const speed = size * random.between(4.5, 7.5) * (fuel ? 0.75 : 1)\n const s1 = size * random.between(0.42, 0.62)\n const sg = size * random.between(0.12, 0.22)\n const life = random.between(def.smoke.life * 0.7, def.smoke.life)\n const h0 = random.between(1.05, 1.35) * heat\n const hl = fuel ? random.between(0.8, 1.4) * (def.heatLifeScale ?? 1) : random.between(0.22, 0.42)\n addPuff(core, random, {\n x: x + d.x * size * 0.15, y: y + size * 0.25 + d.y * size * 0.1, z: z + d.z * size * 0.15,\n vx: d.x * speed, vy: d.y * speed + (fuel ? size * 1.4 : size * 0.6), vz: d.z * speed,\n s0: size * 0.22, s1, sg, gk: 9, life, h0, hl, drag: fuel ? 4.2 : 6.5, buoy: fuel ? 2.2 : 1.2, color: context.smokeColor, kind: 0,\n })\n }\n}\n\nfunction composeSmoke(context: Context): void {\n const { core, def, random, x, y, z, size, scale } = context\n if (!core.layers.smoke || !def.smoke.count) return\n const count = Math.round(def.smoke.count * Math.max(scale, 0.3))\n for (let index = 0; index < count; index++) {\n const d = random.direction(SCRATCH)\n d.y = Math.abs(d.y)\n const vy = size * random.between(0.6, 2.2)\n const s1 = size * random.between(0.55, 0.85)\n const sg = size * random.between(0.18, 0.3)\n const life = random.between(def.smoke.life * 0.7, def.smoke.life * 1.1)\n addPuff(core, random, {\n x: x + d.x * size * 0.6, y: y + size * 0.4 + d.y * size * 0.5, z: z + d.z * size * 0.6,\n vx: d.x * size * 2.4, vy, vz: d.z * size * 2.4, s0: size * 0.25, s1, sg, gk: 4, life, h0: 0.32, hl: 0.25, drag: 3, buoy: 0.45, color: context.smokeColor, kind: def.smoke.kind ?? 0,\n })\n }\n}\n\nfunction composeShock(context: Context): void {\n const { core, def, x, y, z, size, scale } = context\n if (!core.layers.shock || def.shock === false || !(scale > 0.15)) return\n const duration = def.shock ? def.shock.duration : DEFAULT_SHOCK_DURATION\n const spec = { x, y: y + size * 0.3, z, shellRadius: def.lethal * 0.9, groundRadius: def.injury * 0.6, duration }\n core.trace?.shock?.(spec)\n spawnShock(core.shocks, spec)\n}\n\nfunction composeDust(context: Context): void {\n const { core, def, random, x, z, size, scale } = context\n if (!core.layers.smoke || !def.dust.count || !(scale > 0.15)) return\n const count = Math.round(def.dust.count * scale)\n const color = hexToLinearRgb(def.dust.color)\n const cone = def.cone\n for (let index = 0; index < count; index++) {\n let angle = random.next() * Math.PI * 2\n if (cone) angle = coneAngle(context) + random.between(-cone.half, cone.half)\n const speed = random.between(0.6, 1) * def.injury * (cone ? 1.6 : 0.9)\n const vy = random.between(0.2, 1.2)\n const s1 = size * random.between(0.5, 0.8)\n const sg = size * random.between(0.2, 0.35)\n const life = random.between(2.2, 4)\n addPuff(core, random, {\n x: x + Math.cos(angle) * 0.3, y: 0.15, z: z + Math.sin(angle) * 0.3,\n vx: Math.cos(angle) * speed, vy, vz: Math.sin(angle) * speed, s0: size * 0.2, s1, sg, gk: 5, life, drag: 3.6, buoy: 0.2, color, kind: 1,\n })\n }\n}\n\n/** The angle of the cone's axis: the direction it is aimed at, else the one in its profile. */\nfunction coneAngle(context: Context): number {\n const cone = context.def.cone\n if (!cone) return 0\n return context.direction ? Math.atan2(context.direction.z, context.direction.x) : cone.angle\n}\n\nfunction sparkDirection(context: Context): MutableVec3 {\n const { def, random, direction } = context\n const cone = def.cone\n if (cone) {\n const angle = coneAngle(context) + random.between(-cone.half, cone.half)\n SCRATCH.x = Math.cos(angle)\n SCRATCH.y = random.between(-0.05, 0.25)\n SCRATCH.z = Math.sin(angle)\n return SCRATCH\n }\n const d = random.direction(SCRATCH)\n d.y = Math.abs(d.y) * 0.9 + 0.05\n if (direction) normalize(addScaled(d, direction, def.directionBias ?? 1))\n return d\n}\n\nfunction composeEmbers(context: Context): void {\n const { core, def, random, x, y, z, size, scale } = context\n const embers = def.shrapnel.embers\n if (!embers) return\n for (let index = 0; index < embers * scale; index++) {\n const d = random.direction(SCRATCH)\n d.y = Math.abs(d.y)\n const vx = d.x * random.between(2, 6)\n const vy = random.between(3, 8)\n const vz = d.z * random.between(2, 6)\n addSpark(core, { x, y: y + size * 0.5, z, vx, vy, vz, life: random.between(1.2, 2.6), w: 0.04, st: 0.02, kind: 4, drag: 1.6, g: 2.5 })\n }\n}\n\nfunction composeShrapnel(context: Context): void {\n const { core, def, random, x, y, z, size, scale } = context\n if (!core.layers.shrapnel || !def.shrapnel.count) return\n const count = Math.round(def.shrapnel.count * scale)\n for (let index = 0; index < count; index++) {\n const d = sparkDirection(context)\n const speed = def.shrapnel.speed * random.between(0.45, 1)\n addSpark(core, {\n x: x + d.x * 0.1, y: y + size * 0.25, z: z + d.z * 0.1, vx: d.x * speed, vy: d.y * speed, vz: d.z * speed,\n life: random.between(0.35, 1.1), w: def.shrapnel.width ?? 0.035, st: 0.03, kind: def.shrapnel.kind, drag: def.shrapnel.kind === 1 ? 0.15 : 0.9,\n })\n }\n composeEmbers(context)\n}\n\nfunction composeDebris(context: Context): void {\n const { core, def, random, x, y, z, scale, direction } = context\n const chunks = def.chunks\n if (!core.layers.shrapnel || !chunks.count || scale < 0.5) return\n const count = Math.round(chunks.count * (scale >= 1 ? 1 : 0.5))\n for (let index = 0; index < count; index++) {\n const d = random.direction(SCRATCH)\n d.y = Math.abs(d.y) * 0.9 + 0.2\n if (direction) normalize(addScaled(d, direction, 0.8))\n const speed = random.between(4, 11) * (chunks.speed ?? 1)\n const s = random.between(0.07, 0.2) * (chunks.size ?? 1)\n const plate = chunks.plate ? random.next() < 0.6 : random.next() < 0.15\n const sy = plate ? s * 0.3 : s * random.between(0.6, 1)\n const color = hexToRgb(chunks.colors.length > 0 ? pick(random, chunks.colors) : DEFAULT_CHUNK_COLOR)\n const hot = random.next() < chunks.hot\n addChunk(core, random, {\n x: x + d.x * 0.2, y: y + 0.2, z: z + d.z * 0.2, vx: d.x * speed, vy: d.y * speed + 2, vz: d.z * speed,\n sx: plate ? s * 1.6 : s, sy, sz: plate ? s * 1.1 : s, color, plate, hot,\n })\n }\n}\n\nfunction composeRimDebris(context: Context): void {\n const { core, random, x, z } = context\n const radius = context.def.mark.crater ?? 0\n if (!core.layers.shrapnel) return\n const speedScale = context.def.chunks.speed ?? 1\n const count = Math.round(4 + radius * 4)\n for (let index = 0; index < count; index++) {\n const angle = random.next() * Math.PI * 2\n const speed = random.between(3, 8) * speedScale\n const s = random.between(0.12, 0.28)\n const vy = random.between(4, 10)\n const color = hexToRgb(random.next() < 0.6 ? ROCK_COLORS[0] : ROCK_COLORS[1])\n addChunk(core, random, {\n x: x + Math.cos(angle) * 0.3, y: 0.1, z: z + Math.sin(angle) * 0.3, vx: Math.cos(angle) * speed * 0.6, vy, vz: Math.sin(angle) * speed * 0.6,\n sx: s * 1.6, sy: s * 0.35, sz: s * 1.2, color, plate: true,\n })\n }\n}\n\nfunction composeMushroom(context: Context, spec: MushroomSpec): void {\n const { core, random, x, y, z } = context\n core.trace?.mushroom?.(x, y, z, spec)\n const color = spec.color !== undefined ? hexToLinearRgb(spec.color) : SMOKE_COLORS.black\n const ring = spawnRing(core.rings, {\n x, z, y0: y + spec.height * 0.15, rise: spec.height, rk: spec.riseRate ?? 0.55, R0: spec.radius * 0.3, R1: spec.radius, r: spec.radius * 0.42, roll: spec.roll ?? 2.4, life: spec.life || 7,\n })\n const lod = core.clock.lod\n const count = Math.round((spec.count || 40) * Math.max(lod, 0.4))\n for (let index = 0; index < count; index++) {\n const s1 = spec.radius * random.between(0.35, 0.5)\n const life = random.between(ring.life * 0.75, ring.life)\n const h0 = random.between(1, 1.25)\n const hl = random.between(0.9, 1.6)\n const puff = addPuff(core, random, { x, y, z, s0: spec.radius * 0.2, s1, sg: spec.radius * 0.06, gk: 3, life, h0, hl, color, kind: 0 })\n puff.ring = ring\n puff.ph = random.next() * Math.PI * 2\n puff.th = random.next() * Math.PI * 2\n }\n const stemCount = Math.round((spec.stem || 18) * Math.max(lod, 0.4))\n for (let index = 0; index < stemCount; index++) {\n const spread = random.next() * 0.6\n const px = x + random.between(-0.4, 0.4) * spec.radius * 0.2\n const pz = z + random.between(-0.4, 0.4) * spec.radius * 0.2\n const vx = random.between(-0.3, 0.3)\n const vy = spec.height * random.between(0.6, 1.4) * (1 - spread)\n const vz = random.between(-0.3, 0.3)\n const s1 = spec.radius * random.between(0.22, 0.32)\n const life = random.between(3, 5)\n const h0 = random.between(0.9, 1.2)\n const hl = random.between(0.6, 1.1)\n addPuff(core, random, { x: px, y: y + 0.3, z: pz, vx, vy, vz, s0: spec.radius * 0.12, s1, sg: spec.radius * 0.05, gk: 4, life, h0, hl, drag: 1.2, buoy: 0.5, color })\n }\n}\n\nfunction composeAfterEffects(context: Context): void {\n const { core, def, random, x, y, z } = context\n const mark = def.mark\n if (mark.crater && mark.dent && y < 1.2) {\n core.emit({ type: 'crater', x, z, radius: mark.crater, depth: mark.dent })\n core.trace?.crater?.(x, z, mark.crater, mark.dent)\n addCrater(core.marks, core.ground, random, { x, z, radius: mark.crater, depth: mark.dent, marks: core.layers.mark })\n if (core.layers.shrapnel) composeRimDebris(context)\n }\n if (mark.scorch && y < 1.2 && core.layers.mark) {\n core.trace?.scorch?.(x, z, mark.scorch)\n addScorch(core.marks, random, x, z, mark.scorch)\n }\n if (def.mushroom && core.layers.fire) composeMushroom(context, def.mushroom)\n if (def.residualFires && core.layers.fire) {\n for (const fire of def.residualFires) {\n addFire(core, random, {\n x: x + (fire.dx ?? 0), y: 0, z: z + (fire.dz ?? 0), r: fire.radius, life: fire.life, rate: fire.rate, smoke: fire.smoke, startRadius: fire.startRadius, grow: fire.grow,\n color: fire.smokeColor !== undefined ? hexToLinearRgb(fire.smokeColor) : undefined,\n }, context.call.handle)\n }\n }\n}\n\nfunction emitRequests(context: Context): void {\n const { core, def, x, y, z } = context\n const point = [x, y, z] as const\n core.emit({\n type: 'blast_front', explosion: def.id, point, glassRadius: Math.min(def.injury, 20) * 0.85, speed: 340, lethal: def.lethal, injury: def.injury, push: def.push,\n hotParts: def.hotParts === true, blinding: def.flash.blinding === true, cone: def.cone ? { angle: coneAngle(context), half: def.cone.half, length: def.cone.length } : undefined,\n })\n if (def.ignite) core.emit({ type: 'ignite', point, radius: def.ignite })\n}\n\n/**\n * The Lab's layer compositor (`blast`, L642-714), layer by layer in the Lab's order and drawing from the stream in the Lab's order: flash, fireball,\n * its own smoke, shock wave, dust, shrapnel, debris, then marks, mushroom and lingering fires, and last what the host does (glass, characters).\n */\nexport function composeExplosion(core: VfxCore, def: ExplosionDef, call: ExplosionCall): number {\n const cameraDistance = distanceBetween(core.camera.x, core.camera.y, core.camera.z, call.x, call.y, call.z)\n const forced = core.clock.forcedLod\n const bandScale = forced ?? lodScale(core.bands, cameraDistance, def.visualRadius)\n const capScale = core.areaCap ? core.areaCap.register(core.clock.time, call.x, call.z) : 1\n const scale = forced ?? bandScale * capScale\n core.clock.lod = scale\n core.clock.lastBlast = core.clock.time\n core.spawned.puffs = core.spawned.sparks = core.spawned.chunks = core.spawned.lights = 0\n const context: Context = {\n core, def, call, random: call.random, x: call.x, y: call.y, z: call.z, size: def.visualRadius, scale, direction: call.direction,\n smokeColor: hexToLinearRgb(def.smoke.color), cameraDistance,\n }\n composeFlash(context)\n core.screen.shake = Math.max(core.screen.shake, (def.shake || 1) / (1 + cameraDistance * 0.12))\n composeFireballs(context)\n composeSmoke(context)\n composeShock(context)\n composeDust(context)\n composeShrapnel(context)\n composeDebris(context)\n composeAfterEffects(context)\n emitRequests(context)\n return scale\n}\n","import type { VfxCore } from '../core'\nimport type { Chunk } from './chunks'\nimport { addBloodSplat } from '../marks'\nimport { SMOKE_COLORS } from '../constants'\nimport { addPuff, addSpark } from '../spawn'\n\nconst RESTITUTION = -0.32\nconst GROUND_FRICTION = 0.5\nconst REST_SPEED = 0.6\nconst REST_SLIDE = 0.5\nconst TRAIL_SECONDS = 1.8\nconst TRAIL_STEP = 0.025\nconst QUARTER_TURN = Math.PI / 2\n\nfunction bounce(core: VfxCore, chunk: Chunk, floor: number): void {\n chunk.y = floor\n if (chunk.blood && !chunk.splat && core.layers.mark) {\n chunk.splat = true\n addBloodSplat(core.marks, core.ground, chunk.rng, { x: chunk.x, z: chunk.z, radius: chunk.rng.between(0.06, 0.13) })\n }\n chunk.vy *= RESTITUTION\n chunk.vx *= GROUND_FRICTION\n chunk.vz *= GROUND_FRICTION\n chunk.ax *= GROUND_FRICTION\n chunk.ay *= GROUND_FRICTION\n chunk.az *= GROUND_FRICTION\n if (Math.abs(chunk.vy) < REST_SPEED && Math.hypot(chunk.vx, chunk.vz) < REST_SLIDE) {\n chunk.rest = true\n chunk.rx = Math.round(chunk.rx / QUARTER_TURN) * QUARTER_TURN\n chunk.rz = Math.round(chunk.rz / QUARTER_TURN) * QUARTER_TURN\n }\n}\n\nfunction leaveTrail(core: VfxCore, chunk: Chunk, dt: number): void {\n chunk.trail -= dt\n if (chunk.trail > 0) return\n chunk.trail = TRAIL_STEP\n const random = chunk.rng\n addSpark(core, {\n x: chunk.x, y: chunk.y, z: chunk.z, vx: chunk.vx * 0.15, vy: chunk.vy * 0.15, vz: chunk.vz * 0.15,\n life: random.between(0.25, 0.45), w: 0.05 + chunk.sx * 0.2, st: 0.05, kind: 0, g: 0, drag: 1,\n })\n if (random.next() < 0.25) {\n addPuff(core, random, { x: chunk.x, y: chunk.y, z: chunk.z, s0: 0.04, s1: 0.14 + chunk.sx * 0.3, sg: 0.15, life: random.between(1, 1.6), drag: 2, buoy: 0.6, color: SMOKE_COLORS.grey, kind: 0 })\n }\n}\n\n/** `updateChunks` (L383-398): gravity, spin, a bounce that kills speed, a rest pose on a quarter turn, and the ember trail of a hot piece. */\nexport function updateChunks(core: VfxCore, dt: number): void {\n for (const chunk of core.chunks.items) {\n chunk.t += dt\n if (chunk.rest) continue\n chunk.vy -= core.gravity * dt\n chunk.x += chunk.vx * dt\n chunk.y += chunk.vy * dt\n chunk.z += chunk.vz * dt\n chunk.rx += chunk.ax * dt\n chunk.ry += chunk.ay * dt\n chunk.rz += chunk.az * dt\n const floor = chunk.sy * 0.45 + core.groundAt(chunk.x, chunk.z)\n if (chunk.y < floor) bounce(core, chunk, floor)\n if (chunk.hot && chunk.t < TRAIL_SECONDS && core.layers.smoke) leaveTrail(core, chunk, dt)\n }\n}\n","import type { ScreenState } from './types'\n\nconst DECAY = { shake: 5, white: 7, red: 2.2, side: 3, chroma: 3, desat: 0.7, gasSeconds: 5, beat: 6 } as const\nexport const INITIAL_FLASH_DECAY = 6\n\nexport function createScreenState(): ScreenState {\n return { shake: 0, flash: 0, flashDecay: INITIAL_FLASH_DECAY, white: 0, red: 0, directionLeft: 0, directionRight: 0, chroma: 0, desat: 0, gas: 0, beat: 0 }\n}\n\nexport function resetScreenState(state: ScreenState): void {\n Object.assign(state, createScreenState())\n}\n\n/**\n * The decays of the Lab (L1087, L1092: flash by its own rate, shake by 5 per second) and the Workshop (W354-355: white, red, the two sides, chroma,\n * desaturation, gas and the heartbeat), with the same constants.\n */\nexport function updateScreen(state: ScreenState, dt: number): void {\n state.flash *= Math.exp(-state.flashDecay * dt)\n state.shake *= Math.exp(-DECAY.shake * dt)\n state.white *= Math.exp(-DECAY.white * dt)\n state.red *= Math.exp(-DECAY.red * dt)\n state.directionLeft *= Math.exp(-DECAY.side * dt)\n state.directionRight *= Math.exp(-DECAY.side * dt)\n state.chroma *= Math.exp(-DECAY.chroma * dt)\n state.desat *= Math.exp(-DECAY.desat * dt)\n state.gas = Math.max(0, state.gas - dt / DECAY.gasSeconds)\n state.beat *= Math.exp(-DECAY.beat * dt)\n}\n","import type { SpriteKindDef } from './kinds'\n\nconst clamp = (v: number, lo: number, hi: number): number => (v < lo ? lo : v > hi ? hi : v)\nconst lerp = (a: number, b: number, t: number): number => a + (b - a) * t\n\nfunction rgb(hex: number): readonly [number, number, number] {\n return [((hex >> 16) & 255) / 255, ((hex >> 8) & 255) / 255, (hex & 255) / 255]\n}\n\n/** Per-spawn overrides. */\nexport interface SpriteSpawnOptions {\n /** `0xRRGGBB`: replaces the kind's colour ramp. */\n color?: number\n /** Multiplier on the start size. */\n size?: number\n /** Multiplier on the life. */\n life?: number\n /** Multiplier on the peak alpha. */\n alpha?: number\n /** Non-zero: a `land` sprite (a drip) that reaches the ground calls the owner's `onLand` with this tag. */\n tag?: number\n /** Who hears the landing (see `VfxWorld.onLand`). */\n owner?: string\n /** Height the sprite stops or lands at, instead of the ground's under it (a splash on a table top). */\n floor?: number\n /** Multiplier on the kind's upward acceleration (slow steam). */\n rise?: number\n}\n\nexport interface KindPoolHost {\n groundAt(x: number, z: number): number\n gravity: number\n land(owner: string, x: number, y: number, z: number, color: number, tag: number): void\n}\n\n/** The destruction renderer's old generator (mulberry32), so a seed gives the same sprites. */\nexport function spriteRandom(seed: number): () => number {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) >>> 0\n let t = a\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/**\n * One fixed-size ring of sprites of the game's kinds, in typed arrays a renderer draws as points: `position`, `color`, `alpha` and `size` are what it\n * reads, `drawCount` how many records from the start. Additive and normal blending are two instances.\n */\nexport class SpriteKindPool {\n live = 0\n /** Records from the start the renderer draws (the highest live index + 1). */\n drawCount = 0\n readonly position: Float32Array\n readonly color: Float32Array\n readonly alpha: Float32Array\n readonly size: Float32Array\n private next = 0\n private high = 0\n private readonly velocity: Float32Array\n private readonly age: Float32Array\n private readonly life: Float32Array\n private readonly size0: Float32Array\n private readonly alive: Uint8Array\n private readonly kind: Uint8Array\n private readonly seed: Float32Array\n private readonly alphaMul: Float32Array\n private readonly tag: Int32Array\n private readonly owner: Int32Array\n private readonly colorHex: Int32Array\n private readonly rgbStart: Float32Array\n private readonly rgbEnd: Float32Array\n private readonly bounced: Uint8Array\n private readonly floor: Float32Array\n private readonly riseMul: Float32Array\n\n constructor(\n readonly capacity: number,\n private readonly defs: readonly SpriteKindDef[],\n private readonly owners: string[],\n ) {\n const n = Math.max(1, capacity)\n this.position = new Float32Array(n * 3)\n this.color = new Float32Array(n * 3)\n this.alpha = new Float32Array(n)\n this.size = new Float32Array(n)\n this.velocity = new Float32Array(n * 3)\n this.age = new Float32Array(n)\n this.life = new Float32Array(n)\n this.size0 = new Float32Array(n)\n this.alive = new Uint8Array(n)\n this.kind = new Uint8Array(n)\n this.seed = new Float32Array(n)\n this.alphaMul = new Float32Array(n)\n this.tag = new Int32Array(n)\n this.owner = new Int32Array(n)\n this.colorHex = new Int32Array(n)\n this.rgbStart = new Float32Array(n * 3)\n this.rgbEnd = new Float32Array(n * 3)\n this.bounced = new Uint8Array(n)\n this.floor = new Float32Array(n)\n this.riseMul = new Float32Array(n)\n }\n\n spawn(kind: number, p: readonly number[], v: readonly number[], random: () => number, options?: SpriteSpawnOptions): void {\n if (this.capacity <= 0) return\n const def = this.defs[kind]!\n const i = this.next\n this.next = (this.next + 1) % this.capacity\n if (this.alive[i]) this.live--\n this.alive[i] = 1\n this.live++\n if (i + 1 > this.high) this.high = i + 1\n this.kind[i] = kind\n this.position.set(p, i * 3)\n this.velocity.set(v, i * 3)\n this.age[i] = 0\n this.life[i] = lerp(def.life[0], def.life[1], random()) * (options?.life ?? 1)\n this.size0[i] = lerp(def.size[0], def.size[1], random()) * (options?.size ?? 1)\n this.seed[i] = random()\n this.alphaMul[i] = options?.alpha ?? 1\n this.tag[i] = options?.tag ?? 0\n this.owner[i] = options?.owner === undefined ? -1 : this.ownerIndex(options.owner)\n this.colorHex[i] = options?.color ?? -1\n this.rgbStart.set(rgb(options?.color ?? def.c0), i * 3)\n this.rgbEnd.set(rgb(options?.color ?? def.c1), i * 3)\n this.bounced[i] = 0\n this.floor[i] = options?.floor ?? Number.NaN\n this.riseMul[i] = options?.rise ?? 1\n this.size[i] = this.size0[i]!\n this.alpha[i] = 0\n }\n\n private ownerIndex(name: string): number {\n let index = this.owners.indexOf(name)\n if (index < 0) index = this.owners.push(name) - 1\n return index\n }\n\n private kill(i: number): void {\n if (!this.alive[i]) return\n this.alive[i] = 0\n this.live--\n this.alpha[i] = 0\n this.size[i] = 0\n }\n\n clear(): void {\n this.alive.fill(0)\n this.alpha.fill(0)\n this.size.fill(0)\n this.live = 0\n this.high = 0\n this.next = 0\n this.drawCount = 0\n }\n\n /** Shoves the live sprites within `radius` of a point away from it (a blast). */\n push(cx: number, cy: number, cz: number, radius: number, speed: number): void {\n for (let i = 0; i < this.high; i++) {\n if (!this.alive[i]) continue\n const dx = this.position[i * 3]! - cx\n const dy = this.position[i * 3 + 1]! - cy\n const dz = this.position[i * 3 + 2]! - cz\n const d = Math.hypot(dx, dy, dz)\n if (d > radius || d < 1e-4) continue\n const f = (1 - d / radius) * speed\n this.velocity[i * 3]! += (dx / d) * f\n this.velocity[i * 3 + 1]! += (dy / d) * f\n this.velocity[i * 3 + 2]! += (dz / d) * f\n }\n }\n\n update(dt: number, host: KindPoolHost): void {\n let top = 0\n for (let i = 0; i < this.high; i++) {\n if (!this.alive[i]) continue\n const def = this.defs[this.kind[i]!]!\n const age = (this.age[i]! + dt)\n this.age[i] = age\n const life = this.life[i]!\n if (age >= life) {\n this.kill(i)\n continue\n }\n const t = age / life\n const i3 = i * 3\n let vx = this.velocity[i3]!\n let vy = this.velocity[i3 + 1]!\n let vz = this.velocity[i3 + 2]!\n vy += (def.rise * this.riseMul[i]! - def.gravity * host.gravity) * dt\n if (def.flutter) {\n const phase = age * 7 + this.seed[i]! * 40\n vx += Math.sin(phase) * def.flutter * dt\n vz += Math.cos(phase * 1.3) * def.flutter * dt\n }\n if (def.drag > 0) {\n const k = Math.exp(-def.drag * dt)\n vx *= k\n vy *= k\n vz *= k\n }\n const x = this.position[i3]! + vx * dt\n let y = this.position[i3 + 1]! + vy * dt\n const z = this.position[i3 + 2]! + vz * dt\n if (def.ground !== 'none') {\n const own = this.floor[i]!\n const gy = Number.isNaN(own) ? host.groundAt(x, z) + 0.005 : own\n if (y < gy) {\n if (def.ground === 'land') {\n const tag = this.tag[i]!\n const owner = this.owner[i]!\n if (tag !== 0 && owner >= 0) host.land(this.owners[owner]!, x, gy, z, this.colorHex[i]! >= 0 ? this.colorHex[i]! : def.c0, tag)\n this.kill(i)\n continue\n }\n y = gy\n if (def.ground === 'bounce' && !this.bounced[i]) {\n this.bounced[i] = 1\n vy = Math.abs(vy) * 0.35\n vx *= 0.6\n vz *= 0.6\n } else {\n vx = vy = vz = 0\n }\n }\n }\n this.velocity[i3] = vx\n this.velocity[i3 + 1] = vy\n this.velocity[i3 + 2] = vz\n this.position[i3] = x\n this.position[i3 + 1] = y\n this.position[i3 + 2] = z\n this.size[i] = this.size0[i]! * lerp(1, def.grow, t)\n this.color[i3] = lerp(this.rgbStart[i3]!, this.rgbEnd[i3]!, t)\n this.color[i3 + 1] = lerp(this.rgbStart[i3 + 1]!, this.rgbEnd[i3 + 1]!, t)\n this.color[i3 + 2] = lerp(this.rgbStart[i3 + 2]!, this.rgbEnd[i3 + 2]!, t)\n let envelope = t < def.fadeIn ? t / def.fadeIn : 1 - (t - def.fadeIn) / (1 - def.fadeIn)\n if (def.flicker) envelope *= 1 - def.flicker * (0.5 + 0.5 * Math.sin(age * 38 + this.seed[i]! * 50))\n this.alpha[i] = clamp(envelope, 0, 1) * def.alpha * this.alphaMul[i]!\n top = i + 1\n }\n this.high = top\n this.drawCount = top\n }\n}\n\nexport { rgb as hexToUnitRgb }\n","{\n \"fire\": {\n \"id\": \"fire\",\n \"additive\": true,\n \"life\": [\n 0.45,\n 0.9\n ],\n \"size\": [\n 0.1,\n 0.2\n ],\n \"grow\": 0.3,\n \"gravity\": 0,\n \"rise\": 2.4,\n \"drag\": 1.2,\n \"c0\": 16760896,\n \"c1\": 12591104,\n \"alpha\": 0.9,\n \"fadeIn\": 0.12,\n \"cone\": 0.7,\n \"ground\": \"none\",\n \"flicker\": 0.35\n },\n \"smoke\": {\n \"id\": \"smoke\",\n \"additive\": false,\n \"life\": [\n 1.8,\n 3.2\n ],\n \"size\": [\n 0.14,\n 0.24\n ],\n \"grow\": 3.2,\n \"gravity\": 0,\n \"rise\": 0.7,\n \"drag\": 0.8,\n \"c0\": 6710886,\n \"c1\": 10132122,\n \"alpha\": 0.35,\n \"fadeIn\": 0.15,\n \"cone\": 0.6,\n \"ground\": \"none\"\n },\n \"sparks\": {\n \"id\": \"sparks\",\n \"additive\": true,\n \"life\": [\n 0.25,\n 0.6\n ],\n \"size\": [\n 0.018,\n 0.03\n ],\n \"grow\": 0.5,\n \"gravity\": 1,\n \"rise\": 0,\n \"drag\": 0.3,\n \"c0\": 16773792,\n \"c1\": 16738832,\n \"alpha\": 1,\n \"fadeIn\": 0.02,\n \"cone\": 0.55,\n \"ground\": \"bounce\"\n },\n \"dust\": {\n \"id\": \"dust\",\n \"additive\": false,\n \"life\": [\n 1,\n 2\n ],\n \"size\": [\n 0.08,\n 0.14\n ],\n \"grow\": 2.5,\n \"gravity\": 0.05,\n \"rise\": 0,\n \"drag\": 2.5,\n \"c0\": 9274745,\n \"c1\": 9274745,\n \"alpha\": 0.4,\n \"fadeIn\": 0.1,\n \"cone\": 0.4,\n \"ground\": \"none\"\n },\n \"shards\": {\n \"id\": \"shards\",\n \"additive\": true,\n \"life\": [\n 0.8,\n 1.4\n ],\n \"size\": [\n 0.02,\n 0.035\n ],\n \"grow\": 0.8,\n \"gravity\": 1,\n \"rise\": 0,\n \"drag\": 0.2,\n \"c0\": 14677247,\n \"c1\": 10473727,\n \"alpha\": 0.9,\n \"fadeIn\": 0.03,\n \"cone\": 0.5,\n \"ground\": \"bounce\",\n \"flicker\": 0.5\n },\n \"splinters\": {\n \"id\": \"splinters\",\n \"additive\": false,\n \"life\": [\n 0.8,\n 1.5\n ],\n \"size\": [\n 0.02,\n 0.035\n ],\n \"grow\": 1,\n \"gravity\": 1,\n \"rise\": 0,\n \"drag\": 0.3,\n \"c0\": 10516042,\n \"c1\": 8017200,\n \"alpha\": 1,\n \"fadeIn\": 0.02,\n \"cone\": 0.5,\n \"ground\": \"bounce\"\n },\n \"chips\": {\n \"id\": \"chips\",\n \"additive\": false,\n \"life\": [\n 0.8,\n 1.5\n ],\n \"size\": [\n 0.025,\n 0.04\n ],\n \"grow\": 1,\n \"gravity\": 1,\n \"rise\": 0,\n \"drag\": 0.3,\n \"c0\": 9077624,\n \"c1\": 7235679,\n \"alpha\": 1,\n \"fadeIn\": 0.02,\n \"cone\": 0.5,\n \"ground\": \"bounce\"\n },\n \"fibers\": {\n \"id\": \"fibers\",\n \"additive\": false,\n \"life\": [\n 1.5,\n 2.5\n ],\n \"size\": [\n 0.02,\n 0.03\n ],\n \"grow\": 1,\n \"gravity\": 0.15,\n \"rise\": 0,\n \"drag\": 2,\n \"c0\": 12101768,\n \"c1\": 12101768,\n \"alpha\": 0.9,\n \"fadeIn\": 0.05,\n \"cone\": 0.4,\n \"ground\": \"stop\",\n \"flutter\": 2.5\n },\n \"leaves\": {\n \"id\": \"leaves\",\n \"additive\": false,\n \"life\": [\n 1.5,\n 2.8\n ],\n \"size\": [\n 0.03,\n 0.05\n ],\n \"grow\": 1,\n \"gravity\": 0.15,\n \"rise\": 0,\n \"drag\": 2,\n \"c0\": 6003260,\n \"c1\": 4882224,\n \"alpha\": 0.95,\n \"fadeIn\": 0.05,\n \"cone\": 0.4,\n \"ground\": \"stop\",\n \"flutter\": 2.8\n },\n \"drips\": {\n \"id\": \"drips\",\n \"additive\": false,\n \"life\": [\n 2,\n 3\n ],\n \"size\": [\n 0.025,\n 0.035\n ],\n \"grow\": 1,\n \"gravity\": 1,\n \"rise\": 0,\n \"drag\": 0,\n \"c0\": 6974058,\n \"c1\": 6974058,\n \"alpha\": 1,\n \"fadeIn\": 0.01,\n \"cone\": 0.2,\n \"ground\": \"land\"\n },\n \"ash\": {\n \"id\": \"ash\",\n \"additive\": false,\n \"life\": [\n 2,\n 4\n ],\n \"size\": [\n 0.02,\n 0.04\n ],\n \"grow\": 1.2,\n \"gravity\": 0.08,\n \"rise\": 0,\n \"drag\": 1.5,\n \"c0\": 2762275,\n \"c1\": 1710102,\n \"alpha\": 0.8,\n \"fadeIn\": 0.1,\n \"cone\": 0.5,\n \"ground\": \"stop\",\n \"flutter\": 0.6\n },\n \"steam\": {\n \"id\": \"steam\",\n \"additive\": false,\n \"life\": [\n 1,\n 2\n ],\n \"size\": [\n 0.12,\n 0.2\n ],\n \"grow\": 3,\n \"gravity\": 0,\n \"rise\": 0.9,\n \"drag\": 1,\n \"c0\": 16777215,\n \"c1\": 14739694,\n \"alpha\": 0.35,\n \"fadeIn\": 0.15,\n \"cone\": 0.6,\n \"ground\": \"none\"\n },\n \"flash\": {\n \"id\": \"flash\",\n \"additive\": true,\n \"life\": [\n 0.12,\n 0.2\n ],\n \"size\": [\n 1.2,\n 1.8\n ],\n \"grow\": 1.6,\n \"gravity\": 0,\n \"rise\": 0,\n \"drag\": 0,\n \"c0\": 16774080,\n \"c1\": 16748592,\n \"alpha\": 1,\n \"fadeIn\": 0.1,\n \"cone\": 0,\n \"ground\": \"none\"\n },\n \"foam\": {\n \"id\": \"foam\",\n \"additive\": false,\n \"life\": [\n 1,\n 1.8\n ],\n \"size\": [\n 0.06,\n 0.1\n ],\n \"grow\": 1.5,\n \"gravity\": 0.6,\n \"rise\": 0,\n \"drag\": 1.5,\n \"c0\": 16054527,\n \"c1\": 14542576,\n \"alpha\": 0.8,\n \"fadeIn\": 0.05,\n \"cone\": 0.5,\n \"ground\": \"stop\"\n }\n}\n","import kindData from '../data/sprite-kinds.json'\n\n/** The kinds of sprite the game's pools make: debris, sparks, smoke, steam, drips... (the destruction renderer's old `ParticleKind`). */\nexport type SpriteKind =\n | 'fire' | 'smoke' | 'sparks' | 'dust' | 'shards' | 'splinters' | 'chips' | 'fibers' | 'leaves' | 'drips' | 'ash' | 'steam' | 'flash' | 'foam'\n\n/** What happens to a sprite that reaches the ground. */\nexport type SpriteGround = 'none' | 'bounce' | 'stop' | 'land'\n\nexport interface SpriteKindDef {\n readonly id: SpriteKind\n readonly additive: boolean\n /** Life range in seconds. */\n readonly life: readonly [number, number]\n /** Start size range in metres (billboard diameter). */\n readonly size: readonly [number, number]\n /** Size multiplier reached at the end of the life. */\n readonly grow: number\n /** Gravity multiplier (1 = full gravity). */\n readonly gravity: number\n /** Constant upward acceleration in m/s² (heat, steam). */\n readonly rise: number\n /** Velocity damping per second. */\n readonly drag: number\n /** `0xRRGGBB` at the start and at the end of the life. */\n readonly c0: number\n readonly c1: number\n readonly alpha: number\n /** Fraction of the life spent fading in. */\n readonly fadeIn: number\n /** How much of the emission direction follows the surface normal (1) versus a random direction (0). */\n readonly cone: number\n readonly ground: SpriteGround\n readonly flutter?: number\n readonly flicker?: number\n}\n\nexport const SPRITE_KINDS: Readonly<Record<SpriteKind, SpriteKindDef>> = kindData as unknown as Record<SpriteKind, SpriteKindDef>\n\n/** A copy of the kinds with some changed (a partial replaces the fields it names), added or removed (`null`); a game tunes its sprites without touching the core. */\nexport function patchSpriteKinds(\n base: Readonly<Record<string, SpriteKindDef>>,\n changes: Readonly<Record<string, Partial<SpriteKindDef> | SpriteKindDef | null>>,\n): Record<string, SpriteKindDef> {\n const result: Record<string, SpriteKindDef> = { ...base }\n for (const [id, change] of Object.entries(changes)) {\n if (change === null) delete result[id]\n else result[id] = { ...(base[id] ?? {}), ...change, id } as SpriteKindDef\n }\n return result\n}\n","import { SpriteKindPool, spriteRandom } from './kind-pool'\nimport type { SpriteSpawnOptions } from './kind-pool'\nimport { SPRITE_KINDS } from './kinds'\nimport type { SpriteKind, SpriteKindDef } from './kinds'\n\ntype Vec3 = readonly [number, number, number]\n\nexport interface SpriteKindSystemOptions {\n /** Most live sprites at once (additive takes 40 %, normal the rest). */\n readonly capacity: number\n /** Count multiplier for bursts (0.6 on low quality). */\n readonly density: number\n readonly seed: number\n readonly groundAt: (x: number, z: number) => number\n readonly gravity: number\n readonly kinds?: Readonly<Record<string, SpriteKindDef>>\n}\n\nexport type LandListener = (x: number, y: number, z: number, color: number, tag: number) => void\n\n/**\n * The game's sprites of fixed kinds (debris, sparks, smoke, steam, drips...), burst or spawned one by one: two pooled rings, additive and normal, that\n * a renderer draws as points. This is the destruction renderer's old particle system with the maths unchanged and the drawing taken out.\n */\nexport class SpriteKindSystem {\n readonly additive: SpriteKindPool\n readonly normal: SpriteKindPool\n private readonly random: () => number\n private readonly ids: readonly string[]\n private readonly defs: readonly SpriteKindDef[]\n private readonly index = new Map<string, number>()\n private readonly owners: string[] = []\n private readonly listeners = new Map<string, LandListener>()\n\n constructor(private readonly options: SpriteKindSystemOptions) {\n const kinds: Readonly<Record<string, SpriteKindDef>> = options.kinds ?? SPRITE_KINDS\n this.ids = Object.keys(kinds)\n this.defs = this.ids.map((id) => kinds[id]!)\n this.ids.forEach((id, at) => this.index.set(id, at))\n const additiveCapacity = Math.floor(options.capacity * 0.4)\n this.additive = new SpriteKindPool(additiveCapacity, this.defs, this.owners)\n this.normal = new SpriteKindPool(options.capacity - additiveCapacity, this.defs, this.owners)\n this.random = spriteRandom(options.seed)\n }\n\n get capacity(): number {\n return this.additive.capacity + this.normal.capacity\n }\n\n get live(): number {\n return this.additive.live + this.normal.live\n }\n\n /** Hears the landing of the drips of `owner` (the ones spawned with `{ owner, tag }`). Returns the function that stops listening. */\n onLand(owner: string, listener: LandListener): () => void {\n this.listeners.set(owner, listener)\n return () => {\n if (this.listeners.get(owner) === listener) this.listeners.delete(owner)\n }\n }\n\n private kindOf(kind: string): { index: number; def: SpriteKindDef } {\n const index = this.index.get(kind)\n if (index === undefined) throw new Error(`unknown sprite kind ${kind}`)\n return { index, def: this.defs[index]! }\n }\n\n /** One sprite with an explicit velocity. */\n spawn(kind: SpriteKind | string, point: Vec3, velocity: Vec3, options?: SpriteSpawnOptions): void {\n const { index, def } = this.kindOf(kind)\n ;(def.additive ? this.additive : this.normal).spawn(index, point, velocity, this.random, options)\n }\n\n /** `count` sprites leaving `point` around `normal` at about `speed` m/s. */\n burst(kind: SpriteKind | string, point: Vec3, normal: Vec3, count: number, speed = 1, options?: SpriteSpawnOptions): void {\n const { def } = this.kindOf(kind)\n const n = Math.max(0, Math.round(count * this.options.density))\n const rnd = this.random\n const length = Math.hypot(normal[0], normal[1], normal[2]) || 1\n const nx = normal[0] / length\n const ny = normal[1] / length\n const nz = normal[2] / length\n for (let k = 0; k < n; k++) {\n const u = rnd() * 2 - 1\n const phase = rnd() * Math.PI * 2\n const s = Math.sqrt(1 - u * u)\n const rx = s * Math.cos(phase)\n const ry = u\n const rz = s * Math.sin(phase)\n let dx = nx * def.cone + rx * (1 - def.cone)\n let dy = ny * def.cone + ry * (1 - def.cone)\n let dz = nz * def.cone + rz * (1 - def.cone)\n // a little scatter even for a pure cone, and never push into the surface for debris\n dx += rx * 0.35\n dy += ry * 0.35\n dz += rz * 0.35\n const l = Math.hypot(dx, dy, dz) || 1\n const sp = speed * (0.35 + 0.65 * rnd())\n const jitter = 0.01 + (def.size[1] > 0.5 ? 0.15 : 0.02)\n this.spawn(\n def.id,\n [point[0] + (rnd() - 0.5) * jitter, point[1] + (rnd() - 0.5) * jitter, point[2] + (rnd() - 0.5) * jitter],\n [(dx / l) * sp, (dy / l) * sp, (dz / l) * sp],\n options,\n )\n }\n }\n\n /** Blast wave: shoves the live sprites away from a point. */\n push(point: Vec3, radius: number, speed: number): void {\n this.additive.push(point[0], point[1], point[2], radius, speed)\n this.normal.push(point[0], point[1], point[2], radius, speed)\n }\n\n update(dt: number): void {\n const host = {\n groundAt: this.options.groundAt,\n gravity: this.options.gravity,\n land: (owner: string, x: number, y: number, z: number, color: number, tag: number) => this.listeners.get(owner)?.(x, y, z, color, tag),\n }\n if (this.additive.live > 0 || this.additive.drawCount > 0) this.additive.update(dt, host)\n if (this.normal.live > 0 || this.normal.drawCount > 0) this.normal.update(dt, host)\n }\n\n clear(): void {\n this.additive.clear()\n this.normal.clear()\n }\n}\n","import type { RandomStream, MutableVec3 } from '../random'\nimport { addScaled, normalize } from '../vector'\nimport type { SpriteRange, Vec3Tuple } from './types'\n\nconst TWO_PI_ROUNDED = 6.2832\nconst WIDE_CONE = 3.1\nconst UP: Vec3Tuple = [0, 1, 0]\n\nexport function drawRange(random: RandomStream, range: SpriteRange | undefined): number {\n if (Array.isArray(range)) return random.between(range[0], range[1])\n return (range as number | undefined) || 0\n}\n\n/** `randUnit` (W166): the page rounds a turn to 6.2832, so this is not `RandomStream.direction`. */\nexport function randomUnit(random: RandomStream, out: MutableVec3): MutableVec3 {\n const up = random.next() * 2 - 1\n const angle = random.next() * TWO_PI_ROUNDED\n const ring = Math.sqrt(1 - up * up)\n out.x = ring * Math.cos(angle)\n out.y = up\n out.z = ring * Math.sin(angle)\n return out\n}\n\nconst tangentA: MutableVec3 = { x: 0, y: 0, z: 0 }\nconst tangentB: MutableVec3 = { x: 0, y: 0, z: 0 }\nconst axis: MutableVec3 = { x: 0, y: 0, z: 0 }\n\nfunction cross(out: MutableVec3, a: MutableVec3, b: MutableVec3): MutableVec3 {\n const x = a.y * b.z - a.z * b.y\n const y = a.z * b.x - a.x * b.z\n const z = a.x * b.y - a.y * b.x\n out.x = x\n out.y = y\n out.z = z\n return out\n}\n\n/** `coneDir` (W169-171): a direction inside `cone` radians of `direction`, two draws (a full sphere when the cone is wide). */\nexport function coneDirection(random: RandomStream, direction: Vec3Tuple | undefined, cone: number, out: MutableVec3): MutableVec3 {\n if (cone >= WIDE_CONE) return randomUnit(random, out)\n const [dx, dy, dz] = direction ?? UP\n const cosTilt = 1 - random.next() * (1 - Math.cos(cone))\n const sinTilt = Math.sqrt(1 - cosTilt * cosTilt)\n const phase = random.next() * TWO_PI_ROUNDED\n axis.x = dx\n axis.y = dy\n axis.z = dz\n tangentA.x = 1\n tangentA.y = 0\n tangentA.z = 0\n if (Math.abs(dx) > 0.9) {\n tangentA.x = 0\n tangentA.y = 1\n }\n normalize(cross(tangentB, axis, tangentA))\n normalize(cross(tangentA, tangentB, axis))\n out.x = dx * cosTilt\n out.y = dy * cosTilt\n out.z = dz * cosTilt\n addScaled(out, tangentA, sinTilt * Math.cos(phase))\n addScaled(out, tangentB, sinTilt * Math.sin(phase))\n return out\n}\n","import type { MutableVec3 } from '../random'\nimport { coneDirection, drawRange } from './direction'\nimport type { DebrisSpawn, WorkshopContext } from './types'\n\nconst CAPACITY = 500\nconst GRAVITY = 9.8\nconst QUARTER_TURN = 1.5708\nconst FADE_SECONDS = 0.5\nconst DEFAULT_SIZE = [0.05, 0.05, 0.05] as const\nconst DEFAULT_SPIN = 12\nconst DEFAULT_COLOR = 0x888888\nconst DEFAULT_LIFE = 8\nconst DEFAULT_BOUNCE = 0.3\nconst FULL_TURN_DRAWN = 6\n\nexport interface DebrisPiece {\n on: boolean\n x: number\n y: number\n z: number\n vx: number\n vy: number\n vz: number\n sx: number\n sy: number\n sz: number\n rx: number\n ry: number\n rz: number\n ax: number\n ay: number\n az: number\n life: number\n bounce: number\n rest: boolean\n color: number\n}\n\nfunction createPiece(): DebrisPiece {\n return { on: false, x: 0, y: 0, z: 0, vx: 0, vy: 0, vz: 0, sx: 0, sy: 0, sz: 0, rx: 0, ry: 0, rz: 0, ax: 0, ay: 0, az: 0, life: 0, bounce: 0, rest: false, color: DEFAULT_COLOR }\n}\n\n/** The Workshop's physics debris (W248-263): 500 boxes in a ring buffer, the newest overwriting the oldest, that tumble, bounce, settle on a face and shrink away. */\nexport class DebrisPool {\n readonly pieces: DebrisPiece[] = Array.from({ length: CAPACITY }, createPiece)\n count = 0\n private next = 0\n private readonly direction: MutableVec3 = { x: 0, y: 0, z: 0 }\n\n constructor(private readonly context: WorkshopContext) {}\n\n spawn(options: DebrisSpawn): void {\n const random = this.context.random\n const piece = this.pieces[this.next++ % CAPACITY]!\n coneDirection(random, options.dir, options.cone ?? 3.2, this.direction)\n const speed = drawRange(random, options.sp)\n const size = options.size ?? DEFAULT_SIZE\n const scale = options.k ? drawRange(random, options.k) : 1\n const box = options.box\n const spin = options.spin || DEFAULT_SPIN\n piece.on = true\n piece.x = options.p[0] + (box ? random.between(-box[0], box[0]) : 0)\n piece.y = options.p[1] + (box ? random.between(-box[1], box[1]) : 0)\n piece.z = options.p[2] + (box ? random.between(-box[2], box[2]) : 0)\n piece.vx = this.direction.x * speed + (options.v ? options.v[0] : 0)\n piece.vy = this.direction.y * speed + (options.v ? options.v[1] : 0)\n piece.vz = this.direction.z * speed + (options.v ? options.v[2] : 0)\n piece.sx = (size[0] as number) * scale\n piece.sy = (size[1] as number) * scale\n piece.sz = (size[2] as number) * scale\n piece.rx = random.between(0, FULL_TURN_DRAWN)\n piece.ry = random.between(0, FULL_TURN_DRAWN)\n piece.rz = random.between(0, FULL_TURN_DRAWN)\n piece.ax = random.between(-1, 1) * spin\n piece.ay = random.between(-1, 1) * spin\n piece.az = random.between(-1, 1) * spin\n piece.life = options.life || DEFAULT_LIFE\n piece.bounce = options.bounce ?? DEFAULT_BOUNCE\n piece.rest = false\n piece.color = options.c ?? DEFAULT_COLOR\n }\n\n clear(): void {\n for (const piece of this.pieces) piece.on = false\n this.count = 0\n }\n\n update(dt: number): void {\n this.count = 0\n for (const piece of this.pieces) {\n if (!piece.on) continue\n this.count++\n piece.life -= dt\n if (piece.life <= 0) {\n piece.on = false\n continue\n }\n if (!piece.rest) this.move(piece, dt)\n }\n }\n\n /** Scale at the end of its life, 1 until the last half second (the renderer's `sh`). */\n static fade(piece: DebrisPiece): number {\n return Math.min(1, piece.life / FADE_SECONDS)\n }\n\n private move(piece: DebrisPiece, dt: number): void {\n piece.vy -= GRAVITY * dt\n piece.x += piece.vx * dt\n piece.y += piece.vy * dt\n piece.z += piece.vz * dt\n piece.rx += piece.ax * dt\n piece.ry += piece.ay * dt\n piece.rz += piece.az * dt\n const groundHeight = this.context.groundAt(piece.x, piece.z) + Math.min(piece.sx, piece.sy, piece.sz) * 0.5\n if (piece.y >= groundHeight) return\n piece.y = groundHeight\n piece.vy *= -piece.bounce\n piece.vx *= 0.55\n piece.vz *= 0.55\n piece.ax *= 0.5\n piece.ay *= 0.5\n piece.az *= 0.5\n if (Math.abs(piece.vy) < 0.5 && Math.hypot(piece.vx, piece.vz) < 0.3) {\n piece.rest = true\n piece.rx = Math.round(piece.rx / QUARTER_TURN) * QUARTER_TURN\n piece.rz = Math.round(piece.rz / QUARTER_TURN) * QUARTER_TURN\n }\n }\n}\n","import type { DecalOptions, Vec3Tuple, WorkshopContext } from './types'\n\nconst CAPACITY = 400\nconst UP: Vec3Tuple = [0, 1, 0]\nconst DEFAULT_LIFE = 60\nconst DEFAULT_GROW = 1.2\n\n/** The seconds a fluid decal waits and then takes to evaporate away (W276); blood, bile and oil only darken. */\nconst EVAPORATION = { fuel: [6, 5], water: [40, 20] } as const\n\nexport interface Decal {\n on: boolean\n x: number\n y: number\n z: number\n sx: number\n sy: number\n t: number\n life: number\n grow: number\n color: number\n /** Where the surface faces, and the colour a fluid dries to (`-1`: it does not dry). */\n normal: Vec3Tuple\n fluid: DecalOptions['fluid'] | undefined\n dryColor: number\n dryAt: number\n dryTime: number\n}\n\nfunction createDecal(): Decal {\n return { on: false, x: 0, y: 0, z: 0, sx: 0, sy: 0, t: 0, life: 0, grow: 0, color: 0, normal: UP, fluid: undefined, dryColor: -1, dryAt: 0, dryTime: 0 }\n}\n\n/** The Workshop's decals (W265-306): 400 marks on the ground in a ring buffer. Wet ones spread and evaporate (fuel, water), the rest last their life. */\nexport class DecalPool {\n readonly decals: Decal[] = Array.from({ length: CAPACITY }, createDecal)\n count = 0\n private next = 0\n\n constructor(private readonly context: WorkshopContext) {}\n\n add(x: number, y: number, z: number, size: number, color: number, options: DecalOptions = {}): void {\n const random = this.context.random\n const index = this.next++ % CAPACITY\n const decal = this.decals[index]!\n const normal = options.n ?? UP\n random.between(0, 6.28)\n const offset = 0.004 + (index % 40) * 0.0004\n decal.on = true\n decal.x = x + normal[0] * offset\n decal.y = y + normal[1] * offset\n decal.z = z + normal[2] * offset\n decal.sx = size * (options.ar ? 1 : random.between(0.8, 1.2))\n decal.sy = size * (options.ar || random.between(0.65, 1.1))\n decal.t = -(options.delay || 0)\n decal.grow = options.grow ?? DEFAULT_GROW\n decal.life = options.life || DEFAULT_LIFE\n decal.color = color\n decal.normal = normal\n const fluid = options.fluid ?? (options.dark ? 'blood' : undefined)\n decal.fluid = fluid\n decal.dryAt = options.dark && !options.fluid ? 0 : options.dryAt ?? (fluid === 'blood' || fluid === 'bile' ? 40 : 0)\n decal.dryTime = options.dark && !options.fluid ? options.dark : options.dryT ?? (fluid === 'blood' || fluid === 'bile' ? 30 : 0)\n decal.dryColor = options.dry ?? (fluid === 'bile' ? 0x3e4220 : -1)\n }\n\n clear(): void {\n for (const decal of this.decals) decal.on = false\n this.count = 0\n }\n\n update(dt: number): void {\n this.count = 0\n for (const decal of this.decals) {\n if (!decal.on) continue\n this.count++\n decal.t += dt\n if (decal.t < 0) continue\n decal.life -= dt\n if (decal.life <= 0) {\n decal.on = false\n continue\n }\n const evaporation = decal.fluid === 'fuel' || decal.fluid === 'water' ? EVAPORATION[decal.fluid] : undefined\n if (evaporation && (decal.t - evaporation[0]) / evaporation[1] >= 1) decal.on = false\n }\n }\n}\n","import type { MeshSpawn, MeshShape, Vec3Tuple } from './types'\n\nconst CAPACITY = 400\nconst IDENTITY: Quaternion = [0, 0, 0, 1]\n\n/** A unit quaternion `[x, y, z, w]`. */\nexport type Quaternion = readonly [number, number, number, number]\n\n/** One solid particle as the pool keeps it; a renderer draws it from these fields and never changes them. */\nexport interface MeshParticle {\n /** Grows by one for every particle ever spawned: a renderer knows a new one by it. */\n readonly id: number\n readonly shape: MeshShape\n readonly radius: number\n readonly height: number\n readonly segments: number\n readonly segments2: number\n readonly color: number\n readonly additive: boolean\n readonly lit: boolean\n /** Where the group is, how it is turned (placement and roll), where the piece sits in it (before the scale) and how the piece is turned in it (Euler XYZ, changes with `spin`). */\n x: number\n y: number\n z: number\n readonly frame: Quaternion\n readonly at: Vec3Tuple\n rx: number\n ry: number\n rz: number\n scale: number\n opacity: number\n age: number\n readonly life: number\n vx: number\n vy: number\n vz: number\n readonly spin: Vec3Tuple\n readonly gravity: number\n readonly drag: number\n readonly grow: number\n readonly ramp: readonly [number, number] | undefined\n readonly fade: boolean\n readonly startOpacity: number\n}\n\nfunction multiply(a: Quaternion, b: Quaternion): Quaternion {\n const [ax, ay, az, aw] = a\n const [bx, by, bz, bw] = b\n return [aw * bx + ax * bw + ay * bz - az * by, aw * by - ax * bz + ay * bw + az * bx, aw * bz + ax * by - ay * bx + az * bw, aw * bw - ax * bx - ay * by - az * bz]\n}\n\n/** The turn of `angle` about the x axis. */\nconst aboutX = (angle: number): Quaternion => [Math.sin(angle / 2), 0, 0, Math.cos(angle / 2)]\n\n/**\n * The solids of the Workshop's recipes: the gallery's `Particles` (thrown with a velocity and a spin, slowed, lifted by a negative gravity, grown and faded) without\n * the floor, in order of birth. The oldest goes when the pool is full. Each frame does what the gallery's did, in its order: age, fade, gravity, drag, move, spin, grow.\n */\nexport class MeshPool {\n readonly particles: MeshParticle[] = []\n private serial = 0\n\n constructor(readonly capacity: number = CAPACITY) {}\n\n get count(): number {\n return this.particles.length\n }\n\n spawn(options: MeshSpawn, frame: Quaternion = IDENTITY): MeshParticle {\n const velocity = options.v ?? [0, 0, 0]\n const world = options.wv ?? [0, 0, 0]\n const particle: MeshParticle = {\n id: ++this.serial,\n shape: options.shape,\n radius: options.r,\n height: options.h ?? 0,\n segments: options.seg ?? 0,\n segments2: options.seg2 ?? 0,\n color: options.c0,\n additive: options.add === true,\n lit: options.lit === true,\n x: options.p[0],\n y: options.p[1],\n z: options.p[2],\n frame: options.roll ? multiply(frame, aboutX(options.roll)) : frame,\n at: options.at ?? [0, 0, 0],\n rx: options.rot?.[0] ?? 0,\n ry: options.rot?.[1] ?? 0,\n rz: options.rot?.[2] ?? 0,\n scale: 1,\n opacity: options.a,\n age: 0,\n life: options.life,\n vx: velocity[0] + world[0],\n vy: velocity[1] + world[1],\n vz: velocity[2] + world[2],\n spin: options.spin ?? [0, 0, 0],\n gravity: options.g ?? 0,\n drag: options.drag ?? 0,\n grow: options.grow ?? 0,\n ramp: options.ramp,\n fade: options.fade === true,\n startOpacity: options.a,\n }\n this.particles.push(particle)\n if (this.particles.length > this.capacity) this.particles.shift()\n return particle\n }\n\n update(dt: number): void {\n const live = this.particles\n for (let index = 0; index < live.length; index++) {\n const particle = live[index]!\n particle.age += dt\n if (particle.ramp ? particle.age >= particle.life : particle.age > particle.life) {\n live.splice(index--, 1)\n continue\n }\n if (particle.fade) particle.opacity = Math.max(0, particle.startOpacity * (1 - particle.age / particle.life))\n particle.vy -= particle.gravity * dt\n if (particle.drag) {\n const keep = Math.max(0, 1 - particle.drag * dt)\n particle.vx *= keep\n particle.vy *= keep\n particle.vz *= keep\n }\n particle.x += particle.vx * dt\n particle.y += particle.vy * dt\n particle.z += particle.vz * dt\n particle.rx += particle.spin[0] * dt\n particle.ry += particle.spin[1] * dt\n particle.rz += particle.spin[2] * dt\n if (particle.grow) particle.scale *= 1 + particle.grow * dt\n if (particle.ramp) particle.scale = particle.ramp[0] + Math.min(1, particle.age / particle.life) * particle.ramp[1]\n }\n }\n\n clear(): void {\n this.particles.length = 0\n }\n}\n","import { hexToRgb } from '../color'\nimport { lerp } from '../vector'\nimport type { MutableVec3, RandomStream } from '../random'\nimport { coneDirection, drawRange, randomUnit } from './direction'\nimport type { SpriteSpawn, WorkshopContext } from './types'\n\n/** Colour, size and alpha of a particle at its current age: what the renderer reads (`col`, `siz`, `alp`). */\nconst DEFAULT_FADE_IN = 0.1\nconst FLOATS_PER_VECTOR = 3\nconst BYTE_MAX = 255\n\nexport interface DecalFromSprite {\n (x: number, y: number, z: number, size: number, color: number, options: { readonly grow: number; readonly fluid: 'blood' }): void\n}\n\n/**\n * The Workshop's `PSys` (W179-220): a pool of sprites in typed arrays, as the page keeps them. A dead record is replaced by the last one, so the order\n * in the arrays is the page's, and the golden hashes the arrays as they are. Additive and normal-blend systems are two instances.\n */\nexport class SpritePool {\n count = 0\n readonly position: Float32Array\n readonly velocity: Float32Array\n readonly colorStart: Float32Array\n readonly colorEnd: Float32Array\n readonly life: Float32Array\n readonly maxLife: Float32Array\n readonly startSize: Float32Array\n readonly growth: Float32Array\n readonly startAlpha: Float32Array\n readonly gravity: Float32Array\n readonly drag: Float32Array\n readonly fadeIn: Float32Array\n readonly groundMode: Uint8Array\n readonly decalSize: Float32Array\n /** Written by `update`: what the renderer draws. */\n readonly color: Float32Array\n readonly size: Float32Array\n readonly alpha: Float32Array\n private readonly vectorArrays: readonly Float32Array[]\n private readonly scalarArrays: readonly (Float32Array | Uint8Array)[]\n private readonly direction: MutableVec3 = { x: 0, y: 0, z: 0 }\n private readonly unit: MutableVec3 = { x: 0, y: 0, z: 0 }\n\n constructor(readonly capacity: number, private readonly context: WorkshopContext) {\n const vectorArray = (): Float32Array => new Float32Array(capacity * FLOATS_PER_VECTOR)\n const scalarArray = (): Float32Array => new Float32Array(capacity)\n this.position = vectorArray()\n this.velocity = vectorArray()\n this.colorStart = vectorArray()\n this.colorEnd = vectorArray()\n this.color = vectorArray()\n this.life = scalarArray()\n this.maxLife = scalarArray()\n this.startSize = scalarArray()\n this.growth = scalarArray()\n this.startAlpha = scalarArray()\n this.gravity = scalarArray()\n this.drag = scalarArray()\n this.fadeIn = scalarArray()\n this.decalSize = scalarArray()\n this.size = scalarArray()\n this.alpha = scalarArray()\n this.groundMode = new Uint8Array(capacity)\n this.vectorArrays = [this.position, this.velocity, this.colorStart, this.colorEnd]\n this.scalarArrays = [this.life, this.maxLife, this.startSize, this.growth, this.startAlpha, this.gravity, this.drag, this.fadeIn, this.groundMode, this.decalSize]\n }\n\n spawn(options: SpriteSpawn): void {\n if (this.count >= this.capacity) return\n const random: RandomStream = this.context.random\n const index = this.count++\n const offset = index * FLOATS_PER_VECTOR\n let [x, y, z] = options.p\n if (options.r) {\n randomUnit(random, this.unit)\n const reach = Math.cbrt(random.next()) * options.r\n x += this.unit.x * reach\n y += this.unit.y * reach * (options.flat ? 0 : 1)\n z += this.unit.z * reach\n }\n if (options.box) {\n x += random.between(-options.box[0], options.box[0])\n y += random.between(-options.box[1], options.box[1])\n z += random.between(-options.box[2], options.box[2])\n }\n this.position[offset] = x\n this.position[offset + 1] = y\n this.position[offset + 2] = z\n coneDirection(random, options.dir, options.cone ?? 3.2, this.direction)\n const speed = drawRange(random, options.sp)\n this.velocity[offset] = this.direction.x * speed + (options.v ? options.v[0] : 0)\n this.velocity[offset + 1] = this.direction.y * speed + (options.v ? options.v[1] : 0)\n this.velocity[offset + 2] = this.direction.z * speed + (options.v ? options.v[2] : 0)\n const start = hexToRgb(options.c0 ?? 0xffffff)\n const end = options.c1 != null ? hexToRgb(options.c1) : start\n for (let channel = 0; channel < FLOATS_PER_VECTOR; channel++) {\n this.colorStart[offset + channel] = start[channel]\n this.colorEnd[offset + channel] = end[channel]\n }\n this.life[index] = this.maxLife[index] = drawRange(random, options.life || 1)\n this.startSize[index] = drawRange(random, options.size || 0.1)\n this.growth[index] = options.grow || 1\n this.startAlpha[index] = options.a ?? 1\n this.gravity[index] = options.g || 0\n this.drag[index] = options.drag || 0\n this.fadeIn[index] = options.fi ?? DEFAULT_FADE_IN\n this.groundMode[index] = options.gnd || 0\n this.decalSize[index] = options.ds ? drawRange(random, options.ds) : 0.1\n }\n\n kill(index: number): void {\n const last = --this.count\n if (index === last) return\n for (const array of this.vectorArrays) {\n for (let component = 0; component < FLOATS_PER_VECTOR; component++) array[index * FLOATS_PER_VECTOR + component] = array[last * FLOATS_PER_VECTOR + component]\n }\n for (const array of this.scalarArrays) array[index] = array[last]\n }\n\n clear(): void {\n this.count = 0\n }\n\n update(dt: number, leaveDecal: DecalFromSprite): void {\n const { position, velocity } = this\n for (let index = this.count - 1; index >= 0; index--) {\n this.life[index] -= dt\n if (this.life[index] <= 0) {\n this.kill(index)\n continue\n }\n const offset = index * FLOATS_PER_VECTOR\n const age = 1 - this.life[index] / this.maxLife[index]\n velocity[offset + 1] -= this.gravity[index] * dt\n const factor = Math.max(0, 1 - this.drag[index] * dt)\n velocity[offset] *= factor\n velocity[offset + 1] *= factor\n velocity[offset + 2] *= factor\n position[offset] += velocity[offset] * dt\n position[offset + 1] += velocity[offset + 1] * dt\n position[offset + 2] += velocity[offset + 2] * dt\n const mode = this.groundMode[index]\n if (mode) {\n const groundHeight = this.context.groundAt(position[offset], position[offset + 2])\n if (position[offset + 1] < groundHeight) {\n if (mode === 1) {\n this.kill(index)\n continue\n }\n if (mode === 2) {\n position[offset + 1] = groundHeight + 0.001\n velocity[offset + 1] *= -0.3\n velocity[offset] *= 0.55\n velocity[offset + 2] *= 0.55\n }\n if (mode === 3) {\n if (this.context.quality.level < 2) {\n const red = (this.colorStart[offset] * BYTE_MAX) << 16\n const green = (this.colorStart[offset + 1] * BYTE_MAX) << 8\n leaveDecal(position[offset], groundHeight, position[offset + 2], this.decalSize[index], red | green | (this.colorStart[offset + 2] * BYTE_MAX), { grow: 0.15, fluid: 'blood' })\n }\n this.kill(index)\n continue\n }\n }\n }\n this.size[index] = this.startSize[index] * (1 + (this.growth[index] - 1) * age)\n const fadeIn = this.fadeIn[index]\n this.alpha[index] = this.startAlpha[index] * (fadeIn > 0 && age < fadeIn ? age / fadeIn : 1 - (age - fadeIn) / (1 - fadeIn))\n for (let channel = 0; channel < FLOATS_PER_VECTOR; channel++) this.color[offset + channel] = lerp(this.colorStart[offset + channel], this.colorEnd[offset + channel], age)\n }\n }\n}\n","import { hexToRgb } from '../color'\nimport type { MutableVec3 } from '../random'\nimport { lerp } from '../vector'\nimport { coneDirection, drawRange } from './direction'\nimport type { SpriteSpawn, WorkshopContext } from './types'\n\nconst FLOATS_PER_VECTOR = 3\nconst SEGMENT_FLOATS = 6\nconst TAIL_BRIGHTNESS = 0.15\n\n/** The Workshop's `Streaks` (W223-245): short lines that follow their own velocity (sparks, tracers, rain-like glints). Same swap-with-last pool as `SpritePool`. */\nexport class StreakPool {\n count = 0\n readonly point: Float32Array\n readonly velocity: Float32Array\n readonly colorStart: Float32Array\n readonly colorEnd: Float32Array\n readonly life: Float32Array\n readonly maxLife: Float32Array\n readonly length: Float32Array\n readonly gravity: Float32Array\n readonly drag: Float32Array\n readonly groundMode: Uint8Array\n readonly startAlpha: Float32Array\n /** Two end points and two colours per line: what the renderer draws. */\n readonly segment: Float32Array\n readonly segmentColor: Float32Array\n private readonly vectorArrays: readonly Float32Array[]\n private readonly scalarArrays: readonly (Float32Array | Uint8Array)[]\n private readonly direction: MutableVec3 = { x: 0, y: 0, z: 0 }\n\n constructor(readonly capacity: number, private readonly context: WorkshopContext) {\n const vectorArray = (): Float32Array => new Float32Array(capacity * FLOATS_PER_VECTOR)\n const scalarArray = (): Float32Array => new Float32Array(capacity)\n this.point = vectorArray()\n this.velocity = vectorArray()\n this.colorStart = vectorArray()\n this.colorEnd = vectorArray()\n this.life = scalarArray()\n this.maxLife = scalarArray()\n this.length = scalarArray()\n this.gravity = scalarArray()\n this.drag = scalarArray()\n this.startAlpha = scalarArray()\n this.groundMode = new Uint8Array(capacity)\n this.segment = new Float32Array(capacity * SEGMENT_FLOATS)\n this.segmentColor = new Float32Array(capacity * SEGMENT_FLOATS)\n this.vectorArrays = [this.point, this.velocity, this.colorStart, this.colorEnd]\n this.scalarArrays = [this.life, this.maxLife, this.length, this.gravity, this.drag, this.groundMode, this.startAlpha]\n }\n\n spawn(options: SpriteSpawn): void {\n if (this.count >= this.capacity) return\n const random = this.context.random\n const index = this.count++\n const offset = index * FLOATS_PER_VECTOR\n let [x, y, z] = options.p\n if (options.box) {\n x += random.between(-options.box[0], options.box[0])\n y += random.between(-options.box[1], options.box[1])\n z += random.between(-options.box[2], options.box[2])\n }\n this.point[offset] = x\n this.point[offset + 1] = y\n this.point[offset + 2] = z\n coneDirection(random, options.dir, options.cone ?? 3.2, this.direction)\n const speed = drawRange(random, options.sp)\n this.velocity[offset] = this.direction.x * speed + (options.v ? options.v[0] : 0)\n this.velocity[offset + 1] = this.direction.y * speed + (options.v ? options.v[1] : 0)\n this.velocity[offset + 2] = this.direction.z * speed + (options.v ? options.v[2] : 0)\n const start = hexToRgb(options.c0 ?? 0xffd080)\n const end = options.c1 != null ? hexToRgb(options.c1) : start\n for (let channel = 0; channel < FLOATS_PER_VECTOR; channel++) {\n this.colorStart[offset + channel] = start[channel]\n this.colorEnd[offset + channel] = end[channel]\n }\n this.life[index] = this.maxLife[index] = drawRange(random, options.life || 0.4)\n this.length[index] = options.len || 0.02\n this.gravity[index] = options.g || 0\n this.drag[index] = options.drag || 0\n this.groundMode[index] = options.gnd || 0\n this.startAlpha[index] = options.a ?? 1\n }\n\n kill(index: number): void {\n const last = --this.count\n if (index === last) return\n for (const array of this.vectorArrays) {\n for (let component = 0; component < FLOATS_PER_VECTOR; component++) array[index * FLOATS_PER_VECTOR + component] = array[last * FLOATS_PER_VECTOR + component]\n }\n for (const array of this.scalarArrays) array[index] = array[last]\n }\n\n clear(): void {\n this.count = 0\n }\n\n update(dt: number): void {\n const { point, velocity } = this\n for (let index = this.count - 1; index >= 0; index--) {\n this.life[index] -= dt\n if (this.life[index] <= 0) {\n this.kill(index)\n continue\n }\n const offset = index * FLOATS_PER_VECTOR\n const age = 1 - this.life[index] / this.maxLife[index]\n velocity[offset + 1] -= this.gravity[index] * dt\n const factor = Math.max(0, 1 - this.drag[index] * dt)\n velocity[offset] *= factor\n velocity[offset + 1] *= factor\n velocity[offset + 2] *= factor\n point[offset] += velocity[offset] * dt\n point[offset + 1] += velocity[offset + 1] * dt\n point[offset + 2] += velocity[offset + 2] * dt\n if (this.groundMode[index]) {\n const groundHeight = this.context.groundAt(point[offset], point[offset + 2])\n if (point[offset + 1] < groundHeight) {\n if (this.groundMode[index] === 1) {\n this.kill(index)\n continue\n }\n point[offset + 1] = groundHeight + 0.001\n velocity[offset + 1] *= -0.35\n velocity[offset] *= 0.6\n velocity[offset + 2] *= 0.6\n }\n }\n const length = this.length[index]\n const alpha = this.startAlpha[index] * (1 - age)\n const at = index * SEGMENT_FLOATS\n this.segment[at] = point[offset]\n this.segment[at + 1] = point[offset + 1]\n this.segment[at + 2] = point[offset + 2]\n this.segment[at + 3] = point[offset] - velocity[offset] * length\n this.segment[at + 4] = point[offset + 1] - velocity[offset + 1] * length\n this.segment[at + 5] = point[offset + 2] - velocity[offset + 2] * length\n for (let channel = 0; channel < FLOATS_PER_VECTOR; channel++) {\n const shade = lerp(this.colorStart[offset + channel], this.colorEnd[offset + channel], age) * alpha\n this.segmentColor[at + channel] = shade\n this.segmentColor[at + 3 + channel] = shade * TAIL_BRIGHTNESS\n }\n }\n }\n}\n","import type { Vec3Tuple, WorkshopContext } from './types'\n\nconst RING_CAPACITY = 120\nconst LIGHT_CAPACITY = 4\nconst UP: Vec3Tuple = [0, 1, 0]\nconst DEFAULT_LIGHT_DISTANCE = 14\n\nexport interface WaveRing {\n on: boolean\n point: Vec3Tuple\n from: number\n to: number\n t: number\n duration: number\n color: number\n normal: Vec3Tuple\n hold: number\n}\n\n/** The Workshop's expanding rings on the ground (W308-315): 120 in a ring buffer. A ring with `hold` stays at that brightness until cleared. */\nexport class WaveRingPool {\n readonly rings: WaveRing[] = Array.from({ length: RING_CAPACITY }, () => ({ on: false, point: UP, from: 0, to: 0, t: 0, duration: 1, color: 0, normal: UP, hold: 0 }))\n count = 0\n private next = 0\n\n add(point: Vec3Tuple, from: number, to: number, duration: number, color: number, normal?: Vec3Tuple, hold?: number): void {\n const ring = this.rings[this.next++ % RING_CAPACITY]!\n ring.on = true\n ring.point = [point[0], point[1], point[2]]\n ring.from = from\n ring.to = to\n ring.t = 0\n ring.duration = duration\n ring.color = color\n ring.normal = normal ?? UP\n ring.hold = hold || 0\n }\n\n clear(): void {\n for (const ring of this.rings) ring.on = false\n this.count = 0\n }\n\n update(dt: number): void {\n this.count = 0\n for (const ring of this.rings) {\n if (!ring.on) continue\n this.count++\n ring.t += dt\n if (ring.t / ring.duration >= 1 && !ring.hold) ring.on = false\n }\n }\n}\n\nexport interface FlashLight {\n x: number\n y: number\n z: number\n color: number\n distance: number\n peak: number\n duration: number\n t: number\n intensity: number\n /** Holds `peak` until `duration` is over. */\n steady: boolean\n}\n\nexport interface FireLightSlot {\n x: number\n y: number\n z: number\n intensity: number\n}\n\n/** The four short flashes of the Workshop (W333-337), taken in turn, and its two fire lights. */\nexport class FlashLightPool {\n readonly lights: FlashLight[] = Array.from({ length: LIGHT_CAPACITY }, () => ({ x: 0, y: 0, z: 0, color: 0xffc070, distance: DEFAULT_LIGHT_DISTANCE, peak: 0, duration: 1, t: 0, intensity: 0, steady: false }))\n readonly fire: FireLightSlot[] = [\n { x: 0, y: 0, z: 0, intensity: 0 },\n { x: 0, y: 0, z: 0, intensity: 0 },\n ]\n private next = 0\n\n constructor(private readonly context: WorkshopContext) {}\n\n get lit(): number {\n return this.lights.filter((light) => light.intensity > 0).length\n }\n\n flash(point: Vec3Tuple, color: number, intensity: number, duration: number, distance?: number, force?: boolean | 'boom', steady?: boolean): void {\n const { level } = this.context.quality\n if (level >= 1 && !force) return\n if (level >= 2 && force !== 'boom') return\n const light = this.lights[this.next++ % LIGHT_CAPACITY]!\n light.x = point[0]\n light.y = point[1]\n light.z = point[2]\n light.color = color\n light.distance = distance || DEFAULT_LIGHT_DISTANCE\n light.peak = intensity\n light.duration = duration\n light.t = 0\n light.steady = steady === true\n light.intensity = intensity\n }\n\n clear(): void {\n for (const light of this.lights) light.intensity = 0\n for (const light of this.fire) light.intensity = 0\n }\n\n update(dt: number): void {\n for (const light of this.lights) {\n if (light.intensity <= 0) continue\n light.t += dt\n const age = light.t / light.duration\n light.intensity = age >= 1 ? 0 : light.steady ? light.peak : light.peak * (1 - age) * (1 - age)\n }\n }\n}\n","import { PROFILES } from '../budget'\nimport type { RandomStream } from '../random'\nimport { createScreenState, resetScreenState, updateScreen } from '../screen'\nimport type { ScreenState, VfxProfile } from '../types'\nimport { DebrisPool } from './debris'\nimport { DecalPool } from './decals'\nimport { RainField } from './rain'\nimport { MeshPool } from './meshes'\nimport type { MeshParticle, Quaternion } from './meshes'\nimport { SpritePool } from './sprites'\nimport { StreakPool } from './streaks'\nimport type { DebrisSpawn, DecalOptions, MeshSpawn, SpriteSpawn, SpriteSystem, Vec3Tuple, WorkshopContext, WorkshopTrace } from './types'\nimport { FlashLightPool, WaveRingPool } from './waves'\n\nconst QUALITY_MULTIPLIERS = [1, 0.5, 0.2] as const\nconst FIRE_FLICKER_SWAY = 0.25\nconst FIRE_FLICKER_JITTER = 0.08\nconst LENS_FADE = 0.16\n\n/** Water or blood on the camera lens: a soft blob that fades and runs down (W351-352). */\nexport interface LensBlob {\n x: number\n y: number\n radius: number\n color: string\n alpha: number\n fall: number\n}\n\n/** The page's `P0` (W347, W1277): what an effect asks of the post-process for this frame only; it is emptied before every frame's tick. */\nexport interface PostProcess {\n desat?: number\n tunnel?: number\n blur?: number\n cold?: number\n chroma?: number\n hue?: number\n red?: number\n tintAlpha?: number\n tintColor?: string\n}\n\n/**\n * Where an effect is put when it is played at a point instead of on the Workshop's set: what the recipe wrote at `anchor` lands at `origin`, turned\n * about the vertical axis by `yaw`. Positions are moved and turned, directions and velocities only turned. With an `orientation` (a unit quaternion) the turn is\n * that one, pitch and roll included, and `yaw` is not used.\n */\nexport interface Placement {\n readonly origin: Vec3Tuple\n readonly anchor: Vec3Tuple\n readonly yaw: number\n readonly orientation?: Quaternion\n}\n\n/** The vector turned by the unit quaternion (three.js's `applyQuaternion`). */\nfunction rotate(q: Quaternion, v: Vec3Tuple): Vec3Tuple {\n const [qx, qy, qz, qw] = q\n const ix = qw * v[0] + qy * v[2] - qz * v[1]\n const iy = qw * v[1] + qz * v[0] - qx * v[2]\n const iz = qw * v[2] + qx * v[1] - qy * v[0]\n const iw = -qx * v[0] - qy * v[1] - qz * v[2]\n return [ix * qw + iw * -qx + iy * -qz - iz * -qy, iy * qw + iw * -qy + iz * -qx - ix * -qz, iz * qw + iw * -qz + ix * -qy - iy * -qx]\n}\n\nexport interface WorkshopOptions {\n readonly random: RandomStream\n readonly profile?: VfxProfile\n readonly groundAt?: (x: number, z: number) => number\n readonly trace?: WorkshopTrace\n}\n\n/** The default ground of the Workshop scene: a raised kerb 12 cm high between z -4.5 and -2.9 (W29). */\nexport function workshopGround(x: number, z: number): number {\n return z < -2.9 && z > -4.5 && Math.abs(x) < 13 ? 0.12 : 0\n}\n\n/**\n * Everything the Workshop's recipes spawn into and the loop that ages it (W168-371, W1285-1287): sprites, streaks, debris, decals, rings, lights, the\n * screen state and the lens blobs, plus the quality level that thins what a recipe asks for and the accumulators that turn a rate into spawns.\n */\nexport class WorkshopEngine {\n readonly context: WorkshopContext\n readonly add: SpritePool\n readonly normal: SpritePool\n readonly streaks: StreakPool\n readonly debris: DebrisPool\n readonly decals: DecalPool\n readonly rings = new WaveRingPool()\n readonly lights: FlashLightPool\n readonly rain = new RainField(this)\n readonly meshes = new MeshPool()\n readonly screen: ScreenState = createScreenState()\n readonly lens: LensBlob[] = []\n post: PostProcess = {}\n /** Set by whoever runs an effect for the time it runs; `undefined` leaves every number as the recipe wrote it. */\n placement: Placement | undefined\n private readonly accumulators = new Map<string, number>()\n\n constructor(options: WorkshopOptions) {\n const profile = options.profile ?? PROFILES.high\n this.context = { random: options.random, groundAt: options.groundAt ?? workshopGround, quality: { level: 0, mult: 1 }, trace: options.trace }\n this.add = new SpritePool(profile.sprites.add, this.context)\n this.normal = new SpritePool(profile.sprites.normal, this.context)\n this.streaks = new StreakPool(profile.streaks, this.context)\n this.debris = new DebrisPool(this.context)\n this.decals = new DecalPool(this.context)\n this.lights = new FlashLightPool(this.context)\n }\n\n get random(): RandomStream {\n return this.context.random\n }\n\n get quality(): number {\n return this.context.quality.level\n }\n\n setQuality(level: number): void {\n this.context.quality.level = level\n this.context.quality.mult = QUALITY_MULTIPLIERS[level] ?? 1\n }\n\n /** `n` (W340): a count thinned by the quality level, never to zero when something was asked. */\n scaled(count: number): number {\n return Math.max(count > 0 ? 1 : 0, Math.round(count * this.context.quality.mult))\n }\n\n /** A point of the recipe's space in the world (`undefined` placement: as is). */\n place(point: Vec3Tuple): Vec3Tuple {\n const placement = this.placement\n if (!placement) return point\n const { anchor, origin, yaw, orientation } = placement\n if (orientation) {\n const turned = rotate(orientation, [point[0] - anchor[0], point[1] - anchor[1], point[2] - anchor[2]])\n return [origin[0] + turned[0], origin[1] + turned[1], origin[2] + turned[2]]\n }\n const x = point[0] - anchor[0]\n const z = point[2] - anchor[2]\n const cos = Math.cos(yaw)\n const sin = Math.sin(yaw)\n return [origin[0] + cos * x + sin * z, origin[1] + point[1] - anchor[1], origin[2] - sin * x + cos * z]\n }\n\n /** A direction or velocity of the recipe's space in the world. */\n turn(vector: Vec3Tuple): Vec3Tuple {\n const placement = this.placement\n if (!placement) return vector\n if (placement.orientation) return rotate(placement.orientation, vector)\n const cos = Math.cos(placement.yaw)\n const sin = Math.sin(placement.yaw)\n return [cos * vector[0] + sin * vector[2], vector[1], -sin * vector[0] + cos * vector[2]]\n }\n\n private placed<T extends { readonly p: Vec3Tuple; readonly dir?: Vec3Tuple; readonly v?: Vec3Tuple }>(options: T): T {\n if (!this.placement) return options\n return { ...options, p: this.place(options.p), ...(options.dir ? { dir: this.turn(options.dir) } : {}), ...(options.v ? { v: this.turn(options.v) } : {}) }\n }\n\n spawn(system: SpriteSystem, recipe: SpriteSpawn): void {\n const options = this.placed(recipe)\n this.context.trace?.(system, [options])\n if (system === 'add') this.add.spawn(options)\n else if (system === 'normal') this.normal.spawn(options)\n else this.streaks.spawn(options)\n }\n\n burst(system: SpriteSystem, count: number, options: SpriteSpawn): void {\n const total = this.scaled(count)\n for (let spawned = 0; spawned < total; spawned++) this.spawn(system, options)\n }\n\n /** `emit` (W343-345): `rate` per second, thinned by the quality, carried over between frames under `key`. `options` is read again for every particle. */\n emit(key: string, system: SpriteSystem, rate: number, dt: number, options: () => SpriteSpawn): void {\n let carried = (this.accumulators.get(key) ?? 0) + rate * this.context.quality.mult * dt\n while (carried >= 1) {\n carried -= 1\n this.spawn(system, options())\n }\n this.accumulators.set(key, carried)\n }\n\n /** A solid particle (a cone, a sphere): the group sits at `p` turned by the placement, `v` is turned with it and `wv` is not. */\n mesh(recipe: MeshSpawn): MeshParticle {\n const placement = this.placement\n const options: MeshSpawn = placement ? { ...recipe, p: this.place(recipe.p), ...(recipe.v ? { v: this.turn(recipe.v) } : {}) } : recipe\n this.context.trace?.('mesh', [options])\n // a piece of a group (`at`, `roll`) is turned with the placement; a free one (smoke, a flame) keeps its own turn in the world\n const grouped = recipe.at !== undefined || recipe.roll !== undefined\n return this.meshes.spawn(options, placement && grouped ? (placement.orientation ?? ([0, Math.sin(placement.yaw / 2), 0, Math.cos(placement.yaw / 2)] as const)) : undefined)\n }\n\n debrisPiece(recipe: DebrisSpawn): void {\n const options = this.placed(recipe)\n this.context.trace?.('debris', [options])\n this.debris.spawn(options)\n }\n\n decal(recipe: readonly [number, number, number, number, number, DecalOptions?]): void {\n let args = recipe\n if (this.placement) {\n const [x, y, z] = this.place([recipe[0], recipe[1], recipe[2]])\n const options = recipe[5]\n args = [x, y, z, recipe[3], recipe[4], options?.n ? { ...options, n: this.turn(options.n) } : options]\n }\n this.context.trace?.('decal', args)\n this.decals.add(args[0], args[1], args[2], args[3], args[4], args[5])\n }\n\n ring(recipe: readonly [Vec3Tuple, number, number, number, number, Vec3Tuple?, number?]): void {\n const args = this.placement ? ([this.place(recipe[0]), recipe[1], recipe[2], recipe[3], recipe[4], recipe[5] && this.turn(recipe[5]), recipe[6]] as const) : recipe\n this.context.trace?.('ring', args)\n this.rings.add(args[0], args[1], args[2], args[3], args[4], args[5], args[6])\n }\n\n /** `steady` (a seventh number): the light holds its intensity for its duration and goes out, where the Workshop's fades with the square of its age. */\n flash(recipe: readonly [Vec3Tuple, number, number, number, number?, (boolean | 'boom')?, boolean?]): void {\n const args = this.placement ? ([this.place(recipe[0]), recipe[1], recipe[2], recipe[3], recipe[4], recipe[5], recipe[6]] as const) : recipe\n this.context.trace?.('flash', args.slice(0, 6))\n this.lights.flash(args[0], args[1], args[2], args[3], args[4], args[5], args[6])\n }\n\n /** `fireLight` (W400): sways with the clock and flickers with one draw. */\n fireLight(slot: 0 | 1, recipe: Vec3Tuple, intensity: number, time: number): void {\n const light = this.lights.fire[slot]!\n const point = this.place(recipe)\n light.x = point[0]\n light.y = point[1]\n light.z = point[2]\n light.intensity = intensity * (0.75 + FIRE_FLICKER_SWAY * Math.sin(time * 23) * Math.sin(time * 7.3) + this.random.between(-FIRE_FLICKER_JITTER, FIRE_FLICKER_JITTER))\n }\n\n lensBlob(x: number, y: number, radius: number, color: string, alpha: number): void {\n this.lens.push({ x, y, radius, color, alpha, fall: this.random.between(2, 8) })\n }\n\n /** The order of the page's loop (W1285-1287): the sprites, streaks, debris, decals, rings and lights, then the screen and its lens. */\n update(dt: number): void {\n const leaveDecal = (x: number, y: number, z: number, size: number, color: number, options: DecalOptions): void => {\n this.decal([x, y, z, size, color, options])\n }\n this.add.update(dt, leaveDecal)\n this.normal.update(dt, leaveDecal)\n this.streaks.update(dt)\n this.debris.update(dt)\n this.decals.update(dt)\n this.rings.update(dt)\n this.meshes.update(dt)\n this.lights.update(dt)\n updateScreen(this.screen, dt)\n for (let index = this.lens.length - 1; index >= 0; index--) {\n const blob = this.lens[index]!\n blob.alpha -= dt * LENS_FADE\n blob.y += blob.fall * dt\n if (blob.alpha <= 0) this.lens.splice(index, 1)\n }\n }\n\n clear(): void {\n this.add.clear()\n this.normal.clear()\n this.streaks.clear()\n this.debris.clear()\n this.decals.clear()\n this.rings.clear()\n this.meshes.clear()\n this.lights.clear()\n this.rain.clear()\n this.accumulators.clear()\n resetScreenState(this.screen)\n this.lens.length = 0\n this.post = {}\n }\n}\n","import type { Rgb } from './color'\n\nexport type { Rgb }\n\nexport type Vec3Like = readonly [number, number, number]\n\n/** The six layers of an explosion the viewer can turn off one by one (L478): flash and light, fire, shock wave, smoke and dust, shrapnel and debris, marks on the ground. */\nexport type VfxLayer = 'flash' | 'fire' | 'shock' | 'smoke' | 'shrapnel' | 'mark'\n\nexport const VFX_LAYERS: readonly VfxLayer[] = ['flash', 'fire', 'shock', 'smoke', 'shrapnel', 'mark']\n\n/** A chain of things that move: anything with a position, or a position. */\nexport type Follow = { readonly x: number; readonly y: number; readonly z: number } | { readonly position: { readonly x: number; readonly y: number; readonly z: number } }\n\n/** A residual fire left behind by an explosion (L798 `residual`), or started by `world.fire`. */\nexport interface FireSpec {\n /** Offsets from the blast point. */\n readonly dx?: number\n readonly dz?: number\n readonly radius: number\n readonly life: number\n readonly rate?: number\n readonly smoke?: number\n /** Grows from `startRadius` to `radius` over `grow` seconds. */\n readonly startRadius?: number\n readonly grow?: number\n /** `0xRRGGBB` of the smoke the fire gives (default soot black). */\n readonly smokeColor?: number\n}\n\nexport interface MushroomSpec {\n readonly height: number\n readonly radius: number\n readonly count: number\n readonly stem: number\n readonly life: number\n /** How fast the ring climbs towards `height` (the Lab's `rk`, default .55). */\n readonly riseRate?: number\n readonly roll?: number\n readonly color?: number\n}\n\n/** The Lab's explosion profile with English names; every number is the Lab's (`sources` lists the lines they come from). */\nexport interface ExplosionDef {\n readonly id: string\n /** Radius (m) inside which a body is torn apart, and the one inside which it is hurt. */\n readonly lethal: number\n readonly injury: number\n /** Radius of the fireball (`vis`). */\n readonly visualRadius: number\n readonly fireballs: number\n readonly fuel?: boolean\n readonly heat?: number\n readonly heatLifeScale?: number\n readonly smoke: { readonly color: number; readonly count: number; readonly life: number; readonly kind?: 0 | 3 }\n readonly dust: { readonly color: number; readonly count: number }\n readonly shrapnel: { readonly count: number; readonly kind: 0 | 1 | 2 | 3 | 4; readonly speed: number; readonly width?: number; readonly embers?: number }\n readonly chunks: { readonly count: number; readonly colors: readonly number[]; readonly plate?: boolean; readonly hot: number; readonly speed?: number; readonly size?: number }\n readonly mark: { readonly scorch?: number; readonly crater?: number; readonly dent?: number }\n readonly flash: { readonly light: number; readonly life?: number; readonly color?: number; readonly intensity?: number; readonly blinding?: boolean }\n readonly shock?: false | { readonly duration: number }\n readonly shake: number\n readonly push: number\n readonly mushroom?: MushroomSpec\n readonly residualFires?: readonly FireSpec[]\n /** Radius (m) in which characters catch fire. */\n readonly ignite?: number\n /** The pieces that fly are hot (the characters' parts burn). */\n readonly hotParts?: boolean\n readonly cone?: { readonly angle: number; readonly half: number; readonly length: number }\n readonly directionBias?: number\n readonly sources: readonly string[]\n}\n\n/** What a host does with what an effect cannot do by itself (break the windows, hurt the characters, dig the ground). */\nexport type VfxSideRequest =\n | { readonly type: 'crater'; readonly x: number; readonly z: number; readonly radius: number; readonly depth: number }\n | { readonly type: 'ignite'; readonly point: Vec3Like; readonly radius: number }\n | {\n readonly type: 'blast_front'\n readonly explosion: string\n readonly point: Vec3Like\n /** Where the glass breaks, damage and push reach: the Lab's `min(injury, 20) * .85`. */\n readonly glassRadius: number\n /** Metres per second the front travels (the speed of sound): the host delays what it breaks by `distance / speed`. */\n readonly speed: number\n readonly lethal: number\n readonly injury: number\n readonly push: number\n readonly hotParts: boolean\n readonly blinding: boolean\n readonly cone?: { readonly angle: number; readonly half: number; readonly length: number }\n }\n\nexport interface VfxProfile {\n readonly puffs: number\n readonly sparks: number\n readonly glows: number\n readonly chunks: number\n readonly sprites: { readonly add: number; readonly normal: number }\n readonly streaks: number\n readonly debris: number\n}\n\nexport type VfxProfileName = 'low' | 'medium' | 'high'\n\nexport interface LodBands {\n /** Distances (m) at which the scale drops. */\n readonly edges: readonly [number, number, number]\n /** The scale in each of the four bands. */\n readonly scales: readonly [number, number, number, number]\n /** How many visual radii are taken off the distance: a big blast stays detailed farther away. */\n readonly radiusFactor: number\n}\n\nexport interface AreaCap {\n readonly radius: number\n readonly window: number\n readonly count: number\n readonly excessScale: number\n}\n\nexport interface ScreenState {\n /** Camera shake amplitude (the Lab's `shakeAmp`). */\n shake: number\n /** White flash of the Lab, 0..1, and how fast it fades. */\n flash: number\n flashDecay: number\n white: number\n red: number\n directionLeft: number\n directionRight: number\n chroma: number\n desat: number\n gas: number\n beat: number\n}\n\nexport interface VfxStats {\n readonly puffs: number\n readonly sparks: number\n readonly glows: number\n readonly chunks: number\n readonly fires: number\n readonly shocks: number\n readonly rings: number\n /** Blast lights and fire lights that are lit. */\n readonly blastLights: number\n readonly fireLights: number\n /** What the last explosion made: puffs, sparks, chunks, lights. */\n readonly lastBlast: { readonly puffs: number; readonly sparks: number; readonly chunks: number; readonly lights: number }\n /** The scale the last explosion was made at (LOD times the area cap). */\n readonly lod: number\n /** Seconds since the last explosion, or `-1` before the first. */\n readonly blastTime: number\n}\n","import { AREA_CAP_GAME, createAreaCap } from './area-cap'\nimport { PROFILES } from './budget'\nimport { EXPLOSIONS, EXPLOSION_ALIASES } from './catalog'\nimport { hexToLinearRgb } from './color'\nimport { DEFAULT_GRAVITY, DEFAULT_WIND } from './constants'\nimport type { RandomMode, VfxCore } from './core'\nimport { addFire, createFirePool, updateFires } from './emitters/fire'\nimport type { Fire } from './emitters/fire'\nimport { GAME_EFFECTS } from './effects/catalog'\nimport { createEffectPlayer } from './effects/player'\nimport type { EffectPlayer, PlayOptions } from './effects/player'\nimport type { EffectDef } from './effects/types'\nimport { composeExplosion } from './explosion'\nimport type { GroundField } from './ground'\nimport { createLightPool, resetLightPool, updateLights } from './lights'\nimport type { LightPool } from './lights'\nimport { LOD_GAME } from './lod'\nimport { createMarkStore } from './marks'\nimport type { MarkEvent, MarkStore } from './marks'\nimport type { OrderedPool } from './pool'\nimport { updateChunks } from './pools/chunk-motion'\nimport { createChunkPool } from './pools/chunks'\nimport type { Chunk } from './pools/chunks'\nimport { createGlowPool, updateGlows } from './pools/glows'\nimport type { Glow } from './pools/glows'\nimport { createPuffPool, updatePuffs } from './pools/puffs'\nimport type { Puff, Ring } from './pools/puffs'\nimport { createRingPool, updateRings } from './pools/rings'\nimport { createShockPool, updateShocks } from './pools/shocks'\nimport type { Shock } from './pools/shocks'\nimport { createSparkPool, updateSparks } from './pools/sparks'\nimport type { Spark } from './pools/sparks'\nimport { lehmer, streamFor } from './random'\nimport type { MutableVec3, RandomStream } from './random'\nimport { createSchedule } from './schedule'\nimport { createScreenState, resetScreenState, updateScreen } from './screen'\nimport { SpriteKindSystem } from './sprites/system'\nimport type { LandListener } from './sprites/system'\nimport type { SpriteSpawnOptions } from './sprites/kind-pool'\nimport type { SpriteKind, SpriteKindDef } from './sprites/kinds'\nimport type { VfxTrace } from './trace'\nimport { WorkshopEngine } from './workshop/engine'\nimport type { Vec3Tuple } from './workshop/types'\nimport type { AreaCap, ExplosionDef, Follow, LodBands, ScreenState, VfxLayer, VfxProfile, VfxProfileName, VfxSideRequest, VfxStats, Vec3Like } from './types'\nimport { VFX_LAYERS } from './types'\n\nexport interface VfxOptions {\n readonly seed?: number\n /** `per_event` (default): every explosion draws from a stream of its own seed, so a LAN client repeats it from a few bytes. `shared`: one stream for everything, like the Lab page (the goldens). */\n readonly randomMode?: RandomMode\n readonly profile?: VfxProfileName | VfxProfile\n readonly lod?: LodBands\n /** The cap on explosions in one area; `false` turns it off. Default the game's: 6 in 4 s within 40 m, the extra ones at 0.3. */\n readonly areaCap?: AreaCap | false\n /** Height of the ground for what bounces. Default: the `ground` field, else flat at 0. */\n readonly groundAt?: (x: number, z: number) => number\n /** A deformable ground the craters dig into (see `createGroundField`). */\n readonly ground?: GroundField\n readonly wind?: Vec3Like\n readonly gravity?: number\n /** The catalogue by id (default the Lab's 16 and `generic`); build another with `patchExplosions(EXPLOSIONS, ...)`. */\n readonly explosions?: Readonly<Record<string, ExplosionDef>>\n readonly aliases?: Readonly<Record<string, string>>\n /** The Workshop's recipes by id for `play` (default `GAME_EFFECTS`; build another with `patchEffects`). */\n readonly effects?: Readonly<Record<string, EffectDef>>\n /** The sprites of fixed kinds (`burst`, `spawn`): pool size and count multiplier (default 2500 and 1; a `low` profile halves the pool and uses 0.6) and the kinds by id. */\n readonly sprites?: { readonly capacity?: number; readonly density?: number; readonly kinds?: Readonly<Record<string, SpriteKindDef>> }\n readonly reducedMotion?: boolean\n /** Hears everything that spawns, in order (the goldens use it). */\n readonly trace?: VfxTrace\n readonly onRequest?: (request: VfxSideRequest) => void\n}\n\nexport interface ExplosionOptions {\n readonly direction?: Vec3Like\n /** Repeats the same visual: used in `per_event` mode. */\n readonly seed?: number\n /** Multiplies the size of the effect (radius, marks, mushroom, fires). */\n readonly scale?: number\n /** Seconds from now until it goes off (a chain). */\n readonly delay?: number\n}\n\nexport interface FireOptions {\n readonly point: Vec3Like\n readonly radius: number\n readonly life: number\n /** Flames per second per square-ish metre (the Lab's `rate`, default 22) and smoke puffs (default .6). */\n readonly rate?: number\n readonly smoke?: number\n /** Grows from `startRadius` to `radius` over `grow` seconds. */\n readonly startRadius?: number\n readonly grow?: number\n /** `0xRRGGBB` of the smoke (default soot black). */\n readonly smokeColor?: number\n /** Moves with a thing (a burning part): the fire sits at its position plus `offset`. */\n readonly follow?: Follow\n readonly offset?: Vec3Like\n readonly seed?: number\n}\n\n/** The pools as the renderer reads them: live records, oldest first. */\nexport interface VfxPoolsView {\n readonly puffs: OrderedPool<Puff>\n readonly sparks: OrderedPool<Spark>\n readonly glows: OrderedPool<Glow>\n readonly chunks: OrderedPool<Chunk>\n readonly shocks: OrderedPool<Shock>\n readonly rings: OrderedPool<Ring>\n readonly lights: LightPool\n readonly marks: MarkStore\n readonly ground: GroundField | undefined\n}\n\nexport interface VfxWorld {\n /** Sets off an explosion of the catalogue by id (an explosive id or an alias); `null` when the id is unknown. */\n explosion(id: string, point: Vec3Like, options?: ExplosionOptions): number | null\n /** A lingering area fire (a molotov's pool, a burning part). Returns a handle for `stop`. */\n fire(options: FireOptions): number\n /**\n * Plays a recipe of the Workshop (a blood hit, a muzzle flash, a collapse) at `point`, facing `options.direction`, into the world's Workshop pools\n * (`workshop()`); `null` when the id is unknown. Returns a handle for `stop`.\n */\n play(id: string, point: Vec3Like, options?: PlayOptions): number | null\n /** The Workshop's pools (sprites, streaks, debris, decals, rings, lights, screen): what the renderer draws for `play`. Made on first use. */\n workshop(): WorkshopEngine\n /** The Workshop engine if something already made it (`play`, `workshop()`); never creates it. */\n peekWorkshop(): WorkshopEngine | undefined\n /** The ids `play` accepts. */\n effectIds(): readonly string[]\n /** `count` sprites of a kind leaving `point` around `normal` at about `speed` m/s (debris, sparks, smoke, steam, drips...). */\n burst(kind: SpriteKind | string, point: Vec3Like, normal: Vec3Like, count: number, speed?: number, options?: SpriteSpawnOptions): void\n /** One sprite of a kind with an explicit velocity. */\n spawn(kind: SpriteKind | string, point: Vec3Like, velocity: Vec3Like, options?: SpriteSpawnOptions): void\n /** Hears where the sprites of `owner` that land (drips spawned with `{ owner, tag }`) touch the ground. Returns the function that stops listening. */\n onLand(owner: string, listener: LandListener): () => void\n /** The sprite pools as the renderer reads them. */\n sprites(): SpriteKindSystem\n /** Pushes the smoke and dust within `radius` of `point` outwards, as fast as `speed` at the centre. */\n push(point: Vec3Like, radius: number, speed: number): void\n stop(handle: number): void\n setLayer(layer: VfxLayer, on: boolean): void\n layer(layer: VfxLayer): boolean\n setCamera(position: Vec3Like): void\n /** The wind that carries the smoke and dust, in m/s (`VfxOptions.wind` is where it starts). The weather moves it. */\n setWind(wind: Vec3Like): void\n wind(): Vec3Tuple\n /** Forces the scale of every explosion from now on (`null`: back to the distance bands and the cap). */\n forceLod(scale: number | null): void\n update(dt: number): void\n screen(): Readonly<ScreenState>\n stats(): VfxStats\n pools(): VfxPoolsView\n /** The live lingering fires, oldest first. */\n fires(): readonly Fire[]\n /** Hears every mark the moment it is made, and when they are cleared. Returns the function that stops listening. */\n onMarks(listener: (event: MarkEvent) => void): () => void\n /** Seconds the world has run since it was created or cleared. */\n time(): number\n /** The state of the shared stream (`randomMode: 'shared'`): what a golden compares after a run. */\n randomState(): number\n /** Takes everything away (pools, marks, ground, timers, lights, screen) and restarts the clock. */\n clear(): void\n /** The catalogue ids `explosion` accepts, aliases included. */\n catalog(): readonly string[]\n}\n\nconst FIRE_CAPACITY = 64\nconst RING_CAPACITY = 16\nconst SHOCK_CAPACITY = 16\nconst AUTO_SEED = 0x2545f491\n\nfunction resolveProfile(profile: VfxOptions['profile']): VfxProfile {\n if (profile === undefined) return PROFILES.medium\n return typeof profile === 'string' ? PROFILES[profile] : profile\n}\n\nfunction scaleDefinition(def: ExplosionDef, factor: number): ExplosionDef {\n if (factor === 1) return def\n const mushroom = def.mushroom && { ...def.mushroom, height: def.mushroom.height * factor, radius: def.mushroom.radius * factor }\n const residual = def.residualFires?.map((fire) => ({ ...fire, radius: fire.radius * factor, dx: (fire.dx ?? 0) * factor, dz: (fire.dz ?? 0) * factor }))\n return {\n ...def,\n lethal: def.lethal * factor,\n injury: def.injury * factor,\n visualRadius: def.visualRadius * factor,\n mark: { scorch: def.mark.scorch && def.mark.scorch * factor, crater: def.mark.crater && def.mark.crater * factor, dent: def.mark.dent && def.mark.dent * factor },\n ...(mushroom ? { mushroom } : {}),\n ...(residual ? { residualFires: residual } : {}),\n }\n}\n\nexport function createVfx(options: VfxOptions = {}): VfxWorld {\n const profile = resolveProfile(options.profile)\n const sharedRandom = lehmer(options.seed ?? 1)\n const explosions = options.explosions ?? EXPLOSIONS\n const aliases = options.aliases ?? EXPLOSION_ALIASES\n const randomMode = options.randomMode ?? 'per_event'\n const wind: MutableVec3 = { x: DEFAULT_WIND.x, y: DEFAULT_WIND.y, z: DEFAULT_WIND.z }\n if (options.wind) [wind.x, wind.y, wind.z] = options.wind\n const camera: MutableVec3 = { x: 0, y: 1.6, z: 0 }\n const layers = Object.fromEntries(VFX_LAYERS.map((layer) => [layer, true])) as Record<VfxLayer, boolean>\n const ground = options.ground\n const groundAt = options.groundAt ?? (ground ? (x: number, z: number) => ground.heightAt(x, z) : () => 0)\n const handles = { next: 0, events: 0 }\n const low = options.profile === 'low'\n const spriteSystem = new SpriteKindSystem({\n capacity: options.sprites?.capacity ?? (low ? 1250 : 2500),\n density: options.sprites?.density ?? (low ? 0.6 : 1),\n seed: 0x9e3779b1 + (options.seed ?? 0),\n groundAt,\n gravity: options.gravity ?? DEFAULT_GRAVITY,\n ...(options.sprites?.kinds ? { kinds: options.sprites.kinds } : {}),\n })\n const core: VfxCore = {\n profile,\n puffs: createPuffPool(profile.puffs),\n sparks: createSparkPool(profile.sparks),\n glows: createGlowPool(profile.glows),\n chunks: createChunkPool(profile.chunks, sharedRandom),\n fires: createFirePool(FIRE_CAPACITY, sharedRandom),\n shocks: createShockPool(SHOCK_CAPACITY),\n rings: createRingPool(RING_CAPACITY),\n lights: createLightPool(),\n marks: createMarkStore(),\n screen: createScreenState(),\n layers,\n schedule: createSchedule(),\n wind,\n camera,\n ground,\n bands: options.lod ?? LOD_GAME,\n areaCap: options.areaCap === false ? undefined : createAreaCap(options.areaCap ?? AREA_CAP_GAME),\n randomMode,\n sharedRandom,\n reducedMotion: options.reducedMotion ?? false,\n gravity: options.gravity ?? DEFAULT_GRAVITY,\n trace: options.trace,\n spawned: { puffs: 0, sparks: 0, chunks: 0, lights: 0 },\n clock: { time: 0, lastBlast: -1, lod: 1, forcedLod: null },\n groundAt,\n emit: (request) => options.onRequest?.(request),\n }\n\n function definitionOf(id: string): ExplosionDef | undefined {\n return explosions[id] ?? explosions[aliases[id] ?? '']\n }\n\n function streamOf(seed: number | undefined): RandomStream {\n if (randomMode === 'shared') return sharedRandom\n handles.events++\n return streamFor(seed ?? Math.imul(handles.events, AUTO_SEED) + (options.seed ?? 0))\n }\n\n function detonate(def: ExplosionDef, point: Vec3Like, call: { direction: MutableVec3 | undefined; random: RandomStream; handle: number }): void {\n composeExplosion(core, def, { x: point[0], y: point[1], z: point[2], direction: call.direction, random: call.random, handle: call.handle })\n }\n\n let engine: WorkshopEngine | undefined\n let player: EffectPlayer | undefined\n const effects = options.effects ?? GAME_EFFECTS\n const view = { get position(): Vec3Tuple { return [camera.x, camera.y, camera.z] }, forward: (local: readonly number[]): Vec3Tuple => [local[0] ?? 0, local[1] ?? 0, local[2] ?? 0] }\n\n function workshop(): WorkshopEngine {\n return (engine ??= new WorkshopEngine({ random: sharedRandom, profile, groundAt }))\n }\n\n function effectPlayer(): EffectPlayer {\n return (player ??= createEffectPlayer({ engine: workshop(), effects, view }))\n }\n\n return {\n play(id, point, playOptions = {}) {\n if (!(id in effects)) return null\n const seed = playOptions.seed ?? (randomMode === 'shared' ? undefined : Math.imul(++handles.events, AUTO_SEED) + (options.seed ?? 0))\n return effectPlayer().play(id, [point[0], point[1], point[2]], { ...playOptions, ...(seed !== undefined ? { seed } : {}) })\n },\n burst: (kind, point, normal, count, speed, spriteOptions) => spriteSystem.burst(kind, point, normal, count, speed, spriteOptions),\n spawn: (kind, point, velocity, spriteOptions) => spriteSystem.spawn(kind, point, velocity, spriteOptions),\n onLand: (owner, listener) => spriteSystem.onLand(owner, listener),\n sprites: () => spriteSystem,\n workshop,\n peekWorkshop: () => engine,\n effectIds: () => Object.keys(effects),\n explosion(id, point, explosionOptions = {}) {\n const base = definitionOf(id)\n if (!base) return null\n const def = scaleDefinition(base, explosionOptions.scale ?? 1)\n const handle = ++handles.next\n const direction = explosionOptions.direction && { x: explosionOptions.direction[0], y: explosionOptions.direction[1], z: explosionOptions.direction[2] }\n const random = streamOf(explosionOptions.seed)\n if (explosionOptions.delay) core.schedule.at(core.clock.time + explosionOptions.delay, () => detonate(def, point, { direction, random, handle }))\n else detonate(def, point, { direction, random, handle })\n return handle\n },\n fire(fireOptions) {\n const handle = ++handles.next\n const { point, offset, seed, radius, smokeColor, ...rest } = fireOptions\n addFire(core, streamOf(seed), {\n ...rest, r: radius, x: point[0], y: point[1], z: point[2], fx: offset?.[0] ?? 0, fy: offset?.[1] ?? 0, fz: offset?.[2] ?? 0,\n ...(smokeColor !== undefined ? { color: hexToLinearRgb(smokeColor) } : {}),\n }, handle)\n return handle\n },\n push(point, radius, speed) {\n spriteSystem.push(point, radius, speed)\n for (const puff of core.puffs.items) {\n const dx = puff.x - point[0]\n const dy = puff.y - point[1]\n const dz = puff.z - point[2]\n const distance = Math.sqrt(dx * dx + dy * dy + dz * dz)\n if (distance >= radius) continue\n const strength = (speed * (1 - distance / radius)) / (distance + 0.001)\n puff.vx += dx * strength\n puff.vy += dy * strength\n puff.vz += dz * strength\n }\n },\n stop(handle) {\n player?.stop(handle)\n const fires = core.fires\n for (let index = fires.items.length - 1; index >= 0; index--) if (fires.items[index]!.handle === handle) fires.removeAt(index)\n },\n setLayer(layer, on) {\n layers[layer] = on\n },\n layer: (layer) => layers[layer],\n setCamera(position) {\n camera.x = position[0]\n camera.y = position[1]\n camera.z = position[2]\n },\n setWind(next) {\n wind.x = next[0]\n wind.y = next[1]\n wind.z = next[2]\n },\n wind: () => [wind.x, wind.y, wind.z],\n forceLod(scale) {\n core.clock.forcedLod = scale\n },\n update(dt) {\n core.clock.time += dt\n core.schedule.update(core.clock.time)\n updateRings(core.rings, dt)\n updatePuffs(core.puffs, dt, wind)\n updateSparks(core.sparks, { dt, groundAt })\n updateGlows(core.glows, dt)\n updateShocks(core.shocks, core.puffs.items, dt)\n updateChunks(core, dt)\n updateFires(core, dt)\n updateLights(core.lights, { dt, flashLayer: layers.flash ? 1 : 0, clock: core.clock.time, fires: core.fires.items })\n updateScreen(core.screen, dt)\n spriteSystem.update(dt)\n if (engine) {\n engine.post = {}\n player?.update(dt)\n engine.update(dt)\n }\n },\n screen: () => core.screen,\n stats() {\n const lights = core.lights\n return {\n puffs: core.puffs.count,\n sparks: core.sparks.count,\n glows: core.glows.count,\n chunks: core.chunks.count,\n fires: core.fires.count,\n shocks: core.shocks.count,\n rings: core.rings.count,\n blastLights: lights.blast.filter((light) => light.intensity > 0.05).length,\n fireLights: lights.fire.filter((light) => light.intensity > 0.05).length,\n lastBlast: { ...core.spawned },\n lod: core.clock.lod,\n blastTime: core.clock.lastBlast < 0 ? -1 : core.clock.time - core.clock.lastBlast,\n }\n },\n pools: () => ({\n puffs: core.puffs, sparks: core.sparks, glows: core.glows, chunks: core.chunks, shocks: core.shocks, rings: core.rings, lights: core.lights, marks: core.marks, ground,\n }),\n fires: () => core.fires.items,\n onMarks: (listener) => core.marks.subscribe(listener),\n time: () => core.clock.time,\n randomState: () => sharedRandom.state,\n clear() {\n for (const pool of [core.puffs, core.sparks, core.glows, core.chunks, core.fires, core.shocks, core.rings] as OrderedPool<object>[]) pool.clear()\n core.marks.clear()\n core.schedule.clear()\n core.areaCap?.clear()\n ground?.reset()\n resetLightPool(core.lights)\n resetScreenState(core.screen)\n spriteSystem.clear()\n player?.clear()\n engine?.clear()\n core.clock.time = 0\n core.clock.lastBlast = -1\n core.clock.lod = 1\n core.spawned.puffs = core.spawned.sparks = core.spawned.chunks = core.spawned.lights = 0\n },\n catalog: () => [...new Set([...Object.keys(explosions), ...Object.keys(aliases)])],\n }\n}\n","{\n \"spall\": \"impact_{material}\",\n \"stage\": { \"1\": \"stage_crack\", \"2\": \"breach_dust\", \"3\": \"collapse_dust\" },\n \"expose\": \"rebar_expose\",\n \"collapse\": \"collapse_dust\",\n \"explode\": \"explosion\",\n \"fracture\": { \"glass\": \"glass_burst\" }\n}\n","import eventData from '../data/event-effects.json'\n\n/** What a game event looks like to the map: the kind of event and the little that picks its effect. */\nexport interface GameEvent {\n /** `spall`, `stage`, `expose`, `collapse`, `explode`, `fracture`... (strings, so there is no compile dependency on the destruction package). */\n readonly kind: string\n /** The stage of a `stage` event (1, 2 or 3). */\n readonly stage?: number\n /** The material of a `spall` or `fracture` event. */\n readonly material?: string\n}\n\ntype EventMap = Readonly<Record<string, string | Readonly<Record<string, string>>>>\n\nexport const EVENT_EFFECTS_MAP: EventMap = eventData\n\n/**\n * The effect id that plays for an event (`undefined` when the map has none). A string entry may use `{material}`; an object entry is chosen by the event's\n * stage or material. A game passes its own map to add or change entries.\n */\nexport function effectForEvent(event: GameEvent, map: EventMap = EVENT_EFFECTS_MAP): string | undefined {\n const entry = map[event.kind]\n if (entry === undefined) return undefined\n if (typeof entry === 'string') return event.material || !entry.includes('{material}') ? entry.replace('{material}', event.material ?? '') : undefined\n const key = event.stage !== undefined ? String(event.stage) : event.material\n return key === undefined ? undefined : entry[key]\n}\n","import type { EffectTexts } from '../locale'\n\n/** The Workshop's sheet for each effect, in English (the pt-BR texts are the page's own). */\nexport const en: Readonly<Record<string, EffectTexts>> = {\n blood_hit: {\n name: 'Blood by infection age',\n short: 'A mist on the way in, a jet on the way out, a pool that grows. Age changes colour and amount.',\n cost: '≤ 70 part.',\n costNote: '1 pool · 6 splashes',\n paramLabel: 'Age',\n when: 'Every bullet or blow that hits a zombie. The blood value comes from the bestiary age: 1.0 · 0.7 · 0.35 · 0.1.',\n look: 'Fresh sprays bright red and drips. Recent is burgundy. Old is brown and sparse. Decrepit does not bleed: it gives off black dust and dry flakes. The pool grows for 2 to 4 s and darkens in 60 s.',\n budget: 'Up to 70 particles per hit (Fresh), 1 pool and up to 6 splashes on the ground. Drops that land become decals.',\n network: 'Cosmetic. Goes in the impact event with 2 bits of age and the seed.',\n },\n headshot: {\n name: 'Headshot',\n short: 'The head bursts, the eyes go out on the same frame and the body drops.',\n cost: '≤ 70 part.',\n costNote: '8 debris · 1 pool',\n when: 'A head hit that kills (bestiary rule: a head kills at once).',\n look: 'A red mist around the head, a jet of drops backwards, 6 to 8 pieces of bone and skin, a swap to the burst-neck mesh. The eye glow goes out on the same frame, which is the most readable signal from afar.',\n budget: '20 mist + 35 drops + 8 debris + 1 pool. In the horde only the 12 closest get debris.',\n network: 'Cosmetic. The server already sends \"death by head\".',\n },\n dismember: {\n name: 'Dismemberment',\n short: 'The arm comes off whole with physics and the shoulder gushes for half a second.',\n cost: '≤ 60 part.',\n costNote: '1 limb · 4 splashes',\n when: 'Damage to a limb above the threshold (multipliers by region from the bestiary) or an axe blow.',\n look: 'The limb becomes a loose piece with physics and bounces. A short pulsing jet from the shoulder, drops that form a trail to the pool. The zombie staggers but keeps walking.',\n budget: '1 limb with physics (counts toward the cap of 300), a jet of up to 60 drops in 0.7 s.',\n network: 'The server sends which limb came off. The piece is local; each client simulates its own.',\n },\n bloater_cloud: {\n name: 'Bloater cloud',\n short: 'The belly pulses for 0.5 s, bursts and leaves 4 m of gas for 8 s.',\n cost: '≤ 180 part.',\n costNote: 'server entity',\n when: 'Death of the Bloater, by any cause.',\n look: 'A 0.5 s warning with the belly swelling, a burst with pieces and a greenish jet, and a low moss-green cloud that undulates on the ground for 8 s. Loose green glows inside the cloud mark the area.',\n budget: '40 large sprites at the burst and up to 60 alive in the cloud, at half resolution. Fade near the camera so it does not paint the whole screen.',\n network: 'Server entity (radius 4 m, 8 s): blinds for 5 s, doubles the scent trail and makes people cough. The client only draws.',\n },\n screamer_shriek: {\n name: 'Screamer shriek',\n short: 'A 1.5 s wind-up with steam, a wave on the ground and the horde\\'s eyes light up.',\n cost: '≤ 150 part.',\n costNote: '3 rings · aberration',\n when: 'The Screamer spots the player and starts the shriek (1.5 s wind-up, calls everyone within 150 m).',\n look: 'Head back and steam from the mouth during the wind-up. On the shriek, three pressure rings on the ground, dust raised in the radius, a short chromatic aberration on the screen of whoever is near, and the eyes of nearby zombies flare when they hear.',\n budget: '3 rings, up to 150 dust particles. The screen aberration is a 0.4 s post effect.',\n network: 'The server sends \"shriek at X\". The screen effect depends on local distance.',\n },\n eyes_in_fog: {\n name: 'Eyes in the fog',\n short: 'Eye glow that cuts through the fog; runners leave a red trail.',\n cost: '2 sprites/zombie',\n costNote: '0 lights',\n when: 'Always, on every zombie. It is the bestiary reading system: eye colour tells the category.',\n look: 'Two emissive points with bloom that ignore the fog. The body disappears in the mist at 25 m, the eyes stay readable at 60 m. Runners leave a short trail in the eye colour when they run.',\n budget: '2 sprites per zombie in the same instanced batch as the body. Trail only for runners closer than 30 m. No real light.',\n network: 'Nothing goes over the network: it comes from the zombie category.',\n },\n corpse_decay: {\n name: 'Corpse: darken and dissolve',\n short: '15 minutes in 8 seconds: fall, darken, flies and turn to dust.',\n cost: '≤ 40 part.',\n costNote: 'pool of 400 bodies',\n when: 'Zombie death. Bestiary timeline: ragdoll 3 s, frozen mesh, darken, dissolve between 14 and 15 min.',\n look: 'The skin loses colour until almost black, the pool dries to brown, flies appear from minute 5 and in the last minute the body sinks and gives off dark dust.',\n budget: 'Flies: 6 particles per body, only closer than 10 m. Dust: 40 particles once. The body uses the dissolve shader, no extra particle.',\n network: 'The server sends the time of death; each client works out the state.',\n },\n reanimation: {\n name: 'Reanimation',\n short: 'Veins light up, spasms, the eyes switch on and the body gets up.',\n cost: '≤ 30 part.',\n costNote: 'emissive in the shader',\n when: 'End of infection of a player or NPC: reanimates in 2 to 6 min as Fresh (70% Slow, 30% Runner).',\n look: 'Green pulses through the skin (emissive in the shader, not particles), spasms in the arms and head, the eyes light up from the inside out and the body stands. Breath as steam on the first shriek.',\n budget: 'Only animated emissive and 30 particles. It is rare and important, so it may be expensive.',\n network: 'The server sends \"reanimated\". For the friend who sees a teammate get up, it is the strongest moment of co-op.',\n },\n muzzle_flash: {\n name: 'Muzzle flash',\n short: 'Core, petals and smoke scaled by weapon. The Barrett raises dust.',\n cost: '≤ 60 part.',\n costNote: '1 light · 50 ms',\n paramLabel: 'Weapon',\n when: 'Every shot. In first person it uses the weapon model; from afar it is only the core sprite.',\n look: 'Three layers: a white-yellow core of 1 frame, petals along the barrel and grey smoke that stays 1 to 2 s. The 12-gauge has a wide flash and thick smoke. The Barrett vents two side jets through the muzzle brake and raises a ring of dust from the ground. The light illuminates the room for 50 ms (request from the map brief).',\n budget: 'Up to 60 particles and 1 light per shot. An AK burst uses the same light in a loop. A pistol has no light beyond 15 m.',\n network: 'Cosmetic. It comes from the shot event the server already sends (weapon, origin, direction).',\n },\n impact: {\n name: 'Impact by material',\n short: 'Concrete, metal, wood, glass, flesh and water: each with its own response.',\n cost: '≤ 40 part.',\n costNote: '1 hole',\n paramLabel: 'Material',\n when: 'Every bullet that hits something. The material comes from the mesh surface tag.',\n look: 'Concrete: pale dust in a cone and grey chips. Metal: a shower of bouncing sparks, no dust, with a short light. Wood: thin splinters and brown dust. Glass: glint, shards and a crack. Flesh: blood by age. Water: a crown of drops and two rings.',\n budget: '14 dust + 6 chips + up to 18 sparks + 1 hole. At 40 m only the dust remains.',\n network: '12-byte impact event with the material in 4 bits.',\n },\n penetration: {\n name: 'Bullet through the horde',\n short: 'Barrett tracer passing through 5 zombies, in 10x slow motion.',\n cost: '≤ 250 part.',\n costNote: 'aggregate event',\n when: 'Weapon with penetration: the AK goes through 2, the Remington 700 through 3, the Barrett through 6 and cars.',\n look: 'A tracer with a hot-air trail, blood exiting each body in the order the bullet passes (each in the colour of its age), bodies falling one after another and a final impact on the concrete.',\n budget: 'All hits of a shot go in a single aggregate event with the list of points. 5 bodies = 5 exits + 5 pools.',\n network: 'The server sends the shot and the ordered list of hits.',\n },\n casings_and_magazine: {\n name: 'Casings and magazine',\n short: 'Brass that bounces and stays on the ground, an empty magazine falling, smoke from the hot barrel.',\n cost: '200/player',\n costNote: 'physics 1.5 s',\n when: 'Every shot of a semi-automatic weapon, every reload, and the pump of the 12-gauge or the rifle bolt.',\n look: 'The casing leaves the ejection port spinning, bounces on the asphalt two or three times and stays. The empty magazine drops on reload. After a burst, thin smoke rises from the hot barrel for 2 s.',\n budget: 'Physics only for 1.5 s, then it becomes a static instance. Cap of 200 per player, the oldest goes first.',\n network: 'Cosmetic, each client generates its own. Ground position is not synchronised.',\n },\n molotov: {\n name: 'Molotov cocktail',\n short: 'A lit wick in the arc, glass breaking and a pool of fire that spreads.',\n cost: '≤ 300 part.',\n costNote: '2 lights · entity',\n when: 'A molotov hitting the ground or a zombie.',\n look: 'A bottle in an arc with the wick giving off flame and smoke. On impact, green shards and a splash of fire that opens from 0.5 m to 2.2 m in 0.8 s. Low flames, embers, dark smoke and a flickering light for 6 s, then embers and a burn mark.',\n budget: 'Area fire with up to 300 particles and 1 fire light. Burning zombies use a small emitter attached to the body (40 particles) and only the 8 closest.',\n network: 'Fire is a server entity: area, damage per second, time. The client draws from it.',\n },\n grenade: {\n name: 'Fragmentation grenade',\n short: 'A bounce on the asphalt, flash, shock wave, shrapnel and a ring of dust.',\n cost: '≤ 400 part.',\n costNote: 'aggregate event',\n when: 'A grenade exploding (1.8 s fuse after the throw).',\n look: 'The grenade bounces twice. A layered explosion: a white flash that paints the screen, a short fireball, a shock ring on the ground and another facing the camera, bright shrapnel that bounces, a ring of low dust, grey smoke that rises and a burn mark. Zombies in the radius fall outwards.',\n budget: 'Up to 400 particles, 1 strong light of 0.5 s, 16 debris, 1 mark. The 40 zombies hit go in a single aggregate event.',\n network: 'The server sends the explosion and the list of those hit. Visual is local.',\n },\n explosive_barrel: {\n name: 'Explosive barrel',\n short: 'A mushroom of fire, the lid flying, petrol burning on the ground and a column of smoke.',\n cost: '≤ 450 part.',\n costNote: '2 lights · fire entity',\n when: 'A red barrel with damage above the threshold, a shot or fire touching it.',\n look: 'Everything the grenade does, plus: a fireball that rises into a mushroom, the lid and red pieces flying high, three pools of petrol burning for 5 s and a black smoke column that serves as a landmark from afar.',\n budget: 'Peak of 450 particles. The smoke column stays visible beyond 80 m with 6 large sprites.',\n network: 'Explosion + a fire entity in the pools.',\n },\n shopfront_glass: {\n name: 'Shop window bursting',\n short: 'Two cracks, then the whole pane comes down in shards that stay on the pavement.',\n cost: '≤ 80 debris',\n costNote: '1 crack',\n when: 'Glass with accumulated damage (shot, blow, horde pushing). A 20 m noise that draws the horde.',\n look: 'The first blows open star cracks in the glass texture. At the burst the pane vanishes and becomes 60 to 80 shards that fall spinning, glinting in the light, and stay on the pavement. A veil of fine glass dust in front.',\n budget: 'Shards with physics count toward the cap of 300 and become static in 2 s. 3 crack stages in a single mask.',\n network: 'The server sends the glass state (0 to 3). Shards are local.',\n },\n door_stages: {\n name: 'Door giving way in 3 stages',\n short: 'Blows shake dust from the frame, a plank cracks and the door falls.',\n cost: '≤ 120 part.',\n costNote: '3 stages',\n when: 'The horde hitting a door or barricade (the Brute does 3x damage). Stages: 66%, 33%, 0% health.',\n look: 'Each blow shakes the door and loosens dust from the frame and splinters. At stage 2 the middle plank cracks and falls. At 3 the door topples and raises a cloud of low dust, and the zombie comes out of the dark.',\n budget: 'Dust: 12 particles per blow. Fall: 40 of dust and 6 debris. Blows beyond 15 m have no particles, only sound.',\n network: 'The server sends the door health. The visual stage comes from the value.',\n },\n building_collapse: {\n name: 'Collapse',\n short: 'Dust trickling from the awning, blocks falling and a cloud of dust rolling down the street.',\n cost: '≤ 350 part.',\n costNote: '26 debris',\n when: 'A structure that loses its health: explosion, vehicle impact, a big horde pushing (destruction of the map buildings).',\n look: 'Before: fine dust trickling and pebbles falling for 1 s, as a warning. Then: large and small blocks fall, the camera shakes and a cloud of grey-beige dust rolls along the ground and hangs in the air for 5 s, hiding zombies.',\n budget: '26 debris (6 large), 70 dust sprites at half resolution. A rare event, it fits the budget.',\n network: 'The server sends the collapse and the dust area, which blocks zombie sight for 4 s.',\n },\n block_wall: {\n name: 'Wall brought down with holes',\n short: 'A burst leaves holes and chips; the wall falls in blocks and the holes stay on them.',\n cost: '≤ 300 part.',\n costNote: '30 blocks · attached holes',\n when: 'A concrete wall, low wall or barricade that loses health from shots, explosion, the Brute or a car (map and arsenal destruction).',\n look: 'Each bullet opens a dark hole with a chipped rim, giving off dust and pebbles. When the wall gives way it splits into blocks that topple with physics and a cloud of dust rolls along the ground. The bullet holes are attached to the blocks: they stay on the fallen pieces, turned with them, and do not vanish when the wall breaks.',\n budget: 'Holes are decals that are children of the piece (not of the world), up to 12 per block and 128 in total. Blocks count toward the cap of 300 debris and become static at rest. Dust: 60 sprites at half resolution.',\n network: 'The server sends the wall health and the list of holes (2-byte local position per hole). Whoever joins later sees the same holes on the same pieces. The blocks fall using a common seed.',\n },\n metal_door: {\n name: 'Metal door denting',\n short: 'Each blow sinks the plate, flakes the paint and throws sparks; the hinge bursts.',\n cost: '≤ 160 part.',\n costNote: 'deformable mesh',\n when: 'A door, gate or steel plate taking a zombie blow (Brute 3x), a 12-gauge shot or a car hit.',\n look: 'The plate sinks where it is hit (a deformed mesh, not a model swap), with 3 visible levels. Each blow gives off sparks, flakes of green paint and rust dust. When the health runs out the top hinge bursts in sparks, the door topples and scrapes on the ground giving off more sparks.',\n budget: 'Per-vertex deformation only at the moment of the blow (CPU, 400 vertices). Per blow: 8 sparks, 5 flakes, 6 of rust. Fall: 30 sparks and 40 of dust.',\n network: 'The server keeps 3 bits of dent per door zone (9 zones). Whoever joins later sees the same dented door.',\n },\n iron_railing: {\n name: 'Iron railing bending',\n short: 'The horde pushes, the bars bow, the weld pops in a spark and the railing falls.',\n cost: '≤ 200 part.',\n costNote: '3 deformable bars',\n when: 'A railing, iron gate, handrail or chain-link fence with zombies pushing (horde pressure) or a car hitting it.',\n look: 'The bars bow gradually at the point of pressure and the vertical ones tilt with them. Rust falls in a thread during the strain. At two moments the weld pops with a crackle of sparks. At the end the middle post gives and the railing topples, leaving the bent iron on the ground.',\n budget: 'Curvature worked out only when the pressure changes, up to 180 vertices. Rust: 10 per second during the strain. Weld pop: 20 sparks.',\n network: 'The server sends the pressure (0 to 1) and when it gives. The curve comes from the value, the same on all clients.',\n },\n wooden_fence: {\n name: 'Wooden fence breaking',\n short: 'Planks snap one by one, chips and dust, and the section topples as the horde passes.',\n cost: '≤ 150 part.',\n costNote: '12 planks',\n when: 'A fence, yard gate or plank barricade taking a shot, blow or horde pressure.',\n look: 'Each plank snaps at a random point: the stump stays on the rail and the top piece flies off with chips and wood dust. The zombie appears through the gap. At the end the rail cracks and the whole section topples forward.',\n budget: 'Each plank is a piece: breaking swaps it for a stump + a piece with physics. Per break: 6 chips, 8 of dust. Topple: 35 of dust.',\n network: 'The server sends which planks broke (12 bits) and when the section falls.',\n },\n hit_point_breakage: {\n name: 'Breakage by the point hit',\n short: 'A shot to the leg, a machete on the corner, a bat on the top and a 12-gauge up close: each weapon breaks the part it hit.',\n cost: '≤ 120 part.',\n costNote: 'parts with their own health',\n when: 'Any destructible item. The damage goes to the part that was hit, not to the whole item.',\n look: 'A 9 mm shot to the front leg: the lower part of the leg breaks off and the table tips toward that corner. A machete on the corner of the top: the corner comes off whole in a straight cut, with chips in a line. A bat on the other corner: the top cracks and falls apart in pieces with dust. A 12-gauge up close on what is left: 9 grouped holes that stay in the wood.',\n budget: 'Each part has health and material. A common item: 4 to 12 parts. Particles only from the part hit, by its material.',\n network: 'The server sends which part lost health and how much. A loose part simulates on the client; the final position is sent once.',\n },\n pressure_cylinders: {\n name: 'Extinguisher and oxygen cylinder',\n short: 'A shot to the extinguisher makes a white cloud and a spin; on oxygen the valve breaks and the cylinder becomes a rocket.',\n cost: '≤ 250 part.',\n costNote: 'cloud entity',\n paramLabel: 'Cylinder',\n when: 'A shot, a strong blow or fire on an extinguisher, oxygen cylinder or welding cylinder (extinguisher and oxygen_cylinder keys of the map catalogue).',\n look: 'Extinguisher: the hole gives off a jet of white powder, the extinguisher falls, spins on the ground pushed by the jet and fills a 5 m area with a cloud that blocks sight for 6 s. Oxygen: the valve breaks with a crack, the jet becomes propulsion, the cylinder shoots along the ground scraping and throwing sparks, bounces and stops against a wall. With fire nearby, the oxygen blows up like the barrel.',\n budget: 'Jet: 60 particles per second for 3 s. Extinguisher cloud: up to 40 large sprites. Scraping sparks like the car.',\n network: 'The extinguisher cloud is a server entity (blocks zombie and player sight). The cylinder trajectory uses a common seed and the server corrects the final position.',\n },\n building_fire: {\n name: 'Building on fire',\n short: 'Fire coming out of the windows, licking the facade, embers and smoke with the wind.',\n cost: '≤ 600 part.',\n costNote: '2 lights · reference',\n when: 'A building fire (molotov, explosion, vehicle). It lasts minutes and spreads to the neighbour.',\n look: 'Windows lit orange that flicker, tongues of fire coming out of the top of each window and climbing the facade, embers carried by the wind and a thick slanted column of smoke. The light paints the street.',\n budget: 'Up to 600 particles per building and 2 fire lights. Beyond 80 m only the smoke column and the glow of the windows remain, which become a landmark.',\n network: 'A fire entity on the server per building, with a spread state.',\n },\n rain_and_puddles: {\n name: 'Rain, splashes and puddles',\n short: 'Drops with wind, splashes and rings only near the camera, lightning in the storm.',\n cost: '≤ 4,000 drops',\n costNote: 'splash up to 12 m',\n paramLabel: 'Intensity',\n when: 'The weather of the world. Rain raises the background noise and masks footsteps (it can be used for stealth).',\n look: 'A fine drizzle, almost vertical. Rain with splashes on the asphalt and rings in the puddles, which are dark and mirror-like. A storm with drops slanted by the wind, sheets of water passing and a double flash of lightning that lights the scene for 0.2 s and reveals the horde.',\n budget: 'Up to 4,000 drops tied to the camera in a 30 m box. Splashes and rings only within 12 m and only on what the camera sees.',\n network: 'The server sends the weather and the lightning seed, so everyone sees the same flash.',\n },\n fog_and_ash: {\n name: 'Fog and ash',\n short: 'Low layered mist, ash falling and the lamp post with its cone of light.',\n cost: '≤ 120 sprites',\n costNote: '1 cone of light',\n when: 'Before dawn, near the river and in burnt zones (ash). It cuts the sight of the zombies and of the player.',\n look: 'The engine fog plus a layer of low mist that moves slowly, fine ash falling in a spiral and the beam of the lamp posts in view. Zombie silhouettes show before their details.',\n budget: 'Up to 60 large mist sprites (half resolution) and 60 of ash. The lamp cone is an additive mesh, not real volumetric light.',\n network: 'The weather comes from the server. The density is local, by zone.',\n },\n scraping_sparks: {\n name: 'Scraping sparks',\n short: 'A bumper dragging on the asphalt: a river of bouncing sparks and a mark on the ground.',\n cost: '≤ 200 sparks/s',\n costNote: '1 light',\n when: 'A car part in contact with the ground or a wall (a fallen bumper, a rim without a tyre, a flipped car sliding).',\n look: 'A jet of sparks behind the movement, bouncing on the asphalt and dying from white to orange. A glow and a short light at the contact point. A dark scratched mark on the ground.',\n budget: 'Up to 200 sparks per second, 1 light. Beyond 40 m it is only the glow of the point.',\n network: 'Cosmetic, from the part state and speed that are already replicated.',\n },\n engine_smoke: {\n name: 'Engine smoke',\n short: 'White steam, grey smoke, then black with fire, depending on condition.',\n cost: '≤ 120 part.',\n costNote: 'continuous',\n paramLabel: 'Condition',\n when: 'Whenever the engine is on or hot, from the part condition (0 to 100) in the fleet brief.',\n look: '100: exhaust only. 60: a thread of white steam from the bonnet. 30: steady grey smoke and the odd spark. 10: thick black smoke, flames at the grille and fire light, a warning that it will explode.',\n budget: 'Continuous, so cheap: up to 40 particles per second and 1 light only in the critical state.',\n network: 'Comes from the engine condition, which is already replicated.',\n },\n fuel_leak: {\n name: 'Tank leak and fire',\n short: 'Dripping petrol, a pool, a spark and the fire running to the tank.',\n cost: '≤ 400 part.',\n costNote: 'fire entity',\n when: 'A tank punctured by a shot or a crash. A spark, a shot or nearby fire lights the pool.',\n look: 'Drops of petrol with an oily sheen forming a growing pool. A shot on the metal throws a spark, the fire lights on the pool, runs to the car and, if nobody puts it out, the car explodes.',\n budget: 'Drops: 12 per second. Pool fire like the molotov. The final explosion is the next effect.',\n network: 'The pool and the fire are server entities (they can burn zombies and players).',\n },\n car_explosion: {\n name: 'Car explosion',\n short: 'A fireball, the car jumping, the bonnet and doors flying, the shell burning.',\n cost: '≤ 600 part.',\n costNote: 'rare event',\n when: 'A tank on fire for more than 4 s, or damage above the threshold on a car with fuel.',\n look: 'A large explosion (grenade scale 1.8), the car jumps and lands crooked, the bonnet, doors and a wheel fly off, the glass bursts into shards. The bodywork goes black and the shell burns with black smoke for minutes.',\n budget: 'Peak of 600 particles and 34 debris. It is a rare event and may go over the per-event cap, never the global cap.',\n network: 'Explosion on the server. The car becomes a wreck (another prefab) for everyone.',\n },\n windshield: {\n name: 'Windshield: blood and cracks',\n short: 'View from inside the car: blows, cracks in 4 stages and a bloody hand.',\n cost: '0 particles',\n costNote: '4-stage mask',\n when: 'A zombie hitting the windshield or a side window (fleet brief: the glass takes 8 blows).',\n look: 'Each blow shakes the camera and adds a star crack. Stages 2 and 4 leave a blood stain with a handprint running down. At stage 4 the glass is white with cracks and the next blow breaks it.',\n budget: 'Texture only: a crack mask with 4 stages and a blood decal on the glass. Glass dust: 6 particles per blow.',\n network: 'The server sends the glass health. Blood on the glass is local.',\n },\n headlights_in_rain: {\n name: 'Headlights in the rain',\n short: 'A visible beam, drops lit inside the cone and the horde walking into the light.',\n cost: '≤ 600 lit drops',\n costNote: '2 spots, no shadow',\n when: 'Headlights on at night, with rain or fog.',\n look: 'Two cones of light in the air, rain drops that shine only inside the beam and zombie silhouettes that light up when they enter the light. Outside the cone the rain almost disappears.',\n budget: '2 spotlights without shadow, 2 additive cones and up to 600 extra drops only inside the cone. Headlights of cars beyond 40 m stay as a cone only, with no real light.',\n network: 'The state of the headlights is already replicated with the car.',\n },\n damage_and_bite: {\n name: 'Damage and bite',\n short: 'A red edge on the side of the blow, blood on the lens and the pulse of the bite.',\n cost: 'post-process',\n costNote: 'local only',\n when: 'The player takes a blow (with direction) or a bite (100% infection, characters rule).',\n look: 'Blow: a red edge on the side it came from, a short shake and splashes on the lens. Bite: a red flash over the whole screen, the colour drains for 2 s, a heartbeat pulsing in a dark tunnel and big blood on the lens that runs down.',\n budget: 'A post-process effect and one lens layer. No particles in the world besides the normal blood.',\n network: 'Only on the screen of whoever was hit. The others see the blood in the world.',\n },\n infection_phases: {\n name: 'Infection phases',\n short: 'Malaise, fever with a cold edge, delirium with ghosts and the end.',\n cost: 'post-process',\n costNote: 'local only',\n paramLabel: 'Phase',\n when: 'Phases from the characters brief: 2–12 h malaise, 12–30 h fever, 30–48 h delirium, 48 h death.',\n look: 'Malaise: slightly washed colour and a slowly breathing vignette. Fever: a bluish cold edge only for the infected, waves of blur, a cough that shakes the camera. Delirium: colour aberration, an oscillating hue and fake zombies flickering in the fog. 48 h: almost no colour, a green tone, a dark tunnel and a heartbeat.',\n budget: 'Post-process only. The delirium ghosts are 3 zombie instances without collision, only on the infected client.',\n network: 'Never goes over the network. The other player notices only the cough and the breathing (see \"Cough and breath\").',\n },\n panic: {\n name: 'Panic',\n short: 'The aim shakes, the tunnel closes as the horde arrives and the heart speeds up.',\n cost: 'post-process',\n costNote: 'local only',\n when: 'The characters\\' panic meter (rises with visible zombies, runners and a dead companion). Effects above 60 and above 90.',\n look: 'A fine, constant tremor in the camera (the aim shakes), a dark vignette that closes as the nearest zombie arrives and pulses with the heartbeat, which speeds up from 70 to 150 bpm. Colour loses strength.',\n budget: 'Post-process and camera noise only.',\n network: 'Local. Others\\' panic shows in their aim and in the scream (sound).',\n },\n bloater_blindness: {\n name: 'Bloater blindness',\n short: 'Green gas in the face: a blurred screen for 5 s and mucus on the lens.',\n cost: 'post + 30 part.',\n costNote: 'server entity',\n when: 'A player inside the Bloater cloud (radius 4 m) when it spawns.',\n look: 'A green cloud bursts between the zombie and the camera, the screen goes green and blurred and clears in 5 s, with drops of green mucus on the lens that run down. A cough shakes the camera twice.',\n budget: 'Post-process + 30 gas sprites near the camera, with a fade so particles do not cover the whole screen.',\n network: 'The blindness comes from the server entity; the visual is local.',\n },\n campfire: {\n name: 'Campsite fire',\n short: 'A low flame, embers spiralling up and a flickering warm light.',\n cost: '≤ 120 part.',\n costNote: '1 fire light',\n when: 'A campfire lit by the group or by NPCs. It warms, lights and draws zombies from afar (light).',\n look: 'Small low flames, embers that rise turning and fade, thin smoke and a warm light that flickers and paints the survivor.',\n budget: '120 particles and 1 fire light. Several campfires of the camp share the same light if they are closer than 6 m.',\n network: 'A replicated scene object (lit or out). Visual is local.',\n },\n cough_and_breath: {\n name: 'Cough, breath and flashlight',\n short: 'Breath vapour in the cold, the fever cough visible to others and the flashlight beam.',\n cost: '≤ 40 part.',\n costNote: '1 spot with shadow',\n when: 'A cold night: breath always. Infection fever: a cough every few seconds, audible at 10 m.',\n look: 'A short puff of vapour every 2.4 s. On a cough, three quick bigger puffs and the body jolts. The flashlight shows the beam in the fog and is the only light with a shadow.',\n budget: 'Vapour: 8 particles per puff, only closer than 15 m. Flashlight: 1 spot with a shadow per player, only the local player\\'s casts a shadow.',\n network: 'The cough is the social signal of the infection: the server sends the cough event (without saying it is infection) and the others see the vapour and hear it.',\n },\n}\n","import type { EffectTexts } from '../locale'\n\n/** The Workshop's sheet for each effect (W450-1262), as the page wrote it. */\nexport const ptBR: Readonly<Record<string, EffectTexts>> = {\n blood_hit: {\n name: 'Sangue por idade da infecção',\n short: 'Névoa na entrada, jato na saída, poça que cresce. A idade muda cor e quantidade.',\n cost: '≤ 70 part.',\n costNote: '1 poça · 6 respingos',\n paramLabel: 'Idade',\n when: 'Cada acerto de bala ou golpe em zumbi. O valor de sangue vem da idade do bestiário: 1,0 · 0,7 · 0,35 · 0,1.',\n look: 'Fresco espirra vermelho vivo e pinga. Recente sai bordô. Antigo sai marrom e pouco. Decrépito não sangra: solta pó preto e lascas secas. A poça cresce por 2 a 4 s e escurece em 60 s.',\n budget: 'Até 70 partículas por acerto (Fresco), 1 poça e até 6 respingos no chão. Gotas que caem viram decalque.',\n network: 'Cosmético. Vai no evento de impacto com 2 bits de idade e a semente.',\n },\n headshot: {\n name: 'Headshot',\n short: 'A cabeça estoura, os olhos apagam no mesmo quadro e o corpo cai.',\n cost: '≤ 70 part.',\n costNote: '8 detritos · 1 poça',\n when: 'Acerto na cabeça que mata (regra do bestiário: cabeça mata na hora).',\n look: 'Névoa vermelha em volta da cabeça, jato de gotas para trás, 6 a 8 pedaços de osso e pele, troca pela malha de pescoço estourado. O brilho dos olhos apaga no mesmo quadro, que é o sinal mais legível de longe.',\n budget: '20 de névoa + 35 gotas + 8 detritos + 1 poça. Na horda, só os 12 mais próximos ganham detritos.',\n network: 'Cosmético. O servidor já manda “morte por cabeça”.',\n },\n dismember: {\n name: 'Desmembramento',\n short: 'O braço sai inteiro com física e o ombro jorra por meio segundo.',\n cost: '≤ 60 part.',\n costNote: '1 membro · 4 respingos',\n when: 'Dano no membro acima do limite (multiplicadores por região do bestiário) ou golpe de machado.',\n look: 'O membro vira peça solta com física e quica. Jato curto do ombro em pulsos, gotas que formam um rastro até a poça. O zumbi cambaleia mas continua andando.',\n budget: '1 membro com física (conta no teto de 300), jato de até 60 gotas em 0,7 s.',\n network: 'O servidor manda qual membro saiu. A peça é local; cada cliente simula a sua.',\n },\n bloater_cloud: {\n name: 'Nuvem do Inchado',\n short: 'Barriga pulsa por 0,5 s, estoura e deixa 4 m de gás por 8 s.',\n cost: '≤ 180 part.',\n costNote: 'entidade no servidor',\n when: 'Morte do Inchado, por qualquer causa.',\n look: 'Aviso de 0,5 s com a barriga inchando, estouro com pedaços e jato esverdeado, e uma nuvem baixa verde-musgo que ondula no chão por 8 s. Brilhos verdes soltos dentro da nuvem marcam a área.',\n budget: '40 sprites grandes no estouro e até 60 vivos na nuvem, em meia resolução. Fade perto da câmera para não pintar a tela inteira.',\n network: 'Entidade no servidor (raio 4 m, 8 s): cega por 5 s, dobra o rastro de cheiro e faz tossir. O cliente só desenha.',\n },\n screamer_shriek: {\n name: 'Grito do Gritador',\n short: 'Preparo de 1,5 s com vapor, onda no chão e os olhos da horda acendem.',\n cost: '≤ 150 part.',\n costNote: '3 anéis · aberração',\n when: 'O Gritador avista o jogador e começa o grito (preparo de 1,5 s, chama todos num raio de 150 m).',\n look: 'Cabeça para trás e vapor saindo da boca durante o preparo. No grito, três anéis de pressão no chão, poeira levantada no raio, aberração cromática curta na tela de quem está perto e os olhos dos zumbis próximos piscam forte quando escutam.',\n budget: '3 anéis, até 150 partículas de poeira. A aberração na tela é um efeito de pós de 0,4 s.',\n network: 'O servidor manda “grito em X”. O efeito de tela depende da distância local.',\n },\n eyes_in_fog: {\n name: 'Olhos na neblina',\n short: 'Brilho dos olhos que fura a neblina; os corredores deixam rastro vermelho.',\n cost: '2 sprites/zumbi',\n costNote: '0 luzes',\n when: 'Sempre, em todo zumbi. É o sistema de leitura do bestiário: cor do olho diz a categoria.',\n look: 'Dois pontos emissivos com bloom que ignoram a neblina. O corpo some na névoa a 25 m, os olhos continuam legíveis a 60 m. Corredores deixam um rastro curto da cor do olho quando correm.',\n budget: '2 sprites por zumbi no mesmo lote instanciado do corpo. Rastro só para corredores a menos de 30 m. Nenhuma luz real.',\n network: 'Nada vai pela rede: sai da categoria do zumbi.',\n },\n corpse_decay: {\n name: 'Corpo: escurecer e dissolver',\n short: '15 minutos em 8 segundos: queda, escurece, moscas e vira pó.',\n cost: '≤ 40 part.',\n costNote: 'pool de 400 corpos',\n when: 'Morte do zumbi. Linha do tempo do bestiário: ragdoll 3 s, malha congelada, escurece, dissolve entre 14 e 15 min.',\n look: 'A pele perde a cor até ficar quase preta, a poça seca para marrom, aparecem moscas a partir do minuto 5 e no último minuto o corpo afunda e solta pó escuro.',\n budget: 'Moscas: 6 partículas por corpo, só a menos de 10 m. Pó: 40 partículas uma vez. O corpo usa o shader de dissolve, sem partícula extra.',\n network: 'O servidor manda a hora da morte; cada cliente calcula o estado.',\n },\n reanimation: {\n name: 'Reanimação',\n short: 'Veias acendem, espasmos, os olhos ligam e o corpo levanta.',\n cost: '≤ 30 part.',\n costNote: 'emissivo no shader',\n when: 'Fim da infecção de jogador ou NPC: reanima em 2 a 6 min como Fresco (70% Lento, 30% Corredor).',\n look: 'Pulsos verdes pela pele (emissivo no shader, não partícula), espasmos nos braços e na cabeça, os olhos acendem de dentro para fora e o corpo se levanta. Respiração em vapor no primeiro grito.',\n budget: 'Só emissivo animado e 30 partículas. É raro e importante, então pode ser caro.',\n network: 'O servidor manda “reanimou”. Para o amigo que vê o colega levantar, é o momento mais forte do coop.',\n },\n muzzle_flash: {\n name: 'Clarão de disparo',\n short: 'Núcleo, pétalas e fumaça com escala por arma. A Barrett levanta poeira.',\n cost: '≤ 60 part.',\n costNote: '1 luz · 50 ms',\n paramLabel: 'Arma',\n when: 'Cada disparo. Em primeira pessoa usa o modelo da arma; de longe vira só o sprite do núcleo.',\n look: 'Três camadas: núcleo branco-amarelo de 1 quadro, pétalas na direção do cano e fumaça cinza que fica 1 a 2 s. A 12 tem clarão largo e fumaça grossa. A Barrett solta dois jatos laterais pelo freio de boca e levanta um anel de poeira do chão. A luz ilumina o cômodo por 50 ms (pedido do brief do mapa).',\n budget: 'Até 60 partículas e 1 luz por tiro. Rajada de AK usa a mesma luz em loop. Pistola sem luz a mais de 15 m.',\n network: 'Cosmético. Sai do evento de tiro que o servidor já manda (arma, origem, direção).',\n },\n impact: {\n name: 'Impacto por material',\n short: 'Concreto, metal, madeira, vidro, carne e água: cada um com sua resposta.',\n cost: '≤ 40 part.',\n costNote: '1 furo',\n paramLabel: 'Material',\n when: 'Toda bala que acerta algo. O material vem da tag de superfície da malha.',\n look: 'Concreto: pó claro em cone e lascas cinza. Metal: chuva de faíscas que quicam, sem pó, com luz curta. Madeira: lascas finas e pó marrom. Vidro: brilho, cacos e rachadura. Carne: sangue pela idade. Água: coroa de gotas e dois anéis.',\n budget: '14 de pó + 6 lascas + até 18 faíscas + 1 furo. A 40 m sobra só o pó.',\n network: 'Evento de impacto de 12 bytes com material em 4 bits.',\n },\n penetration: {\n name: 'Bala que atravessa a horda',\n short: 'Traçante da Barrett passando por 5 zumbis, em câmera lenta 10×.',\n cost: '≤ 250 part.',\n costNote: 'evento agregado',\n when: 'Arma com penetração: AK atravessa 2, Remington 700 atravessa 3, Barrett atravessa 6 e carros.',\n look: 'Traçante com rastro de ar quente, saída de sangue em cada corpo na ordem em que a bala passa (cada um com a cor da sua idade), corpos caindo um atrás do outro e impacto final no concreto.',\n budget: 'Todos os acertos de um tiro saem num único evento agregado com a lista de pontos. 5 corpos = 5 saídas + 5 poças.',\n network: 'O servidor manda o tiro e a lista ordenada de acertos.',\n },\n casings_and_magazine: {\n name: 'Cápsulas e carregador',\n short: 'Latão que quica e fica no chão, carregador vazio caindo, fumaça do cano quente.',\n cost: '200/jogador',\n costNote: 'física 1,5 s',\n when: 'Cada disparo de arma semiautomática, recarga, e bombeada da 12 ou ferrolho do rifle.',\n look: 'Cápsula sai pela janela de ejeção girando, quica no asfalto duas ou três vezes e fica. O carregador vazio cai na recarga. Depois da rajada, fumaça fina sobe do cano quente por 2 s.',\n budget: 'Física só por 1,5 s, depois vira instância estática. Teto de 200 por jogador, o mais antigo some primeiro.',\n network: 'Cosmético, cada cliente gera as suas. Não sincroniza posição no chão.',\n },\n molotov: {\n name: 'Coquetel molotov',\n short: 'Pavio aceso no arco, vidro quebrando e poça de fogo que espalha.',\n cost: '≤ 300 part.',\n costNote: '2 luzes · entidade',\n when: 'Molotov atingindo o chão ou um zumbi.',\n look: 'Garrafa em arco com pavio soltando chama e fumaça. Ao bater, cacos verdes e um respingo de fogo que abre de 0,5 m para 2,2 m em 0,8 s. Chamas baixas, brasas, fumaça escura e luz tremendo por 6 s, depois brasa e mancha queimada.',\n budget: 'Fogo de área com até 300 partículas e 1 luz de fogo. Zumbis em chamas usam um emissor pequeno preso ao corpo (40 partículas) e só os 8 mais próximos.',\n network: 'Fogo é entidade no servidor: área, dano por segundo, tempo. O cliente desenha a partir dela.',\n },\n grenade: {\n name: 'Granada de fragmentação',\n short: 'Quique no asfalto, clarão, onda de choque, estilhaços e anel de poeira.',\n cost: '≤ 400 part.',\n costNote: 'evento agregado',\n when: 'Granada explodindo (pavio de 1,8 s após o arremesso).',\n look: 'Granada quica duas vezes. Explosão em camadas: clarão branco que pinta a tela, bola de fogo curta, anel de choque no chão e outro de frente para a câmera, estilhaços brilhantes que quicam, anel de poeira rasteira, fumaça cinza que sobe e marca queimada. Zumbis no raio caem para fora.',\n budget: 'Até 400 partículas, 1 luz forte de 0,5 s, 16 detritos, 1 marca. Os 40 zumbis atingidos entram num único evento agregado.',\n network: 'O servidor manda a explosão e a lista de atingidos. Visual local.',\n },\n explosive_barrel: {\n name: 'Barril explosivo',\n short: 'Cogumelo de fogo, tampa voando, gasolina queimando no chão e coluna de fumaça.',\n cost: '≤ 450 part.',\n costNote: '2 luzes · entidade de fogo',\n when: 'Barril vermelho com dano acima do limite, tiro ou fogo encostado.',\n look: 'Tudo da granada, mais: bola de fogo que sobe em cogumelo, tampa e pedaços vermelhos voando alto, três poças de gasolina queimando por 5 s e coluna de fumaça preta que serve de referência de longe.',\n budget: 'Pico de 450 partículas. A coluna de fumaça fica visível além de 80 m com 6 sprites grandes.',\n network: 'Explosão + entidade de fogo nas poças.',\n },\n shopfront_glass: {\n name: 'Vitrine estourando',\n short: 'Duas trincas, depois a placa inteira desce em cacos que ficam na calçada.',\n cost: '≤ 80 detritos',\n costNote: '1 rachadura',\n when: 'Vidro com dano acumulado (tiro, golpe, horda empurrando). Barulho de 20 m que atrai a horda.',\n look: 'Primeiros golpes abrem trincas em estrela na textura do vidro. No estouro a placa some e vira 60 a 80 cacos que caem girando, brilhando na luz, e ficam na calçada. Um véu de pó de vidro fino na frente.',\n budget: 'Cacos com física contam no teto de 300 e viram estáticos em 2 s. 3 estágios de rachadura numa máscara só.',\n network: 'O servidor manda o estado do vidro (0 a 3). Cacos são locais.',\n },\n door_stages: {\n name: 'Porta cedendo em 3 estágios',\n short: 'Pancadas soltam pó do batente, uma tábua racha e a porta cai.',\n cost: '≤ 120 part.',\n costNote: '3 estágios',\n when: 'Horda batendo em porta ou barricada (o Brutamonte faz 3× dano). Estágios: 66%, 33%, 0% de vida.',\n look: 'Cada pancada sacode a porta e solta pó do batente e lascas. No estágio 2 a tábua do meio racha e cai. No 3 a porta tomba e levanta uma nuvem de poeira rasteira, e o zumbi sai do escuro.',\n budget: 'Pó: 12 partículas por pancada. Queda: 40 de poeira e 6 detritos. Pancadas a mais de 15 m sem partícula, só som.',\n network: 'O servidor manda a vida da porta. Estágio visual sai do valor.',\n },\n building_collapse: {\n name: 'Desabamento',\n short: 'Pó escorrendo da marquise, blocos caindo e nuvem de poeira que rola pela rua.',\n cost: '≤ 350 part.',\n costNote: '26 detritos',\n when: 'Estrutura que perde a vida: explosão, veículo batendo, horda grande empurrando (destruição de prédios do mapa).',\n look: 'Antes: pó fino escorrendo e pedrinhas caindo por 1 s, como aviso. Depois: blocos grandes e pequenos caem, a câmera treme e uma nuvem de poeira cinza-bege rola pelo chão e fica no ar por 5 s, escondendo zumbis.',\n budget: '26 detritos (6 grandes), 70 sprites de poeira em meia resolução. É evento raro, cabe no orçamento.',\n network: 'O servidor manda o colapso e a área de poeira, que bloqueia visão de zumbi por 4 s.',\n },\n block_wall: {\n name: 'Parede derrubada com furos',\n short: 'Rajada deixa furos e lascas; a parede cai em blocos e os furos continuam neles.',\n cost: '≤ 300 part.',\n costNote: '30 blocos · furos presos',\n when: 'Parede, mureta ou barricada de concreto que perde a vida por tiros, explosão, Brutamonte ou carro (destruição do mapa e do arsenal).',\n look: 'Cada bala abre um furo escuro com borda lascada, solta pó e pedrinhas. Quando a parede cede, ela se parte em blocos que tombam com física e uma nuvem de poeira rola pelo chão. Os furos de bala estão presos aos blocos: ficam nos pedaços caídos, girados junto com eles, e não somem quando a parede quebra.',\n budget: 'Furos são decalques filhos do pedaço (não do mundo), até 12 por bloco e 128 no total. Blocos contam no teto de 300 detritos e viram estáticos em repouso. Poeira: 60 sprites em meia resolução.',\n network: 'O servidor manda vida da parede e a lista de furos (posição local de 2 bytes por furo). Quem entra depois vê os mesmos furos nos mesmos pedaços. Queda dos blocos usa semente comum.',\n },\n metal_door: {\n name: 'Porta de metal amassando',\n short: 'Cada pancada afunda a chapa, descasca a tinta e solta faísca; a dobradiça arrebenta.',\n cost: '≤ 160 part.',\n costNote: 'malha deformável',\n when: 'Porta, portão ou chapa de aço levando golpe de zumbi (Brutamonte 3×), tiro de 12 ou batida de carro.',\n look: 'A chapa afunda onde apanha (malha deformada, não troca de modelo), com 3 níveis visíveis. Cada pancada solta faísca, lasca de tinta verde e pó de ferrugem. Quando a vida acaba, a dobradiça de cima estoura em faíscas, a porta tomba e raspa no chão soltando mais faísca.',\n budget: 'Deformação por vértice só na hora do golpe (CPU, 400 vértices). Por golpe: 8 faíscas, 5 lascas, 6 de ferrugem. Queda: 30 faíscas e 40 de poeira.',\n network: 'O servidor guarda 3 bits de amassado por zona da porta (9 zonas). Quem entra depois vê a mesma porta amassada.',\n },\n iron_railing: {\n name: 'Grade de ferro entortando',\n short: 'A horda empurra, as barras envergam, a solda estoura em faísca e a grade tomba.',\n cost: '≤ 200 part.',\n costNote: '3 barras deformáveis',\n when: 'Grade, portão de ferro, corrimão ou alambrado com zumbis empurrando (pressão da horda) ou carro batendo.',\n look: 'As barras envergam aos poucos no ponto de pressão e as verticais inclinam junto. Ferrugem cai em fio durante o esforço. Em dois momentos a solda estoura com um estalo de faíscas. No fim o poste do meio cede e a grade tomba, deixando o ferro torto no chão.',\n budget: 'Curvatura calculada só quando a pressão muda, até 180 vértices. Ferrugem: 10 por segundo durante o esforço. Estouro de solda: 20 faíscas.',\n network: 'O servidor manda a pressão (0 a 1) e quando cede. A curva sai do valor, igual em todos os clientes.',\n },\n wooden_fence: {\n name: 'Cerca de madeira quebrando',\n short: 'Tábuas partem uma a uma, lascas e pó, e a seção tomba com a horda passando.',\n cost: '≤ 150 part.',\n costNote: '12 tábuas',\n when: 'Cerca, portão de quintal ou barricada de tábuas recebendo tiro, golpe ou pressão da horda.',\n look: 'Cada tábua parte num ponto aleatório: o toco fica preso no trilho e o pedaço de cima voa com lascas e pó de madeira. O zumbi aparece pelo vão. No fim o trilho racha e a seção inteira tomba para frente.',\n budget: 'Cada tábua é uma peça: quebra troca para toco + pedaço com física. Por quebra: 6 lascas, 8 de pó. Tombo: 35 de poeira.',\n network: 'O servidor manda quais tábuas quebraram (12 bits) e quando a seção cai.',\n },\n hit_point_breakage: {\n name: 'Quebra pelo ponto atingido',\n short: 'Tiro na perna, facão na quina, taco no tampo e 12 de perto: cada arma quebra a parte que pegou.',\n cost: '≤ 120 part.',\n costNote: 'peças com vida própria',\n when: 'Qualquer item destrutível. O dano vai para a peça que foi atingida, não para o item inteiro.',\n look: 'Tiro de 9 mm na perna da frente: a parte de baixo da perna parte e a mesa tomba para aquele canto. Facão na quina do tampo: a quina sai inteira num corte reto, com lascas em linha. Taco no outro canto: o tampo racha e se desfaz em pedaços com pó. 12 de perto no que sobrou: 9 furos agrupados que ficam na madeira.',\n budget: 'Cada peça tem vida e material. Item comum: 4 a 12 peças. Partículas só da peça atingida, pelo material dela.',\n network: 'O servidor manda qual peça perdeu vida e quanto. Peça solta simula no cliente; a posição final é mandada uma vez.',\n },\n pressure_cylinders: {\n name: 'Extintor e cilindro de oxigênio',\n short: 'Tiro no extintor faz nuvem branca e giro; no oxigênio a válvula quebra e o cilindro vira foguete.',\n cost: '≤ 250 part.',\n costNote: 'entidade de nuvem',\n paramLabel: 'Cilindro',\n when: 'Tiro, golpe forte ou fogo em extintor, cilindro de oxigênio ou de solda (chaves extintor e cilindro_oxigenio do catálogo do mapa).',\n look: 'Extintor: o furo solta um jato de pó branco, o extintor cai, gira no chão empurrado pelo jato e enche uma área de 5 m de nuvem que tapa a visão por 6 s. Oxigênio: a válvula quebra com estalo, o jato vira propulsão, o cilindro dispara rente ao chão raspando e soltando faísca, quica e para numa parede. Com fogo por perto, o oxigênio estoura como o barril.',\n budget: 'Jato: 60 partículas por segundo por 3 s. Nuvem do extintor: até 40 sprites grandes. Faísca de raspagem como a do carro.',\n network: 'Nuvem do extintor é entidade no servidor (bloqueia visão de zumbi e de jogador). A trajetória do cilindro usa semente comum e o servidor corrige a posição final.',\n },\n building_fire: {\n name: 'Prédio em chamas',\n short: 'Fogo saindo pelas janelas, lambendo a fachada, brasas e fumaça com vento.',\n cost: '≤ 600 part.',\n costNote: '2 luzes · referência',\n when: 'Incêndio de prédio (molotov, explosão, veículo). Dura minutos e espalha para o vizinho.',\n look: 'Janelas acesas em laranja que tremem, línguas de fogo saindo pela parte de cima de cada janela e subindo pela fachada, brasas levadas pelo vento e uma coluna de fumaça grossa inclinada. A luz pinta a rua.',\n budget: 'Até 600 partículas por prédio e 2 luzes de fogo. Além de 80 m fica só a coluna de fumaça e o brilho das janelas, que viram ponto de referência.',\n network: 'Entidade de fogo no servidor por prédio, com estado de espalhar.',\n },\n rain_and_puddles: {\n name: 'Chuva, respingos e poças',\n short: 'Gotas com vento, respingos e anéis só perto da câmera, relâmpago no temporal.',\n cost: '≤ 4.000 gotas',\n costNote: 'respingo até 12 m',\n paramLabel: 'Intensidade',\n when: 'Clima do mundo. Chuva aumenta o ruído de fundo e mascara passos (dá para usar na furtividade).',\n look: 'Garoa fina quase vertical. Chuva com respingos no asfalto e anéis nas poças, que ficam escuras e espelhadas. Temporal com gotas inclinadas pelo vento, cortinas de água passando e relâmpago duplo que clareia a cena por 0,2 s e revela a horda.',\n budget: 'Até 4.000 gotas presas à câmera numa caixa de 30 m. Respingos e anéis só a menos de 12 m e só em cima do que a câmera vê.',\n network: 'O servidor manda o clima e a semente do relâmpago, para todos verem o mesmo clarão.',\n },\n fog_and_ash: {\n name: 'Neblina e cinzas',\n short: 'Névoa rasteira em camadas, cinza caindo e o poste com cone de luz.',\n cost: '≤ 120 sprites',\n costNote: '1 cone de luz',\n when: 'Madrugada, perto de rio e em zonas queimadas (cinza). Reduz a visão dos zumbis e do jogador.',\n look: 'Neblina do motor mais uma camada de névoa baixa que se move devagar, cinza fina caindo em espiral e o feixe dos postes visível. Silhuetas de zumbis aparecem antes dos detalhes.',\n budget: 'Até 60 sprites grandes de névoa (meia resolução) e 60 de cinza. O cone do poste é uma malha aditiva, não luz volumétrica real.',\n network: 'Clima vem do servidor. Densidade é local por zona.',\n },\n scraping_sparks: {\n name: 'Faíscas de raspagem',\n short: 'Para-choque arrastando no asfalto: rio de faíscas que quicam e marca no chão.',\n cost: '≤ 200 faíscas/s',\n costNote: '1 luz',\n when: 'Peça de carro em contato com o chão ou com parede (para-choque caído, roda sem pneu, carro capotado deslizando).',\n look: 'Jato de faíscas para trás do movimento, que quicam no asfalto e apagam do branco para o laranja. Brilho e luz curta no ponto de contato. Marca escura riscada no chão.',\n budget: 'Até 200 faíscas por segundo, 1 luz. A mais de 40 m vira só o brilho do ponto.',\n network: 'Cosmético, a partir do estado da peça e da velocidade que já são replicados.',\n },\n engine_smoke: {\n name: 'Fumaça do motor',\n short: 'Vapor branco, fumaça cinza, depois preta com fogo, conforme a condição.',\n cost: '≤ 120 part.',\n costNote: 'contínuo',\n paramLabel: 'Condição',\n when: 'Sempre que o motor está ligado ou quente, a partir da condição da peça (0 a 100) do brief da frota.',\n look: '100: só escapamento. 60: fio de vapor branco saindo pelo capô. 30: fumaça cinza constante e faísca de vez em quando. 10: fumaça preta grossa, chamas na grade e luz de fogo, aviso de que vai explodir.',\n budget: 'Contínuo, então barato: até 40 partículas por segundo e 1 luz só no estado crítico.',\n network: 'Sai da condição do motor, que já é replicada.',\n },\n fuel_leak: {\n name: 'Vazamento e incêndio do tanque',\n short: 'Gasolina pingando, poça, uma faísca e o fogo correndo até o tanque.',\n cost: '≤ 400 part.',\n costNote: 'entidade de fogo',\n when: 'Tanque furado por tiro ou batida. Faísca, tiro ou fogo próximo acende a poça.',\n look: 'Pingos de gasolina com brilho oleoso formando uma poça que cresce. Um tiro no metal solta faísca, o fogo acende na poça, corre até o carro e, se ninguém apagar, o carro explode.',\n budget: 'Pingos: 12 por segundo. Fogo de poça como o do molotov. A explosão final é o efeito seguinte.',\n network: 'Poça e fogo são entidades no servidor (podem queimar zumbis e jogadores).',\n },\n car_explosion: {\n name: 'Explosão do carro',\n short: 'Bola de fogo, carro pulando, capô e portas voando, carcaça queimando.',\n cost: '≤ 600 part.',\n costNote: 'evento raro',\n when: 'Tanque em chamas por mais de 4 s, ou dano acima do limite em carro com combustível.',\n look: 'Explosão grande (escala 1,8 da granada), o carro pula e cai torto, capô, portas e uma roda saem voando, vidro estoura em cacos. A lataria fica preta e a carcaça queima com fumaça preta por minutos.',\n budget: 'Pico de 600 partículas e 34 detritos. É evento raro e pode passar do teto por evento, nunca do teto global.',\n network: 'Explosão no servidor. O carro vira carcaça (outro prefab) para todos.',\n },\n windshield: {\n name: 'Para-brisa: sangue e rachadura',\n short: 'Visão de dentro do carro: pancadas, trincas em 4 estágios e mão de sangue.',\n cost: '0 partículas',\n costNote: 'máscara 4 estágios',\n when: 'Zumbi batendo no para-brisa ou no vidro lateral (brief da frota: vidro aguenta 8 golpes).',\n look: 'Cada golpe treme a câmera e soma uma trinca em estrela. Estágio 2 e 4 deixam mancha de sangue com marca de mão escorrendo. No estágio 4 o vidro está branco de rachadura e o próximo golpe quebra.',\n budget: 'Só textura: uma máscara de rachadura com 4 estágios e um decal de sangue no vidro. Pó de vidro: 6 partículas por golpe.',\n network: 'O servidor manda a vida do vidro. Sangue no vidro é local.',\n },\n headlights_in_rain: {\n name: 'Faróis na chuva',\n short: 'Feixe visível, gotas acesas dentro do cone e a horda entrando na luz.',\n cost: '≤ 600 gotas acesas',\n costNote: '2 spots sem sombra',\n when: 'Faróis ligados à noite, com chuva ou neblina.',\n look: 'Dois cones de luz visíveis no ar, gotas de chuva que brilham só dentro do feixe e silhuetas de zumbi que acendem quando entram na luz. Fora do cone, a chuva quase some.',\n budget: '2 spotlights sem sombra, 2 cones aditivos e até 600 gotas extras só dentro do cone. Faróis de carros a mais de 40 m ficam só como cone, sem luz real.',\n network: 'Estado do farol já é replicado com o carro.',\n },\n damage_and_bite: {\n name: 'Dano e mordida',\n short: 'Borda vermelha do lado do golpe, sangue na lente e o pulso da mordida.',\n cost: 'pós-processo',\n costNote: 'só local',\n when: 'Jogador recebe golpe (com direção) ou mordida (infecção 100%, regra dos personagens).',\n look: 'Golpe: borda vermelha do lado de onde veio, tremor curto e respingos na lente. Mordida: clarão vermelho na tela inteira, a cor some por 2 s, batimento pulsando no túnel escuro e sangue grande na lente que escorre.',\n budget: 'Efeito de pós-processo e uma camada de lente. Nenhuma partícula no mundo além do sangue normal.',\n network: 'Só na tela de quem levou. Os outros veem o sangue no mundo.',\n },\n infection_phases: {\n name: 'Fases da infecção',\n short: 'Mal-estar, febre com borda fria, delírio com fantasmas e o fim.',\n cost: 'pós-processo',\n costNote: 'só local',\n paramLabel: 'Fase',\n when: 'Fases do brief de personagens: 2–12 h mal-estar, 12–30 h febre, 30–48 h delírio, 48 h morte.',\n look: 'Mal-estar: cor um pouco lavada e vinheta que respira devagar. Febre: borda fria azulada só para o infectado, desfoque em ondas, tosse que treme a câmera. Delírio: aberração de cor, matiz que oscila e zumbis falsos que piscam na neblina. 48 h: quase sem cor, tom verde, túnel escuro e batimento.',\n budget: 'Só pós-processo. Os fantasmas do delírio são 3 instâncias do zumbi sem colisão, só no cliente infectado.',\n network: 'Nunca vai pela rede. O outro jogador percebe só a tosse e a respiração (ver “Tosse e respiração”).',\n },\n panic: {\n name: 'Pânico',\n short: 'A mira treme, o túnel fecha conforme a horda chega e o coração acelera.',\n cost: 'pós-processo',\n costNote: 'só local',\n when: 'Medidor de pânico dos personagens (sobe com zumbis visíveis, corredores e companheiro morto). Efeitos acima de 60 e de 90.',\n look: 'Tremor fino e constante na câmera (a mira treme), vinheta escura que fecha conforme o zumbi mais próximo chega e pulsa com o batimento, que acelera de 70 para 150 bpm. A cor perde força.',\n budget: 'Só pós-processo e ruído de câmera.',\n network: 'Local. O pânico dos outros aparece na mira deles e no grito (som).',\n },\n bloater_blindness: {\n name: 'Cegueira do Inchado',\n short: 'Gás verde na cara: tela turva por 5 s e muco na lente.',\n cost: 'pós + 30 part.',\n costNote: 'entidade do servidor',\n when: 'Jogador dentro da nuvem do Inchado (raio 4 m) quando ela nasce.',\n look: 'Nuvem verde explode entre o zumbi e a câmera, a tela fica verde e desfocada e clareia em 5 s, com gotas de muco verde na lente que escorrem. Tosse treme a câmera duas vezes.',\n budget: 'Pós-processo + 30 sprites de gás perto da câmera, com fade para não cobrir a tela inteira de partícula.',\n network: 'A cegueira vem da entidade no servidor; o visual é local.',\n },\n campfire: {\n name: 'Fogueira do acampamento',\n short: 'Chama baixa, brasas subindo em espiral e luz quente tremendo.',\n cost: '≤ 120 part.',\n costNote: '1 luz de fogo',\n when: 'Fogueira acesa pelo grupo ou por NPCs. Esquenta, ilumina e atrai zumbis de longe (luz).',\n look: 'Chamas pequenas e baixas, brasas que sobem girando e somem, fumaça fina e uma luz quente que treme e pinta o sobrevivente.',\n budget: '120 partículas e 1 luz de fogo. Várias fogueiras do acampamento dividem a mesma luz se estiverem a menos de 6 m.',\n network: 'Objeto de cena replicado (aceso ou apagado). Visual local.',\n },\n cough_and_breath: {\n name: 'Tosse, respiração e lanterna',\n short: 'Vapor da respiração no frio, tosse da febre visível para os outros e feixe da lanterna.',\n cost: '≤ 40 part.',\n costNote: '1 spot com sombra',\n when: 'Noite fria: respiração sempre. Febre da infecção: tosse a cada poucos segundos, audível a 10 m.',\n look: 'Sopro curto de vapor a cada 2,4 s. Na tosse, três sopros rápidos e maiores e o corpo dá um tranco. A lanterna mostra o feixe na neblina e é a única luz com sombra.',\n budget: 'Vapor: 8 partículas por sopro, só a menos de 15 m. Lanterna: 1 spot com sombra por jogador, só a do jogador local projeta sombra.',\n network: 'A tosse é o sinal social da infecção: o servidor manda o evento de tosse (sem dizer que é infecção) e os outros veem o vapor e ouvem.',\n },\n}\n","import { en } from './locales/en'\nimport { ptBR } from './locales/pt-BR'\n\n/** Locales shipped with the package. Unknown locales fall back to `en`. */\nexport type VfxLocale = 'en' | 'pt-BR'\n\n/** The texts of one Workshop effect: its card in the list and its sheet (when, how it looks, what it costs, what goes over the network). */\nexport interface EffectTexts {\n readonly name: string\n readonly short: string\n /** The cost shown on the card, and what comes with it. */\n readonly cost: string\n readonly costNote: string\n /** The label of the effect's parameter, when it has one. */\n readonly paramLabel?: string\n readonly when: string\n readonly look: string\n readonly budget: string\n readonly network: string\n}\n\n/** The words around the sheet (`renderSheet`, W1266). */\nexport interface SheetLabels {\n readonly when: string\n readonly look: string\n readonly budget: string\n readonly network: string\n readonly quality: string\n readonly replay: string\n readonly auto: string\n}\n\nexport interface VfxStrings {\n readonly effects: Readonly<Record<string, EffectTexts>>\n readonly sheet: SheetLabels\n readonly groups: Readonly<Record<string, string>>\n}\n\nexport const locales: Record<VfxLocale, VfxStrings> = {\n en: {\n effects: en,\n sheet: { when: 'When', look: 'Look', budget: 'Budget', network: 'Network', quality: 'Quality', replay: 'Replay', auto: 'Auto replay' },\n groups: { explosions: 'Explosions', creatures: 'Zombies', weapons: 'Weapons and explosives', world: 'Map, weather and destruction', destruction: 'Scenery destruction', vehicles: 'Vehicles', screen: 'Characters and screen effects' },\n },\n 'pt-BR': {\n effects: ptBR,\n sheet: { when: 'Quando', look: 'Visual', budget: 'Orçamento', network: 'Rede', quality: 'Qualidade', replay: 'Repetir', auto: 'Repetição automática' },\n groups: { explosions: 'Explosões', creatures: 'Zumbis', weapons: 'Armas e explosivos', world: 'Mapa, clima e destruição', destruction: 'Destruição de cenário', vehicles: 'Veículos', screen: 'Personagens e efeitos de tela' },\n },\n}\n\nexport const resolveStrings = (locale: string | undefined): VfxStrings => locales[(locale as VfxLocale) ?? 'en'] ?? locales.en\n","import type { Vec3Tuple } from '../workshop/types'\n\nconst ANIMATION_SPEED = 1.4\nconst START_POSITION: Vec3Tuple = [4, 2.4, 7]\nconst START_TARGET: Vec3Tuple = [0, 1, 0]\n\ntype Vector = [number, number, number]\n\nfunction subtract(a: Vec3Tuple, b: Vec3Tuple): Vector {\n return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]\n}\n\nfunction unit(vector: Vector): Vector {\n const length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]) || 1\n const inverse = 1 / length\n return [vector[0] * inverse, vector[1] * inverse, vector[2] * inverse]\n}\n\nfunction crossProduct(a: Vector, b: Vector): Vector {\n return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]\n}\n\nfunction ease(value: number): number {\n return value < 0 ? 0 : value > 1 ? 1 : value * value * (3 - 2 * value)\n}\n\nfunction mix(from: Vec3Tuple, to: Vec3Tuple, amount: number): Vec3Tuple {\n return [from[0] + (to[0] - from[0]) * amount, from[1] + (to[1] - from[1]) * amount, from[2] + (to[2] - from[2]) * amount]\n}\n\n/** Rotates a vector by the quaternion `(x, y, z, w)` as three.js `applyQuaternion` does. */\nfunction rotate(local: readonly number[], x: number, y: number, z: number, w: number): Vec3Tuple {\n const [vx, vy, vz] = local as Vec3Tuple\n const ix = w * vx + y * vz - z * vy\n const iy = w * vy + z * vx - x * vz\n const iz = w * vz + x * vy - y * vx\n const iw = -x * vx - y * vy - z * vz\n return [ix * w + iw * -x + iy * -z - iz * -y, iy * w + iw * -y + iz * -x - ix * -z, iz * w + iw * -z + ix * -y - iy * -x]\n}\n\n/** The quaternion three.js builds from `lookAt(eye, target)` with the y axis up (`setFromRotationMatrix`). */\nfunction lookAtQuaternion(eye: Vec3Tuple, target: Vec3Tuple): readonly [number, number, number, number] {\n const z = unit(subtract(eye, target))\n const x = unit(crossProduct([0, 1, 0], z))\n const y = crossProduct(z, x)\n const [m11, m21, m31, m12, m22, m32, m13, m23, m33] = [x[0], x[1], x[2], y[0], y[1], y[2], z[0], z[1], z[2]]\n const trace = m11 + m22 + m33\n if (trace > 0) {\n const scale = 0.5 / Math.sqrt(trace + 1)\n return [(m32 - m23) * scale, (m13 - m31) * scale, (m21 - m12) * scale, 0.25 / scale]\n }\n if (m11 > m22 && m11 > m33) {\n const scale = 2 * Math.sqrt(1 + m11 - m22 - m33)\n return [0.25 * scale, (m12 + m21) / scale, (m13 + m31) / scale, (m32 - m23) / scale]\n }\n if (m22 > m33) {\n const scale = 2 * Math.sqrt(1 + m22 - m11 - m33)\n return [(m12 + m21) / scale, 0.25 * scale, (m23 + m32) / scale, (m13 - m31) / scale]\n }\n const scale = 2 * Math.sqrt(1 + m33 - m11 - m22)\n return [(m13 + m31) / scale, (m23 + m32) / scale, 0.25 * scale, (m21 - m12) / scale]\n}\n\n/**\n * The Workshop's view (W1259-1262): it glides to each effect's `view` (`camTo`) in about 0.7 s and persists between effects, so an effect that reads the\n * camera (a ring that faces the viewer, a mist at the lens) sees where the previous one left it.\n */\nexport class EffectCamera {\n position: Vec3Tuple = START_POSITION\n target: Vec3Tuple = START_TARGET\n private animation: { from: Vec3Tuple; fromTarget: Vec3Tuple; to: Vec3Tuple; toTarget: Vec3Tuple; progress: number } | undefined\n\n goTo(eye: Vec3Tuple, target: Vec3Tuple): void {\n this.animation = { from: this.position, fromTarget: this.target, to: eye, toTarget: target, progress: 0 }\n }\n\n place(eye: Vec3Tuple, target: Vec3Tuple): void {\n this.position = eye\n this.target = target\n this.animation = undefined\n }\n\n hold(): void {\n this.animation = undefined\n }\n\n update(dt: number): void {\n const animation = this.animation\n if (!animation) return\n animation.progress = Math.min(1, animation.progress + dt * ANIMATION_SPEED)\n const eased = ease(animation.progress)\n this.position = mix(animation.from, animation.to, eased)\n this.target = mix(animation.fromTarget, animation.toTarget, eased)\n if (animation.progress >= 1) this.animation = undefined\n }\n\n /** A direction given in the camera's own axes, in world axes. */\n forward(local: readonly number[]): Vec3Tuple {\n const [x, y, z, w] = lookAtQuaternion(this.position, this.target)\n return rotate(local, x, y, z, w)\n }\n}\n","import type { RandomStream } from '../random'\nimport type { WorkshopEngine } from '../workshop/engine'\nimport type { Vec3Tuple } from '../workshop/types'\nimport type { Behavior } from './behavior'\nimport { EffectCamera } from './camera'\nimport { EffectInstance } from './instance'\nimport type { CueRequest, EffectDef, EffectStep } from './types'\n\nconst SHAKE_SCALE = 0.06\nconst SHAKE_DEPTH = 0.5\n\nexport interface EffectRunnerOptions {\n readonly engine: WorkshopEngine\n readonly effects: Readonly<Record<string, EffectDef>>\n readonly behaviors?: Readonly<Record<string, Behavior>>\n readonly onCue?: (cue: CueRequest) => void\n}\n\n/**\n * The Workshop's one-effect-at-a-time view (W1253-1295): choosing an effect clears the set and runs it; each frame fires the timers due, runs the tick, ages\n * the pools, glides the camera and draws the camera shake. This is what the bench shows and what the golden replays; `createEffectPlayer` plays many at once.\n */\nexport class EffectRunner {\n readonly camera = new EffectCamera()\n readonly instance: EffectInstance\n /** The camera shake of the last frame, three draws per frame as in the page. */\n shake: Vec3Tuple = [0, 0, 0]\n\n constructor(private readonly options: EffectRunnerOptions) {\n const behaviors = options.behaviors ?? {}\n this.instance = new EffectInstance({\n engine: options.engine,\n view: this.camera,\n behavior: (id) => behaviors[id]!,\n behaviors: () => Object.values(behaviors),\n ...(options.onCue ? { onCue: options.onCue } : {}),\n })\n }\n\n get current(): EffectDef | undefined {\n return this.instance.def\n }\n\n get variables(): Map<string, unknown> {\n return this.instance.variables\n }\n\n get param(): number {\n return this.instance.param\n }\n\n get fresh(): boolean {\n return this.instance.fresh\n }\n\n get time(): number {\n return this.instance.time\n }\n\n /** Seconds since the effect was chosen: unlike `time`, a restart of the loop does not reset it (`el`). */\n get elapsed(): number {\n return this.instance.elapsed\n }\n\n get random(): RandomStream {\n return this.options.engine.random\n }\n\n /** `select` + `startLoop` (W1253-1257): clears everything, then runs the effect's setup and timeline. */\n start(id: string, param?: number): boolean {\n const def = this.options.effects[id]\n if (!def) return false\n if (def.view) this.camera.goTo(def.view.eye, def.view.target)\n else this.camera.hold()\n this.options.engine.clear()\n this.instance.begin(def, param)\n return true\n }\n\n /** `startLoop` again: the same effect from its start (the replay button and the end of the loop). */\n restart(): void {\n if (!this.instance.def) return\n this.options.engine.clear()\n this.instance.restart()\n }\n\n /** One frame of the page (W1280-1295). */\n update(dt: number): void {\n const engine = this.options.engine\n engine.post = {}\n this.instance.step(dt)\n engine.update(dt)\n this.camera.update(dt)\n const amplitude = engine.screen.shake * SHAKE_SCALE + this.instance.tremor\n const random = this.random\n this.shake = [random.between(-1, 1) * amplitude, random.between(-1, 1) * amplitude, random.between(-1, 1) * amplitude * SHAKE_DEPTH]\n }\n\n execute(steps: readonly EffectStep[]): void {\n this.instance.execute(steps)\n }\n}\n","import type { RandomStream } from './random'\n\nexport interface GroundFieldOptions {\n /** Side of the deformable patch in metres (the Lab's 60). */\n readonly size?: number\n /** Cells per side (the Lab's 180: 33 cm cells). */\n readonly segments?: number\n}\n\n/** The deformable ground the Lab's craters dig into (L60-83): a height field, in float32 like the page, centred on the origin. */\nexport interface GroundField {\n readonly size: number\n readonly segments: number\n /** Vertices per side. */\n readonly stride: number\n readonly cellSize: number\n /** World coordinate of the first row and column. */\n readonly origin: number\n readonly heights: Float32Array\n /** Goes up on every dent or reset: a renderer redraws its mesh when it changes. */\n readonly version: number\n heightAt(x: number, z: number): number\n /** A bowl with an uneven floor and a raised rim, drawing from `random` like the Lab's `dent`. */\n dent(random: RandomStream, x: number, z: number, radius: number, depth: number): void\n reset(): void\n}\n\nconst DEFAULT_SIZE = 60\nconst DEFAULT_SEGMENTS = 180\nconst MAX_DEPTH = 3\nconst RIM_REACH = 1.45\nconst REACH_FACTOR = 1.5\n\nexport function createGroundField(options: GroundFieldOptions = {}): GroundField {\n const size = options.size ?? DEFAULT_SIZE\n const segments = options.segments ?? DEFAULT_SEGMENTS\n const stride = segments + 1\n const cellSize = size / segments\n const origin = -size / 2\n const heights = new Float32Array(stride * stride)\n let version = 0\n\n function heightAt(x: number, z: number): number {\n const fx = (x - origin) / cellSize\n const fz = (z - origin) / cellSize\n if (fx < 0 || fz < 0 || fx >= segments || fz >= segments) return 0\n const column = fx | 0\n const row = fz | 0\n const tx = fx - column\n const tz = fz - row\n const index = row * stride + column\n return (heights[index]! * (1 - tx) + heights[index + 1]! * tx) * (1 - tz) + (heights[index + stride]! * (1 - tx) + heights[index + stride + 1]! * tx) * tz\n }\n\n function dent(random: RandomStream, x: number, z: number, radius: number, depth: number): void {\n const reach = radius * REACH_FACTOR\n const column0 = Math.max(0, Math.floor((x - reach - origin) / cellSize))\n const column1 = Math.min(segments, Math.ceil((x + reach - origin) / cellSize))\n const row0 = Math.max(0, Math.floor((z - reach - origin) / cellSize))\n const row1 = Math.min(segments, Math.ceil((z + reach - origin) / cellSize))\n const phaseA = random.next() * 6\n const phaseB = random.next() * 6\n for (let row = row0; row <= row1; row++) {\n for (let column = column0; column <= column1; column++) {\n const px = origin + column * cellSize\n const pz = origin + row * cellSize\n const distance = Math.hypot(px - x, pz - z)\n const angle = Math.atan2(pz - z, px - x)\n const q = distance / (radius * (1 + 0.13 * Math.sin(angle * 5 + phaseA) + 0.07 * Math.sin(angle * 11 + phaseB)))\n let change = 0\n if (q < 1) change = -depth * (1 - q * q) * (0.85 + random.next() * 0.3)\n else if (q < RIM_REACH) {\n const k = (q - 1) / 0.45\n change = depth * 0.3 * Math.sin(k * Math.PI) * (1 - k * 0.3) * (0.6 + random.next() * 0.8)\n }\n if (!change) continue\n const index = row * stride + column\n heights[index] = Math.max(-MAX_DEPTH, heights[index]! + change)\n }\n }\n version++\n }\n\n function reset(): void {\n heights.fill(0)\n version++\n }\n\n return {\n size,\n segments,\n stride,\n cellSize,\n origin,\n heights,\n get version() {\n return version\n },\n heightAt,\n dent,\n reset,\n }\n}\n","/** The additive halo (Lab L297-304), verbatim except for the r160 colour-space chunk. */\nexport const GLOW_VERTEX = `attribute vec4 aP;attribute vec4 aC;varying vec2 vU;varying vec4 vC;\nvoid main(){vec3 R=vec3(viewMatrix[0][0],viewMatrix[1][0],viewMatrix[2][0]);vec3 Up=vec3(viewMatrix[0][1],viewMatrix[1][1],viewMatrix[2][1]);\nvec3 wp=aP.xyz+(R*position.x+Up*position.y)*aP.w;vU=position.xy;vC=aC;gl_Position=projectionMatrix*viewMatrix*vec4(wp,1.);}`\n\nexport const GLOW_FRAGMENT = `varying vec2 vU;varying vec4 vC;void main(){float r=dot(vU,vU);if(r>1.)discard;float f=exp(-r*4.2)-.015;gl_FragColor=vec4(vC.rgb*vC.a*max(f,0.),1.);\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}`\n","/** The value noise the puff shader builds its dissolve from (Lab L116-122), verbatim. */\nexport const GL_NOISE = `\nfloat h3(vec3 p){p=fract(p*.3183099+.1);p*=17.0;return fract(p.x*p.y*p.z*(p.x+p.y+p.z));}\nfloat vn(vec3 x){vec3 i=floor(x),f=fract(x);f=f*f*(3.-2.*f);\n return mix(mix(mix(h3(i),h3(i+vec3(1,0,0)),f.x),mix(h3(i+vec3(0,1,0)),h3(i+vec3(1,1,0)),f.x),f.y),\n mix(mix(h3(i+vec3(0,0,1)),h3(i+vec3(1,0,1)),f.x),mix(h3(i+vec3(0,1,1)),h3(i+vec3(1,1,1)),f.x),f.y),f.z);}\n`\n","import { GL_NOISE } from './noise'\n\n/**\n * The puff shader of the Lab (L130-192), verbatim: a faceted icosahedron per puff, a five-band posterised heat ramp, a noise dissolve and banded light.\n * The only change is the r160 colour-space chunk: `encodings_fragment` (r128) is `colorspace_fragment` now.\n */\nexport const PUFF_VERTEX = `${GL_NOISE}\nattribute vec4 aP;attribute vec4 aD;attribute vec3 aC;\nvarying vec3 vWP;varying vec3 vL;varying vec4 vD;varying vec3 vC;\nvoid main(){\n vec3 p=position;\n float s=aD.z;\n float n=vn(p*1.6+vec3(s*11.0,s*7.0,s*3.0));\n p*=0.78+0.5*n;\n float a=s*6.2831;float c=cos(a),si=sin(a);p.xz=mat2(c,-si,si,c)*p.xz;\n vL=p;\n vec3 wp=aP.xyz+p*aP.w;\n vWP=wp;vD=aD;vC=aC;\n gl_Position=projectionMatrix*viewMatrix*vec4(wp,1.0);\n}`\n\nexport const PUFF_FRAGMENT = `${GL_NOISE}\nuniform vec3 uLight;uniform vec3 uSky;uniform vec3 uGround;uniform vec3 uGlowPos;uniform vec3 uGlowCol;uniform float uGlowI;\nvarying vec3 vWP;varying vec3 vL;varying vec4 vD;varying vec3 vC;\nvec3 L(vec3 c){return pow(c,vec3(2.2));}\nvec3 ramp(float h){\n vec3 c0=L(vec3(.36,.07,.03)),c1=L(vec3(.76,.21,.1)),c2=L(vec3(1.,.54,.16)),c3=L(vec3(1.,.83,.42)),c4=L(vec3(1.,.96,.84));\n if(h<.25)return mix(c0,c1,h/.25);\n if(h<.5)return mix(c1,c2,(h-.25)/.25);\n if(h<.8)return mix(c2,c3,(h-.5)/.3);\n return mix(c3,c4,clamp((h-.8)/.4,0.,1.));\n}\nvoid main(){\n vec3 N=normalize(cross(dFdx(vWP),dFdy(vWP)));\n float age=vD.x,heat=vD.y,kind=vD.w;\n float n=vn(vL*2.4+vD.z*13.0);\n float diss=smoothstep(.5,1.,age);\n if(n<diss*1.08-.04)discard;\n float lam=max(dot(N,uLight),0.);\n float band=lam>.55?1.:lam>.15?.68:.42;\n vec3 col=vC*(vec3(.5,.56,.7)*band*1.05+vec3(.2,.19,.18)+uGround*(.4-.4*N.y));\n vec3 tg=uGlowPos-vWP;float dg=length(tg)+.001;\n float gi=uGlowI/(1.+dg*dg*.05)*(.3+.7*max(dot(N,tg/dg),0.));\n col+=uGlowCol*gi*vC*1.6;\n float h=heat*(.72+.56*n)+heat*(-N.y)*.18;\n if(h>.05){\n float hq=floor(h*5.+.5)/5.;\n vec3 fc=ramp(clamp(hq,0.,1.2))*(1.1+3.1*hq);\n col=mix(col,fc,smoothstep(.04,.2,h));\n }\n if(kind>2.5&&kind<3.5){col+=vec3(.02,.025,.03);}\n gl_FragColor=vec4(col,1.);\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}`\n","/** The streak shader of shrapnel, sparks and embers (Lab L255-275), verbatim except for the r160 colour-space chunk. */\nexport const SPARK_VERTEX = `\nattribute vec3 aPos;attribute vec3 aVel;attribute vec4 aE;varying vec2 vU;varying vec4 vE;\nvoid main(){\n float sp=length(aVel)+1e-4;vec3 d=aVel/sp;\n vec3 tc=normalize(cameraPosition-aPos);\n vec3 sd=normalize(cross(d,tc)+vec3(1e-5));\n float len=max(aE.y*2.5,min(sp*aE.z,2.2));\n vec3 wp=aPos+sd*position.x*aE.y-d*position.y*len;\n vU=position.xy;vE=aE;\n gl_Position=projectionMatrix*viewMatrix*vec4(wp,1.);\n}`\n\nexport const SPARK_FRAGMENT = `\nvarying vec2 vU;varying vec4 vE;\nvoid main(){\n float age=vE.x,k=vE.w;\n float w=1.-abs(vU.x)*2.;w=w*w;\n float tail=1.-vU.y;\n vec3 c;\n if(k<.5){c=mix(vec3(4.,3.3,2.2),vec3(2.4,.7,.12),smoothstep(0.,.55,age));c=mix(c,vec3(.5,.06,.02),smoothstep(.55,1.,age));}\n else if(k<1.5){c=mix(vec3(1.6,1.6,1.6),vec3(.35,.35,.36),smoothstep(0.,.4,age));}\n else if(k<2.5){c=mix(vec3(5.,5.,6.),vec3(1.,1.3,2.),smoothstep(0.,.5,age));}\n else if(k<3.5){c=vec3(.9,1.2,1.4)*(1.-age);}\n else {c=mix(vec3(3.2,1.4,.3),vec3(1.2,.25,.05),age);}\n float a=w*(.35+.65*tail)*(1.-smoothstep(.75,1.,age));\n gl_FragColor=vec4(c*a,1.);\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}`\n","import type * as THREE_NS from 'three'\nimport type { Chunk, Glow, OrderedPool, Puff, Spark } from '@adatechnology/game-vfx'\nimport { GLOW_FRAGMENT, GLOW_VERTEX } from './shaders/glow'\nimport { PUFF_FRAGMENT, PUFF_VERTEX } from './shaders/puff'\nimport { SPARK_FRAGMENT, SPARK_VERTEX } from './shaders/spark'\nimport type { ThreeLib } from './types'\n\nexport interface DrawnLayer {\n readonly mesh: THREE_NS.Mesh\n /** Copies the pool into the instance buffers and answers how many are drawn. */\n sync(): number\n dispose(): void\n}\n\ntype Attribute = THREE_NS.InstancedBufferAttribute\n\nfunction dynamic(THREE: ThreeLib, array: Float32Array, size: number): Attribute {\n return new THREE.InstancedBufferAttribute(array, size).setUsage(THREE.DynamicDrawUsage)\n}\n\nexport interface PuffUniforms {\n uLight: { value: THREE_NS.Vector3 }\n uSky: { value: THREE_NS.Vector3 }\n uGround: { value: THREE_NS.Vector3 }\n uGlowPos: { value: THREE_NS.Vector3 }\n uGlowCol: { value: THREE_NS.Vector3 }\n uGlowI: { value: number }\n uTime: { value: number }\n}\n\nexport function createPuffLayer(THREE: ThreeLib, pool: OrderedPool<Puff>, uniforms: PuffUniforms): DrawnLayer {\n const capacity = pool.capacity\n const geometry = new THREE.InstancedBufferGeometry()\n geometry.setAttribute('position', new THREE.IcosahedronGeometry(1, 1).getAttribute('position'))\n const a = new Float32Array(capacity * 4)\n const d = new Float32Array(capacity * 4)\n const c = new Float32Array(capacity * 3)\n const attributes = [dynamic(THREE, a, 4), dynamic(THREE, d, 4), dynamic(THREE, c, 3)] as const\n geometry.setAttribute('aP', attributes[0])\n geometry.setAttribute('aD', attributes[1])\n geometry.setAttribute('aC', attributes[2])\n geometry.instanceCount = 0\n const material = new THREE.ShaderMaterial({ uniforms: uniforms as never, vertexShader: PUFF_VERTEX, fragmentShader: PUFF_FRAGMENT })\n const mesh = new THREE.Mesh(geometry, material)\n mesh.name = 'vfx-puffs'\n mesh.frustumCulled = false\n return {\n mesh,\n sync() {\n let n = 0\n for (const p of pool.items) {\n a[n * 4] = p.x\n a[n * 4 + 1] = p.y\n a[n * 4 + 2] = p.z\n a[n * 4 + 3] = p.size\n d[n * 4] = p.age\n d[n * 4 + 1] = p.heat\n d[n * 4 + 2] = p.seed\n d[n * 4 + 3] = p.kind\n c[n * 3] = p.color[0]\n c[n * 3 + 1] = p.color[1]\n c[n * 3 + 2] = p.color[2]\n n++\n }\n geometry.instanceCount = n\n for (const attribute of attributes) attribute.needsUpdate = true\n return n\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\nexport function createSparkLayer(THREE: ThreeLib, pool: OrderedPool<Spark>): DrawnLayer {\n const capacity = pool.capacity\n const geometry = new THREE.InstancedBufferGeometry()\n geometry.setAttribute('position', new THREE.Float32BufferAttribute([-0.5, 0, 0, 0.5, 0, 0, 0.5, 1, 0, -0.5, 1, 0], 3))\n geometry.setIndex([0, 1, 2, 0, 2, 3])\n const position = new Float32Array(capacity * 3)\n const velocity = new Float32Array(capacity * 3)\n const extra = new Float32Array(capacity * 4)\n const attributes = [dynamic(THREE, position, 3), dynamic(THREE, velocity, 3), dynamic(THREE, extra, 4)] as const\n geometry.setAttribute('aPos', attributes[0])\n geometry.setAttribute('aVel', attributes[1])\n geometry.setAttribute('aE', attributes[2])\n geometry.instanceCount = 0\n const material = new THREE.ShaderMaterial({ transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, vertexShader: SPARK_VERTEX, fragmentShader: SPARK_FRAGMENT })\n const mesh = new THREE.Mesh(geometry, material)\n mesh.name = 'vfx-sparks'\n mesh.frustumCulled = false\n mesh.renderOrder = 5\n return {\n mesh,\n sync() {\n let n = 0\n for (const s of pool.items) {\n position[n * 3] = s.x\n position[n * 3 + 1] = s.y\n position[n * 3 + 2] = s.z\n velocity[n * 3] = s.vx\n velocity[n * 3 + 1] = s.vy\n velocity[n * 3 + 2] = s.vz\n extra[n * 4] = s.age\n extra[n * 4 + 1] = s.w\n extra[n * 4 + 2] = s.st\n extra[n * 4 + 3] = s.kind\n n++\n }\n geometry.instanceCount = n\n for (const attribute of attributes) attribute.needsUpdate = true\n return n\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\nexport function createGlowLayer(THREE: ThreeLib, pool: OrderedPool<Glow>): DrawnLayer {\n const capacity = pool.capacity\n const geometry = new THREE.InstancedBufferGeometry()\n geometry.setAttribute('position', new THREE.Float32BufferAttribute([-1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0], 3))\n geometry.setIndex([0, 1, 2, 0, 2, 3])\n const where = new Float32Array(capacity * 4)\n const color = new Float32Array(capacity * 4)\n const attributes = [dynamic(THREE, where, 4), dynamic(THREE, color, 4)] as const\n geometry.setAttribute('aP', attributes[0])\n geometry.setAttribute('aC', attributes[1])\n geometry.instanceCount = 0\n const material = new THREE.ShaderMaterial({ transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, vertexShader: GLOW_VERTEX, fragmentShader: GLOW_FRAGMENT })\n const mesh = new THREE.Mesh(geometry, material)\n mesh.name = 'vfx-glows'\n mesh.frustumCulled = false\n mesh.renderOrder = 6\n return {\n mesh,\n sync() {\n let n = 0\n for (const g of pool.items) {\n where[n * 4] = g.outX\n where[n * 4 + 1] = g.outY\n where[n * 4 + 2] = g.outZ\n where[n * 4 + 3] = g.outSize\n color[n * 4] = g.color[0]\n color[n * 4 + 1] = g.color[1]\n color[n * 4 + 2] = g.color[2]\n color[n * 4 + 3] = g.outIntensity\n n++\n }\n geometry.instanceCount = n\n for (const attribute of attributes) attribute.needsUpdate = true\n return n\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\nexport interface ChunkLayer {\n readonly rocks: THREE_NS.InstancedMesh\n readonly plates: THREE_NS.InstancedMesh\n sync(): number\n dispose(): void\n}\n\nexport function createChunkLayer(THREE: ThreeLib, pool: OrderedPool<Chunk>, shapes: { rock: THREE_NS.BufferGeometry; plate: THREE_NS.BufferGeometry }, colorOf: (chunk: Chunk) => readonly [number, number, number]): ChunkLayer {\n const capacity = pool.capacity\n const rockMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0.85, flatShading: true })\n const plateMaterial = rockMaterial.clone()\n const make = (geometry: THREE_NS.BufferGeometry, material: THREE_NS.Material): THREE_NS.InstancedMesh => {\n const mesh = new THREE.InstancedMesh(geometry, material, capacity)\n mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)\n mesh.castShadow = true\n mesh.receiveShadow = true\n mesh.frustumCulled = false\n mesh.count = 0\n mesh.setColorAt(0, new THREE.Color(1, 1, 1))\n return mesh\n }\n const rocks = make(shapes.rock, rockMaterial)\n const plates = make(shapes.plate, plateMaterial)\n const matrix = new THREE.Matrix4()\n const quaternion = new THREE.Quaternion()\n const euler = new THREE.Euler()\n const position = new THREE.Vector3()\n const scale = new THREE.Vector3()\n return {\n rocks,\n plates,\n sync() {\n let rockCount = 0\n let plateCount = 0\n for (const chunk of pool.items) {\n euler.set(chunk.rx, chunk.ry, chunk.rz)\n quaternion.setFromEuler(euler)\n matrix.compose(position.set(chunk.x, chunk.y, chunk.z), quaternion, scale.set(chunk.sx, chunk.sy, chunk.sz))\n const mesh = chunk.plate ? plates : rocks\n const index = chunk.plate ? plateCount++ : rockCount++\n mesh.setMatrixAt(index, matrix)\n const color = colorOf(chunk)\n const colors = mesh.instanceColor!.array as Float32Array\n colors[index * 3] = color[0]\n colors[index * 3 + 1] = color[1]\n colors[index * 3 + 2] = color[2]\n }\n rocks.count = rockCount\n plates.count = plateCount\n for (const mesh of [rocks, plates]) {\n mesh.instanceMatrix.needsUpdate = true\n mesh.instanceColor!.needsUpdate = true\n }\n return rockCount + plateCount\n },\n dispose() {\n rockMaterial.dispose()\n plateMaterial.dispose()\n rocks.dispose()\n plates.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { LightPool } from '@adatechnology/game-vfx'\nimport type { ThreeLib } from './types'\n\nexport interface LightLayer {\n readonly group: THREE_NS.Group\n /** Moves and lights the 4 blast lights and 2 fire lights from the pool; answers how many are lit. */\n sync(): number\n dispose(): void\n}\n\n/** The Lab's light pool as real point lights (L349-365). Colours are the raw numbers the Lab used, not converted from sRGB. */\nexport function createLightLayer(THREE: ThreeLib, pool: LightPool, scale: number): LightLayer {\n const group = new THREE.Group()\n const blast = pool.blast.map(() => {\n const light = new THREE.PointLight(0xffa050, 0, 30, 2)\n light.position.set(0, -50, 0)\n group.add(light)\n return light\n })\n const fire = pool.fire.map(() => {\n const light = new THREE.PointLight(0xff7a2a, 0, 16, 2)\n light.position.set(0, -50, 0)\n group.add(light)\n return light\n })\n return {\n group,\n sync() {\n let lit = 0\n pool.blast.forEach((entry, index) => {\n const light = blast[index]!\n light.position.set(entry.x, entry.y, entry.z)\n light.distance = entry.distance\n light.color.setRGB(entry.color[0], entry.color[1], entry.color[2], THREE.LinearSRGBColorSpace)\n light.intensity = entry.intensity * scale\n if (entry.intensity > 0.05) lit++\n })\n pool.fire.forEach((entry, index) => {\n const light = fire[index]!\n light.position.set(entry.x, entry.y, entry.z)\n light.distance = entry.distance\n light.intensity = entry.intensity * scale\n if (entry.intensity > 0.05) lit++\n })\n return lit\n },\n dispose() {\n for (const light of [...blast, ...fire]) light.dispose()\n },\n }\n}\n","import { lehmer } from '@adatechnology/game-vfx'\nimport type { RandomStream } from '@adatechnology/game-vfx'\nimport type { CanvasContextLike, CanvasLike, ThreeLib } from './types'\nimport type * as THREE_NS from 'three'\n\nconst SCORCH_SEED = 5\nconst TEXTURE_SIZE = 256\nconst FULL_TURN = Math.PI * 2\n\n/** Where a texture draws its randomness: the Lab seeded the page with 5 before it made the marks, so the textures do not touch the effect's own stream. */\nexport function createTextureStream(): RandomStream {\n return lehmer(SCORCH_SEED)\n}\n\n/** Without a DOM (a server, a test in Node) there is nothing to draw on: the textures stay blank and the marks still lay down their geometry. */\nfunction blankCanvas(): CanvasLike {\n return { width: 0, height: 0, getContext: () => null }\n}\n\nfunction defaultCanvas(): CanvasLike {\n if (typeof document === 'undefined') return blankCanvas()\n return document.createElement('canvas') as unknown as CanvasLike\n}\n\nfunction paint(createCanvas: () => CanvasLike, draw: (context: CanvasContextLike, size: number) => void): CanvasLike {\n const canvas = createCanvas()\n canvas.width = TEXTURE_SIZE\n canvas.height = TEXTURE_SIZE\n const context = canvas.getContext('2d')\n if (context) draw(context, TEXTURE_SIZE)\n return canvas\n}\n\nfunction drawScorch(context: CanvasContextLike, size: number, random: RandomStream): void {\n context.clearRect(0, 0, size, size)\n const center = size / 2\n for (let ray = 0; ray < 60; ray++) {\n const angle = random.next() * FULL_TURN\n const length = center * (0.55 + random.next() * 0.42)\n context.strokeStyle = `rgba(8,6,5,${0.25 + random.next() * 0.35})`\n context.lineWidth = 2 + random.next() * 6\n context.beginPath()\n context.moveTo(center, center)\n context.lineTo(center + Math.cos(angle) * length, center + Math.sin(angle) * length)\n context.stroke()\n }\n const gradient = context.createRadialGradient(center, center, 0, center, center, center * 0.72)\n gradient.addColorStop(0, 'rgba(4,3,3,.96)')\n gradient.addColorStop(0.55, 'rgba(10,8,7,.85)')\n gradient.addColorStop(1, 'rgba(14,11,9,0)')\n context.fillStyle = gradient\n context.fillRect(0, 0, size, size)\n for (let spot = 0; spot < 26; spot++) {\n context.fillStyle = `rgba(60,40,28,${0.15 + random.next() * 0.2})`\n context.beginPath()\n context.arc(center + random.between(-0.4, 0.4) * center, center + random.between(-0.4, 0.4) * center, 2 + random.next() * 7, 0, 7)\n context.fill()\n }\n}\n\nfunction drawDirt(context: CanvasContextLike, size: number, random: RandomStream): void {\n const center = size / 2\n context.clearRect(0, 0, size, size)\n const gradient = context.createRadialGradient(center, center, 0, center, center, center)\n gradient.addColorStop(0, 'rgba(92,72,52,1)')\n gradient.addColorStop(0.6, 'rgba(118,92,64,1)')\n gradient.addColorStop(0.82, 'rgba(80,64,50,.8)')\n gradient.addColorStop(1, 'rgba(40,36,34,0)')\n context.fillStyle = gradient\n context.fillRect(0, 0, size, size)\n for (let speck = 0; speck < 420; speck++) {\n const angle = random.next() * FULL_TURN\n const distance = Math.sqrt(random.next()) * center * 0.8\n context.fillStyle = random.next() < 0.5 ? 'rgba(40,30,22,.5)' : 'rgba(160,132,96,.5)'\n context.beginPath()\n context.arc(center + Math.cos(angle) * distance, center + Math.sin(angle) * distance, 1 + random.next() * 3.5, 0, 7)\n context.fill()\n }\n}\n\nexport interface MarkTextures {\n readonly scorch: readonly THREE_NS.CanvasTexture[]\n readonly dirt: THREE_NS.CanvasTexture\n}\n\n/** The three scorch textures and the dirt one (L443-457), drawn once from a stream seeded like the page's. */\nexport function createMarkTextures(THREE: ThreeLib, createCanvas: (() => CanvasLike) | undefined): MarkTextures {\n const make = createCanvas ?? defaultCanvas\n const random = createTextureStream()\n const texture = (canvas: CanvasLike): THREE_NS.CanvasTexture => {\n const result = new THREE.CanvasTexture(canvas as unknown as HTMLCanvasElement)\n result.colorSpace = THREE.SRGBColorSpace\n result.anisotropy = 4\n return result\n }\n const scorch = [0, 1, 2].map(() => texture(paint(make, (context, size) => drawScorch(context, size, random))))\n const dirt = texture(paint(make, (context, size) => drawDirt(context, size, random)))\n return { scorch, dirt }\n}\n","import type * as THREE_NS from 'three'\nimport type { BloodMark, DirtMark, GroundField, Mark, MarkEvent, RockMark, ScorchMark } from '@adatechnology/game-vfx'\nimport { createMarkTextures } from './canvas'\nimport type { MarkTextures } from './canvas'\nimport type { CanvasLike, ThreeLib } from './types'\n\nconst MAX_CONFORM_STEPS = 48\nconst MIN_CONFORM_STEPS = 16\nconst BLOOD_GROW_RATE = 1.2\n\ninterface BloodDrawn {\n readonly mesh: THREE_NS.Mesh\n readonly scaleX: number\n readonly scaleZ: number\n age: number\n}\n\nexport interface MarkLayer {\n readonly group: THREE_NS.Group\n /** The shared rock and plate shapes, so the debris and the rim rocks use the same geometry. */\n handle(event: MarkEvent): void\n update(dt: number): void\n /** The meshes in the group right now. */\n count(): number\n dispose(): void\n}\n\nexport interface MarkLayerOptions {\n readonly ground: GroundField | undefined\n readonly createCanvas: (() => CanvasLike) | undefined\n readonly rockGeometry: THREE_NS.BufferGeometry\n readonly plateGeometry: THREE_NS.BufferGeometry\n}\n\n/**\n * The scorch, dirt, rim rocks and blood of the Lab as meshes (L443-476). A scorch or dirt mesh follows the ground as it was the moment the mark was\n * made (`conform`), so the renderer builds it from the mark event, not later.\n */\nexport function createMarkLayer(THREE: ThreeLib, options: MarkLayerOptions): MarkLayer {\n const group = new THREE.Group()\n const textures: MarkTextures = createMarkTextures(THREE, options.createCanvas)\n const owned: { dispose(): void }[] = [...textures.scorch, textures.dirt]\n const scorchMaterials = textures.scorch.map((map) => {\n const material = new THREE.MeshStandardMaterial({ map, transparent: true, depthWrite: false, roughness: 1, polygonOffset: true, polygonOffsetFactor: -2, polygonOffsetUnits: -2 })\n owned.push(material)\n return material\n })\n const dirtMaterial = new THREE.MeshStandardMaterial({\n map: textures.dirt, transparent: true, depthWrite: false, roughness: 1, flatShading: true, polygonOffset: true, polygonOffsetFactor: -1, polygonOffsetUnits: -1,\n })\n owned.push(dirtMaterial)\n const bloodMaterial = new THREE.MeshStandardMaterial({ color: 0x5c0a0a, roughness: 0.15, metalness: 0.1, polygonOffset: true, polygonOffsetFactor: -3, polygonOffsetUnits: -3 })\n const bloodGeometry = new THREE.CircleGeometry(0.5, 9).rotateX(-Math.PI / 2)\n owned.push(bloodMaterial, bloodGeometry)\n const rockMaterials = new Map<number, THREE_NS.MeshStandardMaterial>()\n const blood: BloodDrawn[] = []\n let meshCount = 0\n\n function rockMaterial(color: number): THREE_NS.MeshStandardMaterial {\n let material = rockMaterials.get(color)\n if (!material) {\n material = new THREE.MeshStandardMaterial({ color, roughness: 0.9, metalness: 0, flatShading: true })\n rockMaterials.set(color, material)\n owned.push(material)\n }\n return material\n }\n\n function conform(mark: ScorchMark | DirtMark, material: THREE_NS.Material): THREE_NS.Mesh {\n const radius = mark.radius\n const steps = Math.max(MIN_CONFORM_STEPS, Math.min(MAX_CONFORM_STEPS, Math.round(radius * 8)))\n const geometry = new THREE.PlaneGeometry(2, 2, steps, steps).rotateX(-Math.PI / 2)\n const position = geometry.attributes.position!\n const cos = Math.cos(mark.rotation)\n const sin = Math.sin(mark.rotation)\n for (let index = 0; index < position.count; index++) {\n const localX = position.getX(index) * radius\n const localZ = position.getZ(index) * radius\n const worldX = mark.x + localX * cos - localZ * sin\n const worldZ = mark.z + localX * sin + localZ * cos\n position.setXYZ(index, worldX, (options.ground?.heightAt(worldX, worldZ) ?? 0) + mark.lift, worldZ)\n }\n geometry.computeVertexNormals()\n const mesh = new THREE.Mesh(geometry, material as THREE_NS.MeshStandardMaterial)\n mesh.receiveShadow = true\n return mesh\n }\n\n function addRock(mark: RockMark): THREE_NS.Mesh {\n const mesh = new THREE.Mesh(mark.plate ? options.plateGeometry : options.rockGeometry, rockMaterial(mark.color))\n mesh.position.set(mark.x, mark.y, mark.z)\n mesh.scale.set(mark.scale[0], mark.scale[1], mark.scale[2])\n mesh.rotation.set(mark.rotation[0], mark.rotation[1], mark.rotation[2])\n mesh.castShadow = true\n mesh.receiveShadow = true\n return mesh\n }\n\n function addBlood(mark: BloodMark): THREE_NS.Mesh {\n const mesh = new THREE.Mesh(bloodGeometry, bloodMaterial)\n mesh.position.set(mark.x, mark.y, mark.z)\n mesh.scale.set(mark.scaleX, 1, mark.scaleZ)\n mesh.rotation.y = mark.rotation\n mesh.receiveShadow = true\n mesh.scale.multiplyScalar(0.05)\n blood.push({ mesh, scaleX: mark.scaleX, scaleZ: mark.scaleZ, age: 0 })\n return mesh\n }\n\n function build(mark: Mark): THREE_NS.Mesh {\n if (mark.kind === 'scorch') return conform(mark, scorchMaterials[mark.variant]!)\n if (mark.kind === 'dirt') return conform(mark, dirtMaterial)\n if (mark.kind === 'rock') return addRock(mark)\n return addBlood(mark)\n }\n\n function clearMeshes(): void {\n for (const child of [...group.children]) {\n group.remove(child)\n const geometry = (child as THREE_NS.Mesh).geometry\n if (geometry !== options.rockGeometry && geometry !== options.plateGeometry && geometry !== bloodGeometry) geometry.dispose()\n }\n blood.length = 0\n meshCount = 0\n }\n\n return {\n group,\n handle(event) {\n if (event.type === 'clear') {\n clearMeshes()\n return\n }\n group.add(build(event.mark))\n meshCount++\n },\n update(dt) {\n for (const drawn of blood) {\n if (drawn.age > 1) continue\n drawn.age += dt * BLOOD_GROW_RATE\n const ease = 1 - Math.pow(1 - Math.min(1, drawn.age), 2.5)\n drawn.mesh.scale.set(drawn.scaleX * Math.max(0.05, ease), 1, drawn.scaleZ * Math.max(0.05, ease))\n }\n },\n count: () => meshCount,\n dispose() {\n clearMeshes()\n for (const item of owned) item.dispose()\n },\n }\n}\n","import type { ScreenState } from '@adatechnology/game-vfx'\n\nexport interface ScreenOverlay {\n update(state: Readonly<ScreenState>): void\n dispose(): void\n}\n\nconst clamp = (value: number, min: number, max: number): number => (value < min ? min : value > max ? max : value)\n\nfunction layer(container: HTMLElement, name: string, blend?: string): HTMLDivElement {\n const element = container.ownerDocument.createElement('div')\n element.dataset.vfxOverlay = name\n Object.assign(element.style, { position: 'absolute', inset: '0', pointerEvents: 'none', opacity: '0' })\n if (blend) element.style.mixBlendMode = blend\n container.appendChild(element)\n return element\n}\n\n/**\n * The screen effects as overlays inside the host's container: the Lab's white flash (L1087, `mix-blend-mode: screen`) and the Workshop's white,\n * red edge, the two sides and the gas tint (W356-366), with the same colours. Nothing is drawn while the state is at rest.\n */\nexport function createScreenOverlay(container: HTMLElement): ScreenOverlay {\n const flash = layer(container, 'flash', 'screen')\n flash.style.background = '#fff'\n const white = layer(container, 'white')\n const red = layer(container, 'red')\n const sides = layer(container, 'sides')\n const gas = layer(container, 'gas')\n const elements = [flash, white, red, sides, gas]\n return {\n update(state) {\n flash.style.opacity = clamp(state.flash, 0, 1).toFixed(3)\n white.style.opacity = '1'\n white.style.background = `rgba(235,240,255,${clamp(state.white, 0, 1).toFixed(2)})`\n red.style.opacity = '1'\n red.style.background = `radial-gradient(ellipse at center, transparent 40%, rgba(170,16,12,${(clamp(state.red, 0, 1) * 0.85).toFixed(2)}) 100%)`\n sides.style.opacity = '1'\n sides.style.background = `linear-gradient(90deg, rgba(190,20,14,${(state.directionLeft * 0.8).toFixed(2)}) 0%, transparent 35%, transparent 65%, rgba(190,20,14,${(state.directionRight * 0.8).toFixed(2)}) 100%)`\n gas.style.opacity = '1'\n gas.style.background = state.gas > 0.01 ? `rgba(90,130,40,${(state.gas * 0.55).toFixed(2)})` : 'transparent'\n },\n dispose() {\n for (const element of elements) element.remove()\n },\n }\n}\n","/** The shock shell (fresnel edge, Lab L322-325) and the dust ring on the ground (L326-333), verbatim except for the r160 colour-space chunk. */\nexport const SHELL_VERTEX = `varying vec3 vN;varying vec3 vV;void main(){vec4 wp=modelMatrix*vec4(position,1.);vN=normalize(mat3(modelMatrix)*normal);vV=normalize(cameraPosition-wp.xyz);gl_Position=projectionMatrix*viewMatrix*wp;}`\n\nexport const SHELL_FRAGMENT = `uniform float uA;varying vec3 vN;varying vec3 vV;void main(){float f=1.-abs(dot(vN,vV));f=pow(f,5.);gl_FragColor=vec4(vec3(1.,.93,.82)*f*uA*.45,1.);\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}`\n\nexport const RING_VERTEX = `varying vec2 vU;void main(){vU=position.xz;gl_Position=projectionMatrix*viewMatrix*modelMatrix*vec4(position,1.);}`\n\nexport const RING_FRAGMENT = `uniform float uA;uniform float uW;uniform vec3 uC;varying vec2 vU;\n float h(vec2 p){return fract(sin(dot(p,vec2(12.9898,78.233)))*43758.5453);}\n void main(){float r=length(vU);float b=smoothstep(1.,1.-uW,r)*smoothstep(1.-uW*3.5,1.-uW,r);float a=atan(vU.y,vU.x);float n=.7+.3*h(vec2(floor(a*14.),1.));gl_FragColor=vec4(uC,b*uA*n);\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}`\n","import type * as THREE_NS from 'three'\nimport type { OrderedPool, Shock } from '@adatechnology/game-vfx'\nimport { RING_FRAGMENT, RING_VERTEX, SHELL_FRAGMENT, SHELL_VERTEX } from './shaders/shock'\nimport type { ThreeLib } from './types'\n\ninterface Pair {\n readonly shell: THREE_NS.Mesh\n readonly ring: THREE_NS.Mesh\n readonly shellAlpha: { value: number }\n readonly ringAlpha: { value: number }\n}\n\nconst RING_HEIGHT = 0.05\n\nexport interface ShockLayer {\n readonly group: THREE_NS.Group\n sync(): number\n dispose(): void\n}\n\n/** The shock shell and ground ring of each live shock (L319-348): one pair of meshes per slot, shown while the slot has a shock. */\nexport function createShockLayer(THREE: ThreeLib, pool: OrderedPool<Shock>): ShockLayer {\n const group = new THREE.Group()\n const shellGeometry = new THREE.SphereGeometry(1, 28, 18)\n const ringGeometry = new THREE.PlaneGeometry(2, 2).rotateX(-Math.PI / 2)\n const pairs: Pair[] = []\n\n function makePair(): Pair {\n const shellAlpha = { value: 0 }\n const ringAlpha = { value: 0 }\n const shellMaterial = new THREE.ShaderMaterial({ transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, uniforms: { uA: shellAlpha }, vertexShader: SHELL_VERTEX, fragmentShader: SHELL_FRAGMENT })\n const ringMaterial = new THREE.ShaderMaterial({\n transparent: true, depthWrite: false, uniforms: { uA: ringAlpha, uW: { value: 0.12 }, uC: { value: new THREE.Color(0.55, 0.5, 0.44) } }, vertexShader: RING_VERTEX, fragmentShader: RING_FRAGMENT,\n })\n const shell = new THREE.Mesh(shellGeometry, shellMaterial)\n shell.renderOrder = 4\n const ring = new THREE.Mesh(ringGeometry, ringMaterial)\n ring.renderOrder = 3\n group.add(shell, ring)\n return { shell, ring, shellAlpha, ringAlpha }\n }\n\n return {\n group,\n sync() {\n const shocks = pool.items\n for (let index = 0; index < shocks.length; index++) {\n const pair = (pairs[index] ??= makePair())\n const shock = shocks[index]!\n pair.shell.visible = pair.ring.visible = true\n pair.shell.position.set(shock.x, shock.y, shock.z)\n pair.shell.scale.setScalar(shock.shellScale)\n pair.shellAlpha.value = shock.shellAlpha\n pair.ring.position.set(shock.x, RING_HEIGHT, shock.z)\n pair.ring.scale.setScalar(shock.ringScale)\n pair.ringAlpha.value = shock.ringAlpha\n }\n for (let index = shocks.length; index < pairs.length; index++) pairs[index]!.shell.visible = pairs[index]!.ring.visible = false\n return shocks.length\n },\n dispose() {\n for (const pair of pairs) {\n ;(pair.shell.material as THREE_NS.Material).dispose()\n ;(pair.ring.material as THREE_NS.Material).dispose()\n }\n shellGeometry.dispose()\n ringGeometry.dispose()\n },\n }\n}\n","/** The soft round point sprite of the game's sprite kinds (moved verbatim from the destruction renderer's particles). */\nexport const SPRITE_VERTEX = `\nuniform float uScale;\nattribute float size;\nattribute float alpha;\nattribute vec3 pcolor;\nvarying float vAlpha;\nvarying vec3 vColor;\nvoid main() {\n vAlpha = alpha;\n vColor = pcolor;\n vec4 mv = modelViewMatrix * vec4(position, 1.0);\n gl_PointSize = min(size * uScale / max(0.1, -mv.z), 256.0);\n gl_Position = projectionMatrix * mv;\n}`\n\nexport const SPRITE_FRAGMENT = `\nvarying float vAlpha;\nvarying vec3 vColor;\nvoid main() {\n float d = length(gl_PointCoord - vec2(0.5)) * 2.0;\n float a = (1.0 - smoothstep(0.35, 1.0, d)) * vAlpha;\n if (a < 0.004) discard;\n gl_FragColor = vec4(vColor, a);\n}`\n","import type * as THREE_NS from 'three'\nimport type { SpriteKindPool, SpriteKindSystem } from '@adatechnology/game-vfx'\nimport { SPRITE_FRAGMENT, SPRITE_VERTEX } from './shaders/sprite'\nimport type { ThreeLib } from './types'\n\nexport interface SpriteLayer {\n readonly additive: THREE_NS.Points\n readonly normal: THREE_NS.Points\n /** Tells the GPU what changed and answers how many sprites are drawn. */\n sync(): number\n dispose(): void\n}\n\ninterface Drawn {\n readonly points: THREE_NS.Points\n sync(): number\n dispose(): void\n}\n\nfunction drawPool(THREE: ThreeLib, pool: SpriteKindPool, additive: boolean, pointScale: number): Drawn {\n const geometry = new THREE.BufferGeometry()\n const attributes: [string, Float32Array, number][] = [['position', pool.position, 3], ['pcolor', pool.color, 3], ['alpha', pool.alpha, 1], ['size', pool.size, 1]]\n const buffers = attributes.map(([name, array, size]) => {\n const attribute = new THREE.BufferAttribute(array, size).setUsage(THREE.DynamicDrawUsage)\n geometry.setAttribute(name, attribute)\n return attribute\n })\n geometry.setDrawRange(0, 0)\n const material = new THREE.ShaderMaterial({\n uniforms: { uScale: { value: pointScale } },\n vertexShader: SPRITE_VERTEX,\n fragmentShader: SPRITE_FRAGMENT,\n transparent: true,\n depthWrite: false,\n blending: additive ? THREE.AdditiveBlending : THREE.NormalBlending,\n })\n const points = new THREE.Points(geometry, material)\n points.frustumCulled = false\n points.name = additive ? 'vfx-sprites-additive' : 'vfx-sprites'\n points.renderOrder = additive ? 11 : 10\n return {\n points,\n sync() {\n geometry.setDrawRange(0, pool.drawCount)\n for (const buffer of buffers) buffer.needsUpdate = true\n return pool.drawCount\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\n/** Draws the game's sprite kinds (debris, sparks, smoke, steam, drips...) as two soft point layers, additive and normal. */\nexport function createSpriteLayer(THREE: ThreeLib, system: SpriteKindSystem, pointScale: number): SpriteLayer {\n const additive = drawPool(THREE, system.additive, true, pointScale)\n const normal = drawPool(THREE, system.normal, false, pointScale)\n return {\n additive: additive.points,\n normal: normal.points,\n sync: () => additive.sync() + normal.sync(),\n dispose() {\n additive.dispose()\n normal.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { MeshParticle, MeshPool } from '@adatechnology/game-vfx'\nimport type { ThreeLib } from './types'\n\nconst SPHERE_DEFAULT_WIDTH = 8\nconst SPHERE_DEFAULT_HEIGHT = 6\n\nexport interface MeshLayer {\n readonly group: THREE_NS.Group\n /** Puts a mesh on every live solid particle and takes it off the ones that ended; answers how many are drawn. */\n sync(): number\n dispose(): void\n}\n\nfunction geometryOf(THREE: ThreeLib, particle: MeshParticle): THREE_NS.BufferGeometry {\n switch (particle.shape) {\n case 'cone': return new THREE.ConeGeometry(particle.radius, particle.height, particle.segments || undefined, particle.segments2 || 1, false)\n case 'cone_open': return new THREE.ConeGeometry(particle.radius, particle.height, particle.segments || undefined, particle.segments2 || 1, true)\n case 'sphere': return new THREE.SphereGeometry(particle.radius, particle.segments || SPHERE_DEFAULT_WIDTH, particle.segments2 || SPHERE_DEFAULT_HEIGHT)\n case 'icosahedron': return new THREE.IcosahedronGeometry(particle.radius, particle.segments)\n }\n}\n\n/** The materials the gallery gives these: a flat, translucent colour (added to what is behind it for a flash), or a rough grey that the scene's lights shade (smoke). */\nfunction materialOf(THREE: ThreeLib, particle: MeshParticle): THREE_NS.Material {\n if (particle.lit) return new THREE.MeshStandardMaterial({ color: particle.color, roughness: 1, metalness: 0, transparent: true, opacity: particle.opacity, depthWrite: false })\n return new THREE.MeshBasicMaterial({ color: particle.color, transparent: true, opacity: particle.opacity, depthWrite: false, ...(particle.additive ? { blending: THREE.AdditiveBlending } : {}) })\n}\n\n/**\n * The Workshop's solid particles (`MeshPool`) as three.js meshes, one each, like the gallery: the geometry and the material belong to the mesh and go with it. A mesh sits at\n * the group's point plus the group's turn applied to the piece's place times the scale, turned by the group's turn and then by the piece's own Euler angles.\n */\nexport function createMeshLayer(THREE: ThreeLib, pool: MeshPool): MeshLayer {\n const group = new THREE.Group()\n group.name = 'workshop-meshes'\n const drawn = new Map<number, THREE_NS.Mesh>()\n const frame = new THREE.Quaternion()\n const euler = new THREE.Euler()\n const turn = new THREE.Quaternion()\n const offset = new THREE.Vector3()\n\n function release(mesh: THREE_NS.Mesh): void {\n mesh.removeFromParent()\n mesh.geometry.dispose()\n ;(mesh.material as THREE_NS.Material).dispose()\n }\n\n return {\n group,\n sync() {\n const live = new Set<number>()\n for (const particle of pool.particles) {\n live.add(particle.id)\n let mesh = drawn.get(particle.id)\n if (!mesh) {\n mesh = new THREE.Mesh(geometryOf(THREE, particle), materialOf(THREE, particle))\n mesh.frustumCulled = false\n mesh.renderOrder = particle.additive ? 5 : 3\n drawn.set(particle.id, mesh)\n group.add(mesh)\n }\n frame.set(particle.frame[0], particle.frame[1], particle.frame[2], particle.frame[3])\n offset.set(particle.at[0], particle.at[1], particle.at[2]).multiplyScalar(particle.scale).applyQuaternion(frame)\n mesh.position.set(particle.x + offset.x, particle.y + offset.y, particle.z + offset.z)\n turn.setFromEuler(euler.set(particle.rx, particle.ry, particle.rz))\n mesh.quaternion.copy(frame).multiply(turn)\n mesh.scale.setScalar(particle.scale)\n ;(mesh.material as THREE_NS.Material).opacity = particle.opacity\n }\n for (const [id, mesh] of drawn) {\n if (live.has(id)) continue\n release(mesh)\n drawn.delete(id)\n }\n return pool.count\n },\n dispose() {\n for (const mesh of drawn.values()) release(mesh)\n drawn.clear()\n group.removeFromParent()\n },\n }\n}\n","/** The Workshop's soft point sprite (W168-171): the size is in metres, clamped to 1..512 px; `uSoft` is 1 for the soft (normal blend) pool. */\nexport const WORKSHOP_SPRITE_VERTEX = `attribute float size;attribute float alpha;attribute vec3 pcol;varying vec3 vC;varying float vA;uniform float uScale;\nvoid main(){vC=pcol;vA=alpha;vec4 mv=modelViewMatrix*vec4(position,1.);gl_PointSize=clamp(size*uScale/-mv.z,1.,512.);gl_Position=projectionMatrix*mv;}`\n\nexport const WORKSHOP_SPRITE_FRAGMENT = `uniform float uSoft;varying vec3 vC;varying float vA;\nvoid main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a=mix(smoothstep(1.,.78,r),pow(1.-r,1.5),uSoft);gl_FragColor=vec4(vC,vA*a);}`\n","import type * as THREE_NS from 'three'\nimport type { Decal, WorkshopEngine } from '@adatechnology/game-vfx'\nimport { createMeshLayer } from './mesh-layer'\nimport { WORKSHOP_SPRITE_FRAGMENT, WORKSHOP_SPRITE_VERTEX } from './shaders/workshop-sprite'\nimport type { ThreeLib } from './types'\n\nconst DEBRIS_CAPACITY = 500\nconst DECAL_CAPACITY = 400\nconst RING_CAPACITY = 120\nconst RIPPLE_SEGMENTS = 12\nconst FADE_SECONDS = 0.5\nconst FIRE_LIGHT_COLOR = 0xff7a2a\nconst FIRE_LIGHT_DISTANCE = 14\nconst GLOSS_DRIED_AT = 0.85\nconst BROWN = 0x2a1610\nconst GROUND_COLOR = 0x888888\nconst FUEL_DRIED = 0x888888\n\nexport interface WorkshopLayers {\n readonly group: THREE_NS.Group\n /** Copies the pools into the draw buffers; answers how many draw calls have something to draw. */\n sync(): number\n dispose(): void\n}\n\ninterface Drawn {\n readonly object: THREE_NS.Object3D\n sync(): boolean\n dispose(): void\n}\n\nconst clamp = (v: number, lo: number, hi: number): number => (v < lo ? lo : v > hi ? hi : v)\n\nfunction spriteLayer(THREE: ThreeLib, pool: WorkshopEngine['add'], additive: boolean, soft: number, scale: number): Drawn {\n const geometry = new THREE.BufferGeometry()\n const arrays: [string, Float32Array, number][] = [['position', pool.position, 3], ['pcol', pool.color, 3], ['size', pool.size, 1], ['alpha', pool.alpha, 1]]\n const buffers = arrays.map(([name, array, size]) => {\n const attribute = new THREE.BufferAttribute(array, size).setUsage(THREE.DynamicDrawUsage)\n geometry.setAttribute(name, attribute)\n return attribute\n })\n geometry.setDrawRange(0, 0)\n const material = new THREE.ShaderMaterial({\n uniforms: { uScale: { value: scale }, uSoft: { value: soft } },\n vertexShader: WORKSHOP_SPRITE_VERTEX,\n fragmentShader: WORKSHOP_SPRITE_FRAGMENT,\n transparent: true,\n depthWrite: false,\n blending: additive ? THREE.AdditiveBlending : THREE.NormalBlending,\n })\n const points = new THREE.Points(geometry, material)\n points.frustumCulled = false\n points.renderOrder = additive ? 3 : 2\n points.name = additive ? 'workshop-add' : 'workshop-normal'\n return {\n object: points,\n sync() {\n geometry.setDrawRange(0, pool.count)\n for (const buffer of buffers) buffer.needsUpdate = true\n return pool.count > 0\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\nfunction streakLayer(THREE: ThreeLib, pool: WorkshopEngine['streaks']): Drawn {\n const geometry = new THREE.BufferGeometry()\n const position = new THREE.BufferAttribute(pool.segment, 3).setUsage(THREE.DynamicDrawUsage)\n const color = new THREE.BufferAttribute(pool.segmentColor, 3).setUsage(THREE.DynamicDrawUsage)\n geometry.setAttribute('position', position)\n geometry.setAttribute('color', color)\n geometry.setDrawRange(0, 0)\n const material = new THREE.LineBasicMaterial({ vertexColors: true, transparent: true, blending: THREE.AdditiveBlending, depthWrite: false })\n const lines = new THREE.LineSegments(geometry, material)\n lines.frustumCulled = false\n lines.renderOrder = 4\n lines.name = 'workshop-streaks'\n return {\n object: lines,\n sync() {\n geometry.setDrawRange(0, pool.count * 2)\n position.needsUpdate = color.needsUpdate = true\n return pool.count > 0\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\n/** The Workshop's rain (W317-320): one line segment per streak, pale blue, 35% opaque. */\nfunction rainLayer(THREE: ThreeLib, rain: WorkshopEngine['rain']): Drawn {\n const geometry = new THREE.BufferGeometry()\n const position = new THREE.BufferAttribute(rain.positions, 3).setUsage(THREE.DynamicDrawUsage)\n geometry.setAttribute('position', position)\n geometry.setDrawRange(0, 0)\n const material = new THREE.LineBasicMaterial({ color: 0x9fb3cf, transparent: true, opacity: 0.35, depthWrite: false })\n const lines = new THREE.LineSegments(geometry, material)\n lines.frustumCulled = false\n lines.name = 'workshop-rain'\n return {\n object: lines,\n sync() {\n const drawn = rain.on && rain.count > 0\n lines.visible = drawn\n geometry.setDrawRange(0, drawn ? rain.count * 2 : 0)\n position.needsUpdate = true\n return drawn\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\nfunction debrisLayer(THREE: ThreeLib, pool: WorkshopEngine['debris']): Drawn {\n const geometry = new THREE.BoxGeometry(1, 1, 1)\n const material = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0.45, metalness: 0.25, flatShading: true })\n const mesh = new THREE.InstancedMesh(geometry, material, DEBRIS_CAPACITY)\n mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)\n mesh.frustumCulled = false\n mesh.name = 'workshop-debris'\n const euler = new THREE.Euler()\n const quaternion = new THREE.Quaternion()\n const position = new THREE.Vector3()\n const scale = new THREE.Vector3()\n const matrix = new THREE.Matrix4()\n const colour = new THREE.Color()\n const hidden = new THREE.Matrix4().makeScale(0, 0, 0)\n for (let index = 0; index < DEBRIS_CAPACITY; index++) mesh.setMatrixAt(index, hidden)\n mesh.setColorAt(0, colour.setHex(0xffffff))\n return {\n object: mesh,\n sync() {\n let drawn = false\n for (let index = 0; index < DEBRIS_CAPACITY; index++) {\n const piece = pool.pieces[index]!\n if (!piece.on) {\n mesh.setMatrixAt(index, hidden)\n continue\n }\n drawn = true\n const shrink = Math.min(1, piece.life / FADE_SECONDS)\n euler.set(piece.rx, piece.ry, piece.rz)\n quaternion.setFromEuler(euler)\n matrix.compose(position.set(piece.x, piece.y, piece.z), quaternion, scale.set(piece.sx * shrink, piece.sy * shrink, piece.sz * shrink))\n mesh.setMatrixAt(index, matrix)\n mesh.setColorAt(index, colour.setHex(piece.color))\n }\n mesh.instanceMatrix.needsUpdate = true\n if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true\n return drawn\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\n/** A decal's current look from its fields (W276-306): it grows, a wet one creeps, dries towards its dry colour or evaporates. */\nfunction decalLook(decal: Decal, colour: THREE_NS.Color, dryColour: THREE_NS.Color, brown: THREE_NS.Color, ground: THREE_NS.Color, index: number): { sx: number; sy: number; dried: boolean } | null {\n const grown = decal.grow > 0 ? 1 - Math.pow(1 - Math.min(1, decal.t / decal.grow), 2.4) : 1\n let sx = decal.sx * grown\n let sy = decal.sy * grown\n colour.setHex(decal.color)\n let dried = false\n const fluid = decal.fluid\n if (fluid) {\n const creep = fluid === 'oil' ? 0.5 : fluid === 'fuel' ? 0.7 : fluid === 'bile' ? 0.25 : fluid === 'water' ? 0.2 : 0.3\n const age = decal.t\n if (decal.dryTime > 0) {\n const k = clamp((age - decal.dryAt) / decal.dryTime, 0, 1)\n if (decal.dryColor >= 0) dryColour.setHex(decal.dryColor)\n else dryColour.copy(colour).multiplyScalar(0.45).lerp(brown, 0.45)\n dried = k > GLOSS_DRIED_AT\n const spread = dried ? 1 + creep : 1 + creep * (1 - Math.exp(-age / 6))\n sx *= dried ? spread : spread * (1 + 0.04 * Math.sin(age * 1.9 + index))\n sy *= dried ? spread : spread * (1 + 0.04 * Math.cos(age * 1.5 + index * 0.7))\n colour.lerp(dryColour, k)\n } else {\n const spread = 1 + creep * (1 - Math.exp(-age / 6))\n sx *= spread * (1 + 0.04 * Math.sin(age * 1.9 + index))\n sy *= spread * (1 + 0.04 * Math.cos(age * 1.5 + index * 0.7))\n if (fluid === 'fuel' || fluid === 'water') {\n const [wait, span] = fluid === 'fuel' ? [6, 5] : [40, 20]\n const gone = clamp((age - wait) / span, 0, 1)\n sx *= 1 - gone * 0.85\n sy *= 1 - gone * 0.85\n colour.lerp(ground.setHex(fluid === 'fuel' ? FUEL_DRIED : GROUND_COLOR), gone * 0.8)\n if (gone >= 1) return null\n }\n }\n }\n return { sx, sy, dried }\n}\n\nfunction decalLayer(THREE: ThreeLib, pool: WorkshopEngine['decals']): Drawn {\n const geometry = new THREE.CircleGeometry(0.5, RIPPLE_SEGMENTS)\n const positions = geometry.getAttribute('position')\n // a blob, not a disc: each rim vertex is pulled in by a fixed amount between .72 and 1.12\n for (let index = 1; index < positions.count; index++) {\n const k = 0.72 + (((index * 2654435761) >>> 0) / 4294967296) * 0.4\n positions.setXY(index, positions.getX(index) * k, positions.getY(index) * k)\n }\n const wet = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0.1, metalness: 0.3, polygonOffset: true, polygonOffsetFactor: -4, polygonOffsetUnits: -4 })\n const dry = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 1, metalness: 0, flatShading: true, polygonOffset: true, polygonOffsetFactor: -4, polygonOffsetUnits: -4 })\n const wetMesh = new THREE.InstancedMesh(geometry, wet, DECAL_CAPACITY)\n const dryMesh = new THREE.InstancedMesh(geometry, dry, DECAL_CAPACITY)\n const group = new THREE.Group()\n group.name = 'workshop-decals'\n for (const mesh of [wetMesh, dryMesh]) {\n mesh.frustumCulled = false\n mesh.renderOrder = 1\n mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)\n group.add(mesh)\n }\n const hidden = new THREE.Matrix4().makeScale(0, 0, 0)\n const colour = new THREE.Color()\n const dryColour = new THREE.Color()\n const brown = new THREE.Color(BROWN)\n const ground = new THREE.Color()\n const normal = new THREE.Vector3()\n const forward = new THREE.Vector3(0, 0, 1)\n const turn = new THREE.Quaternion()\n const quaternion = new THREE.Quaternion()\n const position = new THREE.Vector3()\n const scale = new THREE.Vector3()\n const matrix = new THREE.Matrix4()\n wetMesh.setColorAt(0, colour.setHex(0))\n dryMesh.setColorAt(0, colour.setHex(0))\n for (let index = 0; index < DECAL_CAPACITY; index++) {\n wetMesh.setMatrixAt(index, hidden)\n dryMesh.setMatrixAt(index, hidden)\n }\n return {\n object: group,\n sync() {\n let drawn = false\n for (let index = 0; index < DECAL_CAPACITY; index++) {\n const decal = pool.decals[index]!\n wetMesh.setMatrixAt(index, hidden)\n dryMesh.setMatrixAt(index, hidden)\n if (!decal.on || decal.t < 0) continue\n const look = decalLook(decal, colour, dryColour, brown, ground, index)\n if (!look) continue\n drawn = true\n normal.set(decal.normal[0], decal.normal[1], decal.normal[2])\n quaternion.setFromUnitVectors(forward, normal)\n quaternion.multiply(turn.setFromAxisAngle(forward, index * 2.399963))\n const offset = 0.004 + (index % 40) * 0.0004\n matrix.compose(position.set(decal.x + normal.x * offset, decal.y + normal.y * offset, decal.z + normal.z * offset), quaternion, scale.set(look.sx, look.sy, 1))\n const mesh = look.dried ? dryMesh : wetMesh\n mesh.setMatrixAt(index, matrix)\n mesh.setColorAt(index, colour)\n }\n for (const mesh of [wetMesh, dryMesh]) {\n mesh.instanceMatrix.needsUpdate = true\n if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true\n }\n return drawn\n },\n dispose() {\n geometry.dispose()\n wet.dispose()\n dry.dispose()\n },\n }\n}\n\nfunction ringLayer(THREE: ThreeLib, pool: WorkshopEngine['rings']): Drawn {\n const geometry = new THREE.RingGeometry(0.86, 1, 40)\n const material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true, blending: THREE.AdditiveBlending, depthWrite: false, side: THREE.DoubleSide })\n const mesh = new THREE.InstancedMesh(geometry, material, RING_CAPACITY)\n mesh.frustumCulled = false\n mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)\n mesh.name = 'workshop-rings'\n const hidden = new THREE.Matrix4().makeScale(0, 0, 0)\n const colour = new THREE.Color()\n const normal = new THREE.Vector3()\n const forward = new THREE.Vector3(0, 0, 1)\n const quaternion = new THREE.Quaternion()\n const position = new THREE.Vector3()\n const scale = new THREE.Vector3()\n const matrix = new THREE.Matrix4()\n mesh.setColorAt(0, colour.setHex(0))\n for (let index = 0; index < RING_CAPACITY; index++) mesh.setMatrixAt(index, hidden)\n return {\n object: mesh,\n sync() {\n let drawn = false\n for (let index = 0; index < RING_CAPACITY; index++) {\n const ring = pool.rings[index]!\n if (!ring.on) {\n mesh.setMatrixAt(index, hidden)\n continue\n }\n drawn = true\n const k = Math.min(1, ring.t / ring.duration)\n const radius = ring.from + (ring.to - ring.from) * (1 - Math.pow(1 - k, 2))\n quaternion.setFromUnitVectors(forward, normal.set(ring.normal[0], ring.normal[1], ring.normal[2]))\n matrix.compose(position.set(ring.point[0], ring.point[1], ring.point[2]), quaternion, scale.set(radius, radius, 1))\n mesh.setMatrixAt(index, matrix)\n mesh.setColorAt(index, colour.setHex(ring.color).multiplyScalar(ring.hold ? ring.hold : 1 - k))\n }\n mesh.instanceMatrix.needsUpdate = true\n if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true\n return drawn\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n },\n }\n}\n\n/**\n * Draws the pools of the world's Workshop engine (what `world.play` fills): the two sprite systems, the streaks, the physics debris, the decals, the\n * expanding rings and the flash and fire lights, with the page's shaders and materials.\n */\nexport function createWorkshopLayers(THREE: ThreeLib, engine: WorkshopEngine, pointScale: number, lightScale: number): WorkshopLayers {\n const group = new THREE.Group()\n group.name = 'workshop'\n const layers: Drawn[] = [\n spriteLayer(THREE, engine.add, true, 1, pointScale),\n spriteLayer(THREE, engine.normal, false, 0.55, pointScale),\n streakLayer(THREE, engine.streaks),\n rainLayer(THREE, engine.rain),\n debrisLayer(THREE, engine.debris),\n decalLayer(THREE, engine.decals),\n ringLayer(THREE, engine.rings),\n ]\n for (const layer of layers) group.add(layer.object)\n const meshes = createMeshLayer(THREE, engine.meshes)\n group.add(meshes.group)\n const flashLights = engine.lights.lights.map(() => new THREE.PointLight(0xffc070, 0, 14))\n const fireLights = engine.lights.fire.map(() => new THREE.PointLight(FIRE_LIGHT_COLOR, 0, FIRE_LIGHT_DISTANCE))\n for (const light of [...flashLights, ...fireLights]) group.add(light)\n return {\n group,\n sync() {\n let drawCalls = 0\n for (const layer of layers) if (layer.sync()) drawCalls++\n drawCalls += meshes.sync()\n engine.lights.lights.forEach((source, index) => {\n const light = flashLights[index]!\n light.position.set(source.x, source.y, source.z)\n light.color.setHex(source.color)\n light.distance = source.distance\n light.intensity = source.intensity * lightScale\n })\n engine.lights.fire.forEach((source, index) => {\n const light = fireLights[index]!\n light.position.set(source.x, source.y, source.z)\n light.intensity = source.intensity * lightScale\n })\n return drawCalls\n },\n dispose() {\n for (const layer of layers) layer.dispose()\n meshes.dispose()\n group.clear()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { ControlValue } from '@adatechnology/game-contracts'\nimport { colorOfChunk, createVfx, hexToLinearRgb } from '@adatechnology/game-vfx'\nimport type { ScreenState, VfxWorld, WorkshopEngine } from '@adatechnology/game-vfx'\nimport { createChunkLayer, createGlowLayer, createPuffLayer, createSparkLayer } from './instanced'\nimport type { PuffUniforms } from './instanced'\nimport { createLightLayer } from './lights'\nimport { createMarkLayer } from './marks'\nimport { createScreenOverlay } from './screen-overlay'\nimport { createShockLayer } from './shocks'\nimport { createSpriteLayer } from './sprites'\nimport type { ThreeLib, VfxRenderer, VfxRendererOptions } from './types'\nimport { createWorkshopLayers } from './workshop-layers'\nimport type { WorkshopLayers } from './workshop-layers'\n\nconst LAB_LIGHT_DIRECTION = [-14, 26, 12] as const\nconst SKY_COLOR = 0x6f7c92\nconst GROUND_COLOR = 0x2a241f\nconst LOD_BANDS: Readonly<Record<string, number | null>> = { auto: null, near: 1, middle: 0.5, far: 0.2 }\n/** The quality names the bench offers, as the Workshop's levels (0 keeps every particle). */\nconst QUALITY_LEVELS: Readonly<Record<string, number>> = { high: 0, medium: 1, low: 2 }\n/** `configure({ layer_<id>: false })` hides a layer of the renderer: `puffs`, `sparks`, `glows`, `debris`, `shock`, `sprites`. */\nexport const VFX_LAYERS = ['puffs', 'sparks', 'glows', 'debris', 'shock', 'sprites'] as const\nconst LAYER_PREFIX = 'layer_'\nconst SHAKE_REACH = 0.18\nconst SHAKE_FLOOR = 0.001\n\nfunction isWorld(value: unknown): value is VfxWorld {\n return typeof value === 'object' && value !== null && 'explosion' in value && typeof (value as VfxWorld).explosion === 'function'\n}\n\n/** The overlay shows the Lab's screen and the Workshop's together: the stronger of each field. */\nfunction mergeScreens(lab: ScreenState, workshop: ScreenState | undefined): ScreenState {\n if (!workshop) return lab\n const merged = { ...lab }\n for (const key of Object.keys(lab) as (keyof ScreenState)[]) merged[key] = Math.max(lab[key], workshop[key])\n return merged\n}\n\nfunction prefersReducedMotion(): boolean {\n return typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches\n}\n\n/** Draws a `VfxWorld`: the Lab's shaders, debris, shock, lights, marks and the screen overlay, and plays effects asked of it by id (`EffectSink`). */\nexport function createVfxRenderer(THREE: ThreeLib, options: VfxRendererOptions): VfxRenderer {\n const reducedMotion = options.reducedMotion ?? prefersReducedMotion()\n const requested = options.vfx\n const world = isWorld(requested) ? requested : createVfx({ profile: options.quality ?? 'medium', reducedMotion, ...requested })\n const pools = world.pools()\n const root = new THREE.Group()\n options.scene.add(root)\n\n const direction = new THREE.Vector3(...(options.lightDirection ?? LAB_LIGHT_DIRECTION)).normalize()\n const sky = hexToLinearRgb(SKY_COLOR)\n const ground = hexToLinearRgb(GROUND_COLOR)\n const uniforms: PuffUniforms = {\n uLight: { value: direction },\n uSky: { value: new THREE.Vector3(sky[0] * 0.55, sky[1] * 0.55, sky[2] * 0.55) },\n uGround: { value: new THREE.Vector3(ground[0] * 0.6, ground[1] * 0.6, ground[2] * 0.6) },\n uGlowPos: { value: new THREE.Vector3() },\n uGlowCol: { value: new THREE.Vector3(1, 0.5, 0.2) },\n uGlowI: { value: 0 },\n uTime: { value: 0 },\n }\n const puffs = createPuffLayer(THREE, pools.puffs, uniforms)\n const sparks = createSparkLayer(THREE, pools.sparks)\n const glows = createGlowLayer(THREE, pools.glows)\n const rockGeometry = new THREE.DodecahedronGeometry(0.5, 0)\n const plateGeometry = new THREE.BoxGeometry(1, 1, 1)\n const chunks = createChunkLayer(THREE, pools.chunks, { rock: rockGeometry, plate: plateGeometry }, colorOfChunk)\n const shocks = createShockLayer(THREE, pools.shocks)\n const sprites = createSpriteLayer(THREE, world.sprites(), options.pointScale ?? 700)\n const lights = createLightLayer(THREE, pools.lights, options.lightScale ?? Math.PI)\n const marks = createMarkLayer(THREE, { ground: pools.ground, createCanvas: options.createCanvas, rockGeometry, plateGeometry })\n root.add(puffs.mesh, sparks.mesh, glows.mesh, chunks.rocks, chunks.plates, shocks.group, lights.group, sprites.additive, sprites.normal, marks.group)\n const stopMarks = world.onMarks((event) => marks.handle(event))\n const overlay = options.overlay ? createScreenOverlay(options.overlay) : undefined\n let drawCalls = 0\n let workshopLayers: WorkshopLayers | undefined\n let workshopEngine: WorkshopEngine | undefined\n const layerOn = new Map<string, boolean>()\n const layerObjects = (): Record<string, THREE_NS.Object3D[]> => ({\n puffs: [puffs.mesh],\n sparks: [sparks.mesh],\n glows: [glows.mesh],\n debris: [chunks.rocks, chunks.plates],\n shock: [shocks.group],\n sprites: [sprites.additive, sprites.normal, ...(workshopLayers ? [workshopLayers.group] : [])],\n })\n const applyLayers = (): void => {\n for (const [id, objects] of Object.entries(layerObjects())) for (const object of objects) object.visible = layerOn.get(id) !== false\n }\n const screenNow = (): ScreenState => mergeScreens(world.screen(), world.peekWorkshop()?.screen)\n let clock = 0\n const lastDrawn = { puffs: 0, sparks: 0, glows: 0, chunks: 0, shocks: 0, sprites: 0 }\n\n function followCamera(): void {\n const position = options.camera.position\n world.setCamera([position.x, position.y, position.z])\n }\n\n function syncAll(): void {\n lastDrawn.puffs = puffs.sync()\n lastDrawn.sparks = sparks.sync()\n lastDrawn.glows = glows.sync()\n lastDrawn.chunks = chunks.sync()\n lastDrawn.shocks = shocks.sync()\n lastDrawn.sprites = sprites.sync()\n lights.sync()\n const engine = world.peekWorkshop()\n if (engine && engine !== workshopEngine) {\n workshopLayers?.dispose()\n if (workshopLayers) root.remove(workshopLayers.group)\n workshopEngine = engine\n workshopLayers = createWorkshopLayers(THREE, engine, options.pointScale ?? 700, 1)\n root.add(workshopLayers.group)\n applyLayers()\n }\n const workshopCalls = workshopLayers?.sync() ?? 0\n const glow = pools.lights.glow\n uniforms.uGlowPos.value.set(glow.x, glow.y, glow.z)\n uniforms.uGlowCol.value.set(glow.color[0], glow.color[1], glow.color[2])\n uniforms.uGlowI.value = glow.intensity\n drawCalls = Number(lastDrawn.puffs > 0) + Number(lastDrawn.sparks > 0) + Number(lastDrawn.glows > 0) + Number(chunks.rocks.count > 0) + Number(chunks.plates.count > 0) + Number(sprites.additive.geometry.drawRange.count > 0) + Number(sprites.normal.geometry.drawRange.count > 0) + lastDrawn.shocks * 2 + marks.count() + workshopCalls\n }\n\n return {\n world,\n play(request) {\n followCamera()\n const explosion = world.explosion(request.effect, request.point, {\n ...(request.direction ? { direction: request.direction } : {}),\n ...(request.seed !== undefined ? { seed: request.seed } : {}),\n ...(request.scale !== undefined ? { scale: request.scale } : {}),\n })\n if (explosion !== null) return explosion\n return world.play(request.effect, request.point, {\n ...(request.direction ? { direction: request.direction } : {}),\n ...(request.normal ? { normal: request.normal } : {}),\n ...(request.orientation ? { orientation: request.orientation } : {}),\n ...(request.seed !== undefined ? { seed: request.seed } : {}),\n ...(request.param !== undefined ? { param: request.param } : {}),\n ...(request.values ? { values: request.values } : {}),\n })\n },\n stop: (handle) => world.stop(handle),\n configure(settings: Readonly<Record<string, ControlValue>>) {\n const band = settings.lod_band\n if (typeof band === 'string' && band in LOD_BANDS) world.forceLod(LOD_BANDS[band] ?? null)\n const quality = settings.quality\n if (typeof quality === 'string' && quality in QUALITY_LEVELS) world.workshop().setQuality(QUALITY_LEVELS[quality] ?? 0)\n let layersChanged = false\n for (const [key, value] of Object.entries(settings)) {\n if (!key.startsWith(LAYER_PREFIX) || typeof value !== 'boolean') continue\n layerOn.set(key.slice(LAYER_PREFIX.length), value)\n layersChanged = true\n }\n if (layersChanged) applyLayers()\n },\n catalog: () => [...world.catalog(), ...world.effectIds()],\n update(dt) {\n clock += dt\n uniforms.uTime.value = clock\n followCamera()\n world.update(dt)\n marks.update(dt)\n syncAll()\n overlay?.update(screenNow())\n },\n applyCamera() {\n const shake = screenNow().shake\n if (reducedMotion || !(shake > SHAKE_FLOOR)) return () => {}\n const camera = options.camera as THREE_NS.Camera\n const base = camera.position.clone()\n const reach = shake * SHAKE_REACH\n camera.position.x += Math.sin(clock * 71) * reach\n camera.position.y += Math.sin(clock * 53 + 1) * reach * 0.7\n camera.position.z += Math.sin(clock * 67 + 2) * reach\n return () => camera.position.copy(base)\n },\n stats() {\n const { lastBlast, ...counters } = world.stats()\n return { ...counters, last_puffs: lastBlast.puffs, last_sparks: lastBlast.sparks, last_chunks: lastBlast.chunks, last_lights: lastBlast.lights, drawCalls }\n },\n screen: screenNow,\n dispose() {\n stopMarks()\n overlay?.dispose()\n workshopLayers?.dispose()\n for (const layer of [puffs, sparks, glows, chunks, shocks, lights, marks, sprites]) layer.dispose()\n rockGeometry.dispose()\n plateGeometry.dispose()\n options.scene.remove(root)\n },\n }\n}\n","/** The words of the effects bench, per locale (the effects' own texts live in `@adatechnology/game-vfx`). */\nexport interface BenchText {\n readonly module: string\n readonly controls: Readonly<Record<'effect' | 'variant' | 'replay' | 'auto_repeat' | 'distance' | 'lod_band' | 'quality', string>>\n readonly lod: Readonly<Record<'auto' | 'near' | 'middle' | 'far', string>>\n readonly quality: Readonly<Record<'high' | 'medium' | 'low', string>>\n readonly layers: Readonly<Record<'puffs' | 'sparks' | 'glows' | 'debris' | 'shock' | 'sprites', string>>\n readonly metrics: Readonly<Record<'puffs' | 'sparks' | 'debris' | 'lights' | 'budget_particles' | 'lod' | 'phase' | 'blast_time', string>>\n readonly sheet: Readonly<Record<'explosion' | 'lethal' | 'injury' | 'radius' | 'fireballs' | 'particles' | 'scale', string>>\n readonly none: string\n}\n\nexport const benchTexts: Readonly<Record<string, BenchText>> = {\n en: {\n module: 'Effects',\n controls: { effect: 'Effect', variant: 'Variant', replay: 'Replay', auto_repeat: 'Auto replay', distance: 'Distance', lod_band: 'LOD band', quality: 'Quality' },\n lod: { auto: 'Auto', near: 'Near', middle: 'Middle', far: 'Far' },\n quality: { high: 'High', medium: 'Medium', low: 'Low' },\n layers: { puffs: 'Smoke and fire', sparks: 'Sparks', glows: 'Glows', debris: 'Debris', shock: 'Shock wave', sprites: 'Droplets and recipes' },\n metrics: { puffs: 'Puffs', sparks: 'Sparks', debris: 'Debris', lights: 'Lights', budget_particles: 'Particles of the effect', lod: 'LOD scale', phase: 'Time since replay', blast_time: 'Time since the blast' },\n sheet: { explosion: 'Explosion', lethal: 'Lethal radius', injury: 'Injury radius', radius: 'Fireball', fireballs: 'Fireballs', particles: 'Particles', scale: 'Scale' },\n none: 'None',\n },\n 'pt-BR': {\n module: 'Efeitos',\n controls: { effect: 'Efeito', variant: 'Variante', replay: 'Repetir', auto_repeat: 'Repetição automática', distance: 'Distância', lod_band: 'Faixa de LOD', quality: 'Qualidade' },\n lod: { auto: 'Automático', near: 'Perto', middle: 'Meio', far: 'Longe' },\n quality: { high: 'Alta', medium: 'Média', low: 'Baixa' },\n layers: { puffs: 'Fumaça e fogo', sparks: 'Faíscas', glows: 'Brilhos', debris: 'Destroços', shock: 'Onda de choque', sprites: 'Gotas e receitas' },\n metrics: { puffs: 'Nuvens', sparks: 'Faíscas', debris: 'Destroços', lights: 'Luzes', budget_particles: 'Partículas do efeito', lod: 'Escala de LOD', phase: 'Tempo desde a repetição', blast_time: 'Tempo desde a explosão' },\n sheet: { explosion: 'Explosão', lethal: 'Raio letal', injury: 'Raio de ferimento', radius: 'Bola de fogo', fireballs: 'Bolas de fogo', particles: 'Partículas', scale: 'Escala' },\n none: 'Nenhuma',\n },\n}\n\nexport const benchText = (locale: string): BenchText => benchTexts[locale] ?? benchTexts.en!\n","import type * as THREE_NS from \"three\";\nimport type {\n BenchChange,\n BenchSheet,\n ChoiceOption,\n EffectHandle,\n EffectSink,\n ModuleControl,\n ModuleHost,\n ModuleLayer,\n ModuleMetric,\n TestableModule,\n} from \"@adatechnology/game-contracts\";\nimport {\n EVENT_BUDGET,\n EXPLOSIONS,\n GAME_EFFECTS,\n estimateCost,\n resolveStrings,\n} from \"@adatechnology/game-vfx\";\nimport type { EffectDef, ExplosionDef } from \"@adatechnology/game-vfx\";\nimport { createVfxRenderer, VFX_LAYERS } from \"../renderer\";\nimport type { ThreeLib, VfxRenderer } from \"../types\";\nimport { benchText } from \"./text\";\n\nexport interface VfxTestModuleOptions {\n readonly locale?: string;\n /** The recipes the bench lists (default `GAME_EFFECTS`) and the explosions (default `EXPLOSIONS`). */\n readonly effects?: Readonly<Record<string, EffectDef>>;\n readonly explosions?: Readonly<Record<string, ExplosionDef>>;\n /** Seconds between two replays while `auto_repeat` is on. */\n readonly repeatSeconds?: number;\n}\n\nconst DEFAULT_EFFECT = \"m67\";\n/** The profile the Lab falls back to for an unknown explosive: not something to pick. */\nconst FALLBACK_EXPLOSION = \"generic\";\nconst NO_VARIANT = \"none\";\nconst BLAST_POINT: readonly [number, number, number] = [0, 0.1, 0];\nconst DEFAULT_DISTANCE = 14;\nconst DEFAULT_REPEAT_SECONDS = 4;\nconst LIGHT_BUDGET = EVENT_BUDGET.blastLights + EVENT_BUDGET.fireLights;\nconst SEGMENT_COLORS = [\"#ffb347\", \"#ff7a2a\", \"#8a8f98\", \"#5c6370\"] as const;\n\nconst TEAMS = [\n \"creatures\",\n \"weapons\",\n \"destruction\",\n \"world\",\n \"vehicles\",\n \"screen\",\n] as const;\nconst LAYER_ID = \"show_\";\n\nconst humanize = (id: string): string => id.replace(/_/g, \" \");\n\n/** Where the bench stands for a distance (m): a three-quarter view that keeps the blast in frame. */\nconst eyeFor = (distance: number): [number, number, number] => [\n distance * 0.6,\n distance * 0.35 + 1.4,\n distance * 0.8,\n];\n\n/** The tick marks and segments of a sheet's timeline: an explosion's flash, fireball and smoke, or a recipe's time. */\nfunction timelineOf(\n explosion: ExplosionDef | undefined,\n recipe: EffectDef | undefined,\n metric: string,\n): NonNullable<BenchSheet[\"timeline\"]> {\n if (explosion) {\n const flash = explosion.flash.life ?? 0.2;\n const smoke = Math.max(explosion.smoke.life, 1);\n return {\n segments: [\n { name: \"flash\", start: 0, end: flash, color: SEGMENT_COLORS[0] },\n {\n name: \"fireball\",\n start: 0,\n end: Math.min(smoke, 2.4),\n color: SEGMENT_COLORS[1],\n },\n { name: \"smoke\", start: 0.4, end: smoke, color: SEGMENT_COLORS[2] },\n ],\n ticks: Array.from({ length: Math.ceil(smoke) }, (_, index) => index + 1),\n metric,\n };\n }\n const span = recipe?.loop && recipe.loop > 0 ? recipe.loop : 4;\n return {\n segments: [\n { name: recipe?.id ?? \"\", start: 0, end: span, color: SEGMENT_COLORS[1] },\n ],\n ticks: Array.from({ length: Math.floor(span) }, (_, index) => index + 1),\n metric,\n };\n}\n\n/**\n * The effects bench: pick an explosion or a recipe (listed by team), its variant, the distance, the quality and the layers, replay it or let it repeat,\n * and watch the particle and light counters against the budget. It plays through `host.effects` (the room's world) and, in a host without one, draws\n * into a renderer of its own.\n */\nexport function createVfxTestModule(\n options: VfxTestModuleOptions = {},\n): TestableModule {\n const locale = options.locale ?? \"en\";\n const recipes = options.effects ?? GAME_EFFECTS;\n const explosions = options.explosions ?? EXPLOSIONS;\n const text = benchText(locale);\n const strings = resolveStrings(locale);\n\n const effectOptions = (): ChoiceOption[] => [\n ...Object.keys(explosions)\n .filter((id) => id !== FALLBACK_EXPLOSION)\n .map((id) => ({\n id,\n name: humanize(id),\n group: strings.groups.explosions ?? text.sheet.explosion,\n })),\n // an id the explosions already use is the explosion's: the sink tries the explosions first, so the recipe of the same name could not be reached\n ...TEAMS.flatMap((team) =>\n Object.values(recipes)\n .filter((def) => def.team === team && !(def.id in explosions))\n .map((def) => ({\n id: def.id,\n name: strings.effects[def.id]?.name ?? humanize(def.id),\n group: strings.groups[def.team] ?? def.team,\n })),\n ),\n ];\n\n const sheetFor = (id: string): BenchSheet => {\n const explosion = explosions[id];\n if (explosion) {\n return {\n kicker: strings.groups.explosions ?? text.sheet.explosion,\n title: humanize(id),\n facts: [\n { label: text.sheet.lethal, value: `${explosion.lethal} m` },\n { label: text.sheet.injury, value: `${explosion.injury} m` },\n { label: text.sheet.radius, value: `${explosion.visualRadius} m` },\n { label: text.sheet.fireballs, value: String(explosion.fireballs) },\n {\n label: text.sheet.particles,\n value: `${estimateCost(explosion)} / ${EVENT_BUDGET.particles}`,\n },\n ],\n timeline: timelineOf(explosion, undefined, \"blast_time\"),\n };\n }\n const recipe = recipes[id];\n const words = strings.effects[id];\n const labels = strings.sheet;\n return {\n kicker: recipe ? (strings.groups[recipe.team] ?? recipe.team) : undefined,\n title: words?.name ?? humanize(id),\n ...(words ? { body: words.short } : {}),\n facts: words\n ? [{ label: labels.budget, value: `${words.cost} · ${words.costNote}` }]\n : [],\n steps: words\n ? [\n { at: labels.when, text: words.when },\n { at: labels.look, text: words.look },\n { at: labels.budget, text: words.budget },\n { at: labels.network, text: words.network },\n ]\n : [],\n timeline: timelineOf(undefined, recipe, \"phase\"),\n };\n };\n\n const controls = (): ModuleControl[] => [\n {\n kind: \"choice\",\n id: \"effect\",\n name: text.controls.effect,\n options: effectOptions(),\n default:\n DEFAULT_EFFECT in explosions ? DEFAULT_EFFECT : effectOptions()[0]!.id,\n },\n {\n kind: \"choice\",\n id: \"variant\",\n name: text.controls.variant,\n options: [{ id: NO_VARIANT, name: text.none }],\n default: NO_VARIANT,\n hidden: true,\n },\n { kind: \"action\", id: \"replay\", name: text.controls.replay },\n {\n kind: \"boolean\",\n id: \"auto_repeat\",\n name: text.controls.auto_repeat,\n default: false,\n },\n {\n kind: \"number\",\n id: \"distance\",\n name: text.controls.distance,\n min: 4,\n max: 120,\n step: 1,\n unit: \"m\",\n default: DEFAULT_DISTANCE,\n },\n {\n kind: \"choice\",\n id: \"lod_band\",\n name: text.controls.lod_band,\n options: ([\"auto\", \"near\", \"middle\", \"far\"] as const).map((id) => ({\n id,\n name: text.lod[id],\n })),\n default: \"auto\",\n },\n {\n kind: \"choice\",\n id: \"quality\",\n name: text.controls.quality,\n options: ([\"high\", \"medium\", \"low\"] as const).map((id) => ({\n id,\n name: text.quality[id],\n })),\n default: \"high\",\n },\n ];\n\n const layers = (): ModuleLayer[] =>\n VFX_LAYERS.map((id) => ({ id: `${LAYER_ID}${id}`, name: text.layers[id] }));\n\n /** The live counters: shared by `metrics` and filled by `attach` (a module without a host reads zeros). */\n let read: () => {\n stats: Readonly<Record<string, number>>;\n phase: number;\n budget: number;\n } = () => ({ stats: {}, phase: 0, budget: 0 });\n\n const metrics = (): ModuleMetric[] => [\n {\n id: \"puffs\",\n name: text.metrics.puffs,\n digits: 0,\n read: () => read().stats.puffs ?? 0,\n },\n {\n id: \"sparks\",\n name: text.metrics.sparks,\n digits: 0,\n read: () => read().stats.sparks ?? 0,\n },\n {\n id: \"debris\",\n name: text.metrics.debris,\n digits: 0,\n max: EVENT_BUDGET.debris,\n read: () => read().stats.chunks ?? 0,\n },\n {\n id: \"lights\",\n name: text.metrics.lights,\n digits: 0,\n max: LIGHT_BUDGET,\n read: () =>\n (read().stats.blastLights ?? 0) + (read().stats.fireLights ?? 0),\n },\n {\n id: \"budget_particles\",\n name: text.metrics.budget_particles,\n digits: 0,\n max: EVENT_BUDGET.particles,\n read: () => read().budget,\n },\n {\n id: \"lod\",\n name: text.metrics.lod,\n digits: 2,\n read: () => read().stats.lod ?? 1,\n },\n {\n id: \"phase\",\n name: text.metrics.phase,\n unit: \"s\",\n digits: 2,\n read: () => read().phase,\n },\n {\n id: \"blast_time\",\n name: text.metrics.blast_time,\n unit: \"s\",\n digits: 2,\n read: () => Math.max(0, read().stats.blastTime ?? 0),\n },\n ];\n\n return {\n id: \"vfx\",\n name: text.module,\n group: \"effects\",\n items: () => [],\n controls,\n layers,\n metrics,\n attach(host: ModuleHost) {\n const bench = host.bench;\n let own: VfxRenderer | undefined;\n let sink: EffectSink | undefined = host.effects;\n if (!sink) {\n own = createVfxRenderer(host.THREE as ThreeLib, {\n scene: host.scene as THREE_NS.Scene,\n camera: host.camera as THREE_NS.PerspectiveCamera,\n });\n sink = own;\n }\n const effects = sink;\n let effect = \"m67\";\n let variant = NO_VARIANT;\n let distance = DEFAULT_DISTANCE;\n let auto = false;\n let phase = 0;\n let handle: EffectHandle | null = null;\n let sinceRepeat = 0;\n\n read = () => {\n const def = explosions[effect];\n const recipe = recipes[effect];\n const budget = def\n ? estimateCost(def)\n : (recipe?.budget.particles ?? 0);\n return { stats: effects.stats?.() ?? {}, phase, budget };\n };\n\n function replay(): void {\n if (handle !== null) effects.stop(handle);\n phase = 0;\n sinceRepeat = 0;\n handle = effects.play({\n effect,\n point: [BLAST_POINT[0], BLAST_POINT[1], BLAST_POINT[2]],\n direction: [1, 0.2, 0.4],\n normal: [0, 1, 0],\n ...(variant !== NO_VARIANT &&\n recipes[effect]?.params?.options.includes(variant)\n ? { param: variant }\n : {}),\n });\n }\n\n function choose(id: string): void {\n effect = id;\n const params = recipes[id]?.params;\n variant = params\n ? (params.options[params.default] ?? params.options[0] ?? NO_VARIANT)\n : NO_VARIANT;\n bench?.patch(\n \"variant\",\n params\n ? {\n hidden: false,\n options: params.options.map((option) => ({\n id: option,\n name: option,\n })),\n value: variant,\n }\n : {\n hidden: true,\n options: [{ id: NO_VARIANT, name: text.none }],\n value: NO_VARIANT,\n },\n );\n bench?.sheet?.(sheetFor(id));\n replay();\n }\n\n function look(): void {\n const eye = eyeFor(distance);\n bench?.look(eye, [0, 1.2, 0]);\n }\n\n const apply = (change: BenchChange): void => {\n if (change.kind === \"layer\")\n effects.configure?.({\n [`layer_${change.id.slice(LAYER_ID.length)}`]: change.on,\n });\n else if (change.kind === \"action\") {\n if (change.id === \"replay\") replay();\n } else if (change.id === \"effect\" && typeof change.value === \"string\")\n choose(change.value);\n else if (change.id === \"variant\" && typeof change.value === \"string\") {\n variant = change.value;\n if (recipes[effect]?.params) replay();\n } else if (change.id === \"auto_repeat\") auto = change.value === true;\n else if (change.id === \"distance\" && typeof change.value === \"number\") {\n distance = change.value;\n look();\n } else if (change.id === \"lod_band\" || change.id === \"quality\")\n effects.configure?.({ [change.id]: change.value });\n };\n const offChange = bench?.onChange(apply);\n const offFrame = host.onFrame((dt) => {\n phase += dt;\n sinceRepeat += dt;\n own?.update(dt);\n if (\n auto &&\n sinceRepeat >= (options.repeatSeconds ?? DEFAULT_REPEAT_SECONDS)\n )\n replay();\n });\n return () => {\n offChange?.();\n offFrame();\n if (handle !== null) effects.stop(handle);\n bench?.sheet?.(null);\n own?.dispose();\n read = () => ({ stats: {}, phase: 0, budget: 0 });\n };\n },\n };\n}\n","import type * as THREE_NS from 'three'\nimport type { GroundField } from '@adatechnology/game-vfx'\nimport type { ThreeLib } from './types'\n\nexport interface GroundPatchOptions {\n /** The height field the craters dig; the mesh follows it. */\n readonly field: GroundField\n /** What the patch is made of (default a plain flat-shaded grey standard material). */\n readonly material?: THREE_NS.Material\n /** Texture coordinates repeat every this many metres (the Lab's 17). */\n readonly textureMetres?: number\n}\n\nexport interface GroundPatch {\n readonly mesh: THREE_NS.Mesh\n /** Redraws the vertices when the field changed since the last call. Returns whether it did. */\n sync(): boolean\n dispose(): void\n}\n\nconst DEFAULT_TEXTURE_METRES = 17\n\n/** The Lab's 60 m deformable patch with 33 cm cells (L60-83), as a mesh that follows a `GroundField`. */\nexport function createGroundPatch(THREE: ThreeLib, options: GroundPatchOptions): GroundPatch {\n const field = options.field\n const metres = options.textureMetres ?? DEFAULT_TEXTURE_METRES\n const geometry = new THREE.PlaneGeometry(field.size, field.size, field.segments, field.segments).rotateX(-Math.PI / 2)\n const position = geometry.attributes.position!\n const uv = geometry.attributes.uv!\n for (let index = 0; index < position.count; index++) uv.setXY(index, position.getX(index) / metres, position.getZ(index) / metres)\n const material = options.material ?? new THREE.MeshStandardMaterial({ color: 0x2b2c2f, roughness: 0.93, flatShading: true })\n const mesh = new THREE.Mesh(geometry, material)\n mesh.receiveShadow = true\n let version = -1\n\n function sync(): boolean {\n if (field.version === version) return false\n version = field.version\n for (let index = 0; index < position.count; index++) position.setY(index, field.heights[index]!)\n position.needsUpdate = true\n geometry.computeBoundingSphere()\n return true\n }\n\n return {\n mesh,\n sync,\n dispose() {\n geometry.dispose()\n if (!options.material) material.dispose()\n },\n }\n}\n"],"mappings":"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;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;QACP,OAAS;MACX;MACA,MAAQ;QACN,QAAU;QACV,QAAU;QACV,MAAQ;MACV;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,SAAW;QACT;QACA;MACF;IACF;IACA,IAAM;MACJ,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;QACP,OAAS;MACX;MACA,MAAQ;QACN,QAAU;QACV,QAAU;QACV,MAAQ;MACV;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,SAAW;QACT;QACA;MACF;IACF;IACA,UAAY;MACV,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,MAAQ;QACN,OAAS;QACT,MAAQ;QACR,QAAU;MACZ;MACA,eAAiB;MACjB,SAAW;QACT;QACA;MACF;IACF;IACA,WAAa;MACX,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;QACR,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;QACb,UAAY;MACd;MACA,OAAS;MACT,OAAS;MACT,MAAQ;MACR,SAAW;QACT;QACA;MACF;IACF;IACA,UAAY;MACV,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;QACV,QAAU;QACV,MAAQ;MACV;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,SAAW;QACT;QACA;MACF;IACF;IACA,UAAY;MACV,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,eAAiB;MACjB,SAAW;QACT;QACA;MACF;IACF;IACA,UAAY;MACV,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;MACX;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;QACV,QAAU;QACV,MAAQ;MACV;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,eAAiB;MACjB,SAAW;QACT;QACA;MACF;IACF;IACA,MAAQ;MACN,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,QAAU;MACZ;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,eAAiB;MACjB,SAAW;QACT;QACA;MACF;IACF;IACA,aAAe;MACb,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,QAAU;MACZ;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,UAAY;QACV,QAAU;QACV,QAAU;QACV,OAAS;QACT,MAAQ;QACR,MAAQ;MACV;MACA,eAAiB;QACf;UACE,IAAM;UACN,IAAM;UACN,QAAU;UACV,MAAQ;QACV;QACA;UACE,IAAM;UACN,IAAM;UACN,QAAU;UACV,MAAQ;QACV;QACA;UACE,IAAM;UACN,IAAM;UACN,QAAU;UACV,MAAQ;QACV;MACF;MACA,QAAU;MACV,UAAY;MACZ,SAAW;QACT;QACA;MACF;IACF;IACA,eAAiB;MACf,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,QAAU;MACZ;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,OAAS;QACT,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,UAAY;QACV,QAAU;QACV,QAAU;QACV,OAAS;QACT,MAAQ;QACR,MAAQ;MACV;MACA,QAAU;MACV,UAAY;MACZ,SAAW;QACT;QACA;MACF;IACF;IACA,WAAa;MACX,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,QAAU;MACZ;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,OAAS;QACT,KAAO;MACT;MACA,MAAQ;QACN,QAAU;MACZ;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,UAAY;QACV,QAAU;QACV,QAAU;QACV,OAAS;QACT,MAAQ;QACR,MAAQ;MACV;MACA,eAAiB;QACf;UACE,QAAU;UACV,MAAQ;UACR,MAAQ;QACV;MACF;MACA,QAAU;MACV,UAAY;MACZ,SAAW;QACT;QACA;MACF;IACF;IACA,mBAAqB;MACnB,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,OAAS;QACT,OAAS;MACX;MACA,UAAY;QACV,OAAS;QACT,MAAQ;QACR,OAAS;QACT,QAAU;MACZ;MACA,QAAU;QACR,OAAS;QACT,QAAU;UACR;UACA;UACA;QACF;QACA,KAAO;MACT;MACA,MAAQ;QACN,QAAU;QACV,QAAU;QACV,MAAQ;MACV;MACA,OAAS;QACP,OAAS;QACT,MAAQ;QACR,OAAS;QACT,WAAa;MACf;MACA,OAAS;QACP,UAAY;MACd;MACA,OAAS;MACT,MAAQ;MACR,UAAY;QACV,QAAU;QACV,QAAU;QACV,OAAS;QACT,MAAQ;QACR,MAAQ;QACR,UAAY;MACd;MACA,eAAiB;QACf;UACE,QAAU;UACV,MAAQ;UACR,MAAQ;UACR,OAAS;QACX;QACA;UACE,IAAM;UACN,IAAM;UACN,QAAU;UACV,MAAQ;QACV;QACA;UACE,IAAM;UACN,IAAM;UACN,QAAU;UACV,MAAQ;QACV;MACF;MACA,QAAU;MACV,UAAY;MACZ,SAAW;QACT;QACA;MACF;IACF;IACA,SAAW;MACT,IAAM;MACN,QAAU;MACV,QAAU;MACV,cAAgB;MAChB,WAAa;MACb,MAAQ;MACR,OAAS;QACP,OAAS;QACT,OAAS;QACT,MAAQ;MACV;MACA,MAAQ;QACN,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","names":["VFX_LAYERS","entry","DEFAULT_COLOR","min","puff","ageOrKeep","ring","floor","lerp","behavior","spawn","call","UP","FRESH_BLOOD","local","BLOOD","SPEED","FORWARD","BODY_Z","TIP","PORT","WALL_Z","FACING","CENTRE","FALL_SECONDS","BODIES","SPLINTER_DIRECTION","at","SCRAPE_DIRECTION","camera","CAR_ORIGIN","CAR_ROTATION","WALK_SPEED","DROPS","SLANT","SPARK_DIRECTION","HITS","HIT_X","HIT_Y","blow","WALKERS","ORIGIN","MUZZLE_FLASH","min","max","ring","ORIGIN","OBJECT_ID_DRAWS","FLOOR","clamp","x","y","random","SPOT","QUARTER_TURN","lerp","vx","vy","vz","camera","ease","axis","UP","FULL_TURN_DRAWN","behavior","local","param","screen","ORIGIN","positionOf","ageOrKeep","ring","puff","pick","flash","screen","vy","vx","vz","call","QUARTER_TURN","floor","clamp","lerp","at","rnd","UP","ring","GRAVITY","QUARTER_TURN","DEFAULT_COLOR","FULL_TURN_DRAWN","CAPACITY","DEFAULT_LIFE","decal","BYTE_MAX","FLOATS_PER_VECTOR","cos","sin","RING_CAPACITY","camera","layer","call","local","puff","mesh","cos","sin","mesh","ease","clamp","min","max","flash","ring","mesh","RING_CAPACITY","FADE_SECONDS","clamp","mesh","decal","ring","layer","GROUND_COLOR","VFX_LAYERS","camera","layer","flash","VFX_LAYERS","mesh"]}
|