@v12-engine/engine 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/abilities/buffs.d.ts +83 -0
- package/dist/abilities/castTold.d.ts +12 -0
- package/dist/abilities/charges.d.ts +28 -0
- package/dist/abilities/dispel.d.ts +9 -0
- package/dist/abilities/effectFields.d.ts +10 -0
- package/dist/abilities/effects/buff.d.ts +8 -0
- package/dist/abilities/effects/core.d.ts +1 -0
- package/dist/abilities/effects/damage.d.ts +1 -0
- package/dist/abilities/effects/heal.d.ts +2 -0
- package/dist/abilities/effects/missile.d.ts +1 -0
- package/dist/abilities/effects/moves.d.ts +11 -0
- package/dist/abilities/effects/passives.d.ts +15 -0
- package/dist/abilities/effects/sight.d.ts +4 -0
- package/dist/abilities/effects/spawn.d.ts +2 -0
- package/dist/abilities/effects/timed.d.ts +4 -0
- package/dist/abilities/effects/trade.d.ts +1 -0
- package/dist/abilities/effects.d.ts +122 -0
- package/dist/abilities/land.d.ts +21 -0
- package/dist/abilities/scaled.d.ts +21 -0
- package/dist/abilities/text.d.ts +113 -0
- package/dist/ai/area.d.ts +53 -0
- package/dist/ai/brain.d.ts +528 -0
- package/dist/ai/budget.d.ts +67 -0
- package/dist/ai/checks.d.ts +115 -0
- package/dist/ai/computer.d.ts +166 -0
- package/dist/ai/defence.d.ts +108 -0
- package/dist/ai/define.d.ts +21 -0
- package/dist/ai/economy.d.ts +129 -0
- package/dist/ai/geometry.d.ts +35 -0
- package/dist/ai/goals.d.ts +360 -0
- package/dist/ai/index.d.ts +38 -0
- package/dist/ai/knowledge.d.ts +418 -0
- package/dist/ai/lanes.d.ts +232 -0
- package/dist/ai/melee/build.d.ts +61 -0
- package/dist/ai/melee/goals.d.ts +299 -0
- package/dist/ai/melee/heroes.d.ts +27 -0
- package/dist/ai/melee/index.d.ts +14 -0
- package/dist/ai/melee/production.d.ts +8 -0
- package/dist/ai/melee/surrender.d.ts +24 -0
- package/dist/ai/micro.d.ts +278 -0
- package/dist/ai/mission.d.ts +195 -0
- package/dist/ai/missionRules.d.ts +18 -0
- package/dist/ai/module.d.ts +116 -0
- package/dist/ai/options.d.ts +61 -0
- package/dist/ai/plans/build.d.ts +280 -0
- package/dist/ai/plans/placement.d.ts +82 -0
- package/dist/ai/plans/plans.d.ts +105 -0
- package/dist/ai/plans/production.d.ts +210 -0
- package/dist/ai/plans/purse.d.ts +73 -0
- package/dist/ai/plans/tech.d.ts +37 -0
- package/dist/ai/profiles.d.ts +204 -0
- package/dist/ai/reach.d.ts +4 -0
- package/dist/ai/report.d.ts +203 -0
- package/dist/ai/roles.d.ts +133 -0
- package/dist/ai/rules.d.ts +288 -0
- package/dist/ai/scouting.d.ts +98 -0
- package/dist/ai/settings.d.ts +73 -0
- package/dist/ai/squads.d.ts +429 -0
- package/dist/ai/strength.d.ts +167 -0
- package/dist/ai/task.d.ts +118 -0
- package/dist/ai/tasks/attack.d.ts +7 -0
- package/dist/ai/tasks/capture.d.ts +21 -0
- package/dist/ai/tasks/creep.d.ts +16 -0
- package/dist/ai/tasks/defend.d.ts +29 -0
- package/dist/ai/tasks/drop.d.ts +34 -0
- package/dist/ai/tasks/escort.d.ts +16 -0
- package/dist/ai/tasks/gather.d.ts +23 -0
- package/dist/ai/tasks/harass.d.ts +7 -0
- package/dist/ai/tasks/hold.d.ts +20 -0
- package/dist/ai/tasks/index.d.ts +32 -0
- package/dist/ai/tasks/move.d.ts +19 -0
- package/dist/ai/tasks/patrol.d.ts +8 -0
- package/dist/ai/tasks/retreat.d.ts +20 -0
- package/dist/ai/tasks/scout.d.ts +29 -0
- package/dist/ai/tasks/shared.d.ts +74 -0
- package/dist/ai/team.d.ts +155 -0
- package/dist/ai/threat.d.ts +91 -0
- package/dist/ai/view.d.ts +366 -0
- package/dist/ai/waves.d.ts +126 -0
- package/dist/ai.js +6239 -0
- package/dist/ai.js.map +1 -0
- package/dist/aiTesting.d.ts +179 -0
- package/dist/areas.d.ts +149 -0
- package/dist/attacks.d.ts +66 -0
- package/dist/attributes.d.ts +66 -0
- package/dist/brain-BvVdUhX8.js +7659 -0
- package/dist/brain-BvVdUhX8.js.map +1 -0
- package/dist/builds-C6LfgvEU.js +460 -0
- package/dist/builds-C6LfgvEU.js.map +1 -0
- package/dist/bytes.d.ts +6 -0
- package/dist/camps.d.ts +95 -0
- package/dist/capture.d.ts +131 -0
- package/dist/cellLayers.d.ts +75 -0
- package/dist/cinematics.d.ts +194 -0
- package/dist/clock.d.ts +32 -0
- package/dist/commands.d.ts +235 -0
- package/dist/components.d.ts +184 -0
- package/dist/computers.d.ts +108 -0
- package/dist/concealment.d.ts +61 -0
- package/dist/coreComponents-syuh2fPG.js +5149 -0
- package/dist/coreComponents-syuh2fPG.js.map +1 -0
- package/dist/coreComponents.d.ts +1 -0
- package/dist/dashing.d.ts +8 -0
- package/dist/debug.d.ts +36 -0
- package/dist/debug.js +3 -0
- package/dist/debugCommands-CzjrSm66.js +14739 -0
- package/dist/debugCommands-CzjrSm66.js.map +1 -0
- package/dist/debugCommands.d.ts +213 -0
- package/dist/debugging.d.ts +10 -0
- package/dist/definitions.d.ts +43 -0
- package/dist/defs.d.ts +1162 -0
- package/dist/denying.d.ts +81 -0
- package/dist/destructibles.d.ts +27 -0
- package/dist/determinism-BCymQwiE.js +518 -0
- package/dist/determinism-BCymQwiE.js.map +1 -0
- package/dist/determinism.d.ts +121 -0
- package/dist/dialog.d.ts +94 -0
- package/dist/effectRefs.d.ts +16 -0
- package/dist/effects.d.ts +80 -0
- package/dist/endings.d.ts +22 -0
- package/dist/engagement.d.ts +108 -0
- package/dist/engineEvents.d.ts +710 -0
- package/dist/entity.d.ts +409 -0
- package/dist/entityIndex.d.ts +50 -0
- package/dist/errors.d.ts +85 -0
- package/dist/events.d.ts +97 -0
- package/dist/exactMath.d.ts +63 -0
- package/dist/features.d.ts +10 -0
- package/dist/fields.d.ts +114 -0
- package/dist/fixture.d.ts +17 -0
- package/dist/fog.d.ts +110 -0
- package/dist/formation.d.ts +111 -0
- package/dist/friendlyFire.d.ts +26 -0
- package/dist/game-DiJEN-Ks.js +5800 -0
- package/dist/game-DiJEN-Ks.js.map +1 -0
- package/dist/game.d.ts +501 -0
- package/dist/gameData.d.ts +325 -0
- package/dist/gameFiles.d.ts +26 -0
- package/dist/gates.d.ts +28 -0
- package/dist/generate.d.ts +403 -0
- package/dist/generateWorker.d.ts +39 -0
- package/dist/grid.d.ts +53 -0
- package/dist/ground.d.ts +127 -0
- package/dist/groundSpeed.d.ts +22 -0
- package/dist/hero.d.ts +177 -0
- package/dist/home.d.ts +14 -0
- package/dist/hooks.d.ts +780 -0
- package/dist/hotReload.d.ts +76 -0
- package/dist/ids.d.ts +26 -0
- package/dist/index.d.ts +227 -0
- package/dist/index.js +4701 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect-D9dWHmZ0.js +491 -0
- package/dist/inspect-D9dWHmZ0.js.map +1 -0
- package/dist/inspect.d.ts +176 -0
- package/dist/inventory.d.ts +18 -0
- package/dist/items.d.ts +91 -0
- package/dist/lanes.d.ts +213 -0
- package/dist/life.d.ts +53 -0
- package/dist/local-Dkovq42k.js +1379 -0
- package/dist/local-Dkovq42k.js.map +1 -0
- package/dist/log.d.ts +140 -0
- package/dist/manaBurn.d.ts +39 -0
- package/dist/map/file.d.ts +114 -0
- package/dist/map/images.d.ts +18 -0
- package/dist/map/look.d.ts +47 -0
- package/dist/map/pathProfile.d.ts +13 -0
- package/dist/map/resize.d.ts +54 -0
- package/dist/map/schema.d.ts +10 -0
- package/dist/map/terrain.d.ts +32 -0
- package/dist/map/types.d.ts +613 -0
- package/dist/map.d.ts +7 -0
- package/dist/mapCheck/cells.d.ts +19 -0
- package/dist/mapCheck/rule.d.ts +30 -0
- package/dist/mapCheck/rules/names.d.ts +3 -0
- package/dist/mapCheck/rules/objects.d.ts +3 -0
- package/dist/mapCheck/rules/paths.d.ts +3 -0
- package/dist/mapCheck/rules/players.d.ts +3 -0
- package/dist/mapCheck/rules/races.d.ts +3 -0
- package/dist/mapCheck/rules/random.d.ts +3 -0
- package/dist/mapCheck/rules/regions.d.ts +3 -0
- package/dist/mapCheck/rules/targets.d.ts +3 -0
- package/dist/mapCheck/rules/walking.d.ts +3 -0
- package/dist/mapCheck.d.ts +23 -0
- package/dist/mapFields.d.ts +364 -0
- package/dist/mapFile.d.ts +23 -0
- package/dist/mapMeasure.d.ts +95 -0
- package/dist/mapMerge.d.ts +19 -0
- package/dist/mapObjectives.d.ts +82 -0
- package/dist/mapObjects.d.ts +1 -0
- package/dist/math.d.ts +44 -0
- package/dist/messages.d.ts +150 -0
- package/dist/missionRules-C-bGxm0Q.js +523 -0
- package/dist/missionRules-C-bGxm0Q.js.map +1 -0
- package/dist/missionRules.d.ts +179 -0
- package/dist/mods.d.ts +146 -0
- package/dist/names.d.ts +93 -0
- package/dist/navigation/agentParams.d.ts +4 -0
- package/dist/navigation/air.d.ts +89 -0
- package/dist/navigation/builds.d.ts +140 -0
- package/dist/navigation/groundAreas.d.ts +23 -0
- package/dist/navigation/navigation.d.ts +127 -0
- package/dist/navigation/recast.d.ts +214 -0
- package/dist/navigation/sidePaths.d.ts +69 -0
- package/dist/navigation/sized.d.ts +1 -0
- package/dist/navigation-worker.js +11 -0
- package/dist/navigation-worker.js.map +1 -0
- package/dist/nearest.d.ts +8 -0
- package/dist/noise.d.ts +12 -0
- package/dist/objectives.d.ts +93 -0
- package/dist/orders/basic.d.ts +96 -0
- package/dist/orders/build.d.ts +91 -0
- package/dist/orders/cast.d.ts +105 -0
- package/dist/orders/facts.d.ts +14 -0
- package/dist/orders/harvest.d.ts +94 -0
- package/dist/orders/idle.d.ts +7 -0
- package/dist/orders/items.d.ts +14 -0
- package/dist/orders/queue.d.ts +24 -0
- package/dist/pack.schema.json +6621 -0
- package/dist/packs/director/index.d.ts +81 -0
- package/dist/packs/heroes/campaign.d.ts +137 -0
- package/dist/packs/heroes/carry.d.ts +59 -0
- package/dist/packs/heroes/commands.d.ts +6 -0
- package/dist/packs/heroes/hire.d.ts +9 -0
- package/dist/packs/heroes/index.d.ts +12 -0
- package/dist/packs/heroes/making.d.ts +16 -0
- package/dist/packs/heroes/respawn.d.ts +42 -0
- package/dist/packs/moba/index.d.ts +34 -0
- package/dist/packs/pack.d.ts +84 -0
- package/dist/packs-g5thvmGn.js +3199 -0
- package/dist/packs-g5thvmGn.js.map +1 -0
- package/dist/packs.d.ts +84 -0
- package/dist/paths.d.ts +51 -0
- package/dist/plain.d.ts +17 -0
- package/dist/player.d.ts +117 -0
- package/dist/portals.d.ts +66 -0
- package/dist/prefabs.d.ts +139 -0
- package/dist/presetBuildings.d.ts +52 -0
- package/dist/presetGround.d.ts +22 -0
- package/dist/profiles-B3NS9jwk.js +335 -0
- package/dist/profiles-B3NS9jwk.js.map +1 -0
- package/dist/races.d.ts +136 -0
- package/dist/randomGroups.d.ts +2 -0
- package/dist/registry.d.ts +464 -0
- package/dist/remains.d.ts +119 -0
- package/dist/replication.d.ts +103 -0
- package/dist/rng.d.ts +17 -0
- package/dist/rules.d.ts +395 -0
- package/dist/rulesCheck.d.ts +37 -0
- package/dist/runes.d.ts +41 -0
- package/dist/save.d.ts +277 -0
- package/dist/scenario.d.ts +56 -0
- package/dist/scheduler.d.ts +67 -0
- package/dist/score.d.ts +306 -0
- package/dist/sequences.d.ts +132 -0
- package/dist/server/doorman.d.ts +21 -0
- package/dist/server/gameServer.d.ts +346 -0
- package/dist/server/index.d.ts +24 -0
- package/dist/server/lobby.d.ts +1 -0
- package/dist/server/log.d.ts +13 -0
- package/dist/server/match.d.ts +24 -0
- package/dist/server/mode.d.ts +168 -0
- package/dist/server/navigation-worker.d.ts +1 -0
- package/dist/server/navigation.d.ts +11 -0
- package/dist/server/ops.d.ts +78 -0
- package/dist/server/packs.d.ts +15 -0
- package/dist/server/ratings.d.ts +62 -0
- package/dist/server/relay.d.ts +34 -0
- package/dist/server/rooms.d.ts +162 -0
- package/dist/server/seat.d.ts +2 -0
- package/dist/server/seatSettings.d.ts +15 -0
- package/dist/server/secret.d.ts +5 -0
- package/dist/server/start.d.ts +54 -0
- package/dist/server/websocket.d.ts +74 -0
- package/dist/server.js +2861 -0
- package/dist/server.js.map +1 -0
- package/dist/session/can.d.ts +20 -0
- package/dist/session/commandReplay.d.ts +92 -0
- package/dist/session/debug.d.ts +65 -0
- package/dist/session/delay.d.ts +15 -0
- package/dist/session/delta.d.ts +98 -0
- package/dist/session/entityState.d.ts +1 -0
- package/dist/session/local.d.ts +214 -0
- package/dist/session/memory.d.ts +27 -0
- package/dist/session/protocol.d.ts +1155 -0
- package/dist/session/remote.d.ts +530 -0
- package/dist/session/replay.d.ts +114 -0
- package/dist/session/seed.d.ts +7 -0
- package/dist/session/share.d.ts +78 -0
- package/dist/session/socket.d.ts +8 -0
- package/dist/session/wire.d.ts +153 -0
- package/dist/session/worker.d.ts +227 -0
- package/dist/shared.d.ts +171 -0
- package/dist/sides.d.ts +75 -0
- package/dist/sight.d.ts +27 -0
- package/dist/simulate-oXBiw1Ff.js +167 -0
- package/dist/simulate-oXBiw1Ff.js.map +1 -0
- package/dist/simulate-worker.d.ts +1 -0
- package/dist/simulate-worker.js +28 -0
- package/dist/simulate-worker.js.map +1 -0
- package/dist/simulate.d.ts +154 -0
- package/dist/smart.d.ts +9 -0
- package/dist/spatial.d.ts +62 -0
- package/dist/spawning.d.ts +33 -0
- package/dist/stances.d.ts +76 -0
- package/dist/start.d.ts +71 -0
- package/dist/stats.d.ts +122 -0
- package/dist/summons.d.ts +63 -0
- package/dist/systems/abilities.d.ts +3 -0
- package/dist/systems/combat.d.ts +71 -0
- package/dist/systems/combatTold.d.ts +14 -0
- package/dist/systems/construction.d.ts +34 -0
- package/dist/systems/economy.d.ts +21 -0
- package/dist/systems/fog.d.ts +19 -0
- package/dist/systems/life.d.ts +3 -0
- package/dist/systems/movement.d.ts +105 -0
- package/dist/systems/orders.d.ts +7 -0
- package/dist/systems/production.d.ts +49 -0
- package/dist/systems/productionQueue.d.ts +40 -0
- package/dist/systems/victory.d.ts +14 -0
- package/dist/talk.d.ts +65 -0
- package/dist/tech.d.ts +62 -0
- package/dist/techTree.d.ts +38 -0
- package/dist/terrain.d.ts +173 -0
- package/dist/terrainSave.d.ts +29 -0
- package/dist/testing.d.ts +58 -0
- package/dist/testing.js +822 -0
- package/dist/testing.js.map +1 -0
- package/dist/tiles.d.ts +34 -0
- package/dist/timers.d.ts +146 -0
- package/dist/tomes.d.ts +48 -0
- package/dist/trade.d.ts +28 -0
- package/dist/transport.d.ts +76 -0
- package/dist/tunables.d.ts +45 -0
- package/dist/upkeep.d.ts +16 -0
- package/dist/veterancy.d.ts +80 -0
- package/dist/walls.d.ts +86 -0
- package/dist/world.d.ts +1118 -0
- package/package.json +80 -5
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coreComponents-syuh2fPG.js","names":["leftAreaEvent","enteredAreaEvent","lineSaidEvent","plain","objectiveChangedEvent","entityDiedEvent","bountyEvent","choppedEvent","campReturnedEvent","campClearedEvent","plainData","entity.moving","entity.fighting","entity.deposit","entity.exposure","entity.detection","inventory.inventorySlots","items.shopStock","hero.heroState","hero.respawning","summons.corpses","summons.summoned","summons.illusion","score.scoreData","endings.pauses","talk.sent","timers.waiting","timers.shownTimers","dashing.dashing","cinematics.waits","cinematics.regionCinematicsPlayed","computers.computerSeats","computers.computerDefaults","randomGroups.mapDrops","capture.captures","capture.ready","names.names","names.mapInfo","denying.counted","gates.gateStates","objectives.objectives","stances.stance","tunables.tunings","remains.pileOf","remains.remains","lanes.laneMinion","lanes.lanesState","lanes.heroStrike","transport.cargo","veterancy.veterancy","dialog.current","areas.inside","areas.added","effects.played","camps.campMember","camps.camps","sequences.running","sides.relations","sides.vision","sides.control","sidePaths.sideKnowledge","gameData.redefinitions","construction.constructionSite","harvest.gathering","productionQueue.productionQueue","memory.teamMemory"],"sources":["../src/areas.ts","../src/dialog.ts","../src/effects.ts","../src/objectives.ts","../src/score.ts","../src/systems/economy.ts","../src/names.ts","../src/gates.ts","../src/tunables.ts","../src/camps.ts","../src/navigation/recast.ts","../src/navigation/sidePaths.ts","../src/save.ts","../src/sides.ts","../src/scheduler.ts","../src/computers.ts","../src/capture.ts","../src/denying.ts","../src/lanes.ts","../src/remains.ts","../src/stances.ts","../src/veterancy.ts","../src/coreComponents.ts"],"sourcesContent":["import { enteredArea as enteredAreaEvent, leftArea as leftAreaEvent } from '#engine/engineEvents'\nimport { defineComponent } from './components'\nimport type { Entity } from './entity'\nimport type { Vec2 } from './math'\nimport type { System } from './registry'\nimport type { World } from './world'\nimport { hypot } from './exactMath'\nimport type { MapRegion } from './map'\n\n/**\n * Where an area is on the map: a circle, a rectangle by its middle and size, or a polygon by its corners round a middle\n * of its own (`points`, each from `x` and `z`, three or more, in order round it: moving the middle moves it whole)\n *\n * @beta\n */\nexport type AreaShape =\n\t| { kind: 'circle'; x: number; z: number; radius: number }\n\t| { kind: 'rect'; x: number; z: number; width: number; depth: number }\n\t| { kind: 'polygon'; x: number; z: number; points: Vec2[] }\n\n/**\n * The box round a shape: its least and greatest x and z on the map\n *\n * @beta\n */\nexport function shapeBounds(shape: AreaShape): { x0: number; z0: number; x1: number; z1: number } {\n\tif (shape.kind === 'circle')\n\t\treturn { x0: shape.x - shape.radius, z0: shape.z - shape.radius, x1: shape.x + shape.radius, z1: shape.z + shape.radius }\n\tif (shape.kind === 'rect')\n\t\treturn { x0: shape.x - shape.width / 2, z0: shape.z - shape.depth / 2, x1: shape.x + shape.width / 2, z1: shape.z + shape.depth / 2 }\n\tlet x0 = Infinity\n\tlet z0 = Infinity\n\tlet x1 = -Infinity\n\tlet z1 = -Infinity\n\tfor (const point of shape.points) {\n\t\tx0 = Math.min(x0, shape.x + point.x)\n\t\tz0 = Math.min(z0, shape.z + point.z)\n\t\tx1 = Math.max(x1, shape.x + point.x)\n\t\tz1 = Math.max(z1, shape.z + point.z)\n\t}\n\treturn shape.points.length ? { x0, z0, x1, z1 } : { x0: shape.x, z0: shape.z, x1: shape.x, z1: shape.z }\n}\n\n/**\n * How much ground a shape covers, in cells\n *\n * @beta\n */\nexport function shapeArea(shape: AreaShape): number {\n\tif (shape.kind === 'circle') return Math.PI * shape.radius * shape.radius\n\tif (shape.kind === 'rect') return shape.width * shape.depth\n\tlet twice = 0\n\tconst { points } = shape\n\tfor (let i = 0, j = points.length - 1; i < points.length; j = i++) twice += points[j].x * points[i].z - points[i].x * points[j].z\n\treturn Math.abs(twice) / 2\n}\n\n/**\n * A shape as a circle or a rectangle: a polygon as the rectangle round it. For what draws only those (mist, clouds and\n * weather in a region of the map)\n *\n * @beta\n */\nexport function shapeAsBox(shape: AreaShape): Exclude<AreaShape, { kind: 'polygon' }> {\n\tif (shape.kind !== 'polygon') return shape\n\tconst { x0, z0, x1, z1 } = shapeBounds(shape)\n\treturn { kind: 'rect', x: (x0 + x1) / 2, z: (z0 + z1) / 2, width: x1 - x0, depth: z1 - z0 }\n}\n\n/**\n * A shape moved to stand at a point and sized `scale` times: a prefab's area where the prefab is put\n *\n * @beta\n */\nexport function shapeAt(shape: AreaShape, at: Vec2, scale = 1): AreaShape {\n\tif (shape.kind === 'circle') return { kind: 'circle', x: at.x, z: at.z, radius: shape.radius * scale }\n\tif (shape.kind === 'rect') return { kind: 'rect', x: at.x, z: at.z, width: shape.width * scale, depth: shape.depth * scale }\n\treturn { kind: 'polygon', x: at.x, z: at.z, points: shape.points.map((point) => ({ x: point.x * scale, z: point.z * scale })) }\n}\n\n/**\n * Where something of the map is, by a shape of its own or by a region of the map, named: mist, clouds and weather in\n * places (`MapMistArea.shape`). By the region, it is where the region is, moved with it, and is the rules' too\n *\n * @beta\n */\nexport type AreaRef = AreaShape | { region: string }\n\n/**\n * The shape an `AreaRef` stands for: its own, or the named region's among the map's. Nothing for a region that is\n * not there\n *\n * @beta\n */\nexport function areaShapeOf(ref: AreaRef, regions: readonly MapRegion[]): AreaShape | undefined {\n\tif ('region' in ref) return regions.find((region) => region.name === ref.region)?.shape\n\treturn ref\n}\n\n/**\n * A named part of the map that the rules watch: who walks into it and out of it (`enteredArea`, `leftArea` events),\n * and who is in it now (`world.areas`). Units count, by where their middle is; buildings, scenery and units inside\n * something do not. Given in `GameModule.areas`\n *\n * @beta\n */\nexport interface AreaDef {\n\t/** Shared by every game, like other ids: give it a prefix of the game's (`'td.gate'`) */\n\tid: string\n\tshape: AreaShape\n}\n\n/**\n * Typed help for writing an area\n *\n * @beta\n */\nexport const defineArea = (def: AreaDef): AreaDef => def\n\n/**\n * Whether a point is in a shape\n *\n * @beta\n */\nexport function inShape(shape: AreaShape, point: Vec2): boolean {\n\tconst dx = point.x - shape.x\n\tconst dz = point.z - shape.z\n\tif (shape.kind === 'circle') return dx * dx + dz * dz <= shape.radius * shape.radius\n\tif (shape.kind === 'rect') return Math.abs(dx) <= shape.width / 2 && Math.abs(dz) <= shape.depth / 2\n\t// a polygon: in where a line from the point crosses its edges an odd number of times\n\tconst { points } = shape\n\tlet odd = false\n\tfor (let i = 0, j = points.length - 1; i < points.length; j = i++) {\n\t\tconst a = points[i]\n\t\tconst b = points[j]\n\t\tif (a.z > dz !== b.z > dz && dx < ((b.x - a.x) * (dz - a.z)) / (b.z - a.z) + a.x) odd = !odd\n\t}\n\treturn odd\n}\n\n/**\n * The radius of a circle round the whole shape from its middle (`x`, `z`): what the spatial index is asked for\n *\n * @beta\n */\nexport function shapeReach(shape: AreaShape): number {\n\tif (shape.kind === 'circle') return shape.radius\n\tif (shape.kind === 'rect') return hypot(shape.width, shape.depth) / 2\n\tlet most = 0\n\tfor (const point of shape.points) most = Math.max(most, hypot(point.x, point.z))\n\treturn most\n}\nconst reach = shapeReach\n\n/** Who is in each area, by id: kept in the world, so that a save knows, and nobody walks in twice after loading */\nexport const inside = defineComponent<Record<string, number[]>>('core.areas', { default: () => ({}) })\n/** Areas added while the game runs (`areas.add`): kept in the world, so that a save has them */\nexport const added = defineComponent<AreaDef[]>('core.areasAdded', { default: () => [] })\n\n/**\n * The areas of a world, and who is in them\n *\n * @beta\n */\nexport class Areas {\n\tprivate readonly byId = new Map<string, AreaDef>()\n\t/** Kept between ticks, not made anew */\n\tprivate readonly found: Entity[] = []\n\tprivate readonly now = new Set<number>()\n\n\tconstructor(\n\t\tprivate readonly world: World,\n\t\tdefs: readonly AreaDef[]\n\t) {\n\t\tfor (const def of defs) {\n\t\t\tif (this.byId.has(def.id)) throw new Error(`Area \"${def.id}\" is there twice`)\n\t\t\tthis.byId.set(def.id, def)\n\t\t}\n\t}\n\n\t/** The areas of the game, then those added while it runs */\n\tget all(): Iterable<AreaDef> {\n\t\treturn [...this.byId.values(), ...this.added()]\n\t}\n\n\tget size(): number {\n\t\treturn this.byId.size + this.added().length\n\t}\n\n\tget(id: string): AreaDef {\n\t\tconst def = this.find(id)\n\t\tif (!def) throw new Error(`There is no area \"${id}\"`)\n\t\treturn def\n\t}\n\n\t/** Whether there is an area of that id */\n\thas(id: string): boolean {\n\t\treturn !!this.find(id)\n\t}\n\n\tprivate find(id: string): AreaDef | undefined {\n\t\treturn this.byId.get(id) ?? this.added().find((def) => def.id === id)\n\t}\n\n\tprivate added(): AreaDef[] {\n\t\treturn this.world.state(added)\n\t}\n\n\t/**\n\t * Adds an area while the game runs: a zone a spell leaves, a ring that closes in, a part of the map a quest opens.\n\t * Who is in it is found at the end of the tick, and walks in then. One of the same id, added before, is replaced\n\t */\n\tadd(def: AreaDef): void {\n\t\tif (this.byId.has(def.id)) throw new Error(`Area \"${def.id}\" is one of the game's: it cannot be added again`)\n\t\tconst list = this.added()\n\t\tconst index = list.findIndex((other) => other.id === def.id)\n\t\t// a copy: the shape may be moved by adding it again, not by changing what was given\n\t\tconst copy = { id: def.id, shape: { ...def.shape } }\n\t\tif (index >= 0) list[index] = copy\n\t\telse list.push(copy)\n\t}\n\n\t/** Takes away an area added while the game runs. Who was in it leaves it (`leftArea`). False when there was none */\n\tremove(id: string): boolean {\n\t\tconst list = this.added()\n\t\tconst index = list.findIndex((def) => def.id === id)\n\t\tif (index < 0) return false\n\t\tlist.splice(index, 1)\n\t\tconst state = this.world.state(inside)\n\t\tfor (const entityId of state[id] ?? []) {\n\t\t\tconst entity = this.world.get(entityId)\n\t\t\tif (entity?.alive) this.world.events.emit(leftAreaEvent, { area: id, entity })\n\t\t}\n\t\tdelete state[id]\n\t\treturn true\n\t}\n\n\t/** Whether the entity was in the area when the areas were last looked at: the end of the last tick's movement */\n\tcontains(id: string, entity: Entity): boolean {\n\t\treturn this.idsIn(id).includes(entity.id)\n\t}\n\n\t/** Who is in the area, as of the last look */\n\tinside(id: string): Entity[] {\n\t\tconst result: Entity[] = []\n\t\tfor (const entityId of this.idsIn(id)) {\n\t\t\tconst entity = this.world.get(entityId)\n\t\t\tif (entity) result.push(entity)\n\t\t}\n\t\treturn result\n\t}\n\n\tprivate idsIn(id: string): number[] {\n\t\tthis.get(id)\n\t\treturn this.world.state(inside)[id] ?? []\n\t}\n\n\t/** Looks who is in each area now, and tells who walked in and who walked out. What died in one is just gone */\n\tupdate(): void {\n\t\tconst state = this.world.state(inside)\n\t\t// the game's, then those added: no list made of both every tick\n\t\tfor (const area of this.byId.values()) this.look(area, state)\n\t\tfor (const area of this.added()) this.look(area, state)\n\t}\n\n\t/** Who is in one area now, against who was */\n\tprivate look(area: AreaDef, state: Record<string, number[]>): void {\n\t\tconst { world, found, now } = this\n\t\tconst { shape } = area\n\t\tnow.clear()\n\t\tfor (const entity of world.spatial.query(shape.x, shape.z, reach(shape), found)) {\n\t\t\tif (entity.def.kind !== 'unit' || !entity.alive || entity.hidden || !inShape(shape, entity.pos)) continue\n\t\t\tnow.add(entity.id)\n\t\t}\n\t\tconst before = state[area.id] ?? []\n\t\tfor (const id of before) {\n\t\t\tif (now.has(id)) continue\n\t\t\tconst entity = world.get(id)\n\t\t\tif (entity?.alive) world.events.emit(leftAreaEvent, { area: area.id, entity })\n\t\t}\n\t\tfor (const id of now) {\n\t\t\tif (!before.includes(id)) world.events.emit(enteredAreaEvent, { area: area.id, entity: world.get(id)! })\n\t\t}\n\t\tif (now.size || before.length) state[area.id] = [...now]\n\t}\n}\n\n/** Watches the areas, after everyone has moved. Does nothing in a game without any */\nexport const areaSystem: System = {\n\tname: 'areas',\n\tphase: 'resolve',\n\tupdate(world) {\n\t\tif (world.areas.size) world.areas.update()\n\t}\n}\n","import { lineEnded, lineSaid as lineSaidEvent } from '#engine/engineEvents'\nimport { defineComponent } from './components'\nimport type { PlayerId } from './entity'\nimport { type Message, type MessageRef, toMessage } from './messages'\nimport { type Step, wait } from './sequences'\nimport type { World } from './world'\nimport { replicateEvent } from './replication'\n\n/**\n * Something someone says: a commander between waves, a hero in a cutscene. The rules say a line is said, so that\n * every player hears it at the same moment and a save knows where a conversation was; the view shows it (a box with\n * a portrait, subtitles) and plays its voice. Who the speaker is on the screen, their name and portrait, is the\n * view's (`GameView.cinematics.speakers`)\n *\n * @beta\n */\nexport interface LineDef {\n\t/** Who says it, by an id of the game's (`'td.commander'`) */\n\tspeaker: string\n\t/** What is said, in the words of the game: a message key, with params */\n\ttext: MessageRef\n\t/** How long it stays, in seconds. `LINE_SECONDS` when left out: the rules know the key of the words, not how long they are */\n\tseconds?: number\n}\n\n/**\n * Whom a line is said to: a player, some, or everyone\n *\n * @beta\n */\nexport type Audience = PlayerId | PlayerId[] | 'everyone'\n\n/**\n * A line as it is said: what the engine's `lineSaid` event carries, and what goes to the screen\n *\n * @beta\n */\nexport interface SaidLine {\n\tid: number\n\tspeaker: string\n\ttext: Message\n\tseconds: number\n\t/** Who hears it. Everyone when left out */\n\tto?: PlayerId[]\n}\n\n/**\n * How long a line stays when it does not say: long enough to read a sentence\n *\n * @internal\n */\nexport const LINE_SECONDS = 4\n\n/**\n * The line each player hears now, the sequence waiting on it, and the tick it is over at, for skipping. Kept in the\n * world: a save has it\n */\nexport const current = defineComponent<{ next: number; lines: Record<number, { line: number; run?: number; to?: PlayerId[]; until?: number }> }>(\n\t'core.dialog',\n\t{\n\t\tdefault: () => ({ next: 1, lines: {} })\n\t}\n)\n\n/**\n * What is said in a world\n *\n * @beta\n */\nexport class Dialog {\n\tconstructor(private readonly world: World) {}\n\n\t/**\n\t * Says a line, now. On its own it waits for nothing: in a sequence, `talk` says lines one after the other, each\n\t * for as long as it lasts. `run` is the sequence that waits on it, which skipping the line hurries along\n\t */\n\tsay(to: Audience, line: LineDef, run?: number): SaidLine {\n\t\tconst state = this.world.state(current)\n\t\tconst text = toMessage(line.text)\n\t\tconst players = to === 'everyone' ? undefined : Array.isArray(to) ? to : [to]\n\t\tconst said: SaidLine = { id: state.next++, speaker: line.speaker, text, seconds: line.seconds ?? LINE_SECONDS, to: players }\n\t\t// a line that waits to be moved on lasts until it is\n\t\tconst until = Number.isFinite(said.seconds) ? this.world.tick + Math.ceil(said.seconds * this.world.tickRate) : undefined\n\t\tfor (const player of players ?? this.listeners()) state.lines[player] = { line: said.id, run, to: players, ...(until !== undefined && { until }) }\n\t\tthis.world.events.emit(lineSaidEvent, said)\n\t\treturn said\n\t}\n\n\t/**\n\t * A player asks to skip the line they hear: it ends, and a conversation goes on to its next line. Only a line\n\t * said to them alone can be: what others hear too goes on for them\n\t */\n\tskip(player: PlayerId): void {\n\t\tconst state = this.world.state(current)\n\t\tconst heard = state.lines[player]\n\t\tif (!heard || heard.to?.length !== 1 || heard.to[0] !== player) return\n\t\tdelete state.lines[player]\n\t\t// a line that is over is skipped no more: the sequence that said it waits on something else by now (a minute\n\t\t// before the next wave), which skipping it once cut short\n\t\tif (heard.until !== undefined && this.world.tick >= heard.until) return\n\t\tthis.world.events.emit(lineEnded, { id: heard.line, to: [player] })\n\t\tif (heard.run !== undefined) this.world.sequences.hurry(heard.run)\n\t}\n\n\t/** The players a line said to everyone is heard by: everyone who plays */\n\tprivate listeners(): PlayerId[] {\n\t\tconst players: PlayerId[] = []\n\t\tfor (const player of this.world.players.values()) if (!player.neutral) players.push(player.id)\n\t\treturn players\n\t}\n}\n\n/**\n * The steps of a conversation, for a sequence: each line is said and stays for as long as it lasts, then the next.\n * Skipping a line (the `skipLine` command) goes on to the next at once:\n *\n * defineSequence('td.beforeTheBoss', [...talk(DEFENDER, [{ speaker: 'td.commander', text: 'bossComing' }, ...])])\n *\n * @beta\n */\nexport function talk<D = undefined>(to: Audience, lines: LineDef[]): Step<D>[] {\n\treturn lines.flatMap((line): Step<D>[] => [(world, _data, run) => void world.dialog.say(to, line, run), wait(line.seconds ?? LINE_SECONDS)])\n}\n\n/** A line said, to whom it is for: everyone when it names nobody */\nexport const toldLine = replicateEvent(lineSaidEvent, 'line', (line, view) =>\n\t!line.to || line.to.includes(view.player) ? { type: 'line', line: structuredClone(line) } : undefined\n)\n\n/** A line over, to whom it was for */\nexport const toldLineEnded = replicateEvent(lineEnded, 'lineEnded', ({ id, to }, view) =>\n\tto.includes(view.player) ? { type: 'lineEnded', id } : undefined\n)\n","import { effectStarted, effectStopped } from '#engine/engineEvents'\nimport { defineComponent } from './components'\nimport type { Audience } from './dialog'\nimport type { Entity, PlayerId } from './entity'\nimport type { Vec2 } from './math'\nimport { plain } from './plain'\nimport type { World } from './world'\nimport { replicateEvent } from './replication'\nimport type { SessionView } from './replication'\n\n/*\n * Effects are the screen's: fire, a blast, a glow, made and tuned in a game's view (`GameView.fx.defs`). The rules say when\n * one plays, and where, so that every player who sees the place sees it at the same moment (effects plan A3): a mine\n * going off, a shrine waking. Nothing an effect does decides anything in the game; it is not in the world's state, nor\n * in a save. What lasts is shown by what the world keeps (a building's damaged look, a map's own effects)\n */\n\n/**\n * An effect the rules play on the screens, as the engine's `effect` event carries it (`world.effect`)\n *\n * @beta\n */\nexport interface EffectCue {\n\t/** The rules' handle on it, for `world.stopEffect` */\n\tid: number\n\t/** Which of the view's effects, by name (`GameView.fx.defs`) */\n\teffect: string\n\t/** Where: a place, at a height or on the ground */\n\tx?: number\n\ty?: number\n\tz?: number\n\t/** Or on an entity, by its id: it follows it on the screen, at a point of its model */\n\ton?: number\n\tpoint?: string\n\t/** Its knobs, over the effect's own: plain data, as it goes to every screen */\n\tparams?: Record<string, unknown>\n\t/** What its random parts go by: the same on every screen */\n\tseed: number\n\t/** Who sees it: everyone who sees the place when left out */\n\tto?: PlayerId[]\n\t/** Seen over the fog of war, by whom it is for: what is there to be noticed */\n\toverFog?: boolean\n}\n\n/**\n * How the rules play an effect (`world.effect`)\n *\n * @beta\n */\nexport interface EffectOptions {\n\t/** A place: on the ground (`{ x, z }`) or at a height (`{ x, y, z }`) */\n\tat?: Vec2 | { x: number; y: number; z: number }\n\t/** Or an entity: on the screen it follows it, and ends with it */\n\ton?: Entity | number\n\t/** A point of the entity's model (`ModelDef.points`) */\n\tpoint?: string\n\t/** Its knobs, over the effect's own (`EffectDef.params`): plain data */\n\tparams?: Record<string, unknown>\n\t/** What its random parts go by: one made from the tick when left out, the same on every screen all the same */\n\tseed?: number\n\t/** Who sees it: a player, some, or everyone who sees the place (when left out) */\n\tto?: Audience\n\t/** Seen over the fog of war by whom it is for, as what is there to be noticed. No when left out */\n\toverFog?: boolean\n}\n\n/** A number from a tick and a count, the same wherever the game runs */\nconst seedOf = (tick: number, count: number): number => {\n\tlet h = Math.imul(tick ^ 0x9e3779b9, 0x85ebca6b) ^ Math.imul(count + 1, 0xc2b2ae35)\n\th = Math.imul(h ^ (h >>> 16), 0x7feb352d)\n\treturn (h ^ (h >>> 15)) >>> 0\n}\n\n/**\n * How many effects a world played, for their ids and their seeds: the world's, and saved with it, so that the game\n * loaded from a save gives its next effect the id and the seed the game that went on does (and a stop finds its start)\n */\nexport const played = defineComponent<number>('core.effectsPlayed', { default: () => 0 })\n\n/**\n * Plays one of the view's effects on the screens of the players who see where it is (or those it is for), now. What it\n * gives back stops it (`stopEffect`). Not in the world's state but for its count: a save, and a player who joins later,\n * know nothing of the effect itself\n *\n * @beta\n */\nexport function playEffect(world: World, effect: string, options: EffectOptions = {}): number {\n\tconst count = world.state(played) + 1\n\tworld.setState(played, count)\n\tconst { at, on, point, params, seed, to = 'everyone', overFog } = options\n\tconst entity = typeof on === 'number' ? world.get(on) : on\n\tif (on !== undefined && !entity) return count\n\tconst cue: EffectCue = {\n\t\tid: count,\n\t\teffect,\n\t\tseed: seed ?? seedOf(world.tick, count),\n\t\t...(entity ? { on: entity.id, x: entity.pos.x, z: entity.pos.z } : at && { x: at.x, z: at.z, ...('y' in at && { y: at.y }) }),\n\t\t...(point && { point }),\n\t\t...(params && { params: plain(params, `params of the effect \"${effect}\"`, 'EffectOptions') as Record<string, unknown> }),\n\t\t...(to !== 'everyone' && { to: Array.isArray(to) ? to : [to] }),\n\t\t...(overFog && { overFog })\n\t}\n\tworld.events.emit(effectStarted, cue)\n\treturn count\n}\n\n/**\n * Stops an effect the rules played (`playEffect`), on every screen: as its own `stop` says, over `fade` seconds\n *\n * @beta\n */\nexport function stopEffect(world: World, id: number, options: { fade?: number } = {}): void {\n\tworld.events.emit(effectStopped, { id, ...(options.fade !== undefined && { fade: options.fade }) })\n}\n\n/** The effects of the rules a seat was shown, by id, for a stop to be told to whom saw the start: the latest so many */\nconst SHOWN = {}\n\n/**\n * The effects of the rules a seat was shown (`LocalSession.keptEffects`)\n *\n * @internal\n */\nexport const shownEffects = (view: SessionView): Set<number> => view.keep(SHOWN, () => new Set<number>())\n\n/** An effect the rules play: to whom it is for, who sees where it is (what is there to be noticed, over the fog) */\nexport const toldEffect = replicateEvent(effectStarted, 'fx', ({ id, effect, to, overFog, on, ...rest }, view) => {\n\tif (to && !to.includes(view.player)) return undefined\n\tconst entity = on === undefined ? undefined : view.world.get(on)\n\tconst seen = entity ? view.knows(entity) || (!!overFog && !entity.hidden) : rest.x === undefined || overFog || view.sees(rest.x, rest.z!)\n\tif (!seen) return undefined\n\tconst shown = shownEffects(view)\n\tshown.add(id)\n\t// most are never stopped: the oldest are let go of, as a stop that late has nothing left to stop\n\tif (shown.size > view.mostEffects) shown.delete(shown.values().next().value!)\n\treturn { type: 'fx', id, fx: effect, ...rest, ...(on !== undefined && { on }), ...(overFog && { overFog }) }\n})\n\n/** An effect stopped: to whom saw it start */\nexport const toldEffectStopped = replicateEvent(effectStopped, 'fxStop', ({ id, fade }, view) =>\n\tshownEffects(view).delete(id) ? { type: 'fxStop', id, ...(fade !== undefined && { fade }) } : undefined\n)\n","import { gameOver, objectiveChanged as objectiveChangedEvent } from '#engine/engineEvents'\nimport { defineComponent } from './components'\nimport type { PlayerId } from './entity'\nimport { type Message, type MessageRef, toMessage } from './messages'\nimport type { System } from './registry'\nimport { defeat } from './systems/victory'\nimport type { World } from './world'\nimport { replicateEvent } from './replication'\n\n/**\n * What a player is set to do, in a mission: survive ten waves, keep the hero alive, build a frost tower\n *\n * @beta\n */\nexport interface ObjectiveDef {\n\t/** Shared by every game, like other ids: give it a prefix of the game's (`'td.hold'`) */\n\tid: string\n\t/** What it says, in the words of the game: a message key, with params where it shows numbers */\n\ttext: MessageRef\n\t/** Whether the mission needs it: all of them done is a victory, one failed a defeat. True when left out */\n\trequired?: boolean\n\t/** More about it, in the words of the game: shown under it when the player opens it in the quest panel (campaign plan CP5) */\n\tdetail?: MessageRef\n}\n\n/**\n * Typed help for writing one\n *\n * @beta\n */\nexport const defineObjective = (def: ObjectiveDef): ObjectiveDef => def\n\n/** @beta */\nexport type ObjectiveStatus = 'open' | 'done' | 'failed'\n\n/**\n * An objective of a player, as it stands. Plain data: it is kept in the player's state, and sent to their screen\n *\n * @beta\n */\nexport interface ObjectiveState {\n\tid: string\n\ttext: Message\n\trequired: boolean\n\tstatus: ObjectiveStatus\n\t/** How far along it is, for the ones that count: 3 of 10 waves */\n\tprogress?: { value: number; max: number }\n\t/** Why it failed, for a failed one that says */\n\treason?: Message\n\t/** More about it (`ObjectiveDef.detail`) */\n\tdetail?: Message\n}\n\n/** A player's objectives, in the order they were given */\nexport const objectives = defineComponent<ObjectiveState[]>('core.objectives', { default: () => [] })\n\n/**\n * The objectives of the players of a world. What changes in them is the engine's `objectiveChanged` event, which\n * the player is shown, and which a game's listeners and sequences can wait for\n *\n * @beta\n */\nexport class Objectives {\n\tconstructor(private readonly world: World) {}\n\n\t/** Gives a player an objective, open. Its words' params and its progress can be given with it */\n\tadd(player: PlayerId, def: ObjectiveDef, options: { params?: Message['params']; progress?: { value: number; max: number } } = {}): ObjectiveState {\n\t\tconst list = this.of(player) as ObjectiveState[]\n\t\tif (list.some((objective) => objective.id === def.id)) throw new Error(`Player ${player} has the objective \"${def.id}\" already`)\n\t\tconst text = toMessage(def.text)\n\t\tconst objective: ObjectiveState = {\n\t\t\tid: def.id,\n\t\t\ttext: options.params ? { key: text.key, params: { ...text.params, ...options.params } } : text,\n\t\t\trequired: def.required ?? true,\n\t\t\tstatus: 'open',\n\t\t\tprogress: options.progress && { ...options.progress },\n\t\t\t...(def.detail !== undefined && { detail: toMessage(def.detail) })\n\t\t}\n\t\tlist.push(objective)\n\t\tthis.changed(player, objective, undefined)\n\t\treturn objective\n\t}\n\n\t/** Done. Only an open one can be */\n\tcomplete(player: PlayerId, id: string): void {\n\t\tthis.settle(player, id, 'done')\n\t}\n\n\t/** Failed, and why when that is worth saying. Only an open one can be */\n\tfail(player: PlayerId, id: string, reason?: MessageRef): void {\n\t\tthis.settle(player, id, 'failed', reason === undefined ? undefined : toMessage(reason))\n\t}\n\n\t/** How far along an open one is. Its words' params can change with it: \"wave 3 of 10\" */\n\tprogress(player: PlayerId, id: string, value: number, options: { max?: number; params?: Message['params'] } = {}): void {\n\t\tconst objective = this.get(player, id)\n\t\tif (objective.status !== 'open') return\n\t\tconst max = options.max ?? objective.progress?.max ?? 1\n\t\tif (objective.progress?.value === value && objective.progress.max === max && !options.params) return\n\t\tobjective.progress = { value, max }\n\t\tif (options.params) objective.text = { key: objective.text.key, params: { ...objective.text.params, ...options.params } }\n\t\tthis.changed(player, objective, 'open')\n\t}\n\n\t/** A player's objectives, in the order they were given */\n\tof(player: PlayerId): readonly ObjectiveState[] {\n\t\treturn this.world.player(player).state(objectives)\n\t}\n\n\tget(player: PlayerId, id: string): ObjectiveState {\n\t\tconst objective = this.of(player).find((candidate) => candidate.id === id)\n\t\tif (!objective) throw new Error(`Player ${player} has no objective \"${id}\"`)\n\t\treturn objective\n\t}\n\n\t/** Whether a player has the objective, open or not */\n\thas(player: PlayerId, id: string): boolean {\n\t\treturn this.of(player).some((objective) => objective.id === id)\n\t}\n\n\tprivate settle(player: PlayerId, id: string, status: 'done' | 'failed', reason?: Message): void {\n\t\tconst objective = this.get(player, id)\n\t\tif (objective.status !== 'open') return\n\t\tobjective.status = status\n\t\tif (reason) objective.reason = reason\n\t\tthis.changed(player, objective, 'open')\n\t}\n\n\tprivate changed(player: PlayerId, objective: ObjectiveState, was: ObjectiveStatus | undefined): void {\n\t\tthis.world.events.emit(objectiveChangedEvent, { player, objective, was })\n\t}\n}\n\n/**\n * The rule of a mission: a player who failed an objective the mission needs is out, and a player who did all of\n * them wins, for their team. Like a melee game, a team whose players are all out loses, and the last team standing\n * wins. A game uses it as its `victory`\n *\n * @beta\n */\nexport const objectiveVictory: System = {\n\tname: 'victory',\n\tphase: 'cleanup',\n\tupdate(world) {\n\t\tif (world.winner !== null) return\n\t\tfor (const player of world.players.values()) {\n\t\t\tif (player.neutral || player.defeated) continue\n\t\t\tconst required = world.objectives.of(player.id).filter((objective) => objective.required)\n\t\t\tif (required.some((objective) => objective.status === 'failed')) defeat(world, player.id)\n\t\t\telse if (required.length && required.every((objective) => objective.status === 'done')) return win(world, player.team)\n\t\t}\n\t\t// the last team with anyone still in it\n\t\tconst standing = new Set<number>()\n\t\tfor (const player of world.players.values()) if (!player.neutral && !player.defeated) standing.add(player.team)\n\t\tif (standing.size === 1) win(world, [...standing][0])\n\t}\n}\n\nfunction win(world: World, team: number): void {\n\tworld.winner = team\n\tworld.events.emit(gameOver, { winner: team })\n}\n\n/** An objective changed, to whose it is */\nexport const toldObjective = replicateEvent(objectiveChangedEvent, 'objective', ({ player, objective, was }, view) =>\n\tplayer === view.player ? { type: 'objective', objective: structuredClone(objective), was } : undefined\n)\n","import {\n\tgameOver,\n\tabilityCast,\n\tbounty as bountyEvent,\n\tconstructionFinished,\n\tdamaged,\n\tentityDied as entityDiedEvent,\n\thealed,\n\theroLevelUp,\n\titemPicked,\n\tresourcesDeposited,\n\tresourcesSpent,\n\ttraded,\n\tunitHired,\n\tunitTrained,\n\txpGained\n} from '#engine/engineEvents'\nimport { defineComponent, type Component } from './components'\nimport type { Entity, PlayerId } from './entity'\nimport type { EventKey } from './events'\nimport type { GameModule } from './game'\nimport type { System } from './registry'\nimport type { World } from './world'\nimport { heroOf, heroState } from './hero'\nimport { snapshotPart } from './replication'\nimport type { SessionView } from './replication'\n\n/*\n * The score (a classic RTS score screen): numbers about each player that the rules count as the game goes, from the\n * world's events and from the game's own code. Counted where the rules run, so every machine has the same; kept in the\n * world's state (`core.score`), so a save and a replay have them; told to the players in their snapshots\n * (`Snapshot.score`), each the players the game lets them see (`ScoreRules.live`, `end`). Nothing is counted for a\n * game that does not ask (`GameRules.score`); `presetScore()` is the engine's whole set, to take or pick from.\n */\n\n/**\n * How a stat takes what it is told: `sum` adds it up (the default), `count` adds one each time whatever the amount,\n * `max` keeps the most it was told, `min` the least, `last` what it was told last (a gauge: the army now)\n *\n * @beta\n */\nexport type ScoreKind = 'sum' | 'count' | 'max' | 'min' | 'last'\n\n/**\n * How a stat's number reads on a screen: a whole `number` (the default), a `decimal` one, a `percent` (0..1), or\n * `time` (seconds, as 3:05). A screen's own (`GameView.hud.score.format`) goes over it\n *\n * @beta\n */\nexport type ScoreFormat = 'number' | 'decimal' | 'percent' | 'time'\n\n/**\n * What a stat is told of an event, for a player: how much (`amount`, 1 when left out) and what of (`type`: a unit\n * type, an ability, anything the stat is split by, `ScoreStatDef.byType`)\n *\n * @beta\n */\nexport interface ScoreCount {\n\t/** Whose number it is */\n\tplayer: PlayerId\n\t/** How much: 1 when left out */\n\tamount?: number\n\t/** What it was counted of, for a stat kept `byType`: a unit type, an ability */\n\ttype?: string\n}\n\n/**\n * What a stat's source makes of an event: nothing to count (`undefined`), one player (one more for them), what one\n * player is counted, or several of those\n *\n * @beta\n */\nexport type ScoreCounted = PlayerId | ScoreCount | readonly ScoreCount[] | undefined | void\n\n/**\n * Where a stat's numbers come from: an event of the world's (`'entityDied'`) or of the game's own (`defineEvent`), and\n * what it counts of each (`scoreOn`)\n *\n * @beta\n */\nexport interface ScoreSource {\n\t/** The event: one of the engine's (`entityDied`) or of the game's own (`defineEvent`) */\n\tevent: EventKey<any>\n\t/** What it counts of each: nothing, a player, or what a player is counted */\n\tcount(payload: any, world: World): ScoreCounted\n}\n\n/**\n * A number the score keeps for each player (`GameRules.score`, `defineStat`): what it is called, how it adds up, where\n * it comes from, and how it is shown. One with no source is counted by the game's code alone (`world.score.add`)\n *\n * @beta\n */\nexport interface ScoreStatDef {\n\t/** Its own, among the game's stats: `world.score.add(player, id, …)` names it */\n\tid: string\n\t/** What it is called on a screen: its id when left out */\n\tlabel?: string\n\t/** What the screen says it is, in a tip */\n\tdescription?: string\n\t/** The tab of the score screen it is in: `units`, `heroes`, `resources`, `combat`, or the game's own. `other` when left out */\n\tcategory?: string\n\t/** How it adds up: `sum` when left out, `last` for one that only samples */\n\tkind?: ScoreKind\n\t/** The events it is counted from */\n\tfrom?: ScoreSource | readonly ScoreSource[]\n\t/**\n\t * A gauge: what it is for a player now (their supply used, their gold), read once a second and at each point of the\n\t * timeline, and taken as `kind` says (`last` when left out). Nothing taken for `undefined`\n\t */\n\tsample?(world: World, player: PlayerId): number | undefined\n\t/** Kept by what it was counted of too (`ScoreCount.type`): units killed by unit type, abilities cast by ability */\n\tbyType?: boolean\n\t/** On the timeline: sampled every `ScoreRules.every` seconds, for a screen's graph */\n\ttimeline?: boolean\n\t/** How its number is written: `number` (when left out), `decimal`, `percent` (0 to 1), `time` (seconds) */\n\tformat?: ScoreFormat\n\t/** Counted, and not on the score screen: for the game's own use (an achievement, a mission's goal) */\n\thidden?: boolean\n}\n\n/**\n * Who of the players is told a player's numbers: that player alone (`own`), their side (`allies`), `everyone`, or\n * `none`; or a function of the world, who is told (`undefined` for an observer) and whose numbers they are\n *\n * @beta\n */\nexport type ScoreAudience = 'own' | 'allies' | 'everyone' | 'none' | ((world: World, viewer: PlayerId | undefined, player: PlayerId) => boolean)\n\n/**\n * What a game counts of its players (`GameRules.score`): the stats, how often the timeline is sampled, and who is told\n * what while the game goes on and after it ended. `presetScore()` makes one of the engine's stats\n *\n * @beta\n */\nexport interface ScoreRules {\n\t/** The stats, or what makes them of the game (the engine's set makes one of each resource) */\n\tstats: readonly ScoreStatDef[] | ((game: GameModule) => readonly ScoreStatDef[])\n\t/** Seconds between two points of the timeline: 10 when left out, 0 for no timeline */\n\tevery?: number\n\t/**\n\t * Points the timeline keeps at most: past it, every other point goes and they are twice as far apart, so a long\n\t * game keeps its whole story in as much room. 360 when left out\n\t */\n\tmaxPoints?: number\n\t/** Who is told a player's numbers while the game goes on: their side (`allies`) when left out. An observer is told everyone's */\n\tlive?: ScoreAudience\n\t/** Who is told them once the game is decided: `everyone` when left out */\n\tend?: ScoreAudience\n\t/** Seconds between two tellings of the numbers to the screens while the game goes on: 1 when left out */\n\trefresh?: number\n\t/** Whose numbers are kept: every player but the neutral ones and the creeps when left out */\n\tcounts?(world: World, player: PlayerId): boolean\n\t/** The tabs of the score screen, in order, with their names: those of the stats, in the order met, when left out */\n\tcategories?: readonly { id: string; label: string }[]\n}\n\n/**\n * The score's rules, its stats made: what the registry keeps (`registry.score`)\n *\n * @beta\n */\nexport interface ResolvedScore {\n\t/** The rules as the game gave them */\n\treadonly rules: ScoreRules\n\t/** Every stat, made */\n\treadonly stats: readonly ScoreStatDef[]\n\t/** Every stat by its id */\n\treadonly byId: ReadonlyMap<string, ScoreStatDef>\n\t/** The tabs of the score screen, in order */\n\treadonly categories: readonly { id: string; label: string }[]\n}\n\n/**\n * What the score keeps in the world (`world.state(scoreData)`), plain data for a save: by stat, by player, the number;\n * by stat, player and type, the numbers of a stat kept `byType`; the ticks of the timeline's points, and by stat and\n * player, the number at each\n *\n * @beta\n */\nexport interface ScoreData {\n\t/** By stat, by player: the number */\n\tvalues: Record<string, Record<number, number>>\n\t/** By stat, player and type: the numbers of a stat kept `byType` */\n\ttypes: Record<string, Record<number, Record<string, number>>>\n\t/** Ticks between two points of the timeline, as it is now (doubled each time it was thinned) */\n\tevery: number\n\t/** The ticks of the timeline's points */\n\tticks: number[]\n\t/** By stat and player: the number at each point of the timeline */\n\tline: Record<string, Record<number, number[]>>\n}\n\n/**\n * The world's component the score is kept in (`core.score`, on the world's own entity): what a save keeps of it\n *\n * @beta\n */\nexport const scoreData: Component<ScoreData> = defineComponent<ScoreData>('core.score', {\n\tdefault: () => ({ values: {}, types: {}, every: 0, ticks: [], line: {} })\n})\n\n/**\n * What a player is told of the score (`Snapshot.score`): the numbers of the players they may see, as they stood at\n * `tick`. Rounded to hundredths\n *\n * @beta\n */\nexport interface ScoreState {\n\t/** The tick the numbers stood at */\n\ttick: number\n\t/** The game is decided: these are the numbers it ended with, told as `ScoreRules.end` says */\n\tfinal: boolean\n\t/** Whose numbers are in it */\n\tplayers: PlayerId[]\n\t/** By stat, by player */\n\tvalues: Record<string, Record<number, number>>\n\t/** By stat, by player, by type: of the stats kept `byType` */\n\ttypes?: Record<string, Record<number, Record<string, number>>>\n}\n\n/**\n * The timeline a player is told (`Snapshot.scoreLine`): the ticks of its points, and by stat and player the number at\n * each, for the players they may see\n *\n * @beta\n */\nexport interface ScoreLineState {\n\t/** Seconds between two points */\n\tevery: number\n\t/** The ticks of its points */\n\tticks: number[]\n\t/** By stat and player: the number at each point */\n\tvalues: Record<string, Record<number, number[]>>\n}\n\n/**\n * A source of a stat, typed by its event, the engine's or the game's own: `scoreOn(entityDied, ({ entity, killer }) =>\n * killer && { player: killer.owner })`\n *\n * @beta\n */\nexport function scoreOn<T>(event: EventKey<T>, count: (payload: T, world: World) => ScoreCounted): ScoreSource {\n\treturn { event, count }\n}\n\n/**\n * A stat of the game's own, for `GameRules.score`: `defineStat('towersLost', { label: 'Towers lost', category: 'units',\n * from: scoreOn(entityDied, ({ entity }) => entity.def.tags?.includes('tower') ? entity.owner : undefined) })`.\n * One with no source is counted in code (`world.score.add(player, 'towersLost')`)\n *\n * @beta\n */\nexport function defineStat(id: string, def: Omit<ScoreStatDef, 'id'> = {}): ScoreStatDef {\n\treturn { id, ...def }\n}\n\nconst CATEGORY_LABELS: Record<string, string> = { units: 'Units', heroes: 'Heroes', resources: 'Resources', combat: 'Combat', other: 'Other' }\n\n/** The score's rules with their stats made of the game, checked: an id twice, or a timeline of no length, throws */\nexport function resolveScore(rules: ScoreRules | undefined | null, game: GameModule): ResolvedScore | null {\n\tif (!rules) return null\n\tconst stats = typeof rules.stats === 'function' ? rules.stats(game) : rules.stats\n\tconst byId = new Map<string, ScoreStatDef>()\n\tfor (const stat of stats) {\n\t\tif (byId.has(stat.id)) throw new Error(`The score has the stat \"${stat.id}\" twice`)\n\t\tbyId.set(stat.id, stat)\n\t}\n\tif (rules.every !== undefined && !(rules.every >= 0)) throw new Error(`The score's timeline is sampled every ${rules.every} seconds: 0 or more`)\n\tconst categories = [...(rules.categories ?? [])]\n\tfor (const stat of stats) {\n\t\tconst id = stat.category ?? 'other'\n\t\tif (!stat.hidden && !categories.some((category) => category.id === id)) categories.push({ id, label: CATEGORY_LABELS[id] ?? id })\n\t}\n\treturn { rules, stats, byId, categories }\n}\n\n/** What a kind makes of a number and what is told */\nfunction combine(kind: ScoreKind | undefined, before: number | undefined, amount: number): number {\n\tswitch (kind) {\n\t\tcase 'count':\n\t\t\treturn (before ?? 0) + 1\n\t\tcase 'max':\n\t\t\treturn before === undefined ? amount : Math.max(before, amount)\n\t\tcase 'min':\n\t\t\treturn before === undefined ? amount : Math.min(before, amount)\n\t\tcase 'last':\n\t\t\treturn amount\n\t\tdefault:\n\t\t\treturn (before ?? 0) + amount\n\t}\n}\n\n/** Rounded to hundredths, for the wire */\nconst hundredths = (value: number) => Math.round(value * 100) / 100\n\n/**\n * The score of a world (`world.score`): counts what its stats are told of the world's events, takes the gauges and\n * the timeline's points, and is what the game's code counts with, and reads, in the rules. What it keeps is the\n * world's state (`scoreData`); nothing of it is kept here but what is made again from the game\n *\n * @beta\n */\nexport class Score {\n\t/** Goes up with every change of a number: what a session tells the screens again by */\n\tversion = 0\n\t/** Goes up with every point of the timeline */\n\tlineVersion = 0\n\tprivate offs: (() => void)[] = []\n\n\tconstructor(private readonly world: World) {\n\t\tthis.listen()\n\t}\n\n\t/** The game's score, as its rules say: none for a game that counts nothing */\n\tget rules(): ResolvedScore | null {\n\t\treturn this.world.registry.score\n\t}\n\n\t/** Whether the game counts anything */\n\tget on(): boolean {\n\t\treturn this.world.registry.score !== null\n\t}\n\n\t/** The stats, in order */\n\tstats(): readonly ScoreStatDef[] {\n\t\treturn this.rules?.stats ?? []\n\t}\n\n\t/** Hears the events the stats are counted from: again when the game takes a new version (`reloadGame`) */\n\tlisten(): void {\n\t\tfor (const off of this.offs) off()\n\t\tthis.offs = []\n\t\tconst score = this.rules\n\t\tif (!score) return\n\t\tconst byEvent = new Map<string, { key: EventKey<unknown>; list: { stat: ScoreStatDef; source: ScoreSource }[] }>()\n\t\tfor (const stat of score.stats) {\n\t\t\tconst sources = !stat.from ? [] : Array.isArray(stat.from) ? (stat.from as readonly ScoreSource[]) : [stat.from as ScoreSource]\n\t\t\tfor (const source of sources) {\n\t\t\t\tlet heard = byEvent.get(source.event.id)\n\t\t\t\tif (!heard) byEvent.set(source.event.id, (heard = { key: source.event, list: [] }))\n\t\t\t\theard.list.push({ stat, source })\n\t\t\t}\n\t\t}\n\t\tconst world = this.world\n\t\tfor (const { key, list } of byEvent.values()) {\n\t\t\tthis.offs.push(\n\t\t\t\tworld.events.on(key, (payload: unknown) => {\n\t\t\t\t\tfor (let i = 0; i < list.length; i++) {\n\t\t\t\t\t\tconst { stat, source } = list[i]\n\t\t\t\t\t\t// one switched off for having thrown counts nothing more\n\t\t\t\t\t\tif (world.disabled.size && world.disabled.has(`listener:score:${stat.id}`)) continue\n\t\t\t\t\t\tlet counted: ScoreCounted\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tcounted = source.count(payload, world)\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tworld.caught(error, { kind: 'listener', id: `score:${stat.id}` })\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.take(stat, counted)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\t\t// the last of the gauges and a last point, as the game is decided\n\t\tthis.offs.push(world.events.on(gameOver, () => this.sample(true)))\n\t}\n\n\tprivate take(stat: ScoreStatDef, counted: ScoreCounted): void {\n\t\tif (counted === undefined || counted === null) return\n\t\tif (typeof counted === 'number') this.put(stat, counted, 1, undefined)\n\t\telse if (Array.isArray(counted)) for (const each of counted as readonly ScoreCount[]) this.put(stat, each.player, each.amount ?? 1, each.type)\n\t\telse {\n\t\t\tconst each = counted as ScoreCount\n\t\t\tthis.put(stat, each.player, each.amount ?? 1, each.type)\n\t\t}\n\t}\n\n\t/** Whether a player's numbers are kept: as the rules say, every player but the neutral ones and the creeps when they do not */\n\tcounts(player: PlayerId): boolean {\n\t\tconst own = this.rules?.rules.counts\n\t\tif (own) return own(this.world, player)\n\t\tconst found = this.world.players.get(player)\n\t\treturn !!found && !found.neutral && !found.creeps\n\t}\n\n\t/** Who `counts`, by player id, where the rules leave it to the engine (whether a player is neutral never changes) */\n\tprivate counted: boolean[] = []\n\n\t/** The players whose numbers are kept, by id */\n\tplayers(): PlayerId[] {\n\t\tconst players: PlayerId[] = []\n\t\tfor (const id of this.world.players.keys()) if (this.counts(id)) players.push(id)\n\t\treturn players.sort((a, b) => a - b)\n\t}\n\n\tprivate put(stat: ScoreStatDef, player: PlayerId, amount: number, type: string | undefined): void {\n\t\tif (!Number.isFinite(amount)) return\n\t\tif (this.rules!.rules.counts ? !this.counts(player) : !(this.counted[player] ??= this.counts(player))) return\n\t\tconst data = this.world.state(scoreData)\n\t\tconst values = (data.values[stat.id] ??= {})\n\t\tvalues[player] = combine(stat.kind, values[player], amount)\n\t\tif (stat.byType && type !== undefined) {\n\t\t\tconst types = ((data.types[stat.id] ??= {})[player] ??= {})\n\t\t\ttypes[type] = combine(stat.kind, types[type], amount)\n\t\t}\n\t\tthis.version++\n\t}\n\n\tprivate stat(id: string): ScoreStatDef {\n\t\tconst stat = this.rules?.byId.get(id)\n\t\tif (!stat) {\n\t\t\tthrow new Error(\n\t\t\t\tthis.rules\n\t\t\t\t\t? `The score has no stat \"${id}\": give it in GameRules.score (defineStat)`\n\t\t\t\t\t: `The game counts no score: give GameRules.score (presetScore(), or stats of its own) to count \"${id}\"`\n\t\t\t)\n\t\t}\n\t\treturn stat\n\t}\n\n\t/** Counts something for a player, as the stat's kind takes it (adds it up for a sum): one when no amount is given */\n\tadd(player: PlayerId, id: string, amount = 1, type?: string): void {\n\t\tthis.put(this.stat(id), player, amount, type)\n\t}\n\n\t/** Sets a player's number, whatever the stat's kind */\n\tset(player: PlayerId, id: string, value: number, type?: string): void {\n\t\tthis.put({ ...this.stat(id), kind: 'last' }, player, value, type)\n\t}\n\n\t/** A player's number of a stat: 0 for one never counted */\n\tget(player: PlayerId, id: string): number {\n\t\treturn this.world.state(scoreData).values[id]?.[player] ?? 0\n\t}\n\n\t/** A player's numbers of a stat kept by type, by type */\n\tbyType(player: PlayerId, id: string): Readonly<Record<string, number>> {\n\t\treturn this.world.state(scoreData).types[id]?.[player] ?? {}\n\t}\n\n\t/** A team's number of a stat: its players' added up, or the most or the least of them for `max` and `min` */\n\tteam(team: number, id: string): number {\n\t\tconst stat = this.stat(id)\n\t\tlet total: number | undefined\n\t\tfor (const player of this.players()) {\n\t\t\tif (this.world.player(player).team !== team) continue\n\t\t\tconst value = this.get(player, id)\n\t\t\ttotal = stat.kind === 'max' || stat.kind === 'min' ? (total === undefined ? value : combine(stat.kind, total, value)) : (total ?? 0) + value\n\t\t}\n\t\treturn total ?? 0\n\t}\n\n\t/** The timeline of a player's number of a stat on it: its points, at `ticks` */\n\ttimeline(player: PlayerId, id: string): { ticks: readonly number[]; values: readonly number[] } {\n\t\tconst data = this.world.state(scoreData)\n\t\treturn { ticks: data.ticks, values: data.line[id]?.[player] ?? [] }\n\t}\n\n\t/** Reads the gauges, and on a point of the timeline (or `point`) takes a point. Run once a second by the score's system */\n\tsample(point = false): void {\n\t\tconst score = this.rules\n\t\tif (!score) return\n\t\tconst { world } = this\n\t\tconst players = this.players()\n\t\tfor (const stat of score.stats) {\n\t\t\tif (!stat.sample || (world.disabled.size && world.disabled.has(`system:score:${stat.id}`))) continue\n\t\t\tconst kind = stat.kind ?? 'last'\n\t\t\tfor (const player of players) {\n\t\t\t\tlet value: number | undefined\n\t\t\t\ttry {\n\t\t\t\t\tvalue = stat.sample(world, player)\n\t\t\t\t} catch (error) {\n\t\t\t\t\tworld.caught(error, { kind: 'system', id: `score:${stat.id}` })\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (value !== undefined) this.put(stat.kind ? stat : { ...stat, kind }, player, value, undefined)\n\t\t\t}\n\t\t}\n\t\tconst data = world.state(scoreData)\n\t\tconst every = Math.round((score.rules.every ?? 10) * world.tickRate)\n\t\tif (every <= 0) return\n\t\tif (!data.every) data.every = every\n\t\tconst due = data.ticks.length === 0 || world.tick - data.ticks[data.ticks.length - 1] >= data.every\n\t\tif (!due && !(point && data.ticks[data.ticks.length - 1] !== world.tick)) return\n\t\tdata.ticks.push(world.tick)\n\t\tfor (const stat of score.stats) {\n\t\t\tif (!stat.timeline) continue\n\t\t\tconst line = (data.line[stat.id] ??= {})\n\t\t\tfor (const player of players) {\n\t\t\t\tconst points = (line[player] ??= [])\n\t\t\t\t// a player whose numbers began to be kept late starts at nothing\n\t\t\t\twhile (points.length < data.ticks.length - 1) points.push(0)\n\t\t\t\tpoints.push(data.values[stat.id]?.[player] ?? 0)\n\t\t\t}\n\t\t}\n\t\t// a long game keeps its whole story: every other point goes, and they are twice as far apart\n\t\tconst max = Math.max(score.rules.maxPoints ?? 360, 8)\n\t\tif (data.ticks.length > max) {\n\t\t\tconst keep = (list: number[]) => list.filter((_, i) => i % 2 === 0 || i === list.length - 1)\n\t\t\tdata.ticks = keep(data.ticks)\n\t\t\tfor (const lines of Object.values(data.line)) for (const player in lines) lines[player] = keep(lines[player])\n\t\t\tdata.every *= 2\n\t\t}\n\t\tthis.lineVersion++\n\t\tthis.version++\n\t}\n\n\t/** Whether `viewer` (`undefined` for an observer) is told `player`'s numbers now */\n\ttells(viewer: PlayerId | undefined, player: PlayerId, final: boolean): boolean {\n\t\tconst rules = this.rules?.rules\n\t\tif (!rules) return false\n\t\tconst audience = final ? (rules.end ?? 'everyone') : (rules.live ?? 'allies')\n\t\tif (typeof audience === 'function') return audience(this.world, viewer, player)\n\t\tif (audience === 'none') return false\n\t\tif (viewer === undefined || audience === 'everyone') return true\n\t\tif (audience === 'own') return viewer === player\n\t\treturn viewer === player || this.world.player(viewer).team === this.world.player(player).team\n\t}\n\n\t/** What `viewer` is told of the numbers (`Snapshot.score`): nothing for a game that counts none, or a viewer told of no one */\n\tstateFor(viewer: PlayerId | undefined, final: boolean): ScoreState | undefined {\n\t\tconst score = this.rules\n\t\tif (!score) return undefined\n\t\tconst players = this.players().filter((player) => this.tells(viewer, player, final))\n\t\tif (!players.length) return undefined\n\t\tconst data = this.world.state(scoreData)\n\t\tconst values: ScoreState['values'] = {}\n\t\tlet types: ScoreState['types']\n\t\tfor (const stat of score.stats) {\n\t\t\tconst all = data.values[stat.id]\n\t\t\tif (all) {\n\t\t\t\tconst told: Record<number, number> = {}\n\t\t\t\tfor (const player of players) if (player in all) told[player] = hundredths(all[player])\n\t\t\t\tvalues[stat.id] = told\n\t\t\t}\n\t\t\tconst byType = stat.byType ? data.types[stat.id] : undefined\n\t\t\tif (byType) {\n\t\t\t\tconst told: Record<number, Record<string, number>> = {}\n\t\t\t\tfor (const player of players) {\n\t\t\t\t\tif (!byType[player]) continue\n\t\t\t\t\tconst each: Record<string, number> = {}\n\t\t\t\t\tfor (const type in byType[player]) each[type] = hundredths(byType[player][type])\n\t\t\t\t\ttold[player] = each\n\t\t\t\t}\n\t\t\t\t;(types ??= {})[stat.id] = told\n\t\t\t}\n\t\t}\n\t\treturn { tick: this.world.tick, final, players, values, ...(types && { types }) }\n\t}\n\n\t/** What `viewer` is told of the timeline (`Snapshot.scoreLine`): nothing without one */\n\tlineFor(viewer: PlayerId | undefined, final: boolean): ScoreLineState | undefined {\n\t\tconst score = this.rules\n\t\tif (!score) return undefined\n\t\tconst data = this.world.state(scoreData)\n\t\tif (!data.ticks.length) return undefined\n\t\tconst players = this.players().filter((player) => this.tells(viewer, player, final))\n\t\tif (!players.length) return undefined\n\t\tconst values: ScoreLineState['values'] = {}\n\t\tfor (const stat in data.line) {\n\t\t\tconst told: Record<number, number[]> = {}\n\t\t\tfor (const player of players) if (data.line[stat][player]) told[player] = data.line[stat][player].map(hundredths)\n\t\t\tvalues[stat] = told\n\t\t}\n\t\treturn { every: data.every / this.world.tickRate, ticks: [...data.ticks], values }\n\t}\n}\n\n/** The score's system: the gauges once a second, a point of the timeline when one is due. Only in a game that counts */\nexport function scoreSystem(world: World): System {\n\treturn {\n\t\tname: 'score',\n\t\tphase: 'cleanup',\n\t\tevery: Math.max(Math.round(world.tickRate), 1),\n\t\tupdate: (world) => world.score.sample()\n\t}\n}\n\n// ---- the engine's stats (`presetScore`)\n\nconst enemies = (world: World, a: PlayerId, b: PlayerId) => world.areEnemies(a, b)\n\n/** Whether a death is a loss: what was cancelled, ran out, was removed, a tree felled or a mine dry is not */\nconst lost = (reason: string) =>\n\treason !== 'cancelled' && reason !== 'expired' && reason !== 'removed' && reason !== 'depleted' && reason !== 'felled'\n\nconst killedBy = (world: World, entity: Entity, killer: Entity | undefined) =>\n\tkiller && enemies(world, killer.owner, entity.owner) ? killer.owner : undefined\n\n/**\n * The stats `presetScore` has, by id, those of each resource made of the game (`gathered.gold`, `spent.gold`...)\n *\n * @beta\n */\nexport function engineStats(game: GameModule): ScoreStatDef[] {\n\tconst resources = game.resources ?? []\n\tconst currency = game.currency ?? resources[0]?.id\n\treturn [\n\t\t// units\n\t\tdefineStat('unitsProduced', {\n\t\t\tlabel: 'Units produced',\n\t\t\tcategory: 'units',\n\t\t\tbyType: true,\n\t\t\tfrom: [\n\t\t\t\tscoreOn(unitTrained, ({ unit }) => ({ player: unit.owner, type: unit.def.id })),\n\t\t\t\tscoreOn(unitHired, ({ unit, player }) => ({ player, type: unit.def.id }))\n\t\t\t]\n\t\t}),\n\t\tdefineStat('unitsKilled', {\n\t\t\tlabel: 'Units killed',\n\t\t\tcategory: 'units',\n\t\t\tbyType: true,\n\t\t\ttimeline: true,\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, killer }, world) => {\n\t\t\t\tif (!entity.isUnit) return undefined\n\t\t\t\tconst by = killedBy(world, entity, killer)\n\t\t\t\treturn by === undefined ? undefined : { player: by, type: entity.def.id }\n\t\t\t})\n\t\t}),\n\t\tdefineStat('unitsLost', {\n\t\t\tlabel: 'Units lost',\n\t\t\tcategory: 'units',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, reason }) =>\n\t\t\t\tentity.isUnit && lost(reason) ? { player: entity.owner, type: entity.def.id } : undefined\n\t\t\t)\n\t\t}),\n\t\tdefineStat('buildingsBuilt', {\n\t\t\tlabel: 'Buildings built',\n\t\t\tcategory: 'units',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(constructionFinished, (building) => ({ player: building.owner, type: building.def.id }))\n\t\t}),\n\t\tdefineStat('buildingsRazed', {\n\t\t\tlabel: 'Buildings razed',\n\t\t\tcategory: 'units',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, killer }, world) => {\n\t\t\t\tif (!entity.isBuilding) return undefined\n\t\t\t\tconst by = killedBy(world, entity, killer)\n\t\t\t\treturn by === undefined ? undefined : { player: by, type: entity.def.id }\n\t\t\t})\n\t\t}),\n\t\tdefineStat('buildingsLost', {\n\t\t\tlabel: 'Buildings lost',\n\t\t\tcategory: 'units',\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, reason }) => (entity.isBuilding && lost(reason) ? entity.owner : undefined))\n\t\t}),\n\t\tdefineStat('army', {\n\t\t\tlabel: 'Army',\n\t\t\tdescription: 'The supply used now',\n\t\t\tcategory: 'units',\n\t\t\tkind: 'last',\n\t\t\ttimeline: true,\n\t\t\tsample: (world, player) => world.player(player).supplyUsed\n\t\t}),\n\t\tdefineStat('largestArmy', {\n\t\t\tlabel: 'Largest army',\n\t\t\tdescription: 'The most supply used at once',\n\t\t\tcategory: 'units',\n\t\t\tkind: 'max',\n\t\t\tsample: (world, player) => world.player(player).supplyUsed\n\t\t}),\n\t\t// heroes\n\t\tdefineStat('heroesKilled', {\n\t\t\tlabel: 'Heroes killed',\n\t\t\tcategory: 'heroes',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, killer }, world) => {\n\t\t\t\tif (!entity.has(heroState)) return undefined\n\t\t\t\tconst by = killedBy(world, entity, killer)\n\t\t\t\treturn by === undefined ? undefined : { player: by, type: entity.def.id }\n\t\t\t})\n\t\t}),\n\t\tdefineStat('heroesLost', {\n\t\t\tlabel: 'Heroes lost',\n\t\t\tcategory: 'heroes',\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, reason }) => (heroOf(entity) && lost(reason) ? entity.owner : undefined))\n\t\t}),\n\t\tdefineStat('highestHeroLevel', {\n\t\t\tlabel: 'Highest hero level',\n\t\t\tcategory: 'heroes',\n\t\t\tkind: 'max',\n\t\t\tfrom: scoreOn(heroLevelUp, ({ hero, level }) => ({ player: hero.owner, amount: level, type: hero.def.id }))\n\t\t}),\n\t\tdefineStat('experience', {\n\t\t\tlabel: 'Experience gained',\n\t\t\tcategory: 'heroes',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(xpGained, ({ hero, amount }) => ({ player: hero.owner, amount, type: hero.def.id }))\n\t\t}),\n\t\tdefineStat('creepsKilled', {\n\t\t\tlabel: 'Creeps killed',\n\t\t\tcategory: 'heroes',\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, killer }, world) => (killer && world.player(entity.owner).creeps ? killer.owner : undefined))\n\t\t}),\n\t\tdefineStat('itemsObtained', {\n\t\t\tlabel: 'Items obtained',\n\t\t\tcategory: 'heroes',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(itemPicked, ({ entity, item }) => ({ player: entity.owner, type: item.item }))\n\t\t}),\n\t\tdefineStat('abilitiesCast', {\n\t\t\tlabel: 'Abilities cast',\n\t\t\tcategory: 'heroes',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(abilityCast, ({ caster, ability }) => ({ player: caster.owner, type: ability.id }))\n\t\t}),\n\t\t// combat\n\t\tdefineStat('damageDealt', {\n\t\t\tlabel: 'Damage dealt',\n\t\t\tcategory: 'combat',\n\t\t\tbyType: true,\n\t\t\ttimeline: true,\n\t\t\tfrom: scoreOn(damaged, ({ target, source, amount }, world) =>\n\t\t\t\tsource && enemies(world, source.owner, target.owner) ? { player: source.owner, amount, type: source.def.id } : undefined\n\t\t\t)\n\t\t}),\n\t\tdefineStat('damageTaken', {\n\t\t\tlabel: 'Damage taken',\n\t\t\tcategory: 'combat',\n\t\t\tfrom: scoreOn(damaged, ({ target, amount }) => ({ player: target.owner, amount }))\n\t\t}),\n\t\tdefineStat('healing', {\n\t\t\tlabel: 'Healing done',\n\t\t\tcategory: 'combat',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(healed, ({ target, source, amount }) => ({ player: (source ?? target).owner, amount, type: (source ?? target).def.id }))\n\t\t}),\n\t\t// resources\n\t\t...resources.flatMap((resource) => [\n\t\t\tdefineStat(`gathered.${resource.id}`, {\n\t\t\t\tlabel: `${resource.name} gathered`,\n\t\t\t\tcategory: 'resources',\n\t\t\t\ttimeline: resource.id === currency,\n\t\t\t\tfrom: scoreOn(resourcesDeposited, ({ player, kind, amount }) => (kind === resource.id ? { player, amount } : undefined))\n\t\t\t}),\n\t\t\tdefineStat(`spent.${resource.id}`, {\n\t\t\t\tlabel: `${resource.name} spent`,\n\t\t\t\tcategory: 'resources',\n\t\t\t\tbyType: true,\n\t\t\t\tfrom: scoreOn(resourcesSpent, ({ player, cost, on, refund }) =>\n\t\t\t\t\tcost[resource.id] ? { player, amount: refund ? -cost[resource.id] : cost[resource.id], type: on } : undefined\n\t\t\t\t)\n\t\t\t}),\n\t\t\t...(resource.upkeep\n\t\t\t\t? [\n\t\t\t\t\t\tdefineStat(`upkeep.${resource.id}`, {\n\t\t\t\t\t\t\tlabel: `${resource.name} lost to upkeep`,\n\t\t\t\t\t\t\tcategory: 'resources',\n\t\t\t\t\t\t\tfrom: scoreOn(resourcesDeposited, ({ player, kind, upkeep }) =>\n\t\t\t\t\t\t\t\tkind === resource.id && upkeep ? { player, amount: upkeep } : undefined\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t})\n\t\t\t\t\t]\n\t\t\t\t: [])\n\t\t]),\n\t\t...(currency\n\t\t\t? [\n\t\t\t\t\tdefineStat('bounty', {\n\t\t\t\t\t\tlabel: 'Bounty',\n\t\t\t\t\t\tdescription: `${resources.find((resource) => resource.id === currency)?.name ?? currency} for kills`,\n\t\t\t\t\t\tcategory: 'resources',\n\t\t\t\t\t\tfrom: scoreOn(bountyEvent, ({ player, amount }) => ({ player, amount }))\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t: []),\n\t\t// what went between allies, in a game with something to give\n\t\t...(resources.length\n\t\t\t? [\n\t\t\t\t\tdefineStat('tradedOut', {\n\t\t\t\t\t\tlabel: 'Given to allies',\n\t\t\t\t\t\tcategory: 'resources',\n\t\t\t\t\t\tbyType: true,\n\t\t\t\t\t\tfrom: scoreOn(traded, ({ from, resource, sent }) => ({ player: from, amount: sent, type: resource }))\n\t\t\t\t\t}),\n\t\t\t\t\tdefineStat('tradedIn', {\n\t\t\t\t\t\tlabel: 'Given by allies',\n\t\t\t\t\t\tcategory: 'resources',\n\t\t\t\t\t\tbyType: true,\n\t\t\t\t\t\tfrom: scoreOn(traded, ({ to, resource, received }) => ({ player: to, amount: received, type: resource }))\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t: [])\n\t]\n}\n\n/**\n * What `presetScore` is given: which of the engine's stats (`only`, or all but `without`), stats of the game's own\n * after them, and the score's other rules\n *\n * @beta\n */\nexport interface PresetScoreOptions extends Omit<ScoreRules, 'stats'> {\n\t/** Only these of the engine's stats, by id (`gathered` for every `gathered.<resource>`) */\n\tonly?: readonly string[]\n\t/** The engine's stats but these, by id or as `only` */\n\twithout?: readonly string[]\n\t/** Stats of the game's own, after the engine's */\n\tstats?: readonly ScoreStatDef[]\n}\n\n/**\n * The engine's score, for `GameRules.score`: a classic RTS score screen. Units produced, killed and lost, buildings\n * built, razed and lost, the army and the largest, heroes killed and lost, the highest hero level, experience, creeps\n * killed, items obtained, abilities cast, damage dealt and taken, healing, and of each resource what was gathered,\n * spent and lost to upkeep, the bounty and what went between allies\n *\n * @beta\n */\nexport function presetScore(options: PresetScoreOptions = {}): ScoreRules {\n\tconst { only, without, stats: own = [], ...rules } = options\n\tconst named = (list: readonly string[] | undefined, id: string) => !!list?.some((name) => name === id || id.startsWith(`${name}.`))\n\treturn {\n\t\t...rules,\n\t\tstats: (game) => [...engineStats(game).filter((stat) => (!only || named(only, stat.id)) && !named(without, stat.id)), ...own]\n\t}\n}\n\n/** What a seat was last told of the score, and when: told again once `refresh` seconds passed and it changed, or as the game is decided */\ninterface ScoreTold {\n\tscore?: ScoreState\n\tline?: ScoreLineState\n\ttick: number\n\tversion: number\n\tlineVersion: number\n\tfinal: boolean\n}\n\nconst TOLD = {}\n\n/** What the seat is told of the score now: the same objects while nothing new is to be told */\nfunction scoreTold(view: SessionView): ScoreTold | undefined {\n\tconst { world } = view\n\tconst counted = world.score.rules\n\tif (!counted || view.forComputer) return undefined\n\tconst told = view.keep<ScoreTold>(TOLD, () => ({ tick: -Infinity, version: -1, lineVersion: -1, final: false }))\n\t// asked again within a tick (the score's part, then its line's), it tells the same: nothing new is due\n\tconst final = world.winner !== null || world.failure !== null\n\tconst viewer = view.observer ? undefined : view.player\n\tconst refresh = Math.max(Math.round((counted.rules.refresh ?? 1) * world.tickRate), 1)\n\tconst due = final !== told.final || (world.tick - told.tick >= refresh && world.score.version !== told.version)\n\tif (due) {\n\t\ttold.score = world.score.stateFor(viewer, final)\n\t\ttold.tick = world.tick\n\t\ttold.version = world.score.version\n\t}\n\tif (final !== told.final || world.score.lineVersion !== told.lineVersion) {\n\t\ttold.line = world.score.lineFor(viewer, final)\n\t\ttold.lineVersion = world.score.lineVersion\n\t}\n\ttold.final = final\n\treturn told\n}\n\n/** The score the player is told (`Snapshot.score`) */\nexport const scorePart = snapshotPart('score', (view) => scoreTold(view)?.score)\n\n/** The score's line over time the player is told (`Snapshot.scoreLine`) */\nexport const scoreLinePart = snapshotPart('scoreLine', (view) => scoreTold(view)?.line)\n","import { chopped as choppedEvent, resourceChanged } from '#engine/engineEvents'\nimport type { SupplyCap } from '#engine/hooks'\nimport { productionOf, productionQueue } from './productionQueue'\nimport type { QueuedUnit } from '#engine/rules'\nimport type { System } from '#engine/registry'\nimport { heroState } from '#engine/hero'\nimport { replicateEvent } from '../replication'\nimport type { SessionView } from '../replication'\nimport type { MineInfo } from '../session/protocol'\n\n/**\n * Keeps every player's supply in sync with what they own and have queued: what their units take (`GameRules.supply.of`,\n * those in a queue too) against what their finished buildings provide, changed by the game's `supplyCap` hook and held\n * under the game's most. The same for each of the game's other pools (`GameRules.supply.pools`), from the types' `supplies`\n * and `suppliesProvided`\n */\nexport const supplySystem: System = {\n\tname: 'supply',\n\tphase: 'resolve',\n\tupdate(world) {\n\t\tconst pools = world.rules.supply.pools ?? {}\n\t\tconst names = Object.keys(pools)\n\t\tfor (const player of world.players.values()) {\n\t\t\tplayer.supplyUsed = 0\n\t\t\tplayer.supplyCap = 0\n\t\t\tconst supplies: Record<string, { used: number; cap: number }> = {}\n\t\t\tfor (const name of names) supplies[name] = { used: 0, cap: 0 }\n\t\t\tplayer.supplies = supplies\n\t\t}\n\t\tfor (const entity of world.actors.values()) {\n\t\t\t// fallen heroes keep their place at the table\n\t\t\tif (!entity.alive && !entity.has(heroState)) continue\n\t\t\tconst player = world.player(entity.owner)\n\t\t\tconst { def } = entity\n\t\t\tif (entity.isUnit) {\n\t\t\t\tplayer.supplyUsed += world.rules.supply.of(world, entity)\n\t\t\t\tfor (const name in def.supplies) if (player.supplies[name]) player.supplies[name].used += def.supplies[name]\n\t\t\t} else if (entity.alive && entity.operational) {\n\t\t\t\tplayer.supplyCap += def.supplyProvided ?? 0\n\t\t\t\tfor (const name in def.suppliesProvided) if (player.supplies[name]) player.supplies[name].cap += def.suppliesProvided[name]\n\t\t\t}\n\t\t}\n\t\t// what is queued: only what trains, not every actor asked for a queue (OB5)\n\t\tfor (const entity of world.index.ordered(productionQueue)) {\n\t\t\tif (entity.scenery || (!entity.alive && !entity.has(heroState))) continue\n\t\t\tconst player = world.player(entity.owner)\n\t\t\tfor (const item of productionOf(entity)!.queue) {\n\t\t\t\tif (item.kind !== 'unit') continue\n\t\t\t\tconst queued: QueuedUnit = { def: world.registry.unit(item.id), owner: entity.owner, queued: true }\n\t\t\t\tplayer.supplyUsed += world.rules.supply.of(world, queued)\n\t\t\t\tfor (const name in queued.def.supplies) if (player.supplies[name]) player.supplies[name].used += queued.def.supplies[name]\n\t\t\t}\n\t\t}\n\t\tconst asking = world.hooks.has('supplyCap')\n\t\tfor (const player of world.players.values()) {\n\t\t\tif (asking) {\n\t\t\t\tconst main: SupplyCap = { player: player.id, pool: 'supply', cap: player.supplyCap }\n\t\t\t\tworld.hooks.run('supplyCap', main)\n\t\t\t\tplayer.supplyCap = main.cap\n\t\t\t\tfor (const name of names) {\n\t\t\t\t\tconst pool: SupplyCap = { player: player.id, pool: name, cap: player.supplies[name].cap }\n\t\t\t\t\tworld.hooks.run('supplyCap', pool)\n\t\t\t\t\tplayer.supplies[name].cap = pool.cap\n\t\t\t\t}\n\t\t\t}\n\t\t\tplayer.supplyCap = Math.max(0, Math.min(player.supplyCap, world.rules.supply.max))\n\t\t\tfor (const name of names) player.supplies[name].cap = Math.max(0, Math.min(player.supplies[name].cap, pools[name].max))\n\t\t}\n\t}\n}\n\n/** A tree chopped, to those who see the worker and the tree */\nexport const toldChop = replicateEvent(choppedEvent, 'chop', ({ worker, source }, view) =>\n\tview.knows(worker) && view.knows(source) ? { type: 'chop', id: worker.id, target: source.id } : undefined\n)\n\n/** What an entity carries or holds of a resource changed: its side's alone */\nexport const toldResource = replicateEvent(resourceChanged, 'resource', ({ entity, kind, amount, reason }, view) =>\n\tview.isAlly(entity.owner) ? { type: 'resource', id: entity.id, kind, amount, reason } : undefined\n)\n\n/** What a seat says of the mines, once a tick (`minesFor`) */\nconst MINES = {}\n\n/**\n * Where the game's money is mined, as the map shows it, seen or not (`GameSession.mines`). Worked out once a tick: a\n * walk of every entity, which twelve computers would each take a think. The same list every time within a tick, to read\n *\n * @beta\n */\nexport function minesFor(view: SessionView): readonly MineInfo[] {\n\tconst kept = view.keep(MINES, () => ({ at: -1, infos: [] as readonly MineInfo[] }))\n\tconst { world } = view\n\tif (kept.at === world.tick) return kept.infos\n\tkept.at = world.tick\n\tconst money = world.registry.currency\n\tconst found: MineInfo[] = []\n\tfor (const entity of world.entities.values()) {\n\t\tif (entity.alive && money && entity.def.resource?.kind === money) found.push({ id: entity.id, x: entity.pos.x, z: entity.pos.z })\n\t}\n\tkept.infos = found\n\treturn found\n}\n","import type { GameData } from './gameData'\nimport { defineComponent } from './components'\nimport type { EntityId } from './entity'\nimport type { MapCamera, MapDoodad, MapEnvironment, MapForce, MapItemTable, MapPath, MapPlayer, MapPoint, MapRegion } from './map'\nimport { type MapFieldDef, type MapThing, mapThings } from './mapFields'\nimport { Path, type Spot } from './paths'\n\n/**\n * Entities by the names they were given: on a map, where the editor names what the rules have to find (`MapObject.name`),\n * or in code (`SpawnOptions.name`, `world.setName`). The rules ask for \"the gate\", never for a number or a spot on\n * the map. Kept in the world, so that a save has them\n */\nexport const names = defineComponent<Record<string, EntityId>>('core.names', { default: () => ({}) })\n\n/**\n * What the map a world was made from says that is not an entity, as it is kept in the world: plain data, for a save\n *\n * @beta\n */\nexport interface MapInfo {\n\tname: string\n\tdata: Record<string, unknown>\n\tpoints: MapPoint[]\n\tpaths: MapPath[]\n\t/** What the map looks like, for the screens (`GameSession.environment`) */\n\tenvironment?: MapEnvironment\n\t/** Its scenery, for the screens (`GameSession.doodads`) */\n\tdoodads?: MapDoodad[]\n\t/** Its regions, for the screens (`GameSession.regions`): what mist in places lies over by name. The rules know them as areas */\n\tregions?: MapRegion[]\n\t/** Its views saved under names, for the screens (`GameSession.cameras`) */\n\tcameras?: MapCamera[]\n\t/** Who plays each player, and the game's own fields of each (with what they are when not set) */\n\tplayers?: MapPlayerInfo[]\n\t/** Its teams, named, and what they share */\n\tforces?: MapForce[]\n\t/** What things placed on it drop when they die (`MapObject.drops`) */\n\titemTables?: MapItemTable[]\n\t/** The map's own definitions (`GameMap.definitions`): what a load of the world lays over the game again */\n\tdefinitions?: GameData\n}\n\n/**\n * What the map says of a player beyond what the world has of them: who plays them, and the game's own fields\n *\n * @beta\n */\nexport interface MapPlayerInfo {\n\tid: number\n\tcontroller?: MapPlayer['controller']\n\tdata: Record<string, unknown>\n}\n\nexport const mapInfo = defineComponent<MapInfo>('core.map', { default: () => ({ name: '', data: {}, points: [], paths: [] }) })\n\n/**\n * What the map a world was made from says that is not an entity (`World.map`): its name, what the game kept with it,\n * and its points and paths by name. A game can say which names there are: `world.map.path<RoadPaths>('road')`\n *\n * @beta\n */\nexport class WorldMap {\n\tconstructor(private readonly info: MapInfo) {}\n\n\t/** The name of the map. Empty for a world made without one */\n\tget name(): string {\n\t\treturn this.info.name\n\t}\n\n\t/** What the game kept with the map (`GameMap.data`): a difficulty, the waves of this level */\n\tget data(): Record<string, unknown> {\n\t\treturn this.info.data\n\t}\n\n\t/**\n\t * The things of a kind of the game's own that were put on the map (`MapThing`): a tower defense's ground kept clear,\n\t * a MOBA's lanes. None for a kind the map has nothing of. With `fields`, each thing's own (`data`) has what was not\n\t * set at its default: `world.map.things('td.clearings', clearingFields)`\n\t */\n\tthings(kind: string, fields: readonly Pick<MapFieldDef, 'id' | 'default'>[] = []): MapThing[] {\n\t\tconst things = mapThings(this.info, kind)\n\t\tif (!fields.length) return things\n\t\treturn things.map((thing) => {\n\t\t\tconst data = { ...thing.data }\n\t\t\tfor (const field of fields) if (data[field.id] === undefined && field.default !== undefined) data[field.id] = field.default\n\t\t\treturn { ...thing, data }\n\t\t})\n\t}\n\n\t/** Whether the map has a point or a path of this name */\n\thas(name: string): boolean {\n\t\treturn this.points.some((point) => point.name === name) || this.paths.some((path) => path.name === name)\n\t}\n\n\t/** A point of the map. Throws for one it does not have: a name in the code that is not on the map is a mistake */\n\tpoint<Name extends string = string>(name: Name): Spot {\n\t\tconst point = this.points.find((point) => point.name === name)\n\t\tif (!point) throw new Error(`The map${this.named} has no point \"${name}\"`)\n\t\treturn { x: point.x, z: point.z, facing: point.facing }\n\t}\n\n\t/** A path of the map, to ask how long it is, where along it, what is on it. Throws for one it does not have */\n\tpath<Name extends string = string>(name: Name): Path {\n\t\tconst path = this.paths.find((path) => path.name === name)\n\t\tif (!path) throw new Error(`The map${this.named} has no path \"${name}\"`)\n\t\treturn new Path(path.points, path.width)\n\t}\n\n\t/** What the map looks like, for the screens: its water. Nothing for a world made without a map */\n\tget environment(): MapEnvironment | undefined {\n\t\treturn this.info.environment\n\t}\n\n\t/** The regions of the map, for the screens: what mist in places lies over by name. The rules know them as areas */\n\tget regions(): readonly MapRegion[] {\n\t\treturn this.info.regions ?? []\n\t}\n\n\t/** The scenery of the map, for the screens: the rules never see it, but where it blocks, which the terrain has */\n\tget doodads(): readonly MapDoodad[] {\n\t\treturn this.info.doodads ?? []\n\t}\n\n\t/** What the map says of a player: who plays them (a person, the computer, nobody) and the game's own fields */\n\tplayer(id: number): MapPlayerInfo | undefined {\n\t\treturn this.info.players?.find((player) => player.id === id)\n\t}\n\n\t/** An item table of the map, by name: what something placed on it drops when it dies */\n\titemTable(name: string): MapItemTable | undefined {\n\t\treturn this.info.itemTables?.find((table) => table.name === name)\n\t}\n\n\t/** The teams of the map, named, and what their players share */\n\tget forces(): readonly MapForce[] {\n\t\treturn this.info.forces ?? []\n\t}\n\n\t/** The views of the map saved under names, for the screens */\n\tget cameras(): readonly MapCamera[] {\n\t\treturn this.info.cameras ?? []\n\t}\n\n\t/** The points of the map, as it has them. None in a world saved before maps had points */\n\tget points(): readonly MapPoint[] {\n\t\treturn this.info.points ?? []\n\t}\n\n\t/** The paths of the map, as it has them */\n\tget paths(): readonly MapPath[] {\n\t\treturn this.info.paths ?? []\n\t}\n\n\tprivate get named(): string {\n\t\treturn this.info.name ? ` \"${this.info.name}\"` : ''\n\t}\n}\n","import { defineComponent } from './components'\nimport { defineEvent } from './events'\nimport type { MapDoodad } from './map'\nimport { mapInfo } from './names'\nimport type { World } from './world'\n\n/**\n * Which gates of the map are open, by name: kept with the world and in its save\n *\n * @internal\n */\nexport const gateStates = defineComponent<Record<string, boolean>>('core.gates', { default: () => ({}) })\n\n/**\n * A gate opened or shut while the game runs: every screen hears it, to draw it open or shut\n *\n * @beta\n */\nexport const gateChanged = defineEvent<{ name: string; open: boolean }>('core.gateChanged', { replicate: 'everyone' })\n\n/** Obstacles of gates are kept apart from those of buildings, which go by entity id */\nconst GATE_KEYS = 1_000_000_000\n\nconst gatesOf = (world: World): MapDoodad[] => world.map.doodads.filter((doodad) => doodad.gate && doodad.name && doodad.radius)\n\n/** What a shut gate keeps nothing from walking through: the square around it, as far as it reaches */\nfunction shut(world: World, gate: MapDoodad): void {\n\tif (!world.nav.addObstacle(GATE_KEYS + gate.id, { x: gate.x, z: gate.z, hw: gate.radius!, hd: gate.radius! }))\n\t\tworld.log.warn('navigation', `There is no room for another obstacle: the gate ${gate.name} does not block the way`, { gate: gate.id })\n}\n\n/**\n * Puts the gates of the map in the world as they are: shut ones in the way of what walks. When the world is made from\n * the map, and again when it is loaded from a save, which keeps which are open but not the obstacles\n */\nexport function setUpGates(world: World): void {\n\tconst gates = gatesOf(world)\n\t// a world without gates keeps nothing of them\n\tif (!gates.length) return\n\tconst states = world.state(gateStates)\n\tfor (const gate of gates) {\n\t\tconst open = states[gate.name!] ?? gate.open ?? false\n\t\tstates[gate.name!] = open\n\t\tif (!open) shut(world, gate)\n\t}\n\tworld.setState(gateStates, states)\n}\n\n/**\n * Whether a gate of the map is open, by its name. Nothing for a name that is no gate\n *\n * @beta\n */\nexport function isGateOpen(world: World, name: string): boolean | undefined {\n\treturn world.state(gateStates)[name]\n}\n\n/**\n * Opens or shuts a gate of the map by its name, while the game runs: what walks goes through it or around, and every\n * screen draws it so (`gateChanged`). False when the map has no gate by that name\n *\n * @beta\n */\nexport function setGate(world: World, name: string, open: boolean): boolean {\n\tconst gate = gatesOf(world).find((doodad) => doodad.name === name)\n\tif (!gate) return false\n\tconst states = world.state(gateStates)\n\tif (states[name] === open) return true\n\tworld.setState(gateStates, { ...states, [name]: open })\n\tif (open) world.nav.removeObstacle(GATE_KEYS + gate.id)\n\telse shut(world, gate)\n\t// the map as screens that join later are given it\n\tconst info = world.state(mapInfo)\n\tworld.setState(mapInfo, { ...info, doodads: (info.doodads ?? []).map((doodad) => (doodad.id === gate.id ? { ...doodad, open } : doodad)) })\n\tworld.events.emit(gateChanged, { name, open })\n\treturn true\n}\n","import { defineComponent } from './components'\nimport { defineDebugCommand } from './debugCommands'\nimport { defineEvent } from './events'\nimport { number, string } from './fields'\n\n/**\n * A number of a game's rules to be tuned while it plays: the seconds between waves, how much a kill pays. Read in the\n * rules with `world.tunable(id)`, and changed while the game runs from the editor's play mode (`debug.tune`), in the\n * world itself, so that a save and a screen over a wire have the same. Given in `GameModule.tunables`\n *\n * @beta\n */\nexport interface TunableDef {\n\t/** Shared by every game: give it a prefix of the game's */\n\tid: string\n\t/** What the tuning panel calls it */\n\tname?: string\n\tdefault: number\n\tmin: number\n\tmax: number\n\t/** What the slider steps by. A hundredth of the way from min to max when left out */\n\tstep?: number\n}\n\n/** @beta */\nexport const defineTunable = (def: TunableDef): TunableDef => def\n\n/**\n * The tunables of a game with what a file says over their defaults: the values kept from the tuning panel, in the\n * game's `tuning.json` (`{ \"td.betweenWaves\": 12 }`). Code can still set any of them as it likes\n *\n * @beta\n */\nexport function withTuning(defs: readonly TunableDef[], file: Readonly<Record<string, unknown>> = {}): TunableDef[] {\n\treturn defs.map((def) => {\n\t\tconst value = file[def.id]\n\t\treturn typeof value === 'number' && Number.isFinite(value) ? { ...def, default: Math.min(Math.max(value, def.min), def.max) } : def\n\t})\n}\n\n/**\n * The values the tunables of a world were set to, where they are not their defaults: kept with the world and in its save\n *\n * @internal\n */\nexport const tunings = defineComponent<Record<string, number>>('core.tunings', { default: () => ({}) })\n\n/**\n * A tunable changed while the game runs: for what has to be worked out again from it\n *\n * @beta\n */\nexport const tunableChanged = defineEvent<{ id: string; value: number }>('core.tunableChanged')\n\n/**\n * Sets a tunable while the game runs: for players allowed the debug tools\n *\n * @beta\n */\nexport const tuneCommand = defineDebugCommand('debug.tune', { id: string, value: number }, (world, _player, command) => {\n\tworld.setTunable(command.id, command.value)\n})\n","/**\n * Creep camps: groups of neutral hostile creeps that guard a spot. They go for whoever comes close or attacks one of\n * them, give up when led too far, heal on the way back, and sleep at night. A feature a game turns on by taking\n * `campHooks` into its hooks; the engine itself knows only the player the creeps belong to. Without it, creeps are\n * units like any other, that stand where they are put and fight back.\n */\nimport { campCleared as campClearedEvent, campReturned as campReturnedEvent } from '#engine/engineEvents'\nimport { engageWith, isBlocked, shun } from './engagement'\nimport { defineComponent } from './components'\nimport { at } from './defs'\nimport { edgeDistance, type Entity, type EntityId, type PlayerId, moving, fighting } from './entity'\nimport { defineHook, type HookDef } from './hooks'\nimport { dist, type Vec2 } from './math'\nimport { createOrder, giveOrder } from './orders/queue'\nimport { acquireTarget, canAttack, canSee, disengage, engage } from './systems/combat'\nimport { moveTo } from './systems/movement'\nimport type { System } from './registry'\nimport type { World } from './world'\nimport { cos, sin } from './exactMath'\nimport type { SessionView } from './replication'\nimport type { CampInfo } from './session/protocol'\n\n/**\n * A group of creeps guarding a spot\n *\n * @beta\n */\nexport interface Camp {\n\tid: number\n\tx: number\n\tz: number\n\t/** Levels of its creeps added up, as it was set up */\n\tlevel: number\n\t/** How far from the camp its creeps chase */\n\tleash: number\n\tmembers: EntityId[]\n\t/** Who the camp is fighting. One creep being attacked brings all of them */\n\talarm: EntityId\n\t/** The name it was given on the map, for the rules to find it by (`campNamed`) */\n\tname?: string\n\t/** Who its creeps are, and of what types, for it to come back the same (see `respawn`). None in saves of before */\n\towner?: PlayerId\n\ttypes?: string[]\n\t/**\n\t * Seconds after it was cleared that it comes back, its creeps where they stood, as a hero arena game's jungle camps\n\t * do. Never when left out, as in classic RTS games. Set it from code as the game goes (`campsOf`) to change it\n\t */\n\trespawn?: number\n\t/** When it was found empty, in seconds of the game: it comes back `respawn` seconds after */\n\tclearedAt?: number\n}\n\n/**\n * Ties a creep to the camp it guards\n *\n * @beta\n */\nexport interface CampMember {\n\tcamp: number\n\thome: Vec2\n\t/** On its way back after chasing too far. Nothing distracts it until it is home */\n\treturning: boolean\n\t/** Where it was attacked from by something it could not see, and is going to look */\n\tsearching: Vec2 | null\n}\n\n/**\n * On a creep: the camp it belongs to\n *\n * @beta\n */\nexport const campMember = defineComponent<CampMember>('core.camp')\n\n/**\n * The camps of a world, by id less one\n *\n * @beta\n */\nexport const camps = defineComponent<Camp[]>('core.camps', { default: () => [] })\n\n/** @internal */\nexport const campsOf = (world: World): Camp[] => world.state(camps)\n\n/**\n * The camp of this name, as it was given one on the map. It is there for as long as the game, with or without its creeps\n *\n * @beta\n */\nexport const campNamed = (world: World, name: string): Camp | undefined => campsOf(world).find((camp) => camp.name === name)\n\n/**\n * Where the creeps of a camp stand: the first one in the middle, the rest in a ring around it, facing out\n *\n * @beta\n */\nexport function campLayout(point: Vec2, count: number): { x: number; z: number; facing: number }[] {\n\treturn Array.from({ length: count }, (_, i) => {\n\t\tconst angle = (i / Math.max(count - 1, 1)) * Math.PI * 2\n\t\tconst spread = i === 0 ? 0 : 1.6\n\t\treturn { x: point.x + sin(angle) * spread, z: point.z + cos(angle) * spread, facing: angle }\n\t})\n}\n\n/**\n * Puts a camp of creeps on the map. The creeps stand around the point and come back to it\n *\n * @beta\n */\nexport function spawnCamp(world: World, owner: PlayerId, point: Vec2, types: string[], leash = world.rules.camps.leash): Camp {\n\tconst all = campsOf(world)\n\tconst level = types.reduce((sum, type) => sum + (world.registry.unit(type).level ?? 1), 0)\n\tconst camp: Camp = { id: all.length + 1, x: point.x, z: point.z, level, leash, members: [], alarm: 0, owner, types: [...types] }\n\tconst { respawn } = world.rules.camps\n\tif (respawn !== undefined) camp.respawn = respawn\n\tall.push(camp)\n\tpopulate(world, camp, owner, types)\n\treturn camp\n}\n\n/** Puts a camp's creeps where they stand, as its members */\nfunction populate(world: World, camp: Camp, owner: PlayerId, types: string[]): void {\n\tconst layout = campLayout(camp, types.length)\n\tcamp.members = []\n\ttypes.forEach((type, i) => {\n\t\tconst { x, z, facing } = layout[i]\n\t\tconst creep = world.spawn(type, owner, { x, z }, { facing })\n\t\tcreep.set(campMember, { camp: camp.id, home: { x: creep.pos.x, z: creep.pos.z }, returning: false, searching: null })\n\t\tcamp.members.push(creep.id)\n\t})\n}\n\n/**\n * Brings a cleared camp back now, the same creeps where they stood (`campReturned`): from code, or when its time comes\n *\n * @beta\n */\nexport function respawnCamp(world: World, camp: Camp): void {\n\tif (!camp.types?.length || camp.owner === undefined) return\n\tpopulate(world, camp, camp.owner, camp.types)\n\tcamp.alarm = 0\n\tcamp.clearedAt = undefined\n\tworld.events.emit(campReturnedEvent, { camp })\n}\n\n/** Whether every creep of a camp is gone */\nconst emptied = (world: World, camp: Camp) => camp.members.every((id) => !world.get(id)?.alive)\n\n/**\n * Camps that come back (`Camp.respawn`): told when one is found empty (`campCleared`), and brought back once its time is\n * up, when nobody but its own kind stands in it. Once a second, at the rate of 30 ticks\n *\n * @internal\n */\nexport const campRespawnSystem: System = {\n\tname: 'campRespawn',\n\tphase: 'cleanup',\n\tevery: 30,\n\tupdate(world: World): void {\n\t\tfor (const camp of campsOf(world)) {\n\t\t\tif (!emptied(world, camp)) continue\n\t\t\tif (camp.clearedAt === undefined) {\n\t\t\t\tcamp.clearedAt = world.time\n\t\t\t\tworld.events.emit(campClearedEvent, { camp })\n\t\t\t}\n\t\t\tif (camp.respawn === undefined || world.time - camp.clearedAt < camp.respawn) continue\n\t\t\t// not on top of whoever stands there: it waits for them to go\n\t\t\tconst there = world.spatial.query(camp.x, camp.z, 3, found)\n\t\t\tif (there.some((entity) => entity.alive && entity.isUnit && entity.owner !== camp.owner)) continue\n\t\t\trespawnCamp(world, camp)\n\t\t}\n\t}\n}\n\n/** Part of their health creeps regain per second on the way home */\nconst RETREAT_HEALING = 0.1\nconst found: Entity[] = []\n\n/** Uses an ability that hits what is around the creep, when that is worth it */\nfunction lashOut(world: World, entity: Entity): boolean {\n\tfor (const state of entity.abilities) {\n\t\tif (state.level < 1 || state.cooldown > 0) continue\n\t\tconst ability = world.registry.ability(state.id)\n\t\tif (ability.target !== 'none' || at(ability.manaCost, state.level) > entity.mana) continue\n\t\tconst radius = ability.effects.reduce((max, effect) => Math.max(max, effect.type === 'damage' ? at(effect.radius, state.level) : 0), 0)\n\t\tif (!radius) continue\n\t\tlet caught = 0\n\t\tfor (const other of world.spatial.query(entity.pos.x, entity.pos.z, radius, found)) {\n\t\t\tif (other.isUnit && canAttack(world, entity, other) && edgeDistance(entity, other) <= radius) caught++\n\t\t}\n\t\tif (caught < 2) continue\n\t\tgiveOrder(world, entity, createOrder(world, { type: 'cast', ability: ability.id }))\n\t\treturn true\n\t}\n\treturn false\n}\n\n/**\n * What creeps do: guard their camp. They go for whoever comes close or attacks one of them,\n * give up when led too far from the camp, and heal up on the way back. At night they sleep at home.\n */\nfunction guardCamp(world: World, entity: Entity, dt: number): void {\n\tconst member = entity.get(campMember)!\n\tconst combat = entity.get(fighting)!\n\tconst camp = campsOf(world)[member.camp - 1]\n\tconst m = entity.get(moving)\n\tconst away = dist(entity.pos, member.home)\n\n\tif (entity.asleep) {\n\t\t// what wakes one of them sounds the alarm for the rest\n\t\tif (world.night && !combat.lastAttacker && !world.get(camp.alarm)) return\n\t\tentity.asleep = false\n\t}\n\n\tif (member.returning) {\n\t\tentity.hp = Math.min(entity.hp + entity.maxHp * RETREAT_HEALING * dt, entity.maxHp)\n\t\tif (m && m.status === 'moving') return\n\t\tif (m && away > 1.5 && m.status !== 'failed') {\n\t\t\tmoveTo(world, entity, member.home)\n\t\t\treturn\n\t\t}\n\t\tmember.returning = false\n\t\tcombat.lastAttacker = 0\n\t\tif (camp.alarm && !world.get(camp.alarm)) camp.alarm = 0\n\t\treturn\n\t}\n\n\tconst retreat = () => {\n\t\tcombat.autoTarget = 0\n\t\tdisengage(world, entity)\n\t\tconst intruder = world.get(camp.alarm)\n\t\tif (camp.alarm && (!intruder || dist(intruder.pos, camp) > camp.leash)) camp.alarm = 0\n\t\tif (m && away > 1.5) {\n\t\t\tmember.returning = true\n\t\t\tmoveTo(world, entity, member.home)\n\t\t}\n\t}\n\n\tif (combat.autoTarget) {\n\t\tconst target = world.get(combat.autoTarget)\n\t\t// led too far, or the intruder ran\n\t\tconst tooFar = away > camp.leash || (!!target && dist(target.pos, camp) > camp.leash + 3)\n\t\tif (!tooFar && target && lashOut(world, entity)) return\n\t\tlet result = tooFar ? 'invalid' : engage(world, entity, target, dt, !!m)\n\t\tif (result === 'chasing' && target && isBlocked(world, entity, target)) {\n\t\t\tshun(world, entity, target)\n\t\t\tresult = 'invalid'\n\t\t}\n\t\tif (result === 'attacking' || result === 'chasing') return\n\t\tcombat.autoTarget = 0\n\t\tdisengage(world, entity)\n\t}\n\n\tif ((world.tick + entity.id) % 4 !== 0) return\n\tconst valid = (other: Entity | undefined): other is Entity =>\n\t\t!!other && canAttack(world, entity, other) && canSee(world, entity, other) && dist(other.pos, camp) <= camp.leash + 3\n\tlet next = acquireTarget(world, entity)\n\tif (next && !valid(next)) next = undefined\n\tif (!next && valid(world.get(combat.lastAttacker))) next = world.get(combat.lastAttacker)\n\tif (!next && valid(world.get(camp.alarm))) next = world.get(camp.alarm)\n\tif (!next) {\n\t\t// hit by something it cannot see: go and look where that came from\n\t\tconst unseen = world.get(combat.lastAttacker)\n\t\tif (m && unseen && canAttack(world, entity, unseen) && dist(unseen.pos, camp) <= camp.leash + 3) {\n\t\t\tmember.searching = { x: unseen.pos.x, z: unseen.pos.z }\n\t\t\tmoveTo(world, entity, member.searching)\n\t\t}\n\t}\n\tcombat.lastAttacker = 0\n\tif (next) {\n\t\tengageWith(world, entity, next)\n\t\tmember.searching = null\n\t\tcombat.autoTarget = next.id\n\t\tcamp.alarm = next.id\n\t} else if (member.searching && m?.status === 'moving' && away <= camp.leash) {\n\t\treturn\n\t} else {\n\t\tmember.searching = null\n\t\tretreat()\n\t\tif (world.night && world.rules.camps.sleep && !member.returning && !camp.alarm) entity.asleep = true\n\t}\n}\n\n/**\n * What turns camps on: creeps of a camp guard it instead of doing what idle units do\n *\n * @internal\n */\nexport const campHooks: HookDef[] = [\n\tdefineHook({\n\t\thook: 'idle',\n\t\tid: 'guardCamp',\n\t\trun(world, event) {\n\t\t\tif (event.handled || !event.fights || !event.entity.has(campMember)) return\n\t\t\tguardCamp(world, event.entity, event.dt)\n\t\t\tevent.handled = true\n\t\t}\n\t})\n]\n\n/** What a seat says of the camps, kept up to date once a tick (`campsFor`) */\nconst CAMPS = {}\n\n/**\n * The camps as a seat's player knows them (`GameSession.camps`): where they are and how strong, and which their team\n * has seen empty. Worked out once a tick, as the minimap asks every frame: the same list and objects every time, kept\n * up to date, so it is to read, not to keep\n *\n * @beta\n */\nexport function campsFor(view: SessionView): readonly CampInfo[] {\n\tconst kept = view.keep(CAMPS, () => ({ at: -1, infos: [] as CampInfo[] }))\n\tconst { world } = view\n\tif (kept.at === world.tick) return kept.infos\n\tkept.at = world.tick\n\tconst all = campsOf(world)\n\tconst { cleared } = view.memory\n\tconst occupied = (members: readonly number[]) => members.some((id) => !!world.get(id))\n\tfor (let i = 0; i < all.length; i++) {\n\t\tconst camp = all[i]\n\t\tconst known = cleared.indexOf(camp.id)\n\t\t// an empty camp is only known to be empty once someone has looked\n\t\tif (known < 0 && view.sees(camp.x, camp.z) && !occupied(camp.members)) cleared.push(camp.id)\n\t\telse if (known >= 0 && view.sees(camp.x, camp.z) && occupied(camp.members)) {\n\t\t\t// back, as camps that come back do: known once someone looks again\n\t\t\tcleared.splice(known, 1)\n\t\t}\n\t\tconst info = (kept.infos[i] ??= { id: camp.id, x: camp.x, z: camp.z, level: camp.level, cleared: false })\n\t\tinfo.cleared = cleared.includes(camp.id)\n\t}\n\tkept.infos.length = all.length\n\treturn kept.infos\n}\n","import {\n\tCrowd,\n\ttype CrowdAgent,\n\tDebugDrawerUtils,\n\timportTileCache,\n\ttype NavMesh,\n\tNavMeshQuery,\n\ttype Obstacle,\n\tRaw,\n\ttype TileCache\n} from '@recast-navigation/core'\nimport { createDefaultTileCacheMeshProcess } from '@recast-navigation/generators'\nimport { groundMeshProcess, setAreaCosts } from './groundAreas'\nimport {\n\tbuildNavigationNow,\n\tinitRecast,\n\ttype NavigationBuild,\n\ttype NavigationBuildConfig,\n\ttype NavigationBuilds,\n\ttype NavigationSpeeds,\n\tnavigationData\n} from './builds'\nimport type { Rect, Vec2 } from '#engine/math'\nimport type { Terrain } from '#engine/terrain'\nimport type { AgentParams, AgentSave, AgentState, NavDebugGeometry, Navigation } from './navigation'\n\n/** @beta */\nexport interface RecastNavigationOptions {\n\t/** Who builds it and where what was built is kept: this thread and the process's memory when left out */\n\tbuilds?: NavigationBuilds\n\t/** Navmesh is eroded by this radius, so it has to cover the largest unit */\n\tagentRadius?: number\n\t/** Steepest slope units can walk, in degrees */\n\tmaxSlope?: number\n\t/**\n\t * How many agents the crowd makes room for at first: 512 when left out. It is not a limit: a crowd that is full makes\n\t * room for twice as many, and the agents go on as they were. A game that knows it brings thousands says so, to save\n\t * those moves\n\t */\n\tmaxAgents?: number\n\t/**\n\t * How many obstacles (buildings, shut gates) there is room for: past it, placing one is refused. From the map's\n\t * size when left out: half its cells, at least 8192, at most 65535\n\t */\n\tmaxObstacles?: number\n\t/**\n\t * How many steps a path search takes before it gives up with the best it found: a long path on a large map needs\n\t * more. From the map's size when left out: a quarter of its cells, at least 4096, at most 65535\n\t */\n\tmaxNodes?: number\n\t/**\n\t * Navigations cut for units of these sizes, each unit on the one for the biggest size it is not smaller than: a\n\t * big unit keeps from walls as far as it needs, where all keep 0.5 when left out. Each size is a navigation of its\n\t * own, with its own crowd: units of different sizes walk through each other rather than around (see\n\t * `SizedNavigation`)\n\t */\n\tradii?: number[]\n\tcellSize?: number\n\t/**\n\t * What it is a navigation of: the ground, walked on, or the deep water, sailed on (`Terrain.buildWaterMesh`), at\n\t * the height of its surface. The ground when left out\n\t */\n\tsurface?: 'ground' | 'water'\n\t/**\n\t * How agents steer around each other (Detour's obstacle avoidance): a level (`AVOIDANCE_LEVELS`: how carefully a\n\t * crowd samples the velocities it might go at, `'medium'` being Detour's own), or the parts of `AvoidanceParams`\n\t * to change, Detour's own for the rest. `'medium'` when left out. `'low'` crosses and gathers crowds as well\n\t * in the measured cases for about a quarter less of a tick with a thousand walking, but it plays out other games\n\t * differently (six of the example's tuned AI tests), so it is a game's choice\n\t *\n\t * @beta\n\t */\n\tavoidance?: AvoidanceLevel | Partial<AvoidanceParams>\n\t/**\n\t * How hard agents push each other apart as they walk near each other (within eight radii), 0 for not at all:\n\t * Detour's separation weight. 0.5 when left out: at Detour's 1.5, a unit walking past standing ones is pushed off\n\t * its line and loses a tenth of its speed to it\n\t */\n\tseparation?: number\n\t/**\n\t * How fast one on foot goes over the ground at a point, as a multiplier (`groundSpeedOfCell`): what a path weighs,\n\t * so that a way around slow ground wins where it is quicker (EN2). Asked as the ground is cut, and again for the tiles\n\t * a slowing layer changed on (`groundChanged`). Every cell 1 when left out; never asked of the water\n\t */\n\tspeedAt?: (x: number, z: number) => number\n}\n\n/**\n * How agents steer around each other: Detour's obstacle avoidance parameters, which weigh the velocities an agent\n * samples each tick. The one that costs least wins: going the speed it wants (`weightDesVel`), going as it went\n * (`weightCurVel`), passing on its preferred side (`weightSide`), and how soon it would hit something\n * (`weightToi`, within `horizTime` seconds). `velBias` is how far the samples stray from the velocity it wants, 0..1\n *\n * @beta\n */\nexport interface AvoidanceParams {\n\tvelBias: number\n\tweightDesVel: number\n\tweightCurVel: number\n\tweightSide: number\n\tweightToi: number\n\thorizTime: number\n\t/** Samples a side in the grid sampling, odd. Only the adaptive sampling is used by the engine, which goes by the three below */\n\tgridSize: number\n\tadaptiveDivs: number\n\tadaptiveRings: number\n\tadaptiveDepth: number\n}\n\n/**\n * The engine's avoidance (`RecastNavigationOptions.avoidance`): Detour's own numbers, which `AVOIDANCE_LEVELS` change the sampling of\n *\n * @internal\n */\nexport const DEFAULT_AVOIDANCE: Readonly<AvoidanceParams> = Object.freeze({\n\tvelBias: 0.4,\n\tweightDesVel: 2,\n\tweightCurVel: 0.75,\n\tweightSide: 0.75,\n\tweightToi: 2.5,\n\thorizTime: 2.5,\n\tgridSize: 33,\n\tadaptiveDivs: 7,\n\tadaptiveRings: 2,\n\tadaptiveDepth: 5\n})\n\n/**\n * How carefully a crowd steers: `'low'` samples fewer velocities, a cost a tick that grows with the crowd, `'high'` more\n *\n * @beta\n */\nexport type AvoidanceLevel = 'low' | 'medium' | 'high'\n\n/**\n * What each `AvoidanceLevel` changes of `DEFAULT_AVOIDANCE`: the sampling (`adaptiveDivs`, `adaptiveRings` and\n * `adaptiveDepth`, which what an agent costs a tick goes by)\n *\n * @beta\n */\nexport const AVOIDANCE_LEVELS: Readonly<Record<AvoidanceLevel, Readonly<Partial<AvoidanceParams>>>> = Object.freeze({\n\tlow: Object.freeze({ adaptiveDivs: 5, adaptiveRings: 1, adaptiveDepth: 3 }),\n\tmedium: Object.freeze({}),\n\thigh: Object.freeze({ adaptiveDivs: 7, adaptiveRings: 3, adaptiveDepth: 7 })\n})\n\nconst ANTICIPATE_TURNS = 1\nconst OBSTACLE_AVOIDANCE = 2\nconst SEPARATION = 4\nconst OPTIMIZE_VIS = 8\nconst OPTIMIZE_TOPO = 16\n\nconst DEFAULT_FLAGS = ANTICIPATE_TURNS | OBSTACLE_AVOIDANCE | SEPARATION | OPTIMIZE_VIS | OPTIMIZE_TOPO\nconst GHOST_FLAGS = ANTICIPATE_TURNS | OPTIMIZE_VIS | OPTIMIZE_TOPO\n/**\n * An agent with nowhere to go: no velocity sampled among its neighbours, which for one that wants to stand still comes to\n * standing still all the same (a crowd of idle units: EN1, the same hashes). It is pushed as any agent is\n */\nconst RESTING_FLAGS = ANTICIPATE_TURNS | SEPARATION | OPTIMIZE_VIS | OPTIMIZE_TOPO\n/** What an agent's target is while its path is still being looked for: requesting, waiting for the queue, waiting for the path */\nconst PLANNING = new Set([3, 4, 5])\n/** How fast an agent with no speed left comes to a halt, in ground units per second squared */\nconst BRAKING = 60\n/**\n * Detour's states of an agent. An invalid one is left out of every step of the crowd (no path checked, no neighbours\n * looked for, no velocity sampled, not moved, not pushed) but stays in the grid the others look for neighbours in: it\n * is what an anchored agent is, asleep where it stands, while everyone else still goes around it\n */\nconst INVALID = 0\nconst WALKING = 1\n\ninterface AgentEntry {\n\tagent: CrowdAgent\n\tradius: number\n\tanchored: boolean\n\tanchorX: number\n\tanchorZ: number\n\tghost: boolean\n\t/** Where it was last sent, snapped: kept for a save, which cannot read it back from the crowd */\n\ttarget: Vec2 | null\n}\n\n/** Each cell's speed on the ground, as a build is told it: none where every cell is 1 (the ground cut as it always was) */\nfunction speedsOf(terrain: Terrain, speedAt: (x: number, z: number) => number): NavigationSpeeds | undefined {\n\tconst { width, depth } = terrain\n\tconst values = new Float32Array(width * depth)\n\tlet slow = false\n\tfor (let z = 0; z < depth; z++) {\n\t\tfor (let x = 0; x < width; x++) {\n\t\t\tconst speed = speedAt(x + 0.5, z + 0.5)\n\t\t\tvalues[z * width + x] = speed\n\t\t\tif (speed !== 1) slow = true\n\t\t}\n\t}\n\treturn slow ? { width, depth, values } : undefined\n}\n\n/** The least of one coordinate (0 x, 2 z) of the vertices a mesh's triangles use: where its tiles start, as Recast's bounds do */\nfunction minOf(positions: Float32Array, indices: Uint32Array, axis: number): number {\n\tlet least = Infinity\n\tfor (let i = 0; i < indices.length; i++) least = Math.min(least, positions[indices[i] * 3 + axis])\n\treturn least\n}\n\n/** A limit from the map's size, never less than it was before the map's size counted, never past what Detour counts to */\nconst limitFor = (wanted: number, least: number) => Math.min(Math.max(Math.ceil(wanted), least), 65535)\n\n/** How many requests the tile cache queues, and how many tiles it makes again from one batch of them, at most (Detour's) */\nconst MAX_REQUESTS = 64\n/** Half of Detour's 64: a column of the tile grid may hold more than one layer, and each is a tile of its own */\nconst MAX_HELD_COLUMNS = 32\n\n/** Where the tiles are: their size and where the first starts, in ground units */\ninterface TileGrid {\n\tsize: number\n\toriginX: number\n\toriginZ: number\n}\n\n/** The slot of the crowd's obstacle avoidance parameters every agent uses */\nconst AVOIDANCE_SLOT = 3\n\n/**\n * A crowd on the navmesh with room for `maxAgents` agents, of any radius up to twice the one it was cut for, steering\n * as `avoidance` says\n */\nfunction crowdOf(navMesh: NavMesh, maxAgents: number, agentRadius: number, avoidance: Readonly<AvoidanceParams>, weighs: boolean): Crowd {\n\tconst crowd = new Crowd(navMesh, { maxAgents, maxAgentRadius: Math.max(agentRadius * 2, 1) })\n\tcrowd.navMeshQuery.defaultQueryHalfExtents = { x: 2, y: 6, z: 2 }\n\t// the paths its agents plan pay for slow ground as the navigation's own searches do\n\tif (weighs) setAreaCosts(crowd.getFilter(0))\n\tconst params = new Raw.Module.dtObstacleAvoidanceParams()\n\tparams.velBias = avoidance.velBias\n\tparams.weightDesVel = avoidance.weightDesVel\n\tparams.weightCurVel = avoidance.weightCurVel\n\tparams.weightSide = avoidance.weightSide\n\tparams.weightToi = avoidance.weightToi\n\tparams.horizTime = avoidance.horizTime\n\tparams.gridSize = avoidance.gridSize\n\tparams.adaptiveDivs = avoidance.adaptiveDivs\n\tparams.adaptiveRings = avoidance.adaptiveRings\n\tparams.adaptiveDepth = avoidance.adaptiveDepth\n\tcrowd.raw.setObstacleAvoidanceParams(AVOIDANCE_SLOT, params)\n\tRaw.destroy(params)\n\treturn crowd\n}\n\nexport class RecastNavigation implements Navigation {\n\tversion = 0\n\n\tprivate agents = new Map<number, AgentEntry>()\n\tprivate obstacles = new Map<number, Obstacle>()\n\t/** The room the crowd was first made with: a crowd made anew (`reseat`) starts there, as a loaded world's does */\n\tprivate firstMaxAgents = 0\n\tprivate obstaclesDirty = false\n\t/** Obstacles are put down many at once (`holdObstacles`): their requests wait in the tile cache to be made into tiles together */\n\tprivate holding = false\n\t/** Requests waiting while held, and the columns of the tile grid they touch (x * 65536 + z) */\n\tprivate held = 0\n\tprivate readonly heldColumns = new Set<number>()\n\tprivate readonly scratch = { x: 0, y: 0, z: 0 }\n\n\tprivate constructor(\n\t\tprivate readonly terrain: Terrain,\n\t\tprivate navMesh: NavMesh,\n\t\tprivate tileCache: TileCache,\n\t\tprivate crowd: Crowd,\n\t\tprivate query: NavMeshQuery,\n\t\tprivate readonly agentRadius: number,\n\t\t/** How many agents the crowd has room for now: twice as many each time it is full */\n\t\tprivate maxAgents: number,\n\t\t/** How many obstacles the tile cache was made with room for */\n\t\tprivate readonly maxObstacles: number,\n\t\t/** How many steps a path search takes at most */\n\t\tprivate readonly maxNodes: number,\n\t\t/** What Recast's import made besides the navmesh and the tile cache, which the tile cache uses as long as it lives */\n\t\tprivate owned: readonly unknown[],\n\t\t/** How its agents steer around each other, and how hard they push apart (`RecastNavigationOptions`) */\n\t\treadonly avoidance: Readonly<AvoidanceParams>,\n\t\treadonly separation: number,\n\t\t/** Where its tiles are: to make again those a slowing layer changed on, and to know which an obstacle touches */\n\t\tprivate tiles: TileGrid,\n\t\t/** The height of what it is a navigation of, at a point: the ground, or the water's surface */\n\t\tprivate readonly heightAt: (x: number, z: number) => number = (x, z) => terrain.heightAt(x, z),\n\t\t/** What a path weighs (`speedAt`) */\n\t\tprivate readonly ground?: { speedAt: (x: number, z: number) => number },\n\t\t/** What it is cut from, the ground as it is now, the way it was first cut: to cut it again (`reshape`) */\n\t\tprivate readonly cut?: () => { build: NavigationBuild; tiles: TileGrid }\n\t) {\n\t\tthis.firstMaxAgents = maxAgents\n\t}\n\n\tstatic async create(terrain: Terrain, options: RecastNavigationOptions = {}): Promise<RecastNavigation> {\n\t\tawait initRecast()\n\n\t\tconst cells = terrain.width * terrain.depth\n\t\tconst {\n\t\t\tagentRadius = 0.5,\n\t\t\tmaxSlope = 38,\n\t\t\tmaxAgents = 512,\n\t\t\t// as many as there are cells: a map can be wooded all over (a tree a cell), and a refused one blocks nothing\n\t\t\tmaxObstacles = limitFor(cells, 8192),\n\t\t\tmaxNodes = limitFor(cells / 4, 4096),\n\t\t\tcellSize = 0.25,\n\t\t\tsurface = 'ground',\n\t\t\tseparation = 0.5\n\t\t} = options\n\t\tconst avoidance: Readonly<AvoidanceParams> = Object.freeze({\n\t\t\t...DEFAULT_AVOIDANCE,\n\t\t\t...AVOIDANCE_LEVELS[typeof options.avoidance === 'string' ? options.avoidance : 'medium'],\n\t\t\t...(typeof options.avoidance === 'object' && options.avoidance)\n\t\t})\n\t\tconst cellHeight = 0.2\n\t\tconst water = surface === 'water'\n\t\tconst config: NavigationBuildConfig = {\n\t\t\tcs: cellSize,\n\t\t\tch: cellHeight,\n\t\t\ttileSize: 48,\n\t\t\twalkableSlopeAngle: maxSlope,\n\t\t\twalkableHeight: Math.ceil(2 / cellHeight),\n\t\t\twalkableClimb: Math.ceil(0.6 / cellHeight),\n\t\t\twalkableRadius: Math.ceil(agentRadius / cellSize),\n\t\t\tmaxSimplificationError: 1.1,\n\t\t\tmergeRegionArea: 20,\n\t\t\tmaxVertsPerPoly: 6,\n\t\t\tdetailSampleDist: 4,\n\t\t\tdetailSampleMaxError: 0.5,\n\t\t\texpectedLayersPerTile: 1,\n\t\t\tmaxObstacles\n\t\t}\n\t\t// slow ground, weighed by paths (EN2): the water is sailed at one speed\n\t\tconst speedAt = water ? undefined : options.speedAt\n\t\t// what it is cut from, the ground as it is: now, and again as it is reshaped\n\t\tconst cut = () => {\n\t\t\tconst { positions, indices } = water ? terrain.buildWaterMesh() : terrain.buildMesh(true)\n\t\t\tconst speeds = speedAt && speedsOf(terrain, speedAt)\n\t\t\treturn {\n\t\t\t\tbuild: { positions, indices, config, ...(speeds && { speeds }) },\n\t\t\t\ttiles: { size: config.tileSize * cellSize, originX: minOf(positions, indices, 0), originZ: minOf(positions, indices, 2) }\n\t\t\t}\n\t\t}\n\t\tconst first = cut()\n\t\t// built here or in a worker, or kept from a build of the same ground before (S37): read from what was built\n\t\t// either way, so the two are the same navigation\n\t\tconst data = await navigationData(first.build, options.builds)\n\t\t// what makes a tile again when an obstacle comes or goes: as the build made it, each polygon's area the speed\n\t\t// under it as the ground is now\n\t\tconst process = speedAt ? groundMeshProcess(speedAt) : createDefaultTileCacheMeshProcess()\n\t\tconst { navMesh, tileCache, allocator, compressor } = importTileCache(data, process)\n\t\tconst query = new NavMeshQuery(navMesh, { maxNodes })\n\t\tquery.defaultQueryHalfExtents = { x: 2, y: 6, z: 2 }\n\t\tif (speedAt) setAreaCosts(query.defaultFilter)\n\t\tconst crowd = crowdOf(navMesh, maxAgents, agentRadius, avoidance, !!speedAt)\n\t\treturn new RecastNavigation(\n\t\t\tterrain,\n\t\t\tnavMesh,\n\t\t\ttileCache,\n\t\t\tcrowd,\n\t\t\tquery,\n\t\t\tagentRadius,\n\t\t\tmaxAgents,\n\t\t\tmaxObstacles,\n\t\t\tmaxNodes,\n\t\t\t[process, allocator, compressor],\n\t\t\tavoidance,\n\t\t\tseparation,\n\t\t\tfirst.tiles,\n\t\t\twater ? (x, z) => terrain.waterHeightAt(x, z) : undefined,\n\t\t\tspeedAt && { speedAt },\n\t\t\tcut\n\t\t)\n\t}\n\n\t/**\n\t * The ground it is a navigation of was reshaped (`World.reshapeGround`): cut again from the ground as it is now, at\n\t * once and on this thread, as it was cut first (its options, its slow ground); what is in the way put down again where\n\t * it was, in the order it was, and every agent moved over as it stood, as a crowd that grows is. Every machine cuts it\n\t * the same. False, and the navigation left as it was, where the ground as it is now cannot be cut (no water left)\n\t */\n\treshape(): boolean {\n\t\tif (!this.cut) return false\n\t\tthis.drain()\n\t\tconst { build, tiles } = this.cut()\n\t\tlet made: ReturnType<typeof importTileCache>\n\t\ttry {\n\t\t\tmade = importTileCache(buildNavigationNow(build), this.owned[0] as Parameters<typeof importTileCache>[1])\n\t\t} catch {\n\t\t\treturn false\n\t\t}\n\t\tconst boxes = [...this.obstacles].flatMap(([key, obstacle]) =>\n\t\t\tobstacle.type === 'box'\n\t\t\t\t? [\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tx: obstacle.position.x,\n\t\t\t\t\t\t\t\tz: obstacle.position.z,\n\t\t\t\t\t\t\t\thw: obstacle.halfExtents.x - this.agentRadius,\n\t\t\t\t\t\t\t\thd: obstacle.halfExtents.z - this.agentRadius\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t] as const\n\t\t\t\t\t]\n\t\t\t\t: []\n\t\t)\n\t\tconst agents = [...this.agents.keys()].map((id) => [id, this.saveAgent(id)!] as const)\n\t\tconst old = [this.crowd, this.query, this.tileCache, this.navMesh]\n\t\tthis.navMesh = made.navMesh\n\t\tthis.tileCache = made.tileCache\n\t\tthis.owned = [this.owned[0], made.allocator, made.compressor]\n\t\tthis.tiles = tiles\n\t\tthis.query = new NavMeshQuery(made.navMesh, { maxNodes: this.maxNodes })\n\t\tthis.query.defaultQueryHalfExtents = { x: 2, y: 6, z: 2 }\n\t\tif (this.ground) setAreaCosts(this.query.defaultFilter)\n\t\tthis.crowd = crowdOf(made.navMesh, this.maxAgents, this.agentRadius, this.avoidance, !!this.ground)\n\t\tthis.obstacles.clear()\n\t\tthis.agents.clear()\n\t\tfor (const each of old) each.destroy()\n\t\t// put down together, a tile made once however many are on it, as a world being made puts them down\n\t\tthis.holding = false\n\t\tthis.held = 0\n\t\tthis.heldColumns.clear()\n\t\tthis.obstaclesDirty = false\n\t\tthis.holdObstacles(true)\n\t\tfor (const [key, rect] of boxes) this.addObstacle(key, rect)\n\t\tthis.holdObstacles(false)\n\t\tfor (const [id, save] of agents) this.restoreAgent(id, save)\n\t\tthis.version++\n\t\treturn true\n\t}\n\n\t/**\n\t * A slowing layer of cells changed on these cells (`World.setCells`): the tiles they are on are made again, each\n\t * polygon's area the speed under it now. As fine as the polygons the ground was cut into: a patch painted in play in\n\t * the middle of one counts where the polygon's middle is\n\t */\n\tgroundChanged(cells: readonly number[]): void {\n\t\tif (!this.ground) return\n\t\tthis.drain()\n\t\tconst grid = this.tiles\n\t\tconst { width } = this.terrain\n\t\tconst tiles = new Set<number>()\n\t\tfor (const cell of cells) {\n\t\t\tconst tx = Math.floor(((cell % width) + 0.5 - grid.originX) / grid.size)\n\t\t\tconst tz = Math.floor((Math.floor(cell / width) + 0.5 - grid.originZ) / grid.size)\n\t\t\ttiles.add(tx * 65536 + tz)\n\t\t}\n\t\t// in order, so that every machine makes them the same way\n\t\tfor (const key of [...tiles].sort((a, b) => a - b)) this.tileCache.buildNavMeshTilesAt(Math.floor(key / 65536), key % 65536, this.navMesh)\n\t\tthis.version++\n\t}\n\n\t/** The limits it was made with, from the map's size or the options: obstacles, and the steps of a path search */\n\tget limits(): { maxObstacles: number; maxNodes: number } {\n\t\treturn { maxObstacles: this.maxObstacles, maxNodes: this.maxNodes }\n\t}\n\n\t/** How many agents the crowd has room for before it has to make more */\n\tget capacity(): number {\n\t\treturn this.maxAgents\n\t}\n\n\t/**\n\t * Makes room for twice as many agents. A crowd (Detour's) is made for a number of agents and cannot grow, so a new\n\t * one is made and every agent moved over as it is: where it is, how fast it goes, where to\n\t */\n\tprivate grow(): void {\n\t\tconst saves = [...this.agents.keys()].map((id) => [id, this.saveAgent(id)!] as const)\n\t\tconst old = this.crowd\n\t\tthis.maxAgents *= 2\n\t\tthis.crowd = crowdOf(this.navMesh, this.maxAgents, this.agentRadius, this.avoidance, !!this.ground)\n\t\tthis.agents.clear()\n\t\tfor (const [id, save] of saves) this.restoreAgent(id, save)\n\t\told.destroy()\n\t}\n\n\tprivate toVec3(p: Vec2) {\n\t\tthis.scratch.x = p.x\n\t\tthis.scratch.y = this.heightAt(p.x, p.z)\n\t\tthis.scratch.z = p.z\n\t\treturn this.scratch\n\t}\n\n\taddAgent(id: number, position: Vec2, params: AgentParams): void {\n\t\tif (this.agents.has(id)) this.removeAgent(id)\n\t\tconst start = this.closestPoint(position, 8) ?? position\n\t\tconst agentParams = {\n\t\t\tradius: params.radius,\n\t\t\theight: 2,\n\t\t\tmaxSpeed: params.speed,\n\t\t\tmaxAcceleration: params.speed * 10,\n\t\t\tcollisionQueryRange: params.radius * 8,\n\t\t\tpathOptimizationRange: params.radius * 30,\n\t\t\tseparationWeight: this.separation,\n\t\t\tupdateFlags: RESTING_FLAGS,\n\t\t\tobstacleAvoidanceType: AVOIDANCE_SLOT\n\t\t}\n\t\tlet agent = this.crowd.addAgent(this.toVec3(start), agentParams)\n\t\t// a full crowd says so with an index of -1, and an agent like that never moves: room is made, and it goes in again\n\t\tif (agent.agentIndex < 0) {\n\t\t\tthis.grow()\n\t\t\tagent = this.crowd.addAgent(this.toVec3(start), agentParams)\n\t\t\tif (agent.agentIndex < 0) throw new Error(`Navigation: the crowd has room for ${this.maxAgents} agents and takes no more`)\n\t\t}\n\t\tthis.agents.set(id, { agent, radius: params.radius, anchored: false, anchorX: start.x, anchorZ: start.z, ghost: false, target: null })\n\t}\n\n\tremoveAgent(id: number): void {\n\t\tconst entry = this.agents.get(id)\n\t\tif (!entry) return\n\t\tthis.crowd.removeAgent(entry.agent)\n\t\tthis.agents.delete(id)\n\t}\n\n\thasAgent(id: number): boolean {\n\t\treturn this.agents.has(id)\n\t}\n\n\tsetDestination(id: number, target: Vec2): boolean {\n\t\tconst entry = this.agents.get(id)\n\t\tif (!entry) return false\n\t\tconst snapped = this.closestPoint(target, 6)\n\t\tif (!snapped) return false\n\t\tthis.wake(entry)\n\t\tif (!entry.target && !entry.ghost) entry.agent.updateParameters({ updateFlags: DEFAULT_FLAGS })\n\t\tentry.target = snapped\n\t\treturn entry.agent.requestMoveTarget(this.toVec3(snapped))\n\t}\n\n\tclearDestination(id: number): void {\n\t\tconst entry = this.agents.get(id)\n\t\tif (!entry) return\n\t\tif (entry.target && !entry.ghost) entry.agent.updateParameters({ updateFlags: RESTING_FLAGS })\n\t\tentry.target = null\n\t\tentry.agent.resetMoveTarget()\n\t}\n\n\tteleport(id: number, position: Vec2): void {\n\t\tconst entry = this.agents.get(id)\n\t\tif (!entry) return\n\t\tconst snapped = this.closestPoint(position, 8) ?? position\n\t\tentry.agent.teleport(this.toVec3(snapped))\n\t\tentry.anchorX = snapped.x\n\t\tentry.anchorZ = snapped.z\n\t\t// a teleport wakes the agent in Detour's eyes: an anchored one goes on sleeping where it was put\n\t\tif (entry.anchored) entry.agent.raw.state = INVALID\n\t}\n\n\tsetAnchored(id: number, anchored: boolean): void {\n\t\tconst entry = this.agents.get(id)\n\t\tif (!entry || entry.anchored === anchored) return\n\t\tif (!anchored) {\n\t\t\tthis.wake(entry)\n\t\t\treturn\n\t\t}\n\t\tconst { agent } = entry\n\t\tconst { raw } = agent\n\t\tentry.anchored = true\n\t\tentry.anchorX = raw.get_npos(0)\n\t\tentry.anchorZ = raw.get_npos(2)\n\t\tif (entry.target && !entry.ghost) agent.updateParameters({ updateFlags: RESTING_FLAGS })\n\t\tentry.target = null\n\t\tagent.resetMoveTarget()\n\t\t// it stops dead: the velocity others steer around, and the one read back, are both nothing\n\t\tfor (let i = 0; i < 3; i++) raw.set_vel(i, 0)\n\t\traw.state = INVALID\n\t}\n\n\t/** Lets an anchored agent go: walking again, from where it stood. Detour checks the ground under it on its next step */\n\tprivate wake(entry: AgentEntry): void {\n\t\tif (!entry.anchored) return\n\t\tentry.anchored = false\n\t\tentry.agent.raw.state = WALKING\n\t}\n\n\tsetGhost(id: number, ghost: boolean): void {\n\t\tconst entry = this.agents.get(id)\n\t\tif (!entry || entry.ghost === ghost) return\n\t\tentry.ghost = ghost\n\t\tentry.agent.updateParameters({\n\t\t\tupdateFlags: ghost ? GHOST_FLAGS : entry.target ? DEFAULT_FLAGS : RESTING_FLAGS,\n\t\t\t// with no neighbours in range, a ghost is neither steered nor pushed by anyone\n\t\t\tcollisionQueryRange: ghost ? 0.01 : entry.radius * 8\n\t\t})\n\t}\n\n\tsetSpeed(id: number, speed: number): void {\n\t\t// what is held in place has to be able to brake: with nothing to change its pace by, it would glide on as it was\n\t\tthis.agents.get(id)?.agent.updateParameters({ maxSpeed: speed, maxAcceleration: Math.max(speed * 10, BRAKING) })\n\t}\n\n\tsaveAgent(id: number): AgentSave | undefined {\n\t\tconst entry = this.agents.get(id)\n\t\tif (!entry) return undefined\n\t\tconst { agent, radius, target, anchored, ghost } = entry\n\t\tconst p = agent.position()\n\t\tconst v = agent.velocity()\n\t\treturn {\n\t\t\tx: p.x,\n\t\t\tz: p.z,\n\t\t\tvx: v.x,\n\t\t\tvz: v.z,\n\t\t\tradius,\n\t\t\tspeed: agent.maxSpeed,\n\t\t\tacceleration: agent.maxAcceleration,\n\t\t\ttarget: target && { x: target.x, z: target.z },\n\t\t\tanchored,\n\t\t\tanchor: anchored ? { x: entry.anchorX, z: entry.anchorZ } : undefined,\n\t\t\tghost\n\t\t}\n\t}\n\n\treseat(agents: readonly (readonly [id: number, save: AgentSave])[]): void {\n\t\t// a crowd as a world just loaded has: the room it starts with, nobody in it, then each agent as the save has it\n\t\tconst old = this.crowd\n\t\tthis.maxAgents = this.firstMaxAgents\n\t\tthis.crowd = crowdOf(this.navMesh, this.maxAgents, this.agentRadius, this.avoidance, !!this.ground)\n\t\tthis.agents.clear()\n\t\told.destroy()\n\t\tfor (const [id, save] of agents) this.restoreAgent(id, save)\n\t}\n\n\trestoreAgent(id: number, save: AgentSave): void {\n\t\t// made the way any agent is, then given back what it had\n\t\tthis.addAgent(id, { x: save.x, z: save.z }, { radius: save.radius, speed: save.speed })\n\t\tconst entry = this.agents.get(id)!\n\t\tconst { agent } = entry\n\t\t// it is added on the nearest walkable spot: put it where it was, to the last bit. An anchored one goes where it\n\t\t// holds its ground: that is where it stood, but for a hair in a save from before anchored agents slept\n\t\tconst at = save.anchored ? (save.anchor ?? save) : save\n\t\tagent.teleport({ x: at.x, y: this.heightAt(at.x, at.z), z: at.z })\n\t\tentry.anchorX = at.x\n\t\tentry.anchorZ = at.z\n\t\tif (save.acceleration !== undefined) agent.updateParameters({ maxAcceleration: save.acceleration })\n\t\tthis.setGhost(id, save.ghost)\n\t\tif (save.target) this.setDestination(id, save.target)\n\t\tif (save.anchored) {\n\t\t\tthis.setAnchored(id, true)\n\t\t\treturn\n\t\t}\n\t\t// the crowd keeps velocity as three numbers: x, y and z\n\t\tagent.raw.set_vel(0, save.vx)\n\t\tagent.raw.set_vel(2, save.vz)\n\t}\n\n\tsettle(version: number): void {\n\t\tthis.drain()\n\t\tfor (let i = 0; this.obstaclesDirty; i++) {\n\t\t\tif (i > 100000) throw new Error('Navigation: the obstacles never settled')\n\t\t\tthis.obstaclesDirty = !this.tileCache.update(this.navMesh).upToDate\n\t\t}\n\t\tthis.version = version\n\t\t// an agent that was given somewhere to go heads straight there until its path has been looked for, which the\n\t\t// crowd does a few at a time: look for all of them now, with no time going by, so nothing moves meanwhile\n\t\tfor (let i = 0; i < 1000 && [...this.agents.values()].some(({ agent }) => PLANNING.has(agent.raw.targetState)); i++) this.crowd.update(0)\n\t}\n\n\treadAgent(id: number, out: AgentState): boolean {\n\t\tconst entry = this.agents.get(id)\n\t\tif (!entry) return false\n\t\t// an anchored agent is asleep where it was anchored, and is answered from here: nothing of it is read from the crowd\n\t\tif (entry.anchored) {\n\t\t\tout.x = entry.anchorX\n\t\t\tout.z = entry.anchorZ\n\t\t\tout.vx = 0\n\t\t\tout.vz = 0\n\t\t\tout.cx = out.nx = entry.anchorX\n\t\t\tout.cz = out.nz = entry.anchorZ\n\t\t\treturn true\n\t\t}\n\t\t// each read is a call into WebAssembly: only what is used, on the ground (x and z, never the height)\n\t\tconst raw = entry.agent.raw\n\t\tout.x = raw.get_npos(0)\n\t\tout.z = raw.get_npos(2)\n\t\tout.vx = raw.get_vel(0)\n\t\tout.vz = raw.get_vel(2)\n\t\t// the corridor has no corners once the agent is nearly there\n\t\tconst corners = raw.ncorners\n\t\tif (corners > 0) {\n\t\t\tout.cx = raw.get_cornerVerts(0)\n\t\t\tout.cz = raw.get_cornerVerts(2)\n\t\t} else {\n\t\t\tout.cx = raw.get_targetPos(0)\n\t\t\tout.cz = raw.get_targetPos(2)\n\t\t}\n\t\tif (corners > 1) {\n\t\t\tout.nx = raw.get_cornerVerts(3)\n\t\t\tout.nz = raw.get_cornerVerts(5)\n\t\t} else {\n\t\t\tout.nx = out.cx\n\t\t\tout.nz = out.cz\n\t\t}\n\t\treturn true\n\t}\n\n\tupdate(dt: number): void {\n\t\tthis.drain()\n\t\tif (this.obstaclesDirty) {\n\t\t\tfor (let i = 0; i < 32; i++) {\n\t\t\t\tif (this.tileCache.update(this.navMesh).upToDate) {\n\t\t\t\t\tthis.obstaclesDirty = false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.version++\n\t\t}\n\n\t\t// anchored agents are asleep (INVALID), so Detour, which resolves overlaps symmetrically, does not move them: an\n\t\t// agent that walks into one is pushed off by half the overlap each pass, as ever, and the one that stands its\n\t\t// ground is not moved at all\n\t\tthis.crowd.update(dt)\n\t}\n\n\taddObstacle(key: number, rect: Rect): boolean {\n\t\tthis.removeObstacle(key)\n\t\tif (this.obstacles.size >= this.maxObstacles) return false\n\t\tconst y = this.terrain.heightAt(rect.x, rect.z)\n\t\t// obstacles carve their exact shape, so grow them by the agent radius like the rest of the navmesh\n\t\tconst half = { x: rect.hw + this.agentRadius, y: 4, z: rect.hd + this.agentRadius }\n\t\tthis.makeRoom(rect.x, rect.z, half.x, half.z)\n\t\tconst result = this.tileCache.addBoxObstacle({ x: rect.x, y, z: rect.z }, half, 0)\n\t\t// out of room, or of requests queued: not in the way, and said by the false, never thrown in the middle of a tick\n\t\tif (!result.success) return false\n\t\tthis.obstacles.set(key, result.obstacle)\n\t\tthis.flushObstacles()\n\t\treturn true\n\t}\n\n\t/**\n\t * Holds obstacles back (true) or lets them go (false): while held, a request to put one down or take one up waits in\n\t * the tile cache, and they are made into tiles together when let go or at the first thing asked of the navigation\n\t * before that, each tile once however many obstacles are on it. The same tiles come of it as of making them one by\n\t * one: a wooded tile is made once, not once a tree (RV42). The version goes up for each obstacle all the same\n\t */\n\tholdObstacles(hold: boolean): void {\n\t\tif (this.holding === hold) return\n\t\tthis.holding = hold\n\t\tif (!hold) return this.drain()\n\t\t// a batch starts from a tile cache with nothing queued: what was asked before is made first, and the next update\n\t\t// still says the ground changed, as it would have\n\t\tif (this.obstaclesDirty) {\n\t\t\tthis.held = 1\n\t\t\tthis.drain()\n\t\t\tthis.obstaclesDirty = true\n\t\t}\n\t}\n\n\t/**\n\t * Makes room for one more held request, of an obstacle at (x, z) of these half sizes: the ones held are made into\n\t * tiles first when the tile cache would take no more of them (Detour queues 64), or when their tiles together would\n\t * be more than it makes again from one batch (64, past which it leaves the rest as they were)\n\t */\n\tprivate makeRoom(x: number, z: number, hw: number, hd: number): void {\n\t\tif (!this.holding) return\n\t\tconst columns = this.columnsOf(x, z, hw, hd)\n\t\tlet more = 0\n\t\tfor (const column of columns) if (!this.heldColumns.has(column)) more++\n\t\tif (this.held + 1 > MAX_REQUESTS || this.heldColumns.size + more > MAX_HELD_COLUMNS) this.drain()\n\t\tfor (const column of columns) this.heldColumns.add(column)\n\t}\n\n\t/**\n\t * The columns of the tile grid an obstacle touches, or more: Detour takes a box obstacle's bounds as a square 1.41 times\n\t * its longer half side about its middle, here 1.5 times, so that rounding never leaves one out\n\t */\n\tprivate columnsOf(x: number, z: number, hw: number, hd: number): number[] {\n\t\tconst { size, originX, originZ } = this.tiles\n\t\tconst reach = 1.5 * Math.max(hw, hd)\n\t\tconst x0 = Math.floor((x - reach - originX) / size)\n\t\tconst x1 = Math.floor((x + reach - originX) / size)\n\t\tconst z0 = Math.floor((z - reach - originZ) / size)\n\t\tconst z1 = Math.floor((z + reach - originZ) / size)\n\t\tconst columns: number[] = []\n\t\tfor (let tx = x0; tx <= x1; tx++) for (let tz = z0; tz <= z1; tz++) columns.push(tx * 65536 + tz)\n\t\treturn columns\n\t}\n\n\t/** Every held request made into tiles: the tile cache up to date */\n\tprivate drain(): void {\n\t\tif (!this.held) return\n\t\tthis.held = 0\n\t\tthis.heldColumns.clear()\n\t\tfor (let i = 0; !this.tileCache.update(this.navMesh).upToDate; i++) {\n\t\t\tif (i > 100000) throw new Error('Navigation: the obstacles never settled')\n\t\t}\n\t\tthis.obstaclesDirty = false\n\t}\n\n\tobstacleRoom(): number {\n\t\treturn this.maxObstacles - this.obstacles.size\n\t}\n\n\tremoveObstacle(key: number): void {\n\t\tconst obstacle = this.obstacles.get(key)\n\t\tif (!obstacle) return\n\t\tif (this.holding && obstacle.type === 'box') {\n\t\t\tconst { position, halfExtents } = obstacle\n\t\t\tthis.makeRoom(position.x, position.z, halfExtents.x, halfExtents.z)\n\t\t}\n\t\tthis.tileCache.removeObstacle(obstacle)\n\t\tthis.obstacles.delete(key)\n\t\tthis.flushObstacles()\n\t}\n\n\t/**\n\t * The tile cache only queues a limited number of requests, so process them as they come: but while they are held\n\t * (`holdObstacles`), when they wait to be made into tiles together\n\t */\n\tprivate flushObstacles(): void {\n\t\tif (this.holding) this.held++\n\t\telse this.obstaclesDirty = !this.tileCache.update(this.navMesh).upToDate\n\t\tthis.version++\n\t}\n\n\tclosestPoint(point: Vec2, searchRadius = 4): Vec2 | null {\n\t\tthis.drain()\n\t\tconst result = this.query.findClosestPoint(this.toVec3(point), { halfExtents: { x: searchRadius, y: 8, z: searchRadius } })\n\t\tif (!result.success || result.polyRef === 0) return null\n\t\treturn { x: result.point.x, z: result.point.z }\n\t}\n\n\tfindPath(from: Vec2, to: Vec2): Vec2[] | null {\n\t\tthis.drain()\n\t\tconst start = { ...this.toVec3(from) }\n\t\tconst end = { ...this.toVec3(to) }\n\t\tconst result = this.query.computePath(start, end)\n\t\tif (!result.success || result.path.length === 0) return null\n\t\treturn result.path.map((p) => ({ x: p.x, z: p.z }))\n\t}\n\n\tdebugGeometry(): NavDebugGeometry {\n\t\tthis.drain()\n\t\tconst drawer = new DebugDrawerUtils()\n\t\tconst primitives = drawer.drawNavMesh(this.navMesh)\n\t\tconst triangles: number[] = []\n\t\tconst lines: number[] = []\n\t\tfor (const primitive of primitives) {\n\t\t\tconst target = primitive.type === 'tris' ? triangles : primitive.type === 'lines' ? lines : null\n\t\t\tif (!target) continue\n\t\t\tfor (const v of primitive.vertices) target.push(v[0], v[1], v[2])\n\t\t}\n\t\tdrawer.dispose()\n\t\treturn { triangles: new Float32Array(triangles), lines: new Float32Array(lines) }\n\t}\n\n\tdispose(): void {\n\t\tthis.crowd.destroy()\n\t\tthis.query.destroy()\n\t\tthis.tileCache.destroy()\n\t\tthis.navMesh.destroy()\n\t\tthis.agents.clear()\n\t\tthis.obstacles.clear()\n\t}\n}\n","/**\n * Paths that know only what a side has seen (determinism plan F2, `GameModule.paths: 'seen'`). The world's navigation\n * has every building in it, as it must: nobody walks through a wall. But a route planned on it goes around buildings\n * nobody on the side has seen, and the way a unit goes in the dark says they are there. So each side has a navigation\n * of its own, of the ground and the buildings it knows, to plan its routes on; its units walk them a stretch at a time\n * on the world's (`systems/movement.ts`), a stretch no longer than they can see.\n *\n * What a side knows: what is the map's (the neutral's and the creeps', trees and mines among them), its own and its\n * allies', as they are put down and gone; another side's once a cell of it was in sight, and that one gone once its\n * place is in sight again. The first is the world's to say again at any time; the second is the simulation's, kept in\n * the world (`sideKnowledge`), so a save has it and a load makes the navigations again from both\n */\nimport { entityDied, entityRemoved, entitySpawned } from '#engine/engineEvents'\nimport { defineComponent } from '#engine/components'\nimport type { Entity, PlayerId } from '#engine/entity'\nimport type { Rect, Vec2 } from '#engine/math'\nimport type { System } from '#engine/registry'\nimport type { Terrain } from '#engine/terrain'\nimport type { World } from '#engine/world'\nimport { RecastNavigation, type RecastNavigationOptions } from './recast'\n\n/**\n * A building a side learned of by sight, where it saw it: its id and its rectangle\n *\n * @beta\n */\nexport type KnownBuilding = [id: number, x: number, z: number, hw: number, hd: number]\n\n/**\n * What each side learned of other sides' buildings by sight, by team: the simulation's (so a save keeps it), not a\n * screen's (`teamMemory` is the screens')\n *\n * @internal\n */\nexport const sideKnowledge = defineComponent<Record<number, KnownBuilding[]>>('core.sideKnowledge', { default: () => ({}) })\n\n/** One side's navigation, and what is in it */\ninterface Side {\n\tnavigation: RecastNavigation\n\t/** Every building in its navigation */\n\tknown: Map<number, Rect>\n\t/** Those of them it learned of by sight: another side's, which it forgets only once it sees they are gone */\n\tseen: Map<number, Rect>\n\t/** One more each time what the side knows changes: routes planned before are planned again */\n\tversion: number\n\t/** Learned or forgotten since its navigation was last brought up to date */\n\tdirty: boolean\n}\n\n/**\n * The navigations of the sides, to plan routes on\n *\n * @beta\n */\nexport class SidePaths {\n\tprivate stop?: () => void\n\n\tprivate constructor(private readonly sides: Map<number, Side>) {}\n\n\t/** A navigation for each team, of the terrain alone, cut for `options` (the world's smallest unit) */\n\tstatic async create(terrain: Terrain, teams: readonly number[], options: RecastNavigationOptions = {}): Promise<SidePaths> {\n\t\tconst sides = new Map<number, Side>()\n\t\ttry {\n\t\t\tfor (const team of teams) {\n\t\t\t\tconst navigation = await RecastNavigation.create(terrain, options)\n\t\t\t\t// asked of only once settled (`route`): what is learned and forgotten meanwhile is made into tiles together,\n\t\t\t\t// a wooded tile once, not once a tree (RV42)\n\t\t\t\tnavigation.holdObstacles(true)\n\t\t\t\tsides.set(team, { navigation, known: new Map(), seen: new Map(), version: 0, dirty: false })\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tfor (const side of sides.values()) side.navigation.dispose()\n\t\t\tthrow error\n\t\t}\n\t\treturn new SidePaths(sides)\n\t}\n\n\t/**\n\t * Listens to the world for what every side knows as it happens: the map's, and each side's own and its allies'\n\t * buildings, put down and gone. Given what the world has now, in its order, first: what a load starts from\n\t */\n\tattach(world: World): void {\n\t\tthis.stop?.()\n\t\tfor (const entity of world.entities.values()) this.put(world, entity)\n\t\tconst offs = [\n\t\t\tworld.events.on(entitySpawned, (entity) => this.put(world, entity)),\n\t\t\tworld.events.on(entityDied, ({ entity }) => this.gone(entity)),\n\t\t\tworld.events.on(entityRemoved, (entity) => this.gone(entity))\n\t\t]\n\t\tthis.stop = () => offs.forEach((off) => off())\n\t}\n\n\t/** Whether a team knows a building of `owner`'s without seeing it: the map's, its own, its allies' */\n\tprivate always(world: World, team: number, owner: PlayerId): boolean {\n\t\tconst player = world.players.get(owner)\n\t\tif (!player) return false\n\t\tif (player.neutral || player.creeps || player.team === team) return true\n\t\tfor (const other of world.players.values()) if (other.team === team) return world.areAllies(other.id, owner)\n\t\treturn false\n\t}\n\n\t/** A building put down: what every side knows of it at once */\n\tprivate put(world: World, entity: Entity): void {\n\t\tif (!entity.isStructure || !entity.alive || !entity.cell) return\n\t\tfor (const team of this.sides.keys()) if (this.always(world, team, entity.owner)) this.learn(team, entity.id, entity.rect)\n\t}\n\n\t/** A building gone: forgotten at once where it was known without being seen */\n\tprivate gone(entity: Entity): void {\n\t\tif (!entity.isStructure) return\n\t\tfor (const [team, side] of this.sides) if (side.known.has(entity.id) && !side.seen.has(entity.id)) this.forget(team, entity.id)\n\t}\n\n\t/** Whether a team plans with what it knows */\n\thas(team: number): boolean {\n\t\treturn this.sides.has(team)\n\t}\n\n\t/** One more each time what a team knows changes */\n\tversion(team: number): number {\n\t\treturn this.sides.get(team)?.version ?? 0\n\t}\n\n\tknows(team: number, id: number): boolean {\n\t\treturn !!this.sides.get(team)?.known.has(id)\n\t}\n\n\t/** The buildings a team knows, by id */\n\tknown(team: number): ReadonlyMap<number, Rect> {\n\t\treturn this.sides.get(team)?.known ?? new Map()\n\t}\n\n\t/** A team knows a building from now: it is in the way of its routes. `seen` for one it learned of by sight */\n\tlearn(team: number, id: number, rect: Rect, seen = false): void {\n\t\tconst side = this.sides.get(team)\n\t\tif (!side || side.known.has(id)) return\n\t\tconst kept = { x: rect.x, z: rect.z, hw: rect.hw, hd: rect.hd }\n\t\tside.known.set(id, kept)\n\t\tif (seen) side.seen.set(id, kept)\n\t\tside.navigation.addObstacle(id, rect)\n\t\tside.version++\n\t\tside.dirty = true\n\t}\n\n\t/** A team knows a building is gone */\n\tforget(team: number, id: number): void {\n\t\tconst side = this.sides.get(team)\n\t\tif (!side?.known.delete(id)) return\n\t\tside.seen.delete(id)\n\t\tside.navigation.removeObstacle(id)\n\t\tside.version++\n\t\tside.dirty = true\n\t}\n\n\t/** Brings each navigation up to date with what was learned and forgotten: before a route is planned on it */\n\tsettle(): void {\n\t\tfor (const side of this.sides.values()) {\n\t\t\tif (!side.dirty) continue\n\t\t\tside.navigation.settle(side.navigation.version)\n\t\t\tside.dirty = false\n\t\t}\n\t}\n\n\t/** The corners of a route from one point to another, as the team knows the ground. Null where it knows no way */\n\troute(team: number, from: Vec2, to: Vec2): Vec2[] | null {\n\t\tconst side = this.sides.get(team)\n\t\tif (!side) return null\n\t\tif (side.dirty) this.settle()\n\t\treturn side.navigation.findPath(from, to)\n\t}\n\n\t/** What the world keeps of it (`sideKnowledge`): what each side learned by sight */\n\tsave(): Record<number, KnownBuilding[]> {\n\t\tconst saved: Record<number, KnownBuilding[]> = {}\n\t\tfor (const [team, side] of this.sides) saved[team] = [...side.seen].map(([id, rect]) => [id, rect.x, rect.z, rect.hw, rect.hd])\n\t\treturn saved\n\t}\n\n\t/** After a load: what every side knows of the world as it is (`attach`), then what each learned by sight */\n\trestore(world: World, saved: Record<number, KnownBuilding[]>): void {\n\t\tthis.attach(world)\n\t\tfor (const [team, buildings] of Object.entries(saved)) {\n\t\t\tfor (const [id, x, z, hw, hd] of buildings) this.learn(Number(team), id, { x, z, hw, hd }, true)\n\t\t}\n\t\tthis.settle()\n\t}\n\n\t/** Every enemy building of `team`'s, in the order they were put there: the ones it can come to know by sight */\n\t*strangers(world: World, team: number): Generator<Entity> {\n\t\tfor (const owner of world.players.values()) {\n\t\t\tif (this.always(world, team, owner.id)) continue\n\t\t\tfor (const entity of world.index.ownedBy(owner.id)) if (entity.isStructure && entity.alive && entity.cell) yield entity\n\t\t}\n\t}\n\n\t/** The buildings a team learned of by sight */\n\tseen(team: number): ReadonlyMap<number, Rect> {\n\t\treturn this.sides.get(team)?.seen ?? new Map()\n\t}\n\n\t/** A slowing layer of cells changed on these cells: each side's navigation weighs them again, as the world's does (EN2) */\n\tgroundChanged(cells: readonly number[]): void {\n\t\tfor (const side of this.sides.values()) side.navigation.groundChanged(cells)\n\t}\n\n\t/** The ground was reshaped: each side's navigation cut again of it, as the world's is */\n\treshape(): void {\n\t\tfor (const side of this.sides.values()) side.navigation.reshape?.()\n\t}\n\n\tdispose(): void {\n\t\tthis.stop?.()\n\t\tfor (const side of this.sides.values()) side.navigation.dispose()\n\t\tthis.sides.clear()\n\t}\n}\n\n/** Whether any cell of a rectangle is in a team's sight */\nfunction inSight(world: World, team: number, rect: Rect): boolean {\n\tconst x0 = Math.floor(rect.x - rect.hw)\n\tconst x1 = Math.ceil(rect.x + rect.hw) - 1\n\tconst z0 = Math.floor(rect.z - rect.hd)\n\tconst z1 = Math.ceil(rect.z + rect.hd) - 1\n\tfor (let z = z0; z <= z1; z++) for (let x = x0; x <= x1; x++) if (world.fog.isVisible(team, x + 0.5, z + 0.5)) return true\n\treturn false\n}\n\n/**\n * What each side learns by sight, after the fog is lit (`GameModule.paths: 'seen'`): another side's buildings once a\n * cell of one is in sight, and that one gone once its place is. What it knows without seeing is the world's to tell\n * as it happens (`SidePaths.attach`). Kept in the world (`sideKnowledge`) as it changes\n */\nexport const sideKnowledgeSystem: System = {\n\tname: 'sideKnowledge',\n\tphase: 'cleanup',\n\tevery: 3,\n\tupdate(world) {\n\t\tconst paths = world.sidePaths\n\t\tif (!paths) return\n\t\tlet changed = false\n\t\tconst teams = [...new Set([...world.players.values()].map((player) => player.team))].filter((team) => paths.has(team))\n\t\tfor (const team of teams) {\n\t\t\tfor (const entity of paths.strangers(world, team)) {\n\t\t\t\tif (paths.knows(team, entity.id) || !inSight(world, team, entity.rect)) continue\n\t\t\t\tpaths.learn(team, entity.id, entity.rect, true)\n\t\t\t\tchanged = true\n\t\t\t}\n\t\t\tfor (const [id, rect] of [...paths.seen(team)]) {\n\t\t\t\tconst entity = world.entities.get(id)\n\t\t\t\tif ((entity?.alive && entity.cell) || !inSight(world, team, rect)) continue\n\t\t\t\tpaths.forget(team, id)\n\t\t\t\tchanged = true\n\t\t\t}\n\t\t}\n\t\tif (!changed) return\n\t\tpaths.settle()\n\t\tworld.setState(sideKnowledge, paths.save())\n\t}\n}\n","import type { ErrorSite, WorldFailure } from './errors'\nimport { sideKnowledge } from './navigation/sidePaths'\nimport { COPY_OF, type DataKind, redefinitions, restoreRedefinitions } from './gameData'\nimport type { AbilityDef } from './defs'\nimport { footprintOf } from './defs'\nimport type { SavedRefs } from './components'\nimport { type AbilityState, type BuffInstance, Entity, type EntityId, moving, type Order } from './entity'\nimport type { FogSave } from './fog'\nimport type { GroundItem } from './items'\nimport type { AgentSave } from './navigation/navigation'\nimport { effectRef, type EffectRef, resolveEffect } from './effectRefs'\nimport { plain as plainData } from './plain'\nimport type { PlayerInit, Purse } from './player'\nimport type { Registry } from './registry'\nimport { coreTimers, runningSequences } from './sequences'\nimport { savedGround, type SavedGround } from './ground'\nimport { waitingTimers } from './timers'\nimport type { Delayed, Missile, Projectile, Reveal, World, WorldInternals, Zone } from './world'\n\n/**\n * A world saved: everything it takes to carry on with a game later, somewhere else, or from the same moment more\n * than once. Plain data, and with `encodeSave` text: what is in the world points to definitions by id, and to\n * other entities by id.\n *\n * What is not in it:\n * - the game module (`WorldSave.game` names it), which `loadWorld` is given again;\n * - navigation, which is built again from the terrain and the structures, with the agents put back where they were;\n * - systems added while the game ran (`World.addSystem`), like a computer player: whoever loads adds them again,\n * and what they keep in themselves (`System.save`) goes back into them as they are added;\n * - state a game module keeps outside the world, like in a `WeakMap` keyed by it. Keep it in components instead\n * (`World.state`, `Player.state`, `Entity.get`), which are in here.\n *\n * Two numbers say how old a save is, and they are not the same thing. `format` is the engine's: the shape of the save\n * itself, which the engine brings up to date by itself. `version` is the game's: what the game keeps in a save (its\n * unit types, its components), which the game brings up to date (`GameModule.saves`). A save is read through both\n * (`updateSave`), the engine's first\n *\n * @beta\n */\nexport interface WorldSave {\n\t/** The shape of the save itself (`SAVE_FORMAT`): the engine's to change, and to bring an older one up to */\n\tformat: typeof SAVE_FORMAT\n\t/** Id of the game module the world was made with */\n\tgame: string\n\t/** The version of what the game keeps in a save (`GameModule.saves.version`): 1 for a game that says none */\n\tversion: number\n\t/**\n\t * Which rules it was made with exactly, mods and code included (see `gameHash`): whether it can be loaded as it is.\n\t * What a game does about a save of other rules is its own to say (`GameModule.saves.onMismatch`)\n\t */\n\thash: string\n\ttickRate: number\n\ttick: number\n\twinner: number | null\n\t/** The parts of the game switched off for having thrown (`world.disabled`): off again in the world loaded. None when left out */\n\tdisabled?: ErrorSite[]\n\t/** Why the game ended on an error (`world.failure`), for a save taken of one that did */\n\tfailure?: WorldFailure\n\trng: number\n\tinternals: WorldInternals\n\tcheats: World['cheats']\n\t/** The entity each object of the map became, by the object's id (`World.mapEntities`): as `[object, entity]`. None when left out */\n\tmapEntities?: [number, EntityId][]\n\t/** The ground: all of it, or the map the world was made from and what changed of it since (S36, format 3) */\n\tterrain: SavedGround\n\tplayers: PlayerSave[]\n\tfog: FogSave\n\t/** Where walkable space was at: movement looks for a new path when it changes */\n\tnavVersion: number\n\t/** Everything in the world, in the order it was put there */\n\tentities: EntitySave[]\n\t/** Entities that left the world but are still pointed at, like the caster of something that has yet to land */\n\tdetached: EntitySave[]\n\t/** Ids of the entities that act, in the order they are gone through: who goes first can decide what happens */\n\tactors: EntityId[]\n\t/** Scenery each team sees, by team */\n\tsceneryInSight: Record<number, EntityId[]>\n\tprojectiles: Projectile[]\n\tmissiles: MissileSave[]\n\t/** What missiles sent together have passed through, which they share */\n\tmissileHits: EntityId[][]\n\tdelayed: DelayedSave[]\n\tzones: ZoneSave[]\n\treveals: Reveal[]\n\titems: GroundItem[]\n\t/** State of game modules and mods for the whole game, by component id (see `World.state`) */\n\tstate: Record<string, unknown>\n\t/** What systems keep in themselves (`System.save`), by their name */\n\tsystems?: Record<string, unknown>\n}\n\n/**\n * The format saves are written in now: a save of another is refused. The engine keeps no steps up from an older one\n * while it and its games are made (a game's own versions have `SaveRules.migrate`)\n *\n * @beta\n */\nexport const SAVE_FORMAT = 5\n\ninterface PlayerSave {\n\tinit: PlayerInit\n\tresources: Purse\n\tsupplyUsed: number\n\tsupplyCap: number\n\t/** The game's other pools (`GameRules.supply.pools`): left out of a save made before there were any */\n\tsupplies?: Record<string, { used: number; cap: number }>\n\testablished: boolean\n\tdefeated: boolean\n\tupgrades: [string, number][]\n\tupgradesVersion: number\n\tresearching: string[]\n\t/** State of game modules and mods for the player, by component id */\n\tstate: Record<string, unknown>\n}\n\n/**\n * An entity: its type, and every field it has, as plain data. `agent` is how it moves, when it does\n *\n * @beta\n */\nexport type EntitySave = { id: EntityId; type: string; owner: number; agent?: AgentSave } & Record<string, unknown>\n\ntype MissileSave = Omit<Missile, 'hit' | 'effect'> & { hit: number; effect: EffectRef }\ntype DelayedSave = Omit<Delayed, 'caster' | 'ability' | 'effects'> & { caster: EntityId; ability: string; effects: EffectRef }\ntype ZoneSave = Omit<Zone, 'caster' | 'ability' | 'effect'> & { caster: EntityId; ability: string; effect: EffectRef }\n\n/**\n * What a save keeps of an entity besides its id, type and owner, field by field: nothing else is written, and a save\n * that has anything else is refused. A field the engine adds is either here or among those it works out again\n * (`ENTITY_DERIVED`): a test holds every field of an entity to one of the two\n *\n * @internal\n */\nexport const ENTITY_SAVE = [\n\t'alive',\n\t'hidden',\n\t'scenery',\n\t'pos',\n\t'prevPos',\n\t'facing',\n\t'prevFacing',\n\t'scale',\n\t'look',\n\t'velocity',\n\t'hp',\n\t'seenBy',\n\t'hurtAt',\n\t'expires',\n\t'lifetime',\n\t'unseenIn',\n\t'orders',\n\t'maxHp',\n\t'mana',\n\t'maxMana',\n\t'asleep',\n\t'reviving',\n\t'abilities',\n\t'buffs',\n\t'on',\n\t'cell',\n\t'components'\n] as const satisfies readonly (keyof Entity)[]\n\n/**\n * An entity's fields that are worked out again from the rest, or the engine's bookkeeping: never saved as they are.\n * Its components' values and their order (`slots`, `held`) are saved by id, as `components`, and filed again as it is\n * loaded\n *\n * @internal\n */\nexport const ENTITY_DERIVED = [\n\t'id',\n\t'def',\n\t'owner',\n\t'statsCache',\n\t'spatialStamp',\n\t'index',\n\t'slots',\n\t'held'\n] as const satisfies readonly (keyof Entity)[]\n\nconst SAVED_FIELDS = new Set<string>(ENTITY_SAVE)\n\n// ---- Saving\n\n/**\n * How a world is saved (`saveWorld`)\n *\n * @beta\n */\nexport interface SaveWorldOptions {\n\t/**\n\t * Whether the world's crowd is put back from what the save keeps of it, as loading the save puts it (determinism\n\t * D2): the game saved and a game loaded from the save then go on exactly the same. A save keeps where each agent is\n\t * and where it goes, not the crowd's own working (the order it moves its agents in, the paths it is part way\n\t * along), which cannot be put back as it was. Yes when left out; `false` for a look at the state that leaves the\n\t * world as it was (`worldState`, `worldHash`)\n\t *\n\t * @beta\n\t */\n\treseat?: boolean\n}\n\n/**\n * Saves a world, between two ticks. Throws, saying where, when something in it is not plain data\n *\n * @beta\n */\nexport function saveWorld(world: World, options: SaveWorldOptions = {}): WorldSave {\n\tconst detached = new Map<EntityId, Entity>()\n\tconst ref = (entity: Entity) => {\n\t\tif (world.entities.get(entity.id) !== entity) detached.set(entity.id, entity)\n\t\treturn entity.id\n\t}\n\tconst hitGroups = new Map<Set<EntityId>, number>()\n\tconst missileHits: EntityId[][] = []\n\tconst { terrain } = world\n\n\tconst save: WorldSave = {\n\t\tformat: SAVE_FORMAT,\n\t\tgame: world.registry.game,\n\t\tversion: world.registry.saveVersion,\n\t\thash: world.registry.hash,\n\t\ttickRate: world.tickRate,\n\t\ttick: world.tick,\n\t\twinner: world.winner,\n\t\t...(world.disabled.size > 0 && { disabled: [...world.disabled.values()] }),\n\t\t...(world.failure && { failure: structuredClone(world.failure) }),\n\t\trng: world.rng.save(),\n\t\tinternals: plain(world.internals(), 'commands') as WorldInternals,\n\t\tcheats: { ...world.cheats },\n\t\t...(world.mapEntities.size > 0 && { mapEntities: [...world.mapEntities] }),\n\t\tterrain: savedGround(terrain, world.ground, world.registry.module?.maps, world.registry.module ?? {}),\n\t\tplayers: [...world.players.values()].map((player) => ({\n\t\t\tinit: {\n\t\t\t\tid: player.id,\n\t\t\t\tname: player.name,\n\t\t\t\tteam: player.team,\n\t\t\t\tcolor: [...player.color],\n\t\t\t\tneutral: player.neutral,\n\t\t\t\tcreeps: player.creeps,\n\t\t\t\t...(player.race !== undefined && { race: player.race })\n\t\t\t},\n\t\t\tresources: { ...player.resources },\n\t\t\tsupplyUsed: player.supplyUsed,\n\t\t\tsupplyCap: player.supplyCap,\n\t\t\t...(Object.keys(player.supplies).length > 0 && { supplies: structuredClone(player.supplies) }),\n\t\t\testablished: player.established,\n\t\t\tdefeated: player.defeated,\n\t\t\tupgrades: [...player.upgrades],\n\t\t\tupgradesVersion: player.upgradesVersion,\n\t\t\tresearching: [...player.researching],\n\t\t\tstate: plain(player.states.values, `state of player ${player.id}`) as Record<string, unknown>\n\t\t})),\n\t\tfog: world.fog.save(),\n\t\tnavVersion: world.nav.version,\n\t\tentities: [...world.entities.values()].map((entity) => saveEntity(world, entity)),\n\t\tdetached: [],\n\t\tactors: [...world.actors.keys()],\n\t\tsceneryInSight: Object.fromEntries([...world.sceneryInSight].map(([team, inSight]) => [team, [...inSight].map((entity) => entity.id)])),\n\t\tprojectiles: plain(world.projectiles, 'projectiles') as Projectile[],\n\t\tmissiles: world.missiles.map((missile) => {\n\t\t\tlet group = hitGroups.get(missile.hit)\n\t\t\tif (group === undefined) {\n\t\t\t\thitGroups.set(missile.hit, (group = missileHits.length))\n\t\t\t\tmissileHits.push([...missile.hit])\n\t\t\t}\n\t\t\tconst { hit: _, effect, ...rest } = missile\n\t\t\treturn {\n\t\t\t\t...(plain(rest, `missile ${missile.id}`) as Omit<Missile, 'hit' | 'effect'>),\n\t\t\t\thit: group,\n\t\t\t\teffect: effectRef(world.registry, missile.ability, effect)\n\t\t\t}\n\t\t}),\n\t\tmissileHits,\n\t\tdelayed: world.delayed.map((delayed) => {\n\t\t\tconst { caster, ability, effects, ...rest } = delayed\n\t\t\treturn {\n\t\t\t\t...(plain(rest, 'delayed') as Omit<Delayed, 'caster' | 'ability' | 'effects'>),\n\t\t\t\tcaster: ref(caster),\n\t\t\t\tability: ability.id,\n\t\t\t\teffects: effectRef(world.registry, ability.id, effects)\n\t\t\t}\n\t\t}),\n\t\tzones: world.zones.map((zone) => {\n\t\t\tconst { caster, ability, effect, ...rest } = zone\n\t\t\treturn {\n\t\t\t\t...(plain(rest, `zone ${zone.id}`) as Omit<Zone, 'caster' | 'ability' | 'effect'>),\n\t\t\t\tcaster: ref(caster),\n\t\t\t\tability: ability.id,\n\t\t\t\teffect: effectRef(world.registry, ability.id, effect)\n\t\t\t}\n\t\t}),\n\t\treveals: plain(world.reveals, 'reveals') as Reveal[],\n\t\titems: plain(world.items, 'items') as GroundItem[],\n\t\tstate: plain(world.states.values, 'state') as Record<string, unknown>\n\t}\n\tconst systems: Record<string, unknown> = {}\n\tfor (const system of world.systems) if (system.save) systems[system.name] = plain(system.save(world), `system ${system.name}`)\n\tif (Object.keys(systems).length) save.systems = systems\n\tsave.detached = [...detached.values()].map((entity) => saveEntity(world, entity))\n\tif (options.reseat !== false) {\n\t\t// the crowd as a world loaded from this save will have it: these agents and no others, in this order, put back on\n\t\t// the ground with every structure in it (as a load puts them: an obstacle still waiting to be cut out would have\n\t\t// a target on a tile's edge snap to the other tile), settled\n\t\tworld.nav.settle(save.navVersion)\n\t\tworld.nav.reseat(save.entities.flatMap((saved) => (saved.agent ? [[saved.id, saved.agent] as const] : [])))\n\t\tworld.nav.settle(save.navVersion)\n\t\tworld.saved()\n\t}\n\treturn save\n}\n\nfunction saveEntity(world: World, entity: Entity): EntitySave {\n\tconst where = `${entity.def.id}#${entity.id}`\n\tconst save: EntitySave = { id: entity.id, type: entity.def.id, owner: entity.owner }\n\tfor (const key of ENTITY_SAVE) {\n\t\tconst value = entity[key]\n\t\tif (value === undefined) continue\n\t\tif (key === 'components') save.components = savedComponents(world, entity, where)\n\t\telse save[key] = plain(value, `${where}.${key}`)\n\t}\n\tconst agent = entity.alive && !entity.hidden && entity.get(moving) ? world.nav.saveAgent(entity.id) : undefined\n\tif (agent) save.agent = agent\n\treturn save\n}\n\n/** An entity's components as a save keeps them: each as its component says (`Component.save`), or as it is */\nfunction savedComponents(world: World, entity: Entity, where: string): Record<string, unknown> {\n\tconst saved: Record<string, unknown> = {}\n\tfor (const held of entity.heldComponents()) {\n\t\tconst { id } = held\n\t\tconst value = entity.get(held)\n\t\tconst component = world.registry.component(id)\n\t\tsaved[id] = component?.save\n\t\t\t? plain(component.save(value as never, world), `${where}.components.${id}`)\n\t\t\t: plain(value, `${where}.components.${id}`)\n\t}\n\treturn saved\n}\n\n/**\n * A copy of plain data: numbers, text, true and false, lists, and objects of those. Throws for anything else, saying\n * where, since it would not come back the same from a save: a `Map`, a `Set`, an entity, a function\n */\nconst plain = (value: unknown, where: string): unknown => plainData(value, where, 'Save', 'keep ids and plain objects in game state')\n\n// ---- Loading\n\n/** The players of a save, as a world is made with them */\nexport const savedPlayers = (save: WorldSave): PlayerInit[] => save.players.map((player) => ({ ...player.init, resources: { ...player.resources } }))\n\n/**\n * Fills a world just made from the game module and the terrain and players of the save with the rest of it. The save\n * is one of the format and the version read now: an older one goes through `updateSave` first, as `loadWorld` does\n */\nexport function restoreWorld(world: World, save: WorldSave): void {\n\tif (save.format !== SAVE_FORMAT) throw new SaveError(`Save: format ${save.format} is not one this game reads`, 'notASave')\n\tif (save.tickRate !== world.tickRate) throw new Error(`Save: made at ${save.tickRate} ticks a second, the world runs at ${world.tickRate}`)\n\tconst { registry } = world\n\tworld.tick = save.tick\n\tworld.winner = save.winner\n\tworld.rng.restore(save.rng)\n\tworld.restoreInternals(save.internals)\n\t// what the definitions were changed to while it ran, before anything is made of them\n\trestoreRedefinitions(registry, save.state[redefinitions.id])\n\tObject.assign(world.cheats, save.cheats)\n\tfor (const [object, entity] of save.mapEntities ?? []) world.mapEntities.set(object, entity)\n\n\tfor (const saved of save.players) {\n\t\tconst player = world.player(saved.init.id)\n\t\tObject.assign(player.resources, saved.resources)\n\t\tplayer.supplyUsed = saved.supplyUsed\n\t\tplayer.supplyCap = saved.supplyCap\n\t\tif (saved.supplies) player.supplies = structuredClone(saved.supplies)\n\t\tplayer.established = saved.established\n\t\tplayer.defeated = saved.defeated\n\t\tfor (const [upgrade, level] of saved.upgrades) player.setUpgrade(upgrade, level)\n\t\tplayer.upgradesVersion = saved.upgradesVersion\n\t\tfor (const upgrade of saved.researching) player.researching.add(upgrade)\n\t\tObject.assign(player.states.values, structuredClone(saved.state))\n\t}\n\tworld.fog.restore(save.fog)\n\n\tconst detached = new Map(save.detached.map((saved) => [saved.id, loadEntity(registry, saved)]))\n\t// every structure's obstacle made into the ground's tiles together: a wooded tile once, not once a tree (RV42)\n\tworld.nav.holdObstacles?.(true)\n\tfor (const saved of save.entities) {\n\t\tconst entity = loadEntity(registry, saved)\n\t\tworld.entities.set(entity.id, entity)\n\t\tworld.index.add(entity)\n\t\t// what is on the ground takes up its cells, and is in the way of who walks\n\t\tif (entity.isStructure && entity.alive) {\n\t\t\tworld.spatial.insertStatic(entity)\n\t\t\tif (entity.cell) {\n\t\t\t\t// (a gate standing open is in nobody's way: left out of the ways, as it was when the save was taken)\n\t\t\t\tconst fp = footprintOf(entity.def)\n\t\t\t\tworld.grid.occupy(entity.cell.x, entity.cell.z, fp.w, fp.d, entity.id)\n\t\t\t\tif (!registry.standsOpen(entity) && !world.nav.addObstacle(entity.id, entity.rect))\n\t\t\t\t\tworld.log.warn('navigation', `There is no room for another obstacle: ${entity.def.id} does not block the way`, { entity: entity.id })\n\t\t\t}\n\t\t}\n\t}\n\tworld.nav.holdObstacles?.(false)\n\tworld.restoreDead(save.internals.dead ?? [])\n\t// agents last, on walkable space with every structure in it, cut out first: where an agent and its target are\n\t// snapped to is the same as for the game the save was taken of\n\tworld.nav.settle(save.navVersion)\n\tfor (const saved of save.entities) if (saved.agent) world.nav.restoreAgent(saved.id, saved.agent)\n\tworld.nav.settle(save.navVersion)\n\tfor (const id of save.actors) world.actors.set(id, world.entities.get(id) ?? fail(`actor ${id} is not in the save`))\n\tfor (const [team, ids] of Object.entries(save.sceneryInSight)) {\n\t\tworld.sceneryInSight.set(Number(team), new Set(ids.map((id) => world.entities.get(id) ?? fail(`scenery ${id} is not in the save`))))\n\t}\n\n\tconst entity = (id: EntityId) => world.entities.get(id) ?? detached.get(id) ?? fail(`entity ${id} is not in the save`)\n\tconst ability = (id: string): AbilityDef => registry.ability(id)\n\tworld.projectiles.push(...(structuredClone(save.projectiles) as Projectile[]))\n\tconst hits = save.missileHits.map((ids) => new Set(ids))\n\tfor (const missile of save.missiles) {\n\t\tworld.missiles.push({ ...structuredClone(missile), hit: hits[missile.hit], effect: resolveEffect(registry, missile.ability, missile.effect) })\n\t}\n\tfor (const delayed of save.delayed) {\n\t\tconst { caster, ability: id, effects, ...rest } = structuredClone(delayed)\n\t\tworld.delayed.push({ ...rest, caster: entity(caster), ability: ability(id), effects: resolveEffect(registry, id, effects) })\n\t}\n\tfor (const zone of save.zones) {\n\t\tconst { caster, ability: id, effect, ...rest } = structuredClone(zone)\n\t\tworld.zones.push({ ...rest, caster: entity(caster), ability: ability(id), effect: resolveEffect(registry, id, effect) })\n\t}\n\tworld.reveals.push(...(structuredClone(save.reveals) as Reveal[]))\n\tObject.assign(world.states.values, structuredClone(save.state))\n\t// what each side knows of the buildings in its way, into the navigations it plans on (`GameModule.paths: 'seen'`):\n\t// the world's as it is now, and what each had learned by sight\n\tworld.sidePaths?.restore(world, world.states.has(sideKnowledge) ? world.state(sideKnowledge) : {})\n\tworld.items.push(...(structuredClone(save.items) as GroundItem[]))\n\t// what systems kept, last: what they look up (an entity by its id, the world's state) is back by now. Into those\n\t// there are, and those still to be added\n\tworld.restoreSystems(save.systems ?? {})\n\tif (save.disabled) world.disable(save.disabled)\n\tif (save.failure) world.failure = structuredClone(save.failure)\n}\n\nfunction loadEntity(registry: Registry, saved: EntitySave): Entity {\n\tconst { id, type, owner, agent: _, pos, ...fields } = structuredClone(saved)\n\tconst entity = new Entity(id, registry.unit(type), owner, pos as Entity['pos'])\n\tfor (const key of Object.keys(fields))\n\t\tif (!SAVED_FIELDS.has(key)) fail(`${type}#${id} has \"${key}\", which is not a field of an entity a save keeps`)\n\tfor (const [key, value] of Object.entries(fields)) {\n\t\tif (key === 'components') {\n\t\t\tfor (const [componentId, value] of Object.entries(fields.components as Record<string, unknown>)) {\n\t\t\t\t// one the game has, by `missingIn`'s check before any entity is made\n\t\t\t\tconst component = registry.component(componentId)!\n\t\t\t\tentity.set(component, component.load ? component.load(value, registry) : value)\n\t\t\t}\n\t\t} else entity.restore(key, value)\n\t}\n\treturn entity\n}\n\nfunction fail(what: string): never {\n\tthrow new Error(`Save: ${what}`)\n}\n\n// ---- A save made before: by an older engine, by the game before a patch\n\n/**\n * How a game's saves outlive its patches (`GameModule.saves`). Any change to a game's rules changes which rules they\n * are exactly (`registry.hash`), and most changes are nothing to a save: a number tuned, a bug fixed. A game that\n * declares this loads such a save as it is. A change a save cannot be read through (a unit type renamed, a component\n * of another shape) takes a new `version`, and a step that brings the saves made before up to it\n *\n * @beta\n */\nexport interface SaveRules {\n\t/**\n\t * The version of what the game keeps in a save: a whole number from 1, and 1 when left out. One more with every\n\t * patch that saves made before have to be changed for, together with the step that changes them (`migrate`). A save\n\t * says which it is of (`WorldSave.version`); one of a version newer than the game's is refused\n\t */\n\tversion?: number\n\t/**\n\t * What brings an older save up to date. A step for each version, by the version it starts from (`{ 3: … }` makes a\n\t * save of version 3 one of version 4), run one after the other; or one function for all of it, told the version the\n\t * save is of and the one it is to be of. A save of a version with no step after it is refused, saying so: a version\n\t * with nothing to change has the step `(save) => save`\n\t */\n\tmigrate?: Record<number, SaveMigration> | ((save: WorldSave, from: number, to: number) => WorldSave | void)\n\t/**\n\t * What becomes of a save of the game's version made with other rules, its code, its numbers or its mods having\n\t * changed since: `load` it as it is, `refuse` it, or a function that says which, given the save and the hash of the\n\t * rules now. `load` when left out\n\t */\n\tonMismatch?: 'load' | 'refuse' | ((save: WorldSave, hash: string) => 'load' | 'refuse')\n}\n\n/**\n * A step of a game's own, from one version of its saves to the next. The save is plain data in the engine's format\n * of now (the engine's own steps run first), and a copy: the step changes it in place, or gives another\n *\n * @beta\n */\nexport type SaveMigration = (save: WorldSave) => WorldSave | void\n\n/**\n * Why a save is not loaded:\n * - `notASave`: it is not a save, or says nothing readable of its format or its version\n * - `game`: it is another game's\n * - `newer`: it was made by a newer version of the game, or of the engine, than this one\n * - `noWay`: it is of an older version of the game's saves, and the game has no step from there (`SaveRules.migrate`)\n * - `rules`: it was made with other rules, and the game does not load those (`SaveRules.onMismatch`)\n * - `missing`: it has in it what the game no longer has (`SaveError.missing`)\n * - `ground`: its ground is a map of the game as it was, which the game no longer has as it was (S36)\n *\n * @beta\n */\nexport type SaveRefusal = 'notASave' | 'game' | 'newer' | 'noWay' | 'rules' | 'missing' | 'ground'\n\n/**\n * What a save has in it that the game does not have, by kind: their ids\n *\n * @beta\n */\nexport type SaveMissing = Partial<Record<'unit' | 'ability' | 'buff' | 'item' | 'upgrade' | 'order' | 'component' | 'timer' | 'sequence', string[]>>\n\n/**\n * A save that is not loaded, and why: for a list of saves to say, in words of its own\n *\n * @beta\n */\nexport class SaveError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\treadonly reason: SaveRefusal,\n\t\t/** For `missing`: what the save has that the game does not */\n\t\treadonly missing?: SaveMissing\n\t) {\n\t\tsuper(message)\n\t\tthis.name = 'SaveError'\n\t}\n}\n\n/**\n * What of a save says whether a game reads it, the rest of it apart: kept beside a save, for a list of them to ask with\n *\n * @beta\n */\nexport interface SaveHeader {\n\tformat: number\n\tgame: string\n\t/** 1 when left out, as in a save from before games had versions of their saves */\n\tversion?: number\n\thash: string\n}\n\n/**\n * The header of a save\n *\n * @beta\n */\nexport const saveHeader = (save: SaveHeader): SaveHeader => ({ format: save.format, game: save.game, version: save.version ?? 1, hash: save.hash })\n\nconst isCount = (value: unknown): value is number => typeof value === 'number' && Number.isInteger(value) && value >= 1\n\n/** What a game does about a save of its version made with other rules: what it says, else it loads when it declares `saves` at all */\nconst mismatchPolicy = (registry: Registry) => registry.module?.saves?.onMismatch ?? (registry.module?.saves ? 'load' : 'refuse')\n\nfunction otherRules(header: SaveHeader, registry: Registry): SaveError {\n\treturn new SaveError(\n\t\t`Save: made with another version of \"${registry.game}\" (${header.hash}, this is ${registry.hash}). Its rules or its mods changed since` +\n\t\t\t(registry.module?.saves ? '' : ': a game that declares GameModule.saves loads it all the same'),\n\t\t'rules'\n\t)\n}\n\n/** Why a save is refused that its header alone says: another game's, newer than this reads, or with no way up from its version */\nfunction headerProblem(header: SaveHeader, registry: Registry): SaveError | undefined {\n\tconst { format } = header\n\tconst version = header.version ?? 1\n\tif (!isCount(format)) return new SaveError(`Save: format ${String(format)} is not one this game reads`, 'notASave')\n\tif (!isCount(version)) return new SaveError(`Save: version ${String(version)} is not one this game reads`, 'notASave')\n\tif (header.game !== registry.game) return new SaveError(`Save: made with the game \"${header.game}\", not \"${registry.game}\"`, 'game')\n\tif (format > SAVE_FORMAT) {\n\t\treturn new SaveError(\n\t\t\t`Save: format ${format} is newer than this game reads (${SAVE_FORMAT}): it was saved by a newer version of the game`,\n\t\t\t'newer'\n\t\t)\n\t}\n\t// the engine keeps no way up from a format of its own before this one: the engine and its games change shape freely\n\tif (format < SAVE_FORMAT) return new SaveError(`Save: format ${format} is older than this game reads (${SAVE_FORMAT})`, 'noWay')\n\tconst to = registry.saveVersion\n\tif (version > to) {\n\t\treturn new SaveError(\n\t\t\t`Save: version ${version} of the saves of \"${registry.game}\" is newer than this game reads (${to}): it was saved by a newer version of the game`,\n\t\t\t'newer'\n\t\t)\n\t}\n\tconst migrate = registry.module?.saves?.migrate\n\tif (typeof migrate === 'function') return undefined\n\tfor (let from = version; from < to; from++) {\n\t\tif (!migrate?.[from]) {\n\t\t\treturn new SaveError(\n\t\t\t\t`Save: version ${version} of the saves of \"${registry.game}\", and the game has no way from ${from} to ${from + 1} (GameModule.saves.migrate)`,\n\t\t\t\t'noWay'\n\t\t\t)\n\t\t}\n\t}\n\treturn undefined\n}\n\n/**\n * Whether a game loads a save, as far as the save's header says (`saveHeader`): nothing, or why not. For a list of\n * saves, which has no need to read each of them whole. What only the whole save says (something in it the game no\n * longer has, a game that decides save by save) is found as it is loaded (`updateSave`, `loadWorld`)\n *\n * @beta\n */\nexport function saveProblem(header: SaveHeader, registry: Registry): SaveError | undefined {\n\tconst refused = headerProblem(header, registry)\n\tif (refused) return refused\n\tconst sameVersion = (header.version ?? 1) === registry.saveVersion\n\tif (sameVersion && header.hash !== registry.hash && mismatchPolicy(registry) === 'refuse') return otherRules(header, registry)\n\treturn undefined\n}\n\n/**\n * A save as the game reads it now, whatever it was saved by: brought up from an older version by the game's (`GameModule.saves.migrate`), each one version at a time. `loadWorld` runs\n * it; a tool that keeps saves up to date runs it by itself. The save handed in is not changed. Throws a `SaveError`,\n * which says why, for one that cannot be read: another game's, newer than this game, of a version the game has no\n * step from, made with other rules by a game that refuses those (`anyVersion` loads it all the same), or with\n * something in it the game no longer has, all of which the error names\n *\n * @beta\n */\nexport function updateSave(data: unknown, registry: Registry, options: { anyVersion?: boolean } = {}): WorldSave {\n\tif (typeof data !== 'object' || data === null) throw new SaveError('Save: not a save', 'notASave')\n\tconst header = data as SaveHeader\n\tconst refused = headerProblem(header, registry)\n\tif (refused) throw refused\n\tconst from = header.version ?? 1\n\tconst to = registry.saveVersion\n\tlet save = data as WorldSave\n\tif (from < to) {\n\t\t// a copy: the steps change what they are given, and the save handed in is its owner's\n\t\tsave = structuredClone(data) as WorldSave\n\t\tconst migrate = registry.module?.saves?.migrate\n\t\tif (typeof migrate === 'function') {\n\t\t\tif (from < to) save = migrate(save, from, to) ?? save\n\t\t} else {\n\t\t\tfor (let version = from; version < to; version++) save = migrate ?? save\n\t\t}\n\t}\n\t// the same version, other rules: whether that is a save to load is the game's to say\n\tif (from === to && header.hash !== registry.hash && !options.anyVersion) {\n\t\tconst policy = mismatchPolicy(registry)\n\t\tif ((typeof policy === 'function' ? policy(save, registry.hash) : policy) === 'refuse') throw otherRules(header, registry)\n\t}\n\tconst missing = missingIn(save, registry)\n\tif (missing) {\n\t\tconst said = Object.entries(missing).map(([kind, ids]) => `the ${KINDS[kind as keyof SaveMissing]} ${ids.map((id) => `\"${id}\"`).join(', ')}`)\n\t\tthrow new SaveError(\n\t\t\t`Save: it has what \"${registry.game}\" does not have: ${said.join('; ')}. A step of the game's (GameModule.saves.migrate) says what becomes of them`,\n\t\t\t'missing',\n\t\t\tmissing\n\t\t)\n\t}\n\t// the game's own now: its format, its version, its rules\n\treturn { ...save, format: SAVE_FORMAT, version: to, hash: registry.hash }\n}\n\nconst KINDS: Record<keyof SaveMissing, string> = {\n\tunit: 'unit types',\n\tability: 'abilities',\n\tbuff: 'buffs',\n\titem: 'items',\n\tupgrade: 'upgrades',\n\torder: 'orders',\n\tcomponent: 'components',\n\ttimer: 'timers',\n\tsequence: 'sequences'\n}\n\n/**\n * What a save names that the game does not have: found before a world is made of it, and said all at once, where\n * each would otherwise throw by itself at the moment the game came to it, some of them minutes into the game loaded\n */\nfunction missingIn(save: WorldSave, registry: Registry): SaveMissing | undefined {\n\tconst missing: SaveMissing = {}\n\tconst check = (kind: keyof SaveMissing, has: (id: string) => boolean) => (id: unknown) => {\n\t\tif (typeof id === 'string' && !has(id) && !missing[kind]?.includes(id)) (missing[kind] ??= []).push(id)\n\t}\n\t// copies made while it ran (`copyOf`, see `world.redefine`) are made again as it is loaded: the game has those then\n\tconst kept = (save.state[redefinitions.id] ?? {}) as Record<string, Record<string, Record<string, unknown>> | undefined>\n\tconst defined = (kind: DataKind) => (id: string) => registry.kinds[kind].has(id) || typeof kept[kind]?.[id]?.[COPY_OF] === 'string'\n\tconst unit = check('unit', defined('units'))\n\tconst ability = check('ability', defined('abilities'))\n\tconst buff = check('buff', defined('buffs'))\n\tconst item = check('item', defined('items'))\n\tconst upgrade = check('upgrade', defined('upgrades'))\n\tconst order = check('order', (id) => registry.orders.has(id))\n\t// one the game lists, or the engine's own\n\tconst component = check('component', (id) => registry.component(id) !== undefined)\n\t// each component's own say of what it names (`Component.refs`)\n\tconst named: Record<keyof SavedRefs, (id: unknown) => void> = { units: unit, abilities: ability, buffs: buff, items: item, upgrades: upgrade }\n\tconst components = (values: unknown) => {\n\t\tfor (const [id, value] of Object.entries((values as Record<string, unknown> | undefined) ?? {})) {\n\t\t\tcomponent(id)\n\t\t\tconst refs = registry.component(id)?.refs?.(value)\n\t\t\tif (refs) for (const kind of Object.keys(refs) as (keyof SavedRefs)[]) refs[kind]?.forEach(named[kind])\n\t\t}\n\t}\n\t// an effect made up on the spot is kept whole; one of an ability is found in it again, so the ability has to be there\n\tconst placed = (effect: EffectRef | undefined) => !!effect && 'path' in effect\n\n\tcomponents(save.state)\n\tfor (const player of save.players) {\n\t\tcomponents(player.state)\n\t\tfor (const [id] of player.upgrades) upgrade(id)\n\t\tfor (const id of player.researching) upgrade(id)\n\t}\n\tfor (const entity of [...save.entities, ...save.detached]) {\n\t\tunit(entity.type)\n\t\tcomponents(entity.components)\n\t\tfor (const state of (entity.abilities as AbilityState[] | undefined) ?? []) ability(state.id)\n\t\tfor (const instance of (entity.buffs as BuffInstance[] | undefined) ?? []) buff(instance.id)\n\t\tfor (const given of (entity.orders as Order[] | undefined) ?? []) {\n\t\t\torder(given.type)\n\t\t\tunit(given.init?.unitType)\n\t\t}\n\t}\n\tfor (const missile of save.missiles) if (placed(missile.effect)) ability(missile.ability)\n\tfor (const delayed of save.delayed) ability(delayed.ability)\n\tfor (const zone of save.zones) ability(zone.ability)\n\tfor (const dropped of save.items) item(dropped.item)\n\tconst game = registry.module\n\tif (game) {\n\t\tconst timers = new Set([...coreTimers, ...(registry.assembly?.timers ?? game.timers ?? [])].map((def) => def.id))\n\t\tconst sequences = new Set((game.sequences ?? []).map((def) => def.id))\n\t\twaitingTimers(save.state).forEach(check('timer', (id) => timers.has(id)))\n\t\trunningSequences(save.state).forEach(check('sequence', (id) => sequences.has(id)))\n\t}\n\treturn Object.keys(missing).length > 0 ? missing : undefined\n}\n\n// ---- As text\n\n/**\n * A save as text. JSON, but for numbers JSON has no words for, which game state has: buffs that last forever\n * (`Infinity`), something never hurt (`-Infinity`)\n *\n * @beta\n */\nexport function encodeSave(save: WorldSave): string {\n\treturn JSON.stringify(save, (_key, value) => (typeof value === 'number' && !Number.isFinite(value) ? { $number: String(value) } : value))\n}\n\n/** @beta */\nexport function decodeSave(text: string): WorldSave {\n\treturn JSON.parse(text, (_key, value) =>\n\t\tvalue && typeof value === 'object' && Object.keys(value).length === 1 && typeof value.$number === 'string' ? Number(value.$number) : value\n\t) as WorldSave\n}\n","/**\n * Who is on whose side in a world (`world.sides`): teams, what two players were set to be to each other, which teams see\n * what others see, who may command whose units. What every target, every command and every player's fog asks\n */\nimport { teamChanged } from '#engine/engineEvents'\nimport { defineComponent } from './components'\nimport type { Entity, PlayerId } from './entity'\nimport type { PlayerRelation, World } from './world'\n\n/** Pairs of players set apart from their teams, by `a * RELATION_KEY + b` with a < b */\nconst RELATION_KEY = 65536\nexport const relations = defineComponent<{ pairs: Record<number, PlayerRelation> }>('core.relations', { default: () => ({ pairs: {} }) })\n/** Teams that see what others see: by the team that sees, those it shares with */\nexport const vision = defineComponent<{ teams: Record<number, number[]> }>('core.vision', { default: () => ({ teams: {} }) })\n/** Who may command whose units besides their owner (`shareControl`): by the owner, the players given control. Kept in the world */\nexport const control = defineComponent<{ players: Record<number, number[]> }>('core.control', { default: () => ({ players: {} }) })\nconst NONE: readonly number[] = []\n\n/**\n * Who is on whose side: kept in the world's state, so a save has it\n *\n * @beta\n */\nexport class Sides {\n\tconstructor(private readonly world: World) {}\n\n\t/** Whether everyone on a team is out */\n\tteamDefeated(team: number): boolean {\n\t\tfor (const player of this.world.players.values()) if (player.team === team && !player.neutral && !player.defeated) return false\n\t\treturn true\n\t}\n\n\t/** Whether two players fight each other: their teams, or what they were set to be (`setRelation`) */\n\tenemies(a: PlayerId, b: PlayerId): boolean {\n\t\tif (a === b) return false\n\t\tconst set = this.relationOf(a, b)\n\t\tif (set) return set === 'enemy'\n\t\tconst pa = this.world.player(a)\n\t\tconst pb = this.world.player(b)\n\t\treturn !pa.neutral && !pb.neutral && pa.team !== pb.team\n\t}\n\n\t/**\n\t * What two players are to each other from now on, whatever their teams: `ally`, `enemy`, or `neutral` (neither).\n\t * Null goes back to what their teams say. Creeps that turn friendly to one player; a ceasefire. Kept in the world:\n\t * a save has it. Sight stays the teams' (see `shareVision`)\n\t */\n\tsetRelation(a: PlayerId, b: PlayerId, relation: PlayerRelation | null): void {\n\t\tif (a === b) return\n\t\tconst key = a < b ? a * RELATION_KEY + b : b * RELATION_KEY + a\n\t\tconst { pairs } = this.world.state(relations)\n\t\tif (relation) pairs[key] = relation\n\t\telse delete pairs[key]\n\t}\n\n\t/** What two players were set to be to each other (`setRelation`), if anything */\n\trelationOf(a: PlayerId, b: PlayerId): PlayerRelation | undefined {\n\t\t// read without making the state: a game that sets none pays nothing for it\n\t\tconst set = this.world.states.values[relations.id] as { pairs: Record<number, PlayerRelation> } | undefined\n\t\tif (!set) return undefined\n\t\treturn set.pairs[a < b ? a * RELATION_KEY + b : b * RELATION_KEY + a]\n\t}\n\n\t/**\n\t * Moves a player to another team, one there is or a new one: whom they fight and see with follows. What their units\n\t * were doing goes on; what they fought that is now a friend, they stop fighting on their own\n\t */\n\tsetTeam(player: PlayerId, team: number): void {\n\t\tconst moved = this.world.player(player)\n\t\tif (moved.team === team) return\n\t\tconst from = moved.team\n\t\tthis.world.fog.addTeam(team)\n\t\tmoved.team = team\n\t\tthis.world.events.emit(teamChanged, { player, from, to: team })\n\t}\n\n\t/**\n\t * Lets one team see what another sees, from now on, or no longer: shared vision without an alliance. Kept in the\n\t * world. A team sees what its own units see as ever\n\t */\n\tshareVision(from: number, to: number, shared = true): void {\n\t\tconst { teams } = this.world.state(vision)\n\t\tconst list = (teams[from] ??= [])\n\t\tconst index = list.indexOf(to)\n\t\tif (shared && index < 0 && from !== to) list.push(to)\n\t\tif (!shared && index >= 0) list.splice(index, 1)\n\t\tthis.world.fog.addTeam(to)\n\t}\n\n\t/** The teams that see what this one sees, besides itself */\n\tvisionOf(team: number): readonly number[] {\n\t\tconst set = this.world.states.values[vision.id] as { teams: Record<number, number[]> } | undefined\n\t\treturn set?.teams[team] ?? NONE\n\t}\n\n\t/**\n\t * Lets a player command another's units, from now on, or no longer: shared control, as allies in a melee game give\n\t * each other (a map's force with `sharedControl` gives it to every player of the force). Kept in the world. Who may\n\t * command what is `mayCommand`, which the rules may widen or narrow (`GameRules.mayCommand`)\n\t */\n\tshareControl(owner: PlayerId, withPlayer: PlayerId, shared = true): void {\n\t\tconst { players } = this.world.state(control)\n\t\tconst list = (players[owner] ??= [])\n\t\tconst index = list.indexOf(withPlayer)\n\t\tif (shared && index < 0 && owner !== withPlayer) list.push(withPlayer)\n\t\tif (!shared && index >= 0) list.splice(index, 1)\n\t}\n\n\t/** The players who may command this one's units, besides the owner (`shareControl`) */\n\tcontrolOf(owner: PlayerId): readonly PlayerId[] {\n\t\tconst set = this.world.states.values[control.id] as { players: Record<number, number[]> } | undefined\n\t\treturn set?.players[owner] ?? NONE\n\t}\n\n\t/**\n\t * Shares what a player has with another, from now on, or no longer: their units' control (`shareControl`) and\n\t * what their team sees (`shareVision`, team to team)\n\t */\n\tshare(player: PlayerId, withPlayer: PlayerId, what: { control?: boolean; vision?: boolean }): void {\n\t\tif (what.control !== undefined) this.shareControl(player, withPlayer, what.control)\n\t\tif (what.vision !== undefined) this.shareVision(this.world.player(player).team, this.world.player(withPlayer).team, what.vision)\n\t}\n\n\t/**\n\t * Whether a player may command an entity: its owner, whoever the owner shares control with, and whatever else the\n\t * rules say (`GameRules.mayCommand`). What every command of the player's is checked against\n\t */\n\tmayCommand(player: PlayerId, entity: Entity): boolean {\n\t\treturn this.world.rules.mayCommand(this.world, player, entity)\n\t}\n\n\t/** Whether two players are on one side: one player, a team, or what they were set to be (`setRelation`) */\n\tallies(a: PlayerId, b: PlayerId): boolean {\n\t\tif (a === b) return true\n\t\tconst set = this.relationOf(a, b)\n\t\tif (set) return set === 'ally'\n\t\tconst pa = this.world.player(a)\n\t\tconst pb = this.world.player(b)\n\t\treturn !pa.neutral && !pb.neutral && pa.team === pb.team\n\t}\n}\n","import type { System, SystemPhase } from './registry'\nimport type { World } from './world'\n\n/**\n * The parts of a tick, in the order they run. The player commands of the tick have been applied before any of them.\n * - `commands`: first, for what reacts to the commands, or adds some of its own\n * - `decide`: units choose and carry out what they do: abilities, orders\n * - `move`: everything that moves, moves\n * - `resolve`: what follows from where things ended up: attacks land, buildings go up, units are trained\n * - `cleanup`: bookkeeping once everything happened: what runs out, what each team sees, who won\n *\n * @beta\n */\nexport const PHASES: readonly SystemPhase[] = ['commands', 'decide', 'move', 'resolve', 'cleanup']\n\n/** Where a system without a phase runs: after everything, like the systems of game modules always did */\nconst DEFAULT_PHASE: SystemPhase = 'cleanup'\n\n/** How much of each new tick goes into the averaged time of a system. Small: the panel shows a steady number */\nconst SMOOTHING = 0.02\n\n/**\n * What the scheduler measured of a system: milliseconds per tick, averaged, with the ticks it does not run counted as nothing\n *\n * @beta\n */\nexport interface SystemTiming {\n\tname: string\n\tphase: SystemPhase\n\tms: number\n}\n\n/**\n * Runs the systems of a world in their order, each as often as it asks. The order is worked out whenever a system\n * is added or taken out: by phase first, then by what each says it comes `before` or `after`, then in the order\n * they were added. Measures each one while `profiling` is on, for the stats panel.\n *\n * @beta\n */\nexport class Scheduler {\n\tprivate readonly added: System[] = []\n\tprivate ordered: System[] = []\n\tprivate readonly timings = new Map<string, number>()\n\t/** Whether to time each system. Costs two clock readings per system per tick, so it is off unless someone looks */\n\tprofiling = false\n\n\tconstructor(systems: System[]) {\n\t\tfor (const system of systems) {\n\t\t\tthis.check(system)\n\t\t\tthis.added.push(system)\n\t\t}\n\t\tthis.ordered = order(this.added).filter((system) => !this.off.has(system.name))\n\t}\n\n\t/** The systems, in the order they run */\n\tget systems(): readonly System[] {\n\t\treturn this.ordered\n\t}\n\n\t/** Adds a system to a world that is already running, like a computer player */\n\tadd(system: System): void {\n\t\tthis.check(system)\n\t\tthis.added.push(system)\n\t\tthis.ordered = order(this.added).filter((system) => !this.off.has(system.name))\n\t}\n\n\t/** Takes a system out by name. False when there is none of that name */\n\tremove(name: string): boolean {\n\t\tconst index = this.added.findIndex((system) => system.name === name)\n\t\tif (index < 0) return false\n\t\tthis.added.splice(index, 1)\n\t\tthis.ordered = order(this.added).filter((system) => !this.off.has(system.name))\n\t\tthis.timings.delete(name)\n\t\treturn true\n\t}\n\n\t/** Runs one tick of every system that is due. Each is given the time since it last ran */\n\trun(world: World): void {\n\t\tconst { tick, dt } = world\n\t\tfor (const system of this.ordered) {\n\t\t\tconst every = system.every ?? 1\n\t\t\tconst due = every === 1 || tick % every === (system.offset ?? 0) % every\n\t\t\tif (!this.profiling) {\n\t\t\t\tif (due) this.update(system, world, dt * every)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst start = performance.now()\n\t\t\tif (due) this.update(system, world, dt * every)\n\t\t\tconst took = due ? performance.now() - start : 0\n\t\t\tconst before = this.timings.get(system.name)\n\t\t\tthis.timings.set(system.name, before === undefined ? took : before + (took - before) * SMOOTHING)\n\t\t}\n\t}\n\n\t/** Runs a system. One that throws comes to what the world says of errors (`World.caught`): switched off, where it says so */\n\tprivate update(system: System, world: World, dt: number): void {\n\t\ttry {\n\t\t\tsystem.update?.(world, dt)\n\t\t\tif (system.each) runEach(system, world, dt)\n\t\t} catch (error) {\n\t\t\tworld.caught(error, { kind: 'system', id: system.name })\n\t\t\tthis.disable(system.name)\n\t\t}\n\t}\n\n\tprivate readonly off = new Set<string>()\n\n\t/** Switches a system off: it no longer runs, and stays off when others are added */\n\tdisable(name: string): void {\n\t\tthis.off.add(name)\n\t\tthis.ordered = this.ordered.filter((system) => system.name !== name)\n\t}\n\n\t/** What each system takes, in the order they run. Empty until `profiling` has been on for a while */\n\ttiming(): SystemTiming[] {\n\t\treturn this.ordered.flatMap((system) => {\n\t\t\tconst ms = this.timings.get(system.name)\n\t\t\treturn ms === undefined ? [] : [{ name: system.name, phase: system.phase ?? DEFAULT_PHASE, ms }]\n\t\t})\n\t}\n\n\tprivate check(system: System): void {\n\t\tif (this.added.some((other) => other.name === system.name)) throw new Error(`There is a system called \"${system.name}\" already`)\n\t\tif (!system.update && !system.each) throw new Error(`System \"${system.name}\" has neither update nor each: nothing to run`)\n\t\tif (system.every !== undefined && (!Number.isInteger(system.every) || system.every < 1))\n\t\t\tthrow new Error(`System \"${system.name}\" runs every ${system.every} ticks: that has to be a whole number, 1 or more`)\n\t}\n}\n\n/** Runs a system's `each` over what it says (`System.over`): the actors, what has a component in the order of its id, or a test's */\nfunction runEach(system: System, world: World, dt: number): void {\n\tconst each = system.each!\n\tconst { over } = system\n\tif (over === undefined || over === 'actors') {\n\t\tfor (const entity of world.actors.values()) each.call(system, world, entity, dt)\n\t} else if (typeof over === 'function') {\n\t\tfor (const entity of world.actors.values()) if (over(entity, world)) each.call(system, world, entity, dt)\n\t} else {\n\t\tfor (const entity of world.index.ordered(over)) each.call(system, world, entity, dt)\n\t}\n}\n\n/** What `order` sorts: a system, or anything else that runs in turn and says what it comes before and after (a brain's modules) */\nexport interface Ordered {\n\tname: string\n\tphase?: SystemPhase\n\tbefore?: string[]\n\tafter?: string[]\n}\n\n/**\n * Sorts systems by phase, then by `before` and `after`, keeping the order they were given in where nothing says\n * otherwise. Names that are not among them are passed over: what they named may have been left out of the game.\n * The modules of a computer player's brain are put in their order by it too (`ai/brain.ts`)\n */\nexport function order<T extends Ordered>(systems: T[]): T[] {\n\tconst phaseOf = (system: T) => PHASES.indexOf(system.phase ?? DEFAULT_PHASE)\n\tconst byName = new Map(systems.map((system) => [system.name, system]))\n\t// for each system, the ones that have to run before it\n\tconst needs = new Map<T, Set<T>>(systems.map((system) => [system, new Set()]))\n\tconst rule = (first: T, then: T) => {\n\t\tif (phaseOf(first) > phaseOf(then))\n\t\t\tthrow new Error(`System \"${first.name}\" cannot run before \"${then.name}\": it is in a later phase (${first.phase ?? DEFAULT_PHASE})`)\n\t\tneeds.get(then)!.add(first)\n\t}\n\tfor (const system of systems) {\n\t\tfor (const name of system.before ?? []) if (byName.has(name)) rule(system, byName.get(name)!)\n\t\tfor (const name of system.after ?? []) if (byName.has(name)) rule(byName.get(name)!, system)\n\t}\n\n\tconst result: T[] = []\n\tconst done = new Set<T>()\n\t// phase by phase, the first system in the given order that has nothing left to wait for\n\tconst waiting = [...systems].sort((a, b) => phaseOf(a) - phaseOf(b))\n\twhile (waiting.length) {\n\t\tconst index = waiting.findIndex((system) => [...needs.get(system)!].every((first) => done.has(first)))\n\t\tif (index < 0) throw new Error(`Systems wait for each other in a circle: ${waiting.map((system) => system.name).join(', ')}`)\n\t\tconst [next] = waiting.splice(index, 1)\n\t\tdone.add(next)\n\t\tresult.push(next)\n\t}\n\treturn result\n}\n","/**\n * The computer players of a world (`world.computers`): who is seated where, kept in the world so that a save has them\n * and a loaded game seats them again. The seats alone, no brain: a brain seats itself (`BrainDef.seat`, the AI kit's\n * `defineBrain` gives it one), so that the engine's core loads nothing of the computer player's kit\n * (`@v12-engine/engine/ai`) a game does not list\n */\nimport { defineComponent } from './components'\nimport type { PlayerId } from './entity'\nimport { plainParts } from './plain'\nimport type { World } from './world'\nimport type { AiOptions } from './ai/options'\nimport type { Brain, BrainDef } from './ai/brain'\nimport type { ComputerPlayer, ComputerSystem } from './ai/computer'\n\n/**\n * How a brain is seated at a player (`BrainDef.seat`): the system the seat is, a computer thinking in it. What\n * `defineBrain` and `defineComputer` give a brain, so that the core seats it without knowing how\n *\n * @beta\n */\nexport type BrainSeat = (world: World, player: PlayerId, options: AiOptions) => ComputerSystem\n\n/**\n * What a seat is asked for (`world.computers.seat(player, request)`): the brain (one of the game's, `defineBrain`, or\n * its id; the first the game lists when left out) and what it is seated with (`AiOptions`)\n *\n * @beta\n */\nexport interface SeatRequest extends AiOptions {\n\t/** The brain, or its id (one the game lists in `GameModule.brains`): the first the game lists when left out */\n\tbrain?: BrainDef | string\n}\n\n/**\n * A seat as a save keeps it (`core.computers`): the brain by id, and the data part of its options\n *\n * @beta\n */\nexport interface ComputerSeat {\n\t/** The brain's id. Left out for the first brain the game lists */\n\tbrain?: string\n\t/** What it was seated with, the data of it (`AiOptions`) */\n\toptions: Record<string, unknown>\n}\n\n/**\n * Who the computer plays, by player, with what they were seated with: in the world, so that a save keeps it and a\n * loaded game seats them again by itself (`world.computers`)\n */\nexport const computerSeats = defineComponent<Record<string, ComputerSeat>>('core.computers', { default: () => ({}) })\n\n/**\n * What every seat of the world is given where its request says nothing (`world.computers.defaults`): data only, kept in\n * the world so a save has it, and a computer seated after a load gets it too\n */\nexport const computerDefaults = defineComponent<Record<string, unknown>>('core.computerDefaults', { default: () => ({}) })\n\n/**\n * The computer players of a world: who is seated, kept in the world and in a save (`core.computers`), so that a game\n * loaded from a save has them back without the game's doing, and how the game reaches a seated brain while it plays\n * (`tell`, `pause`, `get`)\n *\n * @beta\n */\nexport class Computers {\n\t/** The seats, by player, in the order they were taken */\n\tprivate readonly seats = new Map<PlayerId, ComputerSystem>()\n\n\tconstructor(private readonly world: World) {}\n\n\t/**\n\t * Seats the computer at a player, and remembers it: a game loaded from a save of this one has it back, with its memory\n\t * (`restore`). `request.brain` is one of the game's (`defineBrain`; one listed in `GameModule.brains` is found again by\n\t * its id for a load, one that is not is kept by id only, and a load without it warns and leaves the seat empty), or\n\t * its id, or left out for the first brain the game lists. Of the rest of the request (`AiOptions`), the data is kept\n\t * (numbers, lists, names); a function given in it is dropped from the save, said in the log, and a load has what the\n\t * brain's definition gives: a game that wants its function back after a load puts it in the brain it lists in\n\t * `GameModule.brains`. A player seated already is unseated first. What thinks in it is a `Brain` unless the brain was\n\t * made otherwise (`defineComputer`: say which)\n\t */\n\tseat<C extends ComputerPlayer = Brain>(player: PlayerId, request: SeatRequest = {}): ComputerSystem<C> {\n\t\tconst { brain: asked_, ...asked } = request\n\t\t// what the world gives every seat, under what the request says (and over what the map says: `withMapAi`)\n\t\tconst options: AiOptions = { ...this.defaults, ...asked }\n\t\t// the seat's brain, else the map's for the player, else its race's (AR3); the game's first where none says\n\t\tconst brain = asked_ ?? this.brainFor(player)\n\t\tconst def = typeof brain === 'string' ? this.brain(brain) : brain\n\t\tif (typeof brain === 'string' && !def) throw new Error(`No brain is called \"${brain}\": list it in GameModule.brains, or seat the brain itself`)\n\t\tif (this.seats.has(player)) this.unseat(player)\n\t\tconst system = this.seated(player, def, options)\n\t\tthis.world.addSystem(system)\n\t\tthis.seats.set(player, system)\n\t\tthis.world.setState(computerSeats, {\n\t\t\t...this.world.state(computerSeats),\n\t\t\t[player]: { ...(def && { brain: def.id }), options: dataOf(options, this.world, player) }\n\t\t})\n\t\treturn system as ComputerSystem<C>\n\t}\n\n\t/**\n\t * What every computer seated from now on is given where its request says nothing (`AiOptions`, data only: a\n\t * difficulty, a personality), over what the map says of the player (`MapPlayer.data.ai`): a campaign's difficulty,\n\t * set before a mission seats its computers. Kept in the world, so a save has it. Those seated already keep what they\n\t * were seated with\n\t */\n\tget defaults(): Readonly<Pick<AiOptions, 'difficulty' | 'personality'>> {\n\t\treturn this.world.states.has(computerDefaults) ? (this.world.state(computerDefaults) as Pick<AiOptions, 'difficulty' | 'personality'>) : {}\n\t}\n\n\tset defaults(defaults: Pick<AiOptions, 'difficulty' | 'personality'>) {\n\t\tthis.world.setState(computerDefaults, { ...defaults })\n\t}\n\n\t/** Takes the computer out of a player's seat, and out of what a save remembers. False where none was seated */\n\tunseat(player: PlayerId): boolean {\n\t\tconst system = this.seats.get(player)\n\t\tif (this.world.states.has(computerSeats) && player in this.world.state(computerSeats)) {\n\t\t\tconst { [player]: _gone, ...rest } = this.world.state(computerSeats)\n\t\t\tthis.world.setState(computerSeats, rest)\n\t\t}\n\t\tif (!system) return false\n\t\tthis.seats.delete(player)\n\t\tthis.world.removeSystem(system.name)\n\t\tsystem.dispose()\n\t\treturn true\n\t}\n\n\t/** The seat the computer plays a player from, while it does */\n\tget(player: PlayerId): ComputerSystem | undefined {\n\t\treturn this.seats.get(player)\n\t}\n\n\t/** The players the computer plays, in the order they were seated */\n\tlist(): PlayerId[] {\n\t\treturn [...this.seats.keys()]\n\t}\n\n\t/**\n\t * Tells a computer player a word, with data to go with it: what a mission's script says to its brain\n\t * (`world.computers.tell(ENEMY, 'raid', { at })`), taken by a rule of the brain's (`when.told`). False where nobody is\n\t * seated there, or what is seated takes no words\n\t */\n\ttell(player: PlayerId, word: string, data?: unknown): boolean {\n\t\tconst computer = this.get(player)?.computer\n\t\tif (!computer?.tell) return false\n\t\tcomputer.tell(word, data, this.world.tick)\n\t\treturn true\n\t}\n\n\t/** Has a computer player sit still until `resume`: kept in a save. False where none is seated, or it cannot be paused */\n\tpause(player: PlayerId): boolean {\n\t\treturn this.setPaused(player, true)\n\t}\n\n\t/** Has a paused computer player think again */\n\tresume(player: PlayerId): boolean {\n\t\treturn this.setPaused(player, false)\n\t}\n\n\tprivate setPaused(player: PlayerId, paused: boolean): boolean {\n\t\tconst computer = this.get(player)?.computer\n\t\tif (!computer || !('paused' in computer)) return false\n\t\tcomputer.paused = paused\n\t\treturn true\n\t}\n\n\t/** The system a player's seat is: the brain's own seat (`BrainDef.seat`), the first brain the game lists where none is named. Throws for a game that lists none */\n\tprivate seated(player: PlayerId, def: BrainDef | undefined, options: AiOptions): ComputerSystem {\n\t\tconst game = this.world.registry.module\n\t\tconst brain = def ?? game?.brains?.[0]\n\t\tif (!brain)\n\t\t\tthrow new Error(\n\t\t\t\t`The game \"${game?.id}\" gives no computer player to seat at player ${player}: list a brain in GameModule.brains (meleeBrain of @v12-engine/engine/ai plays melee), or seat a brain`\n\t\t\t)\n\t\tif (!brain.seat) throw new Error(`The brain \"${brain.id}\" was not made with defineBrain or defineComputer (@v12-engine/engine/ai): it has no seat`)\n\t\treturn brain.seat(this.world, player, options)\n\t}\n\n\t/**\n\t * The brain a player is seated with where the seat names none, by id: the map's for the player (`MapAi.brain`, where\n\t * the map gives the player to the computer), else its race's (`GameAi.races[race].brain`), else the game's defaults'\n\t * (`GameAi.defaults.brain`). Nothing where none says: the game's first brain\n\t */\n\tprivate brainFor(player: PlayerId): string | undefined {\n\t\tconst mapped = this.world.map.player(player)\n\t\tconst map = mapped?.controller === 'computer' ? (mapped.data?.ai as { brain?: unknown } | undefined) : undefined\n\t\tif (map && typeof map === 'object' && typeof map.brain === 'string') return map.brain\n\t\tconst ai = this.world.registry.module?.ai\n\t\tconst race = this.world.players.get(player)?.race\n\t\treturn (race !== undefined ? ai?.races?.[race]?.brain : undefined) ?? ai?.defaults?.brain\n\t}\n\n\t/** A brain by id: one the game lists (`GameModule.brains`) */\n\tbrain(id: string): BrainDef | undefined {\n\t\treturn this.world.registry.module?.brains?.find((brain) => brain.id === id)\n\t}\n\n\t/**\n\t * Seats again the computers a save remembers, in a world loaded from it: what `loadWorld` does before the game's\n\t * `afterLoad`. One the game seated already is left as it is; one whose brain is not to be found (seated by an object\n\t * the game does not list) is left empty, and the log says so\n\t */\n\trestore(): void {\n\t\tif (!this.world.states.has(computerSeats)) return\n\t\tfor (const [id, seat] of Object.entries(this.world.state(computerSeats))) {\n\t\t\tconst player = Number(id)\n\t\t\tif (this.seats.has(player)) continue\n\t\t\tconst def = seat.brain === undefined ? undefined : this.brain(seat.brain)\n\t\t\tif (seat.brain !== undefined && !def) {\n\t\t\t\tthis.world.log.warn(\n\t\t\t\t\t'ai',\n\t\t\t\t\t`the save seats the brain \"${seat.brain}\" at player ${player}, which the game does not list (GameModule.brains): the seat is left empty`,\n\t\t\t\t\t{\n\t\t\t\t\t\tplayer,\n\t\t\t\t\t\tbrain: seat.brain\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst system = this.seated(player, def, seat.options as AiOptions)\n\t\t\tthis.world.addSystem(system)\n\t\t\tthis.seats.set(player, system)\n\t\t}\n\t}\n}\n\n/**\n * The data part of a seat's options, for a save: what is plain data is kept as it is, and what is not (a function, or a\n * list with a function in it: `goals`, a flag given as a function in `settings`) is dropped, said in the log\n */\nfunction dataOf(options: AiOptions, world: World, player: PlayerId): Record<string, unknown> {\n\tconst { kept, dropped } = plainParts(options)\n\tif (dropped.length)\n\t\tworld.log.debug(\n\t\t\t'ai',\n\t\t\t`the options ${dropped.map((key) => `\"${key}\"`).join(', ')} of the computer at player ${player} are code, and not kept in a save`,\n\t\t\t{\n\t\t\t\tplayer,\n\t\t\t\tdropped\n\t\t\t}\n\t\t)\n\treturn kept as Record<string, unknown>\n}\n","import type { AreaDef } from './areas'\nimport type { GamePack } from './packs/pack'\nimport { defineComponent } from './components'\nimport type { PlayerId } from './entity'\nimport { defineEvent } from './events'\nimport type { MapFieldDef, MapThing } from './mapFields'\nimport type { Vec2 } from './math'\nimport type { System } from './registry'\nimport type { World } from './world'\n\n/*\n * Capture points (master plan FI2): places on the map a side takes by standing in them, as a king of the hill or a\n * control point is. A pack a game turns on (`withCapture`): the points come from code (`CapturePoint`) and from the\n * map, as things of the `capture` kind the editor places (the client's `captureKind`); each is an area the rules\n * watch, with its owner and how far a side has got toward taking it kept in the world (`captures`, in a save and in\n * the game's report, which the HUD and the computer read). A system counts who stands in each every few ticks, and\n * says when one changes hands (`captured`) and when a side starts taking it (`capturing`)\n */\n\n/**\n * What a point does while two sides stand in it: nothing moves (`pause`), what was gained is lost (`reset`), or the\n * larger side takes it as if alone (`majority`; a tie pauses)\n *\n * @beta\n */\nexport type Contested = 'pause' | 'reset' | 'majority'\n\n/**\n * A capture point given in code (`withCapture`'s `points`); one placed on the map says the same with its fields\n *\n * @beta\n */\nexport interface CapturePoint {\n\t/** Unique among the game's points: what the events name it by, and `capturePoint` */\n\tid: string\n\tname?: string\n\tat: Vec2\n\t/** How far around its middle counts, in cells: 4 when left out */\n\tradius?: number\n\t/** Seconds a side alone in it takes to make it its own: 10 when left out */\n\ttime?: number\n\t/** What it does while two sides stand in it: `pause` when left out */\n\tcontested?: Contested\n\t/** Whose it is as the game starts: nobody's when left out */\n\towner?: PlayerId\n}\n\n/**\n * A capture point as the world keeps it: where it is, how it is taken, whose it is, and who is taking it now (a team)\n * and how far they have got (0 to 1)\n *\n * @beta\n */\nexport interface CaptureState {\n\tid: string\n\tname?: string\n\tx: number\n\tz: number\n\tradius: number\n\ttime: number\n\tcontested: Contested\n\towner: PlayerId | null\n\tby: number | null\n\tprogress: number\n}\n\n/**\n * The kind of thing on the map a capture point is placed as (the editor's `captureKind`)\n *\n * @beta\n */\nexport const CAPTURE_KIND = 'capture'\n\n/**\n * The fields of a capture point on the map, as the editor's kind offers them and the rules read them: its reach, its\n * time, what it does contested, and whose it is at the start\n *\n * @beta\n */\nexport const CAPTURE_FIELDS: readonly Omit<MapFieldDef, 'for'>[] = [\n\t{ id: 'radius', name: 'Reach', kind: 'number', default: 4, min: 1, max: 24, step: 0.5, hint: 'How far around its middle counts, in cells' },\n\t{\n\t\tid: 'time',\n\t\tname: 'Seconds to take',\n\t\tkind: 'number',\n\t\tdefault: 10,\n\t\tmin: 1,\n\t\tmax: 300,\n\t\tstep: 1,\n\t\thint: 'Seconds a side alone in it takes to make it its own'\n\t},\n\t{\n\t\tid: 'contested',\n\t\tname: 'While contested',\n\t\tkind: 'choice',\n\t\tdefault: 'pause',\n\t\toptions: [\n\t\t\t{ value: 'pause', label: 'Nothing moves' },\n\t\t\t{ value: 'reset', label: 'What was gained is lost' },\n\t\t\t{ value: 'majority', label: 'The larger side takes it' }\n\t\t],\n\t\thint: 'What it does while two sides stand in it'\n\t},\n\t{ id: 'owner', name: 'Whose at the start', kind: 'player', hint: 'Nobody’s when left out' }\n]\n\n/**\n * The capture points of the world, by id: whose each is and who is taking it. Kept in a save; in the game's report\n * as `captures` (a list), for the HUD and the computer\n *\n * @beta\n */\nexport const captures = defineComponent<Record<string, CaptureState>>('core.captures', { default: () => ({}) })\n\n/** Whether the points were set up from the code's list and the map: once a world, kept in a save */\nexport const ready = defineComponent<boolean>('core.capturesReady', { default: () => false })\n\n/**\n * A point changed hands: whose it is now (nobody's for one let go by code), and whose it was\n *\n * @beta\n */\nexport const captured = defineEvent<{ id: string; owner: PlayerId | null; from: PlayerId | null }>('core.captured', { replicate: 'everyone' })\n\n/**\n * A side (a team) began taking a point, or none is any more\n *\n * @beta\n */\nexport const capturing = defineEvent<{ id: string; by: number | null }>('core.capturing', { replicate: 'everyone' })\n\n/**\n * The area of a point, as the rules watch it (`world.areas`)\n *\n * @internal\n */\nexport const captureAreaOf = (id: string): string => `core.capture.${id}`\n\n/**\n * The capture points of a world, as they stand\n *\n * @beta\n */\nexport const capturesOf = (world: World): CaptureState[] => Object.values(world.state(captures))\n\n/**\n * A point by id, or nothing for an id the world has not got\n *\n * @beta\n */\nexport const captureOf = (world: World, id: string): CaptureState | undefined => world.state(captures)[id]\n\n/**\n * Gives a point to a player, or to nobody, from the rules: its progress forgotten, and `captured` said\n *\n * @beta\n */\nexport function capturePoint(world: World, id: string, owner: PlayerId | null): boolean {\n\tconst point = world.state(captures)[id]\n\tif (!point) return false\n\tconst from = point.owner\n\tpoint.owner = owner\n\tpoint.by = null\n\tpoint.progress = 0\n\tworld.events.emit(captured, { id, owner, from })\n\treturn true\n}\n\n/**\n * What a game turns capture points on with (`withCapture`)\n *\n * @beta\n */\nexport interface CaptureOptions {\n\t/** Points given in code, beside what the map places */\n\tpoints?: readonly CapturePoint[]\n\t/** Ticks between two counts of who stands where: 3 when left out */\n\tevery?: number\n\t/** The kind of thing on the map a point is placed as: `capture` when left out */\n\tkind?: string\n}\n\n/** A thing of the map as a point: named as the thing is, else by its number */\nfunction pointOfThing(thing: MapThing): CapturePoint {\n\tconst data = thing.data as { radius?: number; time?: number; contested?: Contested; owner?: unknown }\n\tconst owner = typeof data.owner === 'number' && data.owner > 0 ? data.owner : undefined\n\treturn {\n\t\tid: thing.name ?? `capture-${thing.id}`,\n\t\tname: thing.name,\n\t\tat: { x: thing.x, z: thing.z },\n\t\tradius: data.radius,\n\t\ttime: data.time,\n\t\tcontested: data.contested,\n\t\towner\n\t}\n}\n\n/** Puts the points of the code and the map in the world: once, as the first count comes (a loaded one has them) */\nfunction setUp(world: World, options: CaptureOptions): void {\n\tconst state = world.state(captures)\n\tconst things = world.map.things(options.kind ?? CAPTURE_KIND, CAPTURE_FIELDS).map(pointOfThing)\n\tfor (const point of [...(options.points ?? []), ...things]) {\n\t\tstate[point.id] ??= {\n\t\t\tid: point.id,\n\t\t\t...(point.name && { name: point.name }),\n\t\t\tx: point.at.x,\n\t\t\tz: point.at.z,\n\t\t\tradius: point.radius ?? 4,\n\t\t\ttime: Math.max(point.time ?? 10, 0.1),\n\t\t\tcontested: point.contested ?? 'pause',\n\t\t\towner: point.owner ?? null,\n\t\t\tby: null,\n\t\t\tprogress: 0\n\t\t}\n\t}\n\tworld.setState(ready, true)\n}\n\n/** The area of a point, as the rules watch it: added as the first count comes (a loaded world brings its own back) */\nfunction areaOf(world: World, point: CaptureState): string {\n\tconst id = captureAreaOf(point.id)\n\tif (!world.areas.has(id)) {\n\t\tconst area: AreaDef = { id, shape: { kind: 'circle', x: point.x, z: point.z, radius: point.radius } }\n\t\tworld.areas.add(area)\n\t}\n\treturn id\n}\n\n/** Who stands in a point, by team: how many, and one of them to own it */\nconst standing = new Map<number, { count: number; player: PlayerId }>()\n\n/** A count of who stands in each point, and what follows: progress, a side let go of, a point changed hands */\nfunction count(world: World, dt: number): void {\n\tfor (const point of Object.values(world.state(captures))) {\n\t\tstanding.clear()\n\t\tfor (const entity of world.areas.inside(areaOf(world, point))) {\n\t\t\tif (!entity.alive || entity.hidden || entity.def.kind !== 'unit') continue\n\t\t\tconst player = world.player(entity.owner)\n\t\t\tif (player.neutral) continue\n\t\t\tconst seen = standing.get(player.team)\n\t\t\tif (seen) seen.count++\n\t\t\telse standing.set(player.team, { count: 1, player: entity.owner })\n\t\t}\n\t\t// nobody: as it was\n\t\tif (!standing.size) continue\n\t\tlet actor: { team: number; player: PlayerId } | undefined\n\t\tif (standing.size === 1) {\n\t\t\tconst [team, each] = [...standing][0]\n\t\t\tactor = { team, player: each.player }\n\t\t} else if (point.contested === 'reset') {\n\t\t\tif (point.progress > 0 || point.by !== null) {\n\t\t\t\tpoint.progress = 0\n\t\t\t\tpoint.by = null\n\t\t\t\tworld.events.emit(capturing, { id: point.id, by: null })\n\t\t\t}\n\t\t\tcontinue\n\t\t} else if (point.contested === 'majority') {\n\t\t\tlet best: [number, { count: number; player: PlayerId }] | undefined\n\t\t\tlet tie = false\n\t\t\tfor (const entry of standing) {\n\t\t\t\tif (!best || entry[1].count > best[1].count) {\n\t\t\t\t\tbest = entry\n\t\t\t\t\ttie = false\n\t\t\t\t} else if (entry[1].count === best[1].count) tie = true\n\t\t\t}\n\t\t\tif (!best || tie) continue\n\t\t\tactor = { team: best[0], player: best[1].player }\n\t\t} else continue\n\t\tconst step = dt / point.time\n\t\tconst ownerTeam = point.owner === null ? null : world.player(point.owner).team\n\t\t// its owner's own in it: whatever another side gained fades\n\t\tif (actor.team === ownerTeam) {\n\t\t\tif (point.progress > 0) point.progress = Math.max(0, point.progress - step)\n\t\t\tif (point.progress === 0 && point.by !== null) {\n\t\t\t\tpoint.by = null\n\t\t\t\tworld.events.emit(capturing, { id: point.id, by: null })\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\t// another side's gains fade before this one's begin\n\t\tif (point.by !== null && point.by !== actor.team) {\n\t\t\tpoint.progress = Math.max(0, point.progress - step)\n\t\t\tif (point.progress === 0) point.by = null\n\t\t\tcontinue\n\t\t}\n\t\tif (point.by === null) {\n\t\t\tpoint.by = actor.team\n\t\t\tworld.events.emit(capturing, { id: point.id, by: actor.team })\n\t\t}\n\t\tpoint.progress = Math.min(1, point.progress + step)\n\t\tif (point.progress < 1) continue\n\t\tconst from = point.owner\n\t\tpoint.owner = actor.player\n\t\tpoint.by = null\n\t\tpoint.progress = 0\n\t\tworld.events.emit(captured, { id: point.id, owner: actor.player, from })\n\t}\n}\n\n/**\n * A game with capture points: the points of `options.points` and of the map (things of the `capture` kind, which the\n * editor places with the client's `captureKind`), each an area, counted every few ticks; whose each is and who is\n * taking it in the world (`captures`, `capturesOf`) and in the game's report (`captures`); `captured` and\n * `capturing` as they change; `capturePoint` for the rules' own say. Units count, alive and in sight of nobody in\n * particular; buildings, scenery and the neutral player's do not\n *\n * @beta\n */\nexport function withCapture(options: CaptureOptions = {}): GamePack {\n\tconst every = Math.max(1, Math.round(options.every ?? 3))\n\t// the points are set up as the first count comes, a tick in: the map is in the world by then (a loaded one has them)\n\tconst system: System = {\n\t\tname: 'core.capture',\n\t\tphase: 'cleanup',\n\t\tevery,\n\t\tupdate(world) {\n\t\t\tif (!world.state(ready)) setUp(world, options)\n\t\t\tcount(world, every / world.tickRate)\n\t\t}\n\t}\n\treturn {\n\t\tid: 'capture',\n\t\toptions,\n\t\tcomponents: [captures, ready],\n\t\tevents: [captured, capturing],\n\t\tsystems: [system],\n\t\t// what each point ended as, beside the game's own report\n\t\treport: (world) => ({ captures: capturesOf(world) })\n\t}\n}\n","import { defineComponent } from './components'\nimport type { GamePack } from './packs/pack'\nimport { distSq } from './math'\nimport type { Entity, PlayerId } from './entity'\nimport { grantXp, heroOf, heroState, maxLevelOf, xpWorth } from './hero'\nimport { defineHook, type HookDef } from './hooks'\nimport { attackReaches } from './systems/combat'\nimport type { World } from './world'\n\n/**\n * Denying, as in a MOBA (features-plan E): a player may tell their units to attack one of their own side's, which\n * they never do by themselves, once it is low enough on health that the other side would soon have it: the last hit\n * on it is theirs, not the enemy's. Hooks for `GameModule.hooks`:\n *\n * hooks: [...denying({ below: 0.5 })]\n *\n * Only an attack a player orders (`CanAttack.ordered`): units never pick their own side to attack, nor fight back at it\n *\n * @beta\n */\nexport interface DenyOptions {\n\t/** How low on health, of its most, one of one's own side has to be to be attacked: below half when left out */\n\tbelow?: number\n\t/**\n\t * What of one's own side may be attacked, past `below`: units, not heroes nor structures, when left out. A game's own,\n\t * to let towers be denied, or only creeps\n\t */\n\tdenies?: (world: World, attacker: Entity, target: Entity) => boolean\n\t/** The id of the hook, to replace or leave out: `deny` when left out */\n\tid?: string\n}\n\n/** Units, not heroes nor structures: what the engine lets be denied */\nconst units = (_world: World, _attacker: Entity, target: Entity) => target.isUnit && !target.def.hero\n\n/**\n * Whether an attack on one's own side is a deny the rules allow (`DenyOptions`): told to, low enough, of what may be\n *\n * @beta\n */\nexport function mayDeny(world: World, attacker: Entity, target: Entity, options: DenyOptions = {}): boolean {\n\tif (world.areEnemies(attacker.owner, target.owner)) return false\n\tif (target.hp >= target.maxHp * (options.below ?? 0.5)) return false\n\treturn attackReaches(world, attacker, target) && (options.denies ?? units)(world, attacker, target)\n}\n\n/**\n * The hooks of denying (see `DenyOptions`)\n *\n * @beta\n */\nexport function denying(options: DenyOptions = {}): HookDef[] {\n\treturn [\n\t\tdefineHook({\n\t\t\thook: 'canAttack',\n\t\t\tid: options.id ?? 'deny',\n\t\t\trun(world, event) {\n\t\t\t\tif (event.allowed || !event.ordered) return\n\t\t\t\tif (mayDeny(world, event.attacker, event.target, options)) event.allowed = true\n\t\t\t}\n\t\t})\n\t]\n}\n\n// ---- last hits and denies (features-plan E2)\n\n/**\n * What a game counts of last hits and denies (`withLastHits`)\n *\n * @beta\n */\nexport interface LastHitOptions {\n\t/** The rule of denying (`denying`), or `false` for a game that only counts last hits: the engine's when left out */\n\tdeny?: DenyOptions | false\n\t/**\n\t * The part of a unit's experience the enemy heroes near it still get when it is denied, shared as for a kill: a half\n\t * when left out (none for a kill by the enemy would be no deny at all; all of it, no point in denying)\n\t */\n\texperience?: number\n\t/** Which deaths count, as last hits or denies: units, not heroes nor structures, when left out */\n\tcounts?: (world: World, dead: Entity) => boolean\n}\n\n/** Every player's last hits and denies, by player id: saved with the game */\nexport const counted = defineComponent<Record<string, { lastHits: number; denies: number }>>('lastHits', { default: () => ({}) })\n\n/**\n * A player's last hits (enemy units they gave the killing blow to) and denies (their own side's), as counted\n * (`withLastHits`)\n *\n * @beta\n */\nexport function lastHitsOf(world: World, player: PlayerId): { lastHits: number; denies: number } {\n\tconst all = world.state(counted)\n\treturn all[player] ?? { lastHits: 0, denies: 0 }\n}\n\n/** What the engine counts: units, not heroes nor structures */\nconst countsUnits = (_world: World, dead: Entity) => dead.isUnit && !dead.def.hero\n\n/**\n * A game where last hits and denies count, as in a MOBA: each player's are counted (`lastHitsOf`, saved), a unit\n * denied gives no bounty (as one killed by its own side never does) and only a part of its experience to the enemy\n * heroes near it, and its death says so to the screen (`how: 'denied'`, which the client shows over it). With the rule\n * of denying (`denying`) unless told otherwise\n *\n * @beta\n */\nexport function withLastHits(options: LastHitOptions = {}): GamePack {\n\tconst counts = options.counts ?? countsUnits\n\tconst part = options.experience ?? 0.5\n\tconst count = defineHook({\n\t\thook: 'death',\n\t\tid: 'lastHits',\n\t\trun(world, event) {\n\t\t\tconst { entity, killer } = event\n\t\t\tif (!killer || killer === entity || !counts(world, entity)) return\n\t\t\tconst all = world.state(counted)\n\t\t\tconst player = killer.owner\n\t\t\tconst mine = (all[player] ??= { lastHits: 0, denies: 0 })\n\t\t\tif (world.areEnemies(player, entity.owner)) {\n\t\t\t\tmine.lastHits++\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!world.areAllies(player, entity.owner)) return\n\t\t\tmine.denies++\n\t\t\tevent.how ??= 'denied'\n\t\t\t// the enemy's heroes near it get a part of what it was worth\n\t\t\tconst worth = xpWorth(world, entity) * part\n\t\t\tif (worth <= 0) return\n\t\t\tconst range = world.rules.heroes.xpRange\n\t\t\tconst heroes: Entity[] = []\n\t\t\t// the heroes alone, as the index files them (in the order of their ids, as a walk through every entity met them)\n\t\t\tfor (const hero of world.index.with(heroState)) {\n\t\t\t\tconst state = heroOf(hero)\n\t\t\t\tif (!state || !hero.alive || !world.areEnemies(hero.owner, entity.owner)) continue\n\t\t\t\tif (state.level >= maxLevelOf(world, hero)) continue\n\t\t\t\tif (distSq(hero.pos, entity.pos) <= range * range) heroes.push(hero)\n\t\t\t}\n\t\t\tfor (const hero of heroes) grantXp(world, hero, worth / heroes.length, entity)\n\t\t}\n\t})\n\treturn {\n\t\tid: 'lastHits',\n\t\toptions,\n\t\tcomponents: [counted],\n\t\thooks: [...(options.deny === false ? [] : denying(options.deny)), count]\n\t}\n}\n","import { damaged, gameOver } from '#engine/engineEvents'\nimport { defineComponent } from './components'\nimport type { GamePack } from './packs/pack'\nimport { distSq } from './math'\nimport type { Entity } from './entity'\nimport { engageWith } from './engagement'\nimport { defineListener } from './events'\nimport { defineHook } from './hooks'\nimport { disengage } from './systems/combat'\nimport { defeat } from './systems/victory'\nimport type { GameMap, MapPath } from './map'\nimport { type MapFieldDef, type MapProblem, mapThings, type MapThing } from './mapFields'\nimport type { Vec2 } from './math'\nimport type { PlayerId } from './entity'\nimport type { System } from './registry'\nimport { defineTimer } from './timers'\nimport type { World } from './world'\nimport { atan2, hypot } from './exactMath'\nimport { fighting } from './entity'\n\n/*\n * Lanes (features-plan D): the roads of a MOBA, along which each side's waves of minions walk to the other's base,\n * fighting what they meet. A lane is one of the map's paths (`MapPath`) with a spawner at each end, of two sides: where\n * each side's waves come out. A spawner is a thing of the map's (`MapThing`, kind `lanes.spawners`), of a player, on\n * one lane: the editor puts them down (`LANE_SPAWNER_KIND`), and checks every lane has its two (`checkLanes`)\n */\n\n/**\n * The kind of thing a spawner is: where it is kept in the map's data, by this id\n *\n * @beta\n */\nexport const LANE_SPAWNERS = 'lanes.spawners'\n\n/**\n * How near the end of its lane a spawner is to be that end's: in cells\n *\n * @internal\n */\nexport const LANE_END_REACH = 6\n\n/**\n * The fields of a spawner: whose waves come out of it, and the lane they walk\n *\n * @internal\n */\nexport const LANE_SPAWNER_FIELDS: Omit<MapFieldDef, 'for'>[] = [\n\t{ id: 'player', name: 'Player', kind: 'player', default: 1, hint: 'Whose waves come out of it' },\n\t{ id: 'lane', name: 'Lane', kind: 'path', hint: 'The path its waves walk, from the end it stands at to the other' }\n]\n\n/**\n * A spawner as the editor offers it (a `MapKindDef` of `@v12-engine/client`): its tool, its fields, a ring at each, in\n * the scene's `kinds`\n *\n * @beta\n */\nexport const LANE_SPAWNER_KIND = {\n\tid: LANE_SPAWNERS,\n\tname: 'Spawner',\n\tplural: 'Spawners',\n\thint: 'Where a side’s waves of minions come out, at one end of a lane: its player, and the path it is the end of',\n\ticon: 'tool.circle',\n\tcolor: [0.95, 0.75, 0.25] as [number, number, number],\n\tfields: LANE_SPAWNER_FIELDS,\n\treach: LANE_END_REACH / 2\n}\n\n/**\n * A lane, as the rules read it: the path, and its two ends, each with the spawner of the side whose waves start there\n *\n * @beta\n */\nexport interface Lane {\n\t/** The name of its path (`world.map.path(name)`), what orders that follow it are given */\n\tpath: string\n\tpoints: readonly Vec2[]\n\t/** Its spawners, by the end of the lane they are at: the first point's, then the last's. Either is missing on a map not finished */\n\tends: [LaneEnd | undefined, LaneEnd | undefined]\n}\n\n/**\n * One end of a lane: the spawner there, and whose\n *\n * @beta\n */\nexport interface LaneEnd {\n\tspawner: MapThing\n\tplayer: PlayerId\n\tat: Vec2\n}\n\n/** The path a spawner is on, by the id its field keeps */\nconst pathOf = (paths: readonly MapPath[], spawner: MapThing): MapPath | undefined => {\n\tconst id = spawner.data?.lane\n\treturn typeof id === 'number' ? paths.find((path) => path.id === id) : typeof id === 'string' ? paths.find((path) => path.name === id) : undefined\n}\n\n/** Which end of a path a place is at: 0 the first point's, 1 the last's, or none when it is near neither */\nfunction endOf(path: MapPath, at: Vec2): 0 | 1 | undefined {\n\tconst first = path.points[0]\n\tconst last = path.points[path.points.length - 1]\n\tif (!first || !last) return undefined\n\tconst d0 = hypot(at.x - first.x, at.z - first.z)\n\tconst d1 = hypot(at.x - last.x, at.z - last.z)\n\tif (Math.min(d0, d1) > LANE_END_REACH) return undefined\n\treturn d0 <= d1 ? 0 : 1\n}\n\n/**\n * The lanes of a map: every path a spawner is on, with what stands at each end\n *\n * @beta\n */\nexport function mapLanes(map: { paths: readonly MapPath[]; data: Record<string, unknown> }): Lane[] {\n\tconst lanes = new Map<number, Lane>()\n\tfor (const spawner of mapThings(map, LANE_SPAWNERS)) {\n\t\tconst path = pathOf(map.paths, spawner)\n\t\tif (!path) continue\n\t\tlet lane = lanes.get(path.id)\n\t\tif (!lane) lanes.set(path.id, (lane = { path: path.name, points: path.points, ends: [undefined, undefined] }))\n\t\tconst end = endOf(path, spawner)\n\t\tif (end === undefined) continue\n\t\tlane.ends[end] = { spawner, player: Number(spawner.data?.player ?? 1), at: { x: spawner.x, z: spawner.z } }\n\t}\n\treturn [...lanes.values()]\n}\n\n/**\n * The lanes of a world's map (`mapLanes`): what waves walk\n *\n * @beta\n */\nexport const lanesOf = (world: World): Lane[] => mapLanes({ paths: world.map.paths, data: world.map.data })\n\n/**\n * What is wrong with the lanes of a map, for the editor's checks (`MapEditorDef.check`): a spawner on no lane or away\n * from its ends, a lane without a spawner at each end, or with the same side at both\n *\n * @beta\n */\nexport function checkLanes(map: GameMap): MapProblem[] {\n\tconst problems: MapProblem[] = []\n\tconst teamOf = (player: number) => map.players.find((each) => each.id === player)?.team ?? player\n\tfor (const spawner of mapThings(map, LANE_SPAWNERS)) {\n\t\tconst path = pathOf(map.paths, spawner)\n\t\tconst about = { thing: spawner.id, kind: LANE_SPAWNERS }\n\t\tif (!path)\n\t\t\tproblems.push({ message: 'A spawner is on no lane: pick the path its waves walk', error: true, rule: 'lanes.spawner', at: spawner, about })\n\t\telse if (endOf(path, spawner) === undefined)\n\t\t\tproblems.push({ message: `A spawner of \"${path.name}\" is at neither end of it`, error: true, rule: 'lanes.spawner', at: spawner, about })\n\t}\n\tfor (const lane of mapLanes(map)) {\n\t\tconst path = map.paths.find((each) => each.name === lane.path)!\n\t\tconst about = { path: path.id }\n\t\tconst [first, last] = lane.ends\n\t\tif (!first || !last) {\n\t\t\tconst missing = !first ? path.points[0] : path.points[path.points.length - 1]\n\t\t\tproblems.push({\n\t\t\t\tmessage: `The lane \"${lane.path}\" has no spawner at one end: its waves start at both`,\n\t\t\t\terror: true,\n\t\t\t\trule: 'lanes.ends',\n\t\t\t\tat: missing,\n\t\t\t\tabout\n\t\t\t})\n\t\t} else if (teamOf(first.player) === teamOf(last.player))\n\t\t\tproblems.push({ message: `The lane \"${lane.path}\" has the same side at both ends`, error: true, rule: 'lanes.sides', at: first.at, about })\n\t}\n\treturn problems\n}\n\n// ---- waves (features-plan D2)\n\n/**\n * A wave about to come out of a spawner: which of that spawner's it is (1 and up), the lane and the end it walks from,\n * and whose. What `LanesOptions.wave` makes the units of\n *\n * @beta\n */\nexport interface LaneWave {\n\tnumber: number\n\tlane: Lane\n\tfrom: 0 | 1\n\tplayer: PlayerId\n}\n\n/**\n * What a game's lanes do (`withLanes`). Every part has the engine's own when left out\n *\n * @beta\n */\nexport interface LanesOptions {\n\t/**\n\t * The unit types of the engine's waves, by role: three to five close, two or three that shoot, a siege now and then\n\t * (`melee` and `ranged` are needed, `siege` is left out of the waves when it is). The engine names none: a game that\n\t * gives no `wave` of its own says these\n\t */\n\tminions?: { melee: string; ranged: string; siege?: string }\n\t/** The unit types of a wave, in the order they come out: the engine's grow with time, from `minions` */\n\twave?: (world: World, wave: LaneWave) => string[]\n\t/** Seconds from the start to the first wave, and between waves: 20 and 30 when left out */\n\tfirstWave?: number\n\tevery?: number\n\t/**\n\t * Where a minion goes once it is at the far end of its lane, fighting on the way: the nearest structure of another\n\t * team to that end when left out (their core), the end itself when there is none\n\t */\n\tgoal?: (world: World, minion: Entity, lane: Lane, from: 0 | 1) => Vec2 | undefined\n\t/**\n\t * What the lane towers are: they hit minions before anything else, and a hero who hits a hero of their side within\n\t * their reach before minions (as in a MOBA). Structures that attack, other than cores, when left out\n\t */\n\ttowers?: (world: World, entity: Entity) => boolean\n\t/**\n\t * What the cores are: the unit type's id, or a test of a unit. A side whose cores have all fallen has lost, and the\n\t * last side with one wins. Said by the game (the engine names none); `false` keeps the game's own way of winning\n\t * (`GameModule.victory`)\n\t */\n\tcores: string | ((world: World, entity: Entity) => boolean) | false\n\t/** Seconds a hero who hit a hero is the towers' first target for: 3 when left out */\n\ttowerAggro?: number\n\t/**\n\t * Minions turn on a hero who hits a hero of their side near them (within `radius` cells of it), chase it for `chase`\n\t * seconds at most and no further than `leash` cells from their lane, then go back to it the way they were going:\n\t * 7, 2.5 and 10 when left out. `false` for minions that keep to their lane\n\t */\n\tminionAggro?: { radius?: number; chase?: number; leash?: number } | false\n}\n\n/**\n * A minion of a lane: the lane it walks (its path's name), from which end. On every unit a wave brings\n *\n * @beta\n */\nexport const laneMinion = defineComponent<{ lane: string; from: 0 | 1; chase?: { target: number; until: number } }>('lanes.minion')\n\n/** How many waves each spawner has sent, by its id, and whether the waves were set going */\nexport const lanesState = defineComponent<{ started: boolean; waves: Record<string, number>; chasing?: number[] }>('lanes.state', {\n\tdefault: () => ({ started: false, waves: {} })\n})\n\n/**\n * The engine's waves: three close and two that shoot, one more close every fourth wave and one more that shoots every\n * sixth, a siege every third wave (two from the twelfth). Of the types a game has\n *\n * @beta\n */\nexport function defaultWave(world: World, wave: LaneWave, minions: NonNullable<LanesOptions['minions']>): string[] {\n\tconst { melee, ranged, siege } = minions\n\tconst n = wave.number\n\tconst types = [\n\t\t...Array<string>(3 + Math.floor((n - 1) / 4)).fill(melee),\n\t\t...Array<string>(2 + Math.floor((n - 1) / 6)).fill(ranged),\n\t\t...Array<string>(siege && n % 3 === 0 ? 1 + Math.floor(n / 12) : 0).fill(siege ?? '')\n\t]\n\treturn types.filter((type) => world.registry.units.has(type))\n}\n\n/** The nearest structure of another team to a lane's far end, within reach of it: what a wave goes for once there */\nfunction defaultGoal(world: World, minion: Entity, lane: Lane, from: 0 | 1): Vec2 | undefined {\n\tconst end = lane.points[from === 0 ? lane.points.length - 1 : 0]\n\tlet best: Entity | undefined\n\tlet bestDistance = 24 * 24\n\tfor (const entity of world.entities.values()) {\n\t\tif (!entity.alive || !entity.isStructure || !world.areEnemies(entity.owner, minion.owner)) continue\n\t\tconst d = distSq(entity.pos, end)\n\t\tif (d < bestDistance) {\n\t\t\tbestDistance = d\n\t\t\tbest = entity\n\t\t}\n\t}\n\treturn best ? { x: best.pos.x, z: best.pos.z } : end\n}\n\n/**\n * Sends a spawner's next wave now, whatever its timer, as the game's lanes say (`LanesOptions`): for scripts, tests and debug tools. Its units come out by the\n * spawner, walk the lane fighting what they meet (`attackPath`), then go for the goal at its far end. Gives back the\n * units, none for a spawner on no lane\n *\n * @beta\n */\nexport function sendWave(world: World, spawner: number, options: Partial<LanesOptions>): Entity[] {\n\tfor (const lane of lanesOf(world)) {\n\t\tconst from = lane.ends[0]?.spawner.id === spawner ? 0 : lane.ends[1]?.spawner.id === spawner ? 1 : undefined\n\t\tif (from === undefined) continue\n\t\tconst end = lane.ends[from]!\n\t\tconst state = world.state(lanesState)\n\t\tconst number = (state.waves[spawner] ?? 0) + 1\n\t\tstate.waves[spawner] = number\n\t\tconst wave: LaneWave = { number, lane, from, player: end.player }\n\t\tif (!options.wave && !options.minions) throw new Error('sendWave needs the wave (`wave`) or the unit types of its minions (`minions`)')\n\t\tconst types = options.wave ? options.wave(world, wave) : defaultWave(world, wave, options.minions!)\n\t\t// in a block behind the spawner, along the lane: the first out in front\n\t\tconst next = lane.points[from === 0 ? 1 : lane.points.length - 2] ?? end.at\n\t\tconst length = hypot(next.x - end.at.x, next.z - end.at.z) || 1\n\t\tconst ahead = { x: (next.x - end.at.x) / length, z: (next.z - end.at.z) / length }\n\t\tconst units = types.map((type, i) => {\n\t\t\tconst row = Math.floor(i / 3)\n\t\t\tconst side = (i % 3) - 1\n\t\t\tconst at = { x: end.at.x - ahead.x * row * 1.2 - ahead.z * side * 1.2, z: end.at.z - ahead.z * row * 1.2 + ahead.x * side * 1.2 }\n\t\t\tconst unit = world.spawn(type, end.player, at, { facing: atan2(ahead.x, ahead.z) })\n\t\t\tunit.set(laneMinion, { lane: lane.path, from })\n\t\t\treturn unit\n\t\t})\n\t\tif (!units.length) return units\n\t\talongLane(world, units, lane, from, options)\n\t\treturn units\n\t}\n\treturn []\n}\n\n/** Minions sent along their lane from where they are, the way they go (away from their end), then to the goal */\nfunction alongLane(world: World, units: Entity[], lane: Lane, from: 0 | 1, options: Partial<LanesOptions>): void {\n\tconst entities = units.map((unit) => unit.id)\n\tconst player = units[0].owner\n\tworld.issue({ type: 'order', player, entities, order: { type: 'attackPath', path: lane.path, towards: from === 0 ? 'last' : 'first' } })\n\tconst goal = (options.goal ?? defaultGoal)(world, units[0], lane, from)\n\tif (goal) world.issue({ type: 'order', player, entities, order: { type: 'attackMove', point: goal }, queue: true })\n}\n\n/** How far a place is from a lane's line */\nfunction offLane(lane: Lane, at: Vec2): number {\n\tlet best = Infinity\n\tconst { points } = lane\n\tfor (let i = 1; i < points.length; i++) {\n\t\tconst a = points[i - 1]\n\t\tconst dx = points[i].x - a.x\n\t\tconst dz = points[i].z - a.z\n\t\tconst length = dx * dx + dz * dz\n\t\tconst t = length > 0 ? Math.min(Math.max(((at.x - a.x) * dx + (at.z - a.z) * dz) / length, 0), 1) : 0\n\t\tbest = Math.min(best, hypot(at.x - (a.x + dx * t), at.z - (a.z + dz * t)))\n\t}\n\treturn best\n}\n\n/**\n * How many waves a spawner has sent\n *\n * @beta\n */\nexport const wavesSent = (world: World, spawner: number): number => world.state(lanesState).waves[spawner] ?? 0\n\n/**\n * A game with lanes: its maps' lanes checked in the editor, and waves of minions sent along them from every spawner,\n * the first `firstWave` seconds in and one every `every` seconds after, each from the `wave` of its number (see\n * `LanesOptions`). What it adds goes with what the game has: its timers and components saved, its check after its own\n *\n * @beta\n */\nexport function withLanes(options: LanesOptions): GamePack {\n\t// the engine names no unit type: the game says what its minions and its cores are\n\tif (!options.wave && !(options.minions?.melee && options.minions.ranged))\n\t\tthrow new Error('withLanes needs the unit types of its waves (`minions: { melee, ranged }`) or a `wave` of its own')\n\tif (options.cores === undefined) throw new Error(\"withLanes needs to be told what the cores are (`cores`: a unit type's id, a test, or false)\")\n\tconst firstWave = options.firstWave ?? 20\n\tconst every = options.every ?? 30\n\tconst waveDue = defineTimer<{ spawner: number }>('lanes.wave', (world, data) => {\n\t\tif (world.winner === null) sendWave(world, data.spawner, options)\n\t})\n\t// the waves are set going once, as the game starts: a timer for every spawner, saved with the game from then on\n\tconst start: System = {\n\t\tname: 'lanes.start',\n\t\tevery: 15,\n\t\tupdate(world) {\n\t\t\tconst state = world.state(lanesState)\n\t\t\tif (state.started) return\n\t\t\tstate.started = true\n\t\t\tfor (const lane of lanesOf(world)) {\n\t\t\t\tfor (const end of lane.ends) if (end) world.timers.every(every, waveDue, { first: firstWave, data: { spawner: end.spawner.id } })\n\t\t\t}\n\t\t}\n\t}\n\tconst { hooks, listeners, systems } = towerRules(options)\n\treturn {\n\t\tid: 'lanes',\n\t\toptions,\n\t\tcomponents: [laneMinion, lanesState, heroStrike],\n\t\ttimers: [waveDue],\n\t\tsystems: [start, ...systems],\n\t\thooks,\n\t\tlisteners,\n\t\t...(options.cores !== false && { victory: coreVictory(coresOf(options.cores)) }),\n\t\t// minions are the lanes', not a player's army: they take no supply; the rest what the game says\n\t\trules: (rules) => ({ supply: { of: (world, unit) => ('has' in unit && unit.has(laneMinion) ? 0 : rules.supply.of(world, unit)) } }),\n\t\tcheck: (map) => checkLanes(map)\n\t}\n}\n\n// ---- towers and cores (features-plan D3)\n\n/**\n * When a hero last hit a hero of another side, in seconds of the game's time: what the lane towers of the side it hit\n * go for first, for a while (`LanesOptions.towerAggro`)\n *\n * @beta\n */\nexport const heroStrike = defineComponent<{ at: number }>('lanes.heroStrike')\n\n/** The engine's lane towers: structures that attack, other than cores */\nconst isTower = (world: World, entity: Entity, cores: LanesOptions['cores']) =>\n\tentity.isStructure && !!entity.def.attacks?.length && !(cores && coresOf(cores)(world, entity))\n\n/** What the cores are, as a test of a unit: the unit type's id said, or the game's own test */\nconst coresOf = (cores: string | ((world: World, entity: Entity) => boolean)): ((world: World, entity: Entity) => boolean) =>\n\ttypeof cores === 'string' ? (_world, entity) => entity.def.id === cores : cores\n\n/**\n * The rule of a lanes game: a side whose cores have all fallen is out, and the last side with a core wins. A side\n * takes part once it has had a core\n *\n * @beta\n */\nexport function coreVictory(cores: (world: World, entity: Entity) => boolean): System {\n\treturn {\n\t\tname: 'victory',\n\t\tphase: 'cleanup',\n\t\tevery: 15,\n\t\tupdate(world) {\n\t\t\tif (world.winner !== null) return\n\t\t\tconst standing = new Set<number>()\n\t\t\tfor (const entity of world.entities.values()) if (entity.alive && cores(world, entity)) standing.add(world.player(entity.owner).team)\n\t\t\tconst sides = new Set<number>()\n\t\t\tfor (const player of world.players.values()) {\n\t\t\t\tif (player.neutral || player.creeps) continue\n\t\t\t\tif (standing.has(player.team)) player.established = true\n\t\t\t\tif (!player.established) continue\n\t\t\t\tsides.add(player.team)\n\t\t\t\tif (!standing.has(player.team) && !player.defeated) defeat(world, player.id)\n\t\t\t}\n\t\t\tif (sides.size < 2 || standing.size !== 1) return\n\t\t\tconst [winner] = standing\n\t\t\tworld.winner = winner\n\t\t\tworld.events.emit(gameOver, { winner })\n\t\t}\n\t}\n}\n\n/** The hooks and listeners of the lane towers: minions first, and a hero who hits one of theirs before that */\nfunction towerRules(options: LanesOptions) {\n\tconst towers = options.towers ?? ((world: World, entity: Entity) => isTower(world, entity, options.cores))\n\tconst aggro = options.towerAggro ?? 3\n\tconst struckHero = (world: World, entity: Entity) => {\n\t\tconst strike = entity.get(heroStrike)\n\t\treturn !!strike && world.time - strike.at <= aggro\n\t}\n\tconst targetScore = defineHook({\n\t\thook: 'targetScore',\n\t\tid: 'lanes.towers',\n\t\trun(world, event) {\n\t\t\tif (!towers(world, event.attacker)) return\n\t\t\tif (event.target.def.hero && struckHero(world, event.target)) event.score += 200_000\n\t\t\telse if (event.target.has(laneMinion)) event.score += 100_000\n\t\t}\n\t})\n\tconst minions = options.minionAggro === false ? undefined : { radius: 7, chase: 2.5, leash: 10, ...options.minionAggro }\n\t// a hero hit one: the towers of that side within reach of the one who hit turn on it at once, and its minions near\n\tconst heroHitHero = defineListener({\n\t\tid: 'lanes.heroHitHero',\n\t\tevent: damaged,\n\t\trun(world, { target, source }) {\n\t\t\tif (!source?.alive || !source.def.hero || !target.def.hero || !world.areEnemies(source.owner, target.owner)) return\n\t\t\tsource.set(heroStrike, { at: world.time })\n\t\t\tif (minions) {\n\t\t\t\tconst state = world.state(lanesState)\n\t\t\t\tconst turned: Entity[] = []\n\t\t\t\tfor (const minion of world.spatial.query(target.pos.x, target.pos.z, minions.radius)) {\n\t\t\t\t\tconst lane = minion.get(laneMinion)\n\t\t\t\t\tif (!lane || !minion.alive || lane.chase?.target === source.id || !world.areAllies(minion.owner, target.owner)) continue\n\t\t\t\t\tif (!world.isVisibleTo(source, world.player(minion.owner).team)) continue\n\t\t\t\t\tlane.chase = { target: source.id, until: world.time + minions.chase }\n\t\t\t\t\tturned.push(minion)\n\t\t\t\t\tif (!(state.chasing ??= []).includes(minion.id)) state.chasing.push(minion.id)\n\t\t\t\t}\n\t\t\t\tfor (const owner of new Set(turned.map((minion) => minion.owner))) {\n\t\t\t\t\tconst entities = turned.filter((minion) => minion.owner === owner).map((minion) => minion.id)\n\t\t\t\t\tworld.issue({ type: 'order', player: owner, entities, order: { type: 'attack', target: source.id } })\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const tower of world.spatial.query(source.pos.x, source.pos.z, 16)) {\n\t\t\t\tif (!tower.alive || !tower.get(fighting) || !towers(world, tower) || !world.areAllies(tower.owner, target.owner)) continue\n\t\t\t\tconst reach = world.rules.combat.acquisitionRange(world, tower) + tower.def.radius\n\t\t\t\tif (hypot(tower.pos.x - source.pos.x, tower.pos.z - source.pos.z) > reach) continue\n\t\t\t\tif (tower.get(fighting)!.autoTarget === source.id || !world.isVisibleTo(source, world.player(tower.owner).team)) continue\n\t\t\t\tdisengage(world, tower)\n\t\t\t\tengageWith(world, tower, source)\n\t\t\t\ttower.get(fighting)!.autoTarget = source.id\n\t\t\t}\n\t\t}\n\t})\n\t// minions done chasing go back to their lane: the time is up, what they chased is gone, or they went too far from it\n\tconst back: System = {\n\t\tname: 'lanes.minions',\n\t\tevery: 6,\n\t\tupdate(world) {\n\t\t\tconst state = world.state(lanesState)\n\t\t\tif (!minions || !state.chasing?.length) return\n\t\t\tconst lanes = lanesOf(world)\n\t\t\tstate.chasing = state.chasing.filter((id) => {\n\t\t\t\tconst minion = world.get(id)\n\t\t\t\tconst lane = minion?.get(laneMinion)\n\t\t\t\tif (!minion?.alive || !lane?.chase) return false\n\t\t\t\tconst path = lanes.find((each) => each.path === lane.lane)\n\t\t\t\tconst target = world.get(lane.chase.target)\n\t\t\t\tconst done =\n\t\t\t\t\tworld.time > lane.chase.until ||\n\t\t\t\t\t!target?.alive ||\n\t\t\t\t\t!world.isVisibleTo(target, world.player(minion.owner).team) ||\n\t\t\t\t\t(!!path && offLane(path, minion.pos) > minions.leash)\n\t\t\t\tif (!done) return true\n\t\t\t\tlane.chase = undefined\n\t\t\t\tif (path) alongLane(world, [minion], path, lane.from, options)\n\t\t\t\treturn false\n\t\t\t})\n\t\t}\n\t}\n\treturn { hooks: [targetScore], listeners: [heroHitHero], systems: [back] }\n}\n","import { defineComponent } from './components'\nimport type { GamePack } from './packs/pack'\nimport type { ResourceKind, UnitTypeDef } from './defs'\nimport type { Entity, PlayerId } from './entity'\nimport { defineEvent } from './events'\nimport { defineHook } from './hooks'\nimport { MAP_NEUTRAL } from './map'\nimport { earn } from './player'\nimport type { System } from './registry'\nimport type { World } from './world'\nimport { deposit } from './entity'\n\n/*\n * Remains that are things, an opt-in pack (master plan OH4): a building that falls leaves rubble that blocks the way\n * (a resource with its footprint) until workers clear it, gathering it as a resource (stone, or what the game says);\n * a unit that falls can drop a pile of a resource, picked up by the first unit of a player's that walks over it. What\n * the screen shows of a death (`remains` of the view: a crater, scorch) stays the view's; these are of the world.\n */\n\n/**\n * What rubble or a pile is to be, as a game says it for a death: the unit type it is, and how much of its resource it\n * holds (the type's `resource.amount` when left out)\n *\n * @beta\n */\nexport interface RemainsSpec {\n\ttype: string\n\tamount?: number\n}\n\n/**\n * What the remains of a game are made of (`withRemains`)\n *\n * @beta\n */\nexport interface RemainsOptions {\n\t/**\n\t * The rubble a fallen building leaves, put down where it stood once it is gone: a type (a resource with a footprint,\n\t * see `rubbleType`), worked out for the death, or `null` for none. None when left out\n\t */\n\trubble?: string | ((world: World, dead: Entity) => RemainsSpec | string | null | undefined)\n\t/**\n\t * The pile a fallen unit drops: a type (a resource with no footprint, see `pileType`) and how much, or `null` for\n\t * none. None when left out\n\t */\n\tpiles?: (world: World, dead: Entity, killer: Entity | undefined) => RemainsSpec | null | undefined\n\t/** How near a unit comes to a pile to pick it up, in cells: 0.8 when left out */\n\treach?: number\n\t/** Who may pick a pile up: any unit of a player's that is not a structure, when left out */\n\tpicksUp?: (world: World, unit: Entity, pile: Entity) => boolean\n}\n\n/**\n * What a pile holds: the resource and how much. Told to everyone, for its look and its tooltip\n *\n * @beta\n */\nexport const pileOf = defineComponent<{ kind: ResourceKind; amount: number }>('core.pile', { replicate: 'everyone' })\n\n/** The piles there are and the rubble to put down once the building it is of is gone, kept with the world */\nexport const remains = defineComponent<{ piles: number[]; rubble: Record<number, { type: string; amount?: number; x: number; z: number }> }>(\n\t'core.remains',\n\t{\n\t\tdefault: () => ({ piles: [], rubble: {} })\n\t}\n)\n\n/**\n * A pile was picked up: by whom (a unit's id and its owner), what and how much\n *\n * @beta\n */\nexport const pileTaken = defineEvent<{ pile: number; by: number; player: PlayerId; kind: ResourceKind; amount: number }>('core.pileTaken', {\n\treplicate: 'everyone'\n})\n\n/** The player the map's neutral things are of: rubble and piles are */\nfunction neutralOf(world: World): PlayerId {\n\tfor (const player of world.players.values()) if (player.neutral) return player.id\n\treturn MAP_NEUTRAL\n}\n\n/** Spawns remains of a type, holding so much of their resource */\nfunction putDown(world: World, spec: RemainsSpec, x: number, z: number): Entity | undefined {\n\tif (!world.registry.units.has(spec.type)) return undefined\n\tconst entity = world.spawn(spec.type, neutralOf(world), { x, z })\n\tif (spec.amount !== undefined && entity.get(deposit)) entity.get(deposit)!.amount = spec.amount\n\treturn entity\n}\n\n/**\n * A type of rubble, to put in the game's units: a resource that blocks its footprint, gathered (cleared) as `kind`\n * by the game's workers, with no look of its own (the game's looks give it one)\n *\n * @beta\n */\nexport function rubbleType(def: {\n\tid: string\n\tname?: string\n\tfootprint: { w: number; d: number }\n\tkind: ResourceKind\n\tamount?: number\n\tslots?: number\n}): UnitTypeDef {\n\treturn {\n\t\tid: def.id,\n\t\tname: def.name ?? 'Rubble',\n\t\tkind: 'resource',\n\t\tradius: Math.max(def.footprint.w, def.footprint.d) / 2,\n\t\tfootprint: def.footprint,\n\t\tstats: { health: 1 },\n\t\tsight: 0,\n\t\tresource: { kind: def.kind, amount: def.amount ?? 100, slots: def.slots ?? 3 }\n\t} as UnitTypeDef\n}\n\n/**\n * A type of pile, to put in the game's units: something lying on the ground that blocks nothing, is fought by nobody,\n * and is handed (`pileOf`: its kind and how much) to who walks over it. `kind` and `amount` are what it holds when the\n * death that drops it says nothing else\n *\n * @beta\n */\nexport function pileType(def: {\n\tid: string\n\tname?: string\n\tkind: ResourceKind\n\tamount?: number\n}): UnitTypeDef & { pile: { kind: ResourceKind; amount: number } } {\n\treturn {\n\t\tid: def.id,\n\t\tname: def.name ?? 'Pile',\n\t\tkind: 'unit',\n\t\tradius: 0.2,\n\t\tstats: { health: 1, moveSpeed: 0 },\n\t\tsight: 0,\n\t\tinvulnerable: true,\n\t\tignored: true,\n\t\tpile: { kind: def.kind, amount: def.amount ?? 10 }\n\t} as UnitTypeDef & { pile: { kind: ResourceKind; amount: number } }\n}\n\n/**\n * Remains that are things for a game (`RemainsOptions`): rubble where buildings fell, piles where units did. The game\n * is the same otherwise; its units list the types (`rubbleType`, `pileType`, or its own)\n *\n * @beta\n */\nexport function withRemains(options: RemainsOptions = {}): GamePack {\n\tconst reach = options.reach ?? 0.8\n\tconst picksUp = options.picksUp ?? ((_world: World, unit: Entity) => !unit.isStructure && !unit.isResource && unit.alive && !unit.get(pileOf))\n\n\tconst deathHook = defineHook({\n\t\thook: 'death',\n\t\tid: 'core.remains.death',\n\t\trun(world, event) {\n\t\t\tconst { entity: dead, killer } = event\n\t\t\tconst state = world.state(remains)\n\t\t\tif (dead.isStructure && options.rubble) {\n\t\t\t\tconst said = typeof options.rubble === 'function' ? options.rubble(world, dead) : options.rubble\n\t\t\t\tconst spec = typeof said === 'string' ? { type: said } : said\n\t\t\t\t// put down once the building is gone: its cells are its own until then\n\t\t\t\tif (spec) state.rubble[dead.id] = { ...spec, x: dead.pos.x, z: dead.pos.z }\n\t\t\t} else if (!dead.isStructure && !dead.isResource && options.piles) {\n\t\t\t\tconst spec = options.piles(world, dead, killer)\n\t\t\t\tconst pile = spec && putDown(world, spec, dead.pos.x, dead.pos.z)\n\t\t\t\tif (!pile) return\n\t\t\t\t// what it holds: what the death says, else its type's (`pileType`)\n\t\t\t\tconst kept = (pile.def as { pile?: { kind: ResourceKind; amount: number } }).pile\n\t\t\t\tconst kind = kept?.kind ?? world.registry.resources[0]?.id ?? 'gold'\n\t\t\t\tpile.set(pileOf, { kind, amount: spec.amount ?? kept?.amount ?? 10 })\n\t\t\t\tstate.piles.push(pile.id)\n\t\t\t}\n\t\t}\n\t})\n\tconst removeHook = defineHook({\n\t\thook: 'remove',\n\t\tid: 'core.remains.remove',\n\t\trun(world, entity) {\n\t\t\tconst state = world.state(remains)\n\t\t\tconst rubble = state.rubble[entity.id]\n\t\t\tif (!rubble) return\n\t\t\tdelete state.rubble[entity.id]\n\t\t\tputDown(world, rubble, rubble.x, rubble.z)\n\t\t}\n\t})\n\tconst near: Entity[] = []\n\tconst pickUp: System = {\n\t\tname: 'core.remains.piles',\n\t\tupdate(world: World) {\n\t\t\tconst state = world.state(remains)\n\t\t\tif (!state.piles.length) return\n\t\t\tstate.piles = state.piles.filter((id) => {\n\t\t\t\tconst pile = world.get(id)\n\t\t\t\tconst holds = pile?.get(pileOf)\n\t\t\t\tif (!pile?.alive || !holds) return false\n\t\t\t\tfor (const unit of [...world.spatial.query(pile.pos.x, pile.pos.z, reach, near)]) {\n\t\t\t\t\tif (world.player(unit.owner).neutral || !picksUp(world, unit, pile)) continue\n\t\t\t\t\tconst dx = unit.pos.x - pile.pos.x\n\t\t\t\t\tconst dz = unit.pos.z - pile.pos.z\n\t\t\t\t\tconst within = reach + unit.def.radius\n\t\t\t\t\tif (dx * dx + dz * dz > within * within) continue\n\t\t\t\t\tconst { kind, amount } = holds\n\t\t\t\t\tearn(world.player(unit.owner).resources, kind, amount)\n\t\t\t\t\tworld.events.emit(pileTaken, { pile: pile.id, by: unit.id, player: unit.owner, kind, amount })\n\t\t\t\t\tworld.kill(pile, unit, false, 'taken')\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\treturn true\n\t\t\t})\n\t\t}\n\t}\n\treturn {\n\t\tid: 'remains',\n\t\toptions,\n\t\tcomponents: [remains, pileOf],\n\t\tevents: [pileTaken],\n\t\thooks: [deathHook, removeHook],\n\t\tsystems: [pickUp]\n\t}\n}\n","import { defineCommand } from './commands'\nimport type { GamePack } from './packs/pack'\nimport { defineComponent } from './components'\nimport { edgeDistance, type Entity, type PlayerId, fighting } from './entity'\nimport { ids, string } from './fields'\nimport { defineHook } from './hooks'\nimport { disengage, STRUCTURE_REACH, SWING_SLACK } from './systems/combat'\nimport { rangeAgainst } from './attacks'\nimport type { World } from './world'\n\n/*\n * Stances (master plan FI1): how a unit with nothing to do takes to the enemies around it. Aggressive attacks what\n * comes into sight and chases it; defensive fires at what comes within its reach and stays where it stands; hold fire\n * fires back and no more; no attack ignores everyone. A pack a game turns on (`withStances`): a component on the unit\n * (`stance`), a command the player sends (`stanceCommand`), and the engine's own acquisition read through the\n * `canAttack` and `idle` hooks, so that nothing of the engine names a stance. An attack order is the player's word:\n * it goes through whatever the stance\n */\n\n/**\n * A stance: how a unit without orders takes to the enemies around it\n *\n * @beta\n */\nexport interface StanceDef {\n\tid: string\n\tname: string\n\tdescription?: string\n\t/** The key on the command card, for the HUD's buttons (`stanceButtons` of the client) */\n\thotkey?: string\n\t/** What it attacks of its own accord: anything in its acquisition range, only what its attack reaches, or nothing */\n\tacquire: 'any' | 'near' | 'none'\n\t/** Whether it chases what it fights past the reach of its attack */\n\tpursue: boolean\n\t/** Whether it fights back whoever hits it, for a stance that acquires nothing */\n\tfireBack: boolean\n\t/** Where it goes once a fight is over: back where it stood, or nowhere */\n\treturnTo: 'post' | 'none'\n}\n\n/**\n * The four stances every RTS has: aggressive (the engine's own way, when no stance is set), defensive, hold fire and no\n * attack. A game gives `withStances` its own list in their place, or adds to these\n *\n * @beta\n */\nexport const STANCES: readonly StanceDef[] = [\n\t{\n\t\tid: 'aggressive',\n\t\tname: 'Aggressive',\n\t\tdescription: 'Attacks what comes into sight, and chases it',\n\t\thotkey: 'G',\n\t\tacquire: 'any',\n\t\tpursue: true,\n\t\tfireBack: true,\n\t\treturnTo: 'post'\n\t},\n\t{\n\t\tid: 'defensive',\n\t\tname: 'Defensive',\n\t\tdescription: 'Fires at what comes within reach, and stays where it stands',\n\t\thotkey: 'V',\n\t\tacquire: 'near',\n\t\tpursue: false,\n\t\tfireBack: true,\n\t\treturnTo: 'post'\n\t},\n\t{\n\t\tid: 'holdFire',\n\t\tname: 'Hold fire',\n\t\tdescription: 'Fires back at whoever hits it, and no more',\n\t\thotkey: 'X',\n\t\tacquire: 'none',\n\t\tpursue: false,\n\t\tfireBack: true,\n\t\treturnTo: 'post'\n\t},\n\t{\n\t\tid: 'noAttack',\n\t\tname: 'No attack',\n\t\tdescription: 'Ignores everyone until told otherwise',\n\t\thotkey: 'Z',\n\t\tacquire: 'none',\n\t\tpursue: false,\n\t\tfireBack: false,\n\t\treturnTo: 'none'\n\t}\n]\n\n/**\n * The stance of a unit that was given none: the engine's own way\n *\n * @beta\n */\nexport const DEFAULT_STANCE = 'aggressive'\n\n/**\n * The stance a unit is in, by its id; absent for one in the default stance. Told to its owner, so that the HUD shows it\n *\n * @beta\n */\nexport const stance = defineComponent<string>('core.stance', { replicate: 'owner' })\n\n/**\n * The stance of a unit, as a definition: the one its component names, else the default (the first of `stances` with\n * the default's id, else the first of them)\n *\n * @beta\n */\nexport function stanceOf(entity: Entity, stances: readonly StanceDef[] = STANCES): StanceDef {\n\tconst id = entity.get(stance) ?? DEFAULT_STANCE\n\treturn stances.find((def) => def.id === id) ?? stances.find((def) => def.id === DEFAULT_STANCE) ?? stances[0]\n}\n\n/**\n * Puts units of the player's in a stance (`{ entities, stance }`). Units of another's, and ids of nothing, are left\n * out. A stance the game has not got is kept as a word and behaves as the default: the hooks know the game's list\n *\n * @beta\n */\nexport const stanceCommand = defineCommand('stance', { entities: ids, stance: string }, (world, player, command) => {\n\tconst id = command.stance\n\tfor (const entity of owned(world, player, command.entities)) {\n\t\tconst was = entity.get(stance)\n\t\tif (id === DEFAULT_STANCE) entity.remove(stance)\n\t\telse entity.set(stance, id)\n\t\t// a unit told to stand down lets go of whatever it was chasing: the hooks say whether it may go for it again\n\t\tif (was !== id && entity.get(fighting)) {\n\t\t\tentity.get(fighting)!.autoTarget = 0\n\t\t\tentity.get(fighting)!.lastAttacker = 0\n\t\t\tdisengage(world, entity)\n\t\t}\n\t}\n})\n\n/** The units of the player's among the ids, alive */\nfunction owned(world: World, player: PlayerId, entities: readonly number[]): Entity[] {\n\tconst out: Entity[] = []\n\tfor (const id of entities) {\n\t\tconst entity = world.get(id)\n\t\tif (entity?.alive && entity.owner === player) out.push(entity)\n\t}\n\treturn out\n}\n\n/**\n * What a game turns stances on with (`withStances`)\n *\n * @beta\n */\nexport interface StancesOptions {\n\t/** The stances of this game, in the order the HUD shows them: the usual four (`STANCES`) when left out */\n\tstances?: readonly StanceDef[]\n}\n\n/**\n * A game whose units have stances: the component, the command, and the engine's acquisition read through hooks. In\n * the default stance nothing changes. Defensive units fire at what their attack reaches and let go of what steps out\n * of it, returning to where they stood (the engine's own way home); hold fire fires back at the last to hit it; no\n * attack leaves everyone alone. A unit given an attack order fights whatever its stance\n *\n * @beta\n */\nexport function withStances(options: StancesOptions = {}): GamePack {\n\tconst stances = options.stances ?? STANCES\n\tif (!stances.length) throw new Error('withStances: a game needs a stance at least')\n\n\t/** Whether a unit of its own accord may go for a target, as its stance says */\n\tconst canAttackHook = defineHook({\n\t\thook: 'canAttack',\n\t\tid: 'core.stances.canAttack',\n\t\trun(world, event) {\n\t\t\tif (!event.allowed || event.ordered) return\n\t\t\tconst { attacker, target } = event\n\t\t\tconst def = stanceOf(attacker, stances)\n\t\t\tif (def.acquire === 'any' && def.pursue) return\n\t\t\tconst combat = attacker.get(fighting)\n\t\t\tconst engaged = !!combat && (combat.autoTarget === target.id || combat.lastAttacker === target.id)\n\t\t\tif (def.acquire === 'none') {\n\t\t\t\tevent.allowed = def.fireBack && engaged\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// only what its attack reaches from where it stands: where the engine would chase, it lets go (the same reach\n\t\t\t// `engage` goes by: a structure's edge a little farther, a swing already begun a little more)\n\t\t\tif (def.acquire === 'near' || (!def.pursue && engaged)) {\n\t\t\t\tconst swinging = !!combat && combat.swing > 0 && combat.swingTarget === target.id\n\t\t\t\tconst reach = rangeAgainst(world, attacker, target) + (target.isStructure ? STRUCTURE_REACH : 0) + (swinging ? SWING_SLACK : 0)\n\t\t\t\tif (edgeDistance(attacker, target) > reach) event.allowed = false\n\t\t\t}\n\t\t}\n\t})\n\n\t/** A unit that returns nowhere after a fight: it forgets where it stood as the fight ends */\n\tconst idleHook = defineHook({\n\t\thook: 'idle',\n\t\tid: 'core.stances.idle',\n\t\trun(_world, event) {\n\t\t\tconst { entity } = event\n\t\t\tconst combat = entity.get(fighting)\n\t\t\tif (!combat?.guard || combat.autoTarget) return\n\t\t\tif (stanceOf(entity, stances).returnTo === 'none') combat.guard = null\n\t\t}\n\t})\n\n\treturn {\n\t\tid: 'stances',\n\t\toptions,\n\t\tcomponents: [stance],\n\t\tcommands: [stanceCommand],\n\t\thooks: [canAttackHook, idleHook]\n\t}\n}\n","import { defineComponent } from './components'\nimport type { GamePack } from './packs/pack'\nimport type { StatChange } from './defs'\nimport type { Entity } from './entity'\nimport { defineEvent } from './events'\nimport { heroState, xpWorth } from './hero'\nimport { defineHook } from './hooks'\nimport { invalidateStats } from './stats'\nimport type { World } from './world'\n\n/*\n * Veterancy, an opt-in pack (master plan OH1): units that are not heroes earn experience from what they kill, reach\n * ranks at thresholds, and each rank adds to their stats. A game turns it on with the pack `withVeterancy(options)` in its `packs`; what\n * a unit has is a component (`veterancy`), saved and told to everyone, and a rank reached is an event (`rankedUp`) for\n * the screen. What it looks like (a chevron on the nameplate) is the game's: the client reads the component\n */\n\n/**\n * A rank of veterancy: the experience it starts at, its name, and what it adds to a unit's stats (in place of the rank\n * before's: each says all a unit of that rank has)\n *\n * @beta\n */\nexport interface VeterancyRank {\n\tname: string\n\txp: number\n\tstats?: StatChange\n}\n\n/**\n * What a unit has of veterancy: its experience and the rank it reached (0 for none yet)\n *\n * @beta\n */\nexport interface VeterancyState {\n\txp: number\n\trank: number\n}\n\n/**\n * Ranks as many games have them: three, at 50, 150 and 300 experience, 10%, 20% and 30% more damage and health\n *\n * @beta\n */\nexport const VETERANCY_RANKS: readonly VeterancyRank[] = [\n\t{ name: 'Veteran', xp: 50, stats: { percent: { attackDamage: 0.1, health: 0.1 } } },\n\t{ name: 'Elite', xp: 150, stats: { percent: { attackDamage: 0.2, health: 0.2 } } },\n\t{ name: 'Heroic', xp: 300, stats: { percent: { attackDamage: 0.3, health: 0.3 } } }\n]\n\n/**\n * What veterancy is made of (`withVeterancy`)\n *\n * @beta\n */\nexport interface VeterancyOptions {\n\t/** The ranks, from the lowest: `VETERANCY_RANKS` when left out */\n\tranks?: readonly VeterancyRank[]\n\t/** Who earns it: units of a player's that are not heroes and not structures, when left out */\n\tearns?: (world: World, entity: Entity) => boolean\n\t/** What a kill is worth to the killer: what it is worth to heroes (`xpWorth`), when left out. 0 for nothing */\n\tworth?: (world: World, dead: Entity, killer: Entity) => number\n}\n\n/**\n * What a unit has of veterancy, told to everyone (a rank shows on its plate): none for one that has earned nothing\n *\n * @beta\n */\nexport const veterancy = defineComponent<VeterancyState>('core.veterancy', { replicate: 'everyone' })\n\n/**\n * A unit reached a rank: told to everyone, for a sound or a word on the screen\n *\n * @beta\n */\nexport const rankedUp = defineEvent<{ entity: number; rank: number; name: string }>('core.rankedUp', { replicate: 'everyone' })\n\n/**\n * The rank a unit has reached, as a definition, or none: of the game's ranks (`VeterancyOptions.ranks`)\n *\n * @beta\n */\nexport function rankOf(entity: Entity, ranks: readonly VeterancyRank[] = VETERANCY_RANKS): VeterancyRank | undefined {\n\tconst rank = entity.get(veterancy)?.rank ?? 0\n\treturn rank > 0 ? ranks[rank - 1] : undefined\n}\n\n/**\n * Gives a unit experience, as a kill does: its rank goes up where it reaches the next ones' thresholds, its stats\n * with it, and `rankedUp` is told for each. Gives back the rank it is at. For a game's own rules (a unit that trains\n * at a camp), and what `withVeterancy` does on a kill\n *\n * @beta\n */\nexport function grantVeterancy(world: World, entity: Entity, xp: number, ranks: readonly VeterancyRank[] = VETERANCY_RANKS): number {\n\tconst now = entity.get(veterancy) ?? { xp: 0, rank: 0 }\n\tconst next: VeterancyState = { xp: now.xp + Math.max(0, xp), rank: now.rank }\n\twhile (next.rank < ranks.length && next.xp >= ranks[next.rank].xp) {\n\t\tnext.rank++\n\t\tworld.events.emit(rankedUp, { entity: entity.id, rank: next.rank, name: ranks[next.rank - 1].name })\n\t}\n\tentity.set(veterancy, next)\n\tif (next.rank !== now.rank) invalidateStats(world, entity)\n\treturn next.rank\n}\n\n/**\n * Veterancy for a game's units (`VeterancyOptions`): the killer of an enemy earns what it was worth, ranks come at\n * their thresholds, each rank's stats are added (the `stats` hook). The game is the same otherwise\n *\n * @beta\n */\nexport function withVeterancy(options: VeterancyOptions = {}): GamePack {\n\tconst ranks = options.ranks ?? VETERANCY_RANKS\n\tconst earns = options.earns ?? ((_world: World, entity: Entity) => !entity.has(heroState) && !entity.isStructure && entity.alive)\n\tconst deathHook = defineHook({\n\t\thook: 'death',\n\t\tid: 'core.veterancy.death',\n\t\trun(world, event) {\n\t\t\tconst { entity: dead, killer } = event\n\t\t\tif (!killer || !world.areEnemies(killer.owner, dead.owner) || !earns(world, killer)) return\n\t\t\tconst worth = options.worth ? options.worth(world, dead, killer) : xpWorth(world, dead)\n\t\t\tif (worth > 0) grantVeterancy(world, killer, worth, ranks)\n\t\t}\n\t})\n\tconst statsHook = defineHook({\n\t\thook: 'stats',\n\t\tid: 'core.veterancy.stats',\n\t\trun(_world, event) {\n\t\t\tconst rank = rankOf(event.entity, ranks)\n\t\t\tif (rank?.stats) event.add(rank.stats)\n\t\t}\n\t})\n\treturn {\n\t\tid: 'veterancy',\n\t\toptions,\n\t\tcomponents: [veterancy],\n\t\tevents: [rankedUp],\n\t\thooks: [deathHook, statsHook]\n\t}\n}\n","/**\n * The engine's own components, listed (design review E15): what every world's registry has besides its game's\n * (`Registry.component`), found by id there and not through the process. A component of the engine's is defined where\n * its rules live and added here; one that is not is a part no world finds (`Registry.component`, unlisted)\n */\nimport type { Component } from './components'\nimport * as areas from './areas'\nimport * as camps from './camps'\nimport * as capture from './capture'\nimport * as cinematics from './cinematics'\nimport * as computers from './computers'\nimport * as dashing from './dashing'\nimport * as denying from './denying'\nimport * as dialog from './dialog'\nimport * as effects from './effects'\nimport * as endings from './endings'\nimport * as entity from './entity'\nimport * as gameData from './gameData'\nimport * as gates from './gates'\nimport * as hero from './hero'\nimport * as inventory from './inventory'\nimport * as items from './items'\nimport * as lanes from './lanes'\nimport * as names from './names'\nimport * as sidePaths from './navigation/sidePaths'\nimport * as objectives from './objectives'\nimport * as harvest from './orders/harvest'\nimport * as randomGroups from './randomGroups'\nimport * as remains from './remains'\nimport * as score from './score'\nimport * as sequences from './sequences'\nimport * as memory from './session/memory'\nimport * as sides from './sides'\nimport * as stances from './stances'\nimport * as summons from './summons'\nimport * as construction from './systems/construction'\nimport * as productionQueue from './systems/productionQueue'\nimport * as talk from './talk'\nimport * as timers from './timers'\nimport * as transport from './transport'\nimport * as tunables from './tunables'\nimport * as veterancy from './veterancy'\n\n/**\n * The engine's own components that its computer player's kit defines (`@v12-engine/engine/ai`), listed as the kit loads\n * (`listKitComponents`): the core loads nothing of the kit (E3), and a game that seats no computer has none of them\n */\nconst kit: Component<unknown, unknown>[] = []\n\n/**\n * Lists components of the computer player's kit with the engine's own, as the kit's module loads\n *\n * @internal\n */\nexport function listKitComponents(...components: Component<any, any>[]): void {\n\tfor (const component of components) if (!kit.some((each) => each.id === component.id)) kit.push(component)\n}\n\n/**\n * The engine's own components, in one order: asked for as a registry is made, when every module that defines one has\n * been loaded (the kit's with them, where the game's brains loaded it)\n *\n * @internal\n */\nexport function coreComponents(): readonly Component<unknown, unknown>[] {\n\treturn [\n\t\tentity.moving,\n\t\tentity.fighting,\n\t\tentity.deposit,\n\t\tentity.exposure,\n\t\tentity.detection,\n\t\tinventory.inventorySlots,\n\t\titems.shopStock,\n\t\thero.heroState,\n\t\thero.respawning,\n\t\tsummons.corpses,\n\t\tsummons.summoned,\n\t\tsummons.illusion,\n\t\tscore.scoreData,\n\t\tendings.pauses,\n\t\ttalk.sent,\n\t\ttimers.waiting,\n\t\ttimers.shownTimers,\n\t\tdashing.dashing,\n\t\tcinematics.waits,\n\t\tcinematics.regionCinematicsPlayed,\n\t\tcomputers.computerSeats,\n\t\tcomputers.computerDefaults,\n\t\trandomGroups.mapDrops,\n\t\tcapture.captures,\n\t\tcapture.ready,\n\t\tnames.names,\n\t\tnames.mapInfo,\n\t\tdenying.counted,\n\t\tgates.gateStates,\n\t\tobjectives.objectives,\n\t\tstances.stance,\n\t\ttunables.tunings,\n\t\tremains.pileOf,\n\t\tremains.remains,\n\t\tlanes.laneMinion,\n\t\tlanes.lanesState,\n\t\tlanes.heroStrike,\n\t\ttransport.cargo,\n\t\tveterancy.veterancy,\n\t\tdialog.current,\n\t\tareas.inside,\n\t\tareas.added,\n\t\teffects.played,\n\t\tcamps.campMember,\n\t\tcamps.camps,\n\t\tsequences.running,\n\t\tsides.relations,\n\t\tsides.vision,\n\t\tsides.control,\n\t\tsidePaths.sideKnowledge,\n\t\tgameData.redefinitions,\n\t\tconstruction.constructionSite,\n\t\tharvest.gathering,\n\t\tproductionQueue.productionQueue,\n\t\tmemory.teamMemory,\n\t\t...kit\n\t] as Component<unknown, unknown>[]\n}\n"],"mappings":";;;;;;;;;;AAyBA,SAAgB,YAAY,OAAsE;CACjG,IAAI,MAAM,SAAS,UAClB,OAAO;EAAE,IAAI,MAAM,IAAI,MAAM;EAAQ,IAAI,MAAM,IAAI,MAAM;EAAQ,IAAI,MAAM,IAAI,MAAM;EAAQ,IAAI,MAAM,IAAI,MAAM;CAAO;CACzH,IAAI,MAAM,SAAS,QAClB,OAAO;EAAE,IAAI,MAAM,IAAI,MAAM,QAAQ;EAAG,IAAI,MAAM,IAAI,MAAM,QAAQ;EAAG,IAAI,MAAM,IAAI,MAAM,QAAQ;EAAG,IAAI,MAAM,IAAI,MAAM,QAAQ;CAAE;CACrI,IAAI,KAAK;CACT,IAAI,KAAK;CACT,IAAI,KAAK;CACT,IAAI,KAAK;CACT,KAAK,MAAM,SAAS,MAAM,QAAQ;EACjC,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,MAAM,CAAC;EACnC,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,MAAM,CAAC;EACnC,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,MAAM,CAAC;EACnC,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,MAAM,CAAC;CACpC;CACA,OAAO,MAAM,OAAO,SAAS;EAAE;EAAI;EAAI;EAAI;CAAG,IAAI;EAAE,IAAI,MAAM;EAAG,IAAI,MAAM;EAAG,IAAI,MAAM;EAAG,IAAI,MAAM;CAAE;AACxG;;;;;;AAOA,SAAgB,UAAU,OAA0B;CACnD,IAAI,MAAM,SAAS,UAAU,OAAO,KAAK,KAAK,MAAM,SAAS,MAAM;CACnE,IAAI,MAAM,SAAS,QAAQ,OAAO,MAAM,QAAQ,MAAM;CACtD,IAAI,QAAQ;CACZ,MAAM,EAAE,WAAW;CACnB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,IAAI,OAAO,QAAQ,IAAI,KAAK,SAAS,OAAO,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;CAChI,OAAO,KAAK,IAAI,KAAK,IAAI;AAC1B;;;;;;;AAQA,SAAgB,WAAW,OAA2D;CACrF,IAAI,MAAM,SAAS,WAAW,OAAO;CACrC,MAAM,EAAE,IAAI,IAAI,IAAI,OAAO,YAAY,KAAK;CAC5C,OAAO;EAAE,MAAM;EAAQ,IAAI,KAAK,MAAM;EAAG,IAAI,KAAK,MAAM;EAAG,OAAO,KAAK;EAAI,OAAO,KAAK;CAAG;AAC3F;;;;;;AAOA,SAAgB,QAAQ,OAAkB,IAAU,QAAQ,GAAc;CACzE,IAAI,MAAM,SAAS,UAAU,OAAO;EAAE,MAAM;EAAU,GAAG,GAAG;EAAG,GAAG,GAAG;EAAG,QAAQ,MAAM,SAAS;CAAM;CACrG,IAAI,MAAM,SAAS,QAAQ,OAAO;EAAE,MAAM;EAAQ,GAAG,GAAG;EAAG,GAAG,GAAG;EAAG,OAAO,MAAM,QAAQ;EAAO,OAAO,MAAM,QAAQ;CAAM;CAC3H,OAAO;EAAE,MAAM;EAAW,GAAG,GAAG;EAAG,GAAG,GAAG;EAAG,QAAQ,MAAM,OAAO,KAAK,WAAW;GAAE,GAAG,MAAM,IAAI;GAAO,GAAG,MAAM,IAAI;EAAM,EAAE;CAAE;AAC/H;;;;;;;AAgBA,SAAgB,YAAY,KAAc,SAAsD;CAC/F,IAAI,YAAY,KAAK,OAAO,QAAQ,MAAM,WAAW,OAAO,SAAS,IAAI,MAAM,CAAC,EAAE;CAClF,OAAO;AACR;;;;;;AAoBA,IAAa,cAAc,QAA0B;;;;;;AAOrD,SAAgB,QAAQ,OAAkB,OAAsB;CAC/D,MAAM,KAAK,MAAM,IAAI,MAAM;CAC3B,MAAM,KAAK,MAAM,IAAI,MAAM;CAC3B,IAAI,MAAM,SAAS,UAAU,OAAO,KAAK,KAAK,KAAK,MAAM,MAAM,SAAS,MAAM;CAC9E,IAAI,MAAM,SAAS,QAAQ,OAAO,KAAK,IAAI,EAAE,KAAK,MAAM,QAAQ,KAAK,KAAK,IAAI,EAAE,KAAK,MAAM,QAAQ;CAEnG,MAAM,EAAE,WAAW;CACnB,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,IAAI,OAAO,QAAQ,IAAI,KAAK;EAClE,MAAM,IAAI,OAAO;EACjB,MAAM,IAAI,OAAO;EACjB,IAAI,EAAE,IAAI,OAAO,EAAE,IAAI,MAAM,MAAO,EAAE,IAAI,EAAE,MAAM,KAAK,EAAE,MAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;CAC1F;CACA,OAAO;AACR;;;;;;AAOA,SAAgB,WAAW,OAA0B;CACpD,IAAI,MAAM,SAAS,UAAU,OAAO,MAAM;CAC1C,IAAI,MAAM,SAAS,QAAQ,OAAO,MAAM,MAAM,OAAO,MAAM,KAAK,IAAI;CACpE,IAAI,OAAO;CACX,KAAK,MAAM,SAAS,MAAM,QAAQ,OAAO,KAAK,IAAI,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC;CAC/E,OAAO;AACR;AACA,IAAM,QAAQ;;AAGd,IAAa,SAAS,gBAA0C,cAAc,EAAE,gBAAgB,CAAC,GAAG,CAAC;;AAErG,IAAa,QAAQ,gBAA2B,mBAAmB,EAAE,eAAe,CAAC,EAAE,CAAC;;;;;;AAOxF,IAAa,QAAb,MAAmB;CAOA;CANlB,uBAAwB,IAAI,IAAqB;;CAEjD,QAAmC,CAAC;CACpC,sBAAuB,IAAI,IAAY;CAEvC,YACC,OACA,MACC;EAFgB,KAAA,QAAA;EAGjB,KAAK,MAAM,OAAO,MAAM;GACvB,IAAI,KAAK,KAAK,IAAI,IAAI,EAAE,GAAG,MAAM,IAAI,MAAM,SAAS,IAAI,GAAG,iBAAiB;GAC5E,KAAK,KAAK,IAAI,IAAI,IAAI,GAAG;EAC1B;CACD;;CAGA,IAAI,MAAyB;EAC5B,OAAO,CAAC,GAAG,KAAK,KAAK,OAAO,GAAG,GAAG,KAAK,MAAM,CAAC;CAC/C;CAEA,IAAI,OAAe;EAClB,OAAO,KAAK,KAAK,OAAO,KAAK,MAAM,CAAC,CAAC;CACtC;CAEA,IAAI,IAAqB;EACxB,MAAM,MAAM,KAAK,KAAK,EAAE;EACxB,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,qBAAqB,GAAG,EAAE;EACpD,OAAO;CACR;;CAGA,IAAI,IAAqB;EACxB,OAAO,CAAC,CAAC,KAAK,KAAK,EAAE;CACtB;CAEA,KAAa,IAAiC;EAC7C,OAAO,KAAK,KAAK,IAAI,EAAE,KAAK,KAAK,MAAM,CAAC,CAAC,MAAM,QAAQ,IAAI,OAAO,EAAE;CACrE;CAEA,QAA2B;EAC1B,OAAO,KAAK,MAAM,MAAM,KAAK;CAC9B;;;;;CAMA,IAAI,KAAoB;EACvB,IAAI,KAAK,KAAK,IAAI,IAAI,EAAE,GAAG,MAAM,IAAI,MAAM,SAAS,IAAI,GAAG,iDAAiD;EAC5G,MAAM,OAAO,KAAK,MAAM;EACxB,MAAM,QAAQ,KAAK,WAAW,UAAU,MAAM,OAAO,IAAI,EAAE;EAE3D,MAAM,OAAO;GAAE,IAAI,IAAI;GAAI,OAAO,EAAE,GAAG,IAAI,MAAM;EAAE;EACnD,IAAI,SAAS,GAAG,KAAK,SAAS;OACzB,KAAK,KAAK,IAAI;CACpB;;CAGA,OAAO,IAAqB;EAC3B,MAAM,OAAO,KAAK,MAAM;EACxB,MAAM,QAAQ,KAAK,WAAW,QAAQ,IAAI,OAAO,EAAE;EACnD,IAAI,QAAQ,GAAG,OAAO;EACtB,KAAK,OAAO,OAAO,CAAC;EACpB,MAAM,QAAQ,KAAK,MAAM,MAAM,MAAM;EACrC,KAAK,MAAM,YAAY,MAAM,OAAO,CAAC,GAAG;GACvC,MAAM,SAAS,KAAK,MAAM,IAAI,QAAQ;GACtC,IAAI,QAAQ,OAAO,KAAK,MAAM,OAAO,KAAKA,UAAe;IAAE,MAAM;IAAI;GAAO,CAAC;EAC9E;EACA,OAAO,MAAM;EACb,OAAO;CACR;;CAGA,SAAS,IAAY,QAAyB;EAC7C,OAAO,KAAK,MAAM,EAAE,CAAC,CAAC,SAAS,OAAO,EAAE;CACzC;;CAGA,OAAO,IAAsB;EAC5B,MAAM,SAAmB,CAAC;EAC1B,KAAK,MAAM,YAAY,KAAK,MAAM,EAAE,GAAG;GACtC,MAAM,SAAS,KAAK,MAAM,IAAI,QAAQ;GACtC,IAAI,QAAQ,OAAO,KAAK,MAAM;EAC/B;EACA,OAAO;CACR;CAEA,MAAc,IAAsB;EACnC,KAAK,IAAI,EAAE;EACX,OAAO,KAAK,MAAM,MAAM,MAAM,CAAC,CAAC,OAAO,CAAC;CACzC;;CAGA,SAAe;EACd,MAAM,QAAQ,KAAK,MAAM,MAAM,MAAM;EAErC,KAAK,MAAM,QAAQ,KAAK,KAAK,OAAO,GAAG,KAAK,KAAK,MAAM,KAAK;EAC5D,KAAK,MAAM,QAAQ,KAAK,MAAM,GAAG,KAAK,KAAK,MAAM,KAAK;CACvD;;CAGA,KAAa,MAAe,OAAuC;EAClE,MAAM,EAAE,OAAO,OAAO,QAAQ;EAC9B,MAAM,EAAE,UAAU;EAClB,IAAI,MAAM;EACV,KAAK,MAAM,UAAU,MAAM,QAAQ,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,KAAK,GAAG,KAAK,GAAG;GAChF,IAAI,OAAO,IAAI,SAAS,UAAU,CAAC,OAAO,SAAS,OAAO,UAAU,CAAC,QAAQ,OAAO,OAAO,GAAG,GAAG;GACjG,IAAI,IAAI,OAAO,EAAE;EAClB;EACA,MAAM,SAAS,MAAM,KAAK,OAAO,CAAC;EAClC,KAAK,MAAM,MAAM,QAAQ;GACxB,IAAI,IAAI,IAAI,EAAE,GAAG;GACjB,MAAM,SAAS,MAAM,IAAI,EAAE;GAC3B,IAAI,QAAQ,OAAO,MAAM,OAAO,KAAKA,UAAe;IAAE,MAAM,KAAK;IAAI;GAAO,CAAC;EAC9E;EACA,KAAK,MAAM,MAAM,KAChB,IAAI,CAAC,OAAO,SAAS,EAAE,GAAG,MAAM,OAAO,KAAKC,aAAkB;GAAE,MAAM,KAAK;GAAI,QAAQ,MAAM,IAAI,EAAE;EAAG,CAAC;EAExG,IAAI,IAAI,QAAQ,OAAO,QAAQ,MAAM,KAAK,MAAM,CAAC,GAAG,GAAG;CACxD;AACD;;AAGA,IAAa,aAAqB;CACjC,MAAM;CACN,OAAO;CACP,OAAO,OAAO;EACb,IAAI,MAAM,MAAM,MAAM,MAAM,MAAM,OAAO;CAC1C;AACD;;;;;;;;ACnPA,IAAa,eAAe;;;;;AAM5B,IAAa,UAAU,gBACtB,eACA,EACC,gBAAgB;CAAE,MAAM;CAAG,OAAO,CAAC;AAAE,GACtC,CACD;;;;;;AAOA,IAAa,SAAb,MAAoB;CACU;CAA7B,YAAY,OAA+B;EAAd,KAAA,QAAA;CAAe;;;;;CAM5C,IAAI,IAAc,MAAe,KAAwB;EACxD,MAAM,QAAQ,KAAK,MAAM,MAAM,OAAO;EACtC,MAAM,OAAO,UAAU,KAAK,IAAI;EAChC,MAAM,UAAU,OAAO,aAAa,KAAA,IAAY,MAAM,QAAQ,EAAE,IAAI,KAAK,CAAC,EAAE;EAC5E,MAAM,OAAiB;GAAE,IAAI,MAAM;GAAQ,SAAS,KAAK;GAAS;GAAM,SAAS,KAAK,WAAA;GAAyB,IAAI;EAAQ;EAE3H,MAAM,QAAQ,OAAO,SAAS,KAAK,OAAO,IAAI,KAAK,MAAM,OAAO,KAAK,KAAK,KAAK,UAAU,KAAK,MAAM,QAAQ,IAAI,KAAA;EAChH,KAAK,MAAM,UAAU,WAAW,KAAK,UAAU,GAAG,MAAM,MAAM,UAAU;GAAE,MAAM,KAAK;GAAI;GAAK,IAAI;GAAS,GAAI,UAAU,KAAA,KAAa,EAAE,MAAM;EAAG;EACjJ,KAAK,MAAM,OAAO,KAAKC,UAAe,IAAI;EAC1C,OAAO;CACR;;;;;CAMA,KAAK,QAAwB;EAC5B,MAAM,QAAQ,KAAK,MAAM,MAAM,OAAO;EACtC,MAAM,QAAQ,MAAM,MAAM;EAC1B,IAAI,CAAC,SAAS,MAAM,IAAI,WAAW,KAAK,MAAM,GAAG,OAAO,QAAQ;EAChE,OAAO,MAAM,MAAM;EAGnB,IAAI,MAAM,UAAU,KAAA,KAAa,KAAK,MAAM,QAAQ,MAAM,OAAO;EACjE,KAAK,MAAM,OAAO,KAAK,WAAW;GAAE,IAAI,MAAM;GAAM,IAAI,CAAC,MAAM;EAAE,CAAC;EAClE,IAAI,MAAM,QAAQ,KAAA,GAAW,KAAK,MAAM,UAAU,MAAM,MAAM,GAAG;CAClE;;CAGA,YAAgC;EAC/B,MAAM,UAAsB,CAAC;EAC7B,KAAK,MAAM,UAAU,KAAK,MAAM,QAAQ,OAAO,GAAG,IAAI,CAAC,OAAO,SAAS,QAAQ,KAAK,OAAO,EAAE;EAC7F,OAAO;CACR;AACD;;;;;;;;;AAUA,SAAgB,KAAoB,IAAc,OAA6B;CAC9E,OAAO,MAAM,SAAS,SAAoB,EAAE,OAAO,OAAO,QAAQ,KAAK,MAAM,OAAO,IAAI,IAAI,MAAM,GAAG,GAAG,KAAK,KAAK,WAAA,CAAuB,CAAC,CAAC;AAC5I;;AAGA,IAAa,WAAW,eAAeA,UAAe,SAAS,MAAM,SACpE,CAAC,KAAK,MAAM,KAAK,GAAG,SAAS,KAAK,MAAM,IAAI;CAAE,MAAM;CAAQ,MAAM,gBAAgB,IAAI;AAAE,IAAI,KAAA,CAC7F;;AAGA,IAAa,gBAAgB,eAAe,WAAW,cAAc,EAAE,IAAI,MAAM,SAChF,GAAG,SAAS,KAAK,MAAM,IAAI;CAAE,MAAM;CAAa;AAAG,IAAI,KAAA,CACxD;;;;ACjEA,IAAM,UAAU,MAAc,UAA0B;CACvD,IAAI,IAAI,KAAK,KAAK,OAAO,YAAY,UAAU,IAAI,KAAK,KAAK,QAAQ,GAAG,UAAU;CAClF,IAAI,KAAK,KAAK,IAAK,MAAM,IAAK,UAAU;CACxC,QAAQ,IAAK,MAAM,QAAS;AAC7B;;;;;AAMA,IAAa,SAAS,gBAAwB,sBAAsB,EAAE,eAAe,EAAE,CAAC;;;;;;;;AASxF,SAAgB,WAAW,OAAc,QAAgB,UAAyB,CAAC,GAAW;CAC7F,MAAM,QAAQ,MAAM,MAAM,MAAM,IAAI;CACpC,MAAM,SAAS,QAAQ,KAAK;CAC5B,MAAM,EAAE,IAAI,IAAI,OAAO,QAAQ,MAAM,KAAK,YAAY,YAAY;CAClE,MAAM,SAAS,OAAO,OAAO,WAAW,MAAM,IAAI,EAAE,IAAI;CACxD,IAAI,OAAO,KAAA,KAAa,CAAC,QAAQ,OAAO;CACxC,MAAM,MAAiB;EACtB,IAAI;EACJ;EACA,MAAM,QAAQ,OAAO,MAAM,MAAM,KAAK;EACtC,GAAI,SAAS;GAAE,IAAI,OAAO;GAAI,GAAG,OAAO,IAAI;GAAG,GAAG,OAAO,IAAI;EAAE,IAAI,MAAM;GAAE,GAAG,GAAG;GAAG,GAAG,GAAG;GAAG,GAAI,OAAO,MAAM,EAAE,GAAG,GAAG,EAAE;EAAG;EAC3H,GAAI,SAAS,EAAE,MAAM;EACrB,GAAI,UAAU,EAAE,QAAQC,QAAM,QAAQ,yBAAyB,OAAO,IAAI,eAAe,EAA6B;EACtH,GAAI,OAAO,cAAc,EAAE,IAAI,MAAM,QAAQ,EAAE,IAAI,KAAK,CAAC,EAAE,EAAE;EAC7D,GAAI,WAAW,EAAE,QAAQ;CAC1B;CACA,MAAM,OAAO,KAAK,eAAe,GAAG;CACpC,OAAO;AACR;;;;;;AAOA,SAAgB,WAAW,OAAc,IAAY,UAA6B,CAAC,GAAS;CAC3F,MAAM,OAAO,KAAK,eAAe;EAAE;EAAI,GAAI,QAAQ,SAAS,KAAA,KAAa,EAAE,MAAM,QAAQ,KAAK;CAAG,CAAC;AACnG;;AAGA,IAAM,QAAQ,CAAC;;;;;;AAOf,IAAa,gBAAgB,SAAmC,KAAK,KAAK,6BAAa,IAAI,IAAY,CAAC;;AAGxG,IAAa,aAAa,eAAe,eAAe,OAAO,EAAE,IAAI,QAAQ,IAAI,SAAS,IAAI,GAAG,QAAQ,SAAS;CACjH,IAAI,MAAM,CAAC,GAAG,SAAS,KAAK,MAAM,GAAG,OAAO,KAAA;CAC5C,MAAM,SAAS,OAAO,KAAA,IAAY,KAAA,IAAY,KAAK,MAAM,IAAI,EAAE;CAE/D,IAAI,EADS,SAAS,KAAK,MAAM,MAAM,KAAM,CAAC,CAAC,WAAW,CAAC,OAAO,SAAU,KAAK,MAAM,KAAA,KAAa,WAAW,KAAK,KAAK,KAAK,GAAG,KAAK,CAAE,IAC7H,OAAO,KAAA;CAClB,MAAM,QAAQ,aAAa,IAAI;CAC/B,MAAM,IAAI,EAAE;CAEZ,IAAI,MAAM,OAAO,KAAK,aAAa,MAAM,OAAO,MAAM,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAM;CAC5E,OAAO;EAAE,MAAM;EAAM;EAAI,IAAI;EAAQ,GAAG;EAAM,GAAI,OAAO,KAAA,KAAa,EAAE,GAAG;EAAI,GAAI,WAAW,EAAE,QAAQ;CAAG;AAC5G,CAAC;;AAGD,IAAa,oBAAoB,eAAe,eAAe,WAAW,EAAE,IAAI,QAAQ,SACvF,aAAa,IAAI,CAAC,CAAC,OAAO,EAAE,IAAI;CAAE,MAAM;CAAU;CAAI,GAAI,SAAS,KAAA,KAAa,EAAE,KAAK;AAAG,IAAI,KAAA,CAC/F;;;;;;;;AC/GA,IAAa,mBAAmB,QAAoC;;AAwBpE,IAAa,aAAa,gBAAkC,mBAAmB,EAAE,eAAe,CAAC,EAAE,CAAC;;;;;;;AAQpG,IAAa,aAAb,MAAwB;CACM;CAA7B,YAAY,OAA+B;EAAd,KAAA,QAAA;CAAe;;CAG5C,IAAI,QAAkB,KAAmB,UAAqF,CAAC,GAAmB;EACjJ,MAAM,OAAO,KAAK,GAAG,MAAM;EAC3B,IAAI,KAAK,MAAM,cAAc,UAAU,OAAO,IAAI,EAAE,GAAG,MAAM,IAAI,MAAM,UAAU,OAAO,sBAAsB,IAAI,GAAG,UAAU;EAC/H,MAAM,OAAO,UAAU,IAAI,IAAI;EAC/B,MAAM,YAA4B;GACjC,IAAI,IAAI;GACR,MAAM,QAAQ,SAAS;IAAE,KAAK,KAAK;IAAK,QAAQ;KAAE,GAAG,KAAK;KAAQ,GAAG,QAAQ;IAAO;GAAE,IAAI;GAC1F,UAAU,IAAI,YAAY;GAC1B,QAAQ;GACR,UAAU,QAAQ,YAAY,EAAE,GAAG,QAAQ,SAAS;GACpD,GAAI,IAAI,WAAW,KAAA,KAAa,EAAE,QAAQ,UAAU,IAAI,MAAM,EAAE;EACjE;EACA,KAAK,KAAK,SAAS;EACnB,KAAK,QAAQ,QAAQ,WAAW,KAAA,CAAS;EACzC,OAAO;CACR;;CAGA,SAAS,QAAkB,IAAkB;EAC5C,KAAK,OAAO,QAAQ,IAAI,MAAM;CAC/B;;CAGA,KAAK,QAAkB,IAAY,QAA2B;EAC7D,KAAK,OAAO,QAAQ,IAAI,UAAU,WAAW,KAAA,IAAY,KAAA,IAAY,UAAU,MAAM,CAAC;CACvF;;CAGA,SAAS,QAAkB,IAAY,OAAe,UAAwD,CAAC,GAAS;EACvH,MAAM,YAAY,KAAK,IAAI,QAAQ,EAAE;EACrC,IAAI,UAAU,WAAW,QAAQ;EACjC,MAAM,MAAM,QAAQ,OAAO,UAAU,UAAU,OAAO;EACtD,IAAI,UAAU,UAAU,UAAU,SAAS,UAAU,SAAS,QAAQ,OAAO,CAAC,QAAQ,QAAQ;EAC9F,UAAU,WAAW;GAAE;GAAO;EAAI;EAClC,IAAI,QAAQ,QAAQ,UAAU,OAAO;GAAE,KAAK,UAAU,KAAK;GAAK,QAAQ;IAAE,GAAG,UAAU,KAAK;IAAQ,GAAG,QAAQ;GAAO;EAAE;EACxH,KAAK,QAAQ,QAAQ,WAAW,MAAM;CACvC;;CAGA,GAAG,QAA6C;EAC/C,OAAO,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC,MAAM,UAAU;CAClD;CAEA,IAAI,QAAkB,IAA4B;EACjD,MAAM,YAAY,KAAK,GAAG,MAAM,CAAC,CAAC,MAAM,cAAc,UAAU,OAAO,EAAE;EACzE,IAAI,CAAC,WAAW,MAAM,IAAI,MAAM,UAAU,OAAO,qBAAqB,GAAG,EAAE;EAC3E,OAAO;CACR;;CAGA,IAAI,QAAkB,IAAqB;EAC1C,OAAO,KAAK,GAAG,MAAM,CAAC,CAAC,MAAM,cAAc,UAAU,OAAO,EAAE;CAC/D;CAEA,OAAe,QAAkB,IAAY,QAA2B,QAAwB;EAC/F,MAAM,YAAY,KAAK,IAAI,QAAQ,EAAE;EACrC,IAAI,UAAU,WAAW,QAAQ;EACjC,UAAU,SAAS;EACnB,IAAI,QAAQ,UAAU,SAAS;EAC/B,KAAK,QAAQ,QAAQ,WAAW,MAAM;CACvC;CAEA,QAAgB,QAAkB,WAA2B,KAAwC;EACpG,KAAK,MAAM,OAAO,KAAKC,kBAAuB;GAAE;GAAQ;GAAW;EAAI,CAAC;CACzE;AACD;;;;;;;;AASA,IAAa,mBAA2B;CACvC,MAAM;CACN,OAAO;CACP,OAAO,OAAO;EACb,IAAI,MAAM,WAAW,MAAM;EAC3B,KAAK,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG;GAC5C,IAAI,OAAO,WAAW,OAAO,UAAU;GACvC,MAAM,WAAW,MAAM,WAAW,GAAG,OAAO,EAAE,CAAC,CAAC,QAAQ,cAAc,UAAU,QAAQ;GACxF,IAAI,SAAS,MAAM,cAAc,UAAU,WAAW,QAAQ,GAAG,OAAO,OAAO,OAAO,EAAE;QACnF,IAAI,SAAS,UAAU,SAAS,OAAO,cAAc,UAAU,WAAW,MAAM,GAAG,OAAO,IAAI,OAAO,OAAO,IAAI;EACtH;EAEA,MAAM,2BAAW,IAAI,IAAY;EACjC,KAAK,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG,IAAI,CAAC,OAAO,WAAW,CAAC,OAAO,UAAU,SAAS,IAAI,OAAO,IAAI;EAC9G,IAAI,SAAS,SAAS,GAAG,IAAI,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE;CACrD;AACD;AAEA,SAAS,IAAI,OAAc,MAAoB;CAC9C,MAAM,SAAS;CACf,MAAM,OAAO,KAAK,UAAU,EAAE,QAAQ,KAAK,CAAC;AAC7C;;AAGA,IAAa,gBAAgB,eAAeA,kBAAuB,cAAc,EAAE,QAAQ,WAAW,OAAO,SAC5G,WAAW,KAAK,SAAS;CAAE,MAAM;CAAa,WAAW,gBAAgB,SAAS;CAAG;AAAI,IAAI,KAAA,CAC9F;;;;;;;;ACgCA,IAAa,YAAkC,gBAA2B,cAAc,EACvF,gBAAgB;CAAE,QAAQ,CAAC;CAAG,OAAO,CAAC;CAAG,OAAO;CAAG,OAAO,CAAC;CAAG,MAAM,CAAC;AAAE,GACxE,CAAC;;;;;;;AA0CD,SAAgB,QAAW,OAAoB,OAAgE;CAC9G,OAAO;EAAE;EAAO;CAAM;AACvB;;;;;;;;AASA,SAAgB,WAAW,IAAY,MAAgC,CAAC,GAAiB;CACxF,OAAO;EAAE;EAAI,GAAG;CAAI;AACrB;AAEA,IAAM,kBAA0C;CAAE,OAAO;CAAS,QAAQ;CAAU,WAAW;CAAa,QAAQ;CAAU,OAAO;AAAQ;;AAG7I,SAAgB,aAAa,OAAsC,MAAwC;CAC1G,IAAI,CAAC,OAAO,OAAO;CACnB,MAAM,QAAQ,OAAO,MAAM,UAAU,aAAa,MAAM,MAAM,IAAI,IAAI,MAAM;CAC5E,MAAM,uBAAO,IAAI,IAA0B;CAC3C,KAAK,MAAM,QAAQ,OAAO;EACzB,IAAI,KAAK,IAAI,KAAK,EAAE,GAAG,MAAM,IAAI,MAAM,2BAA2B,KAAK,GAAG,QAAQ;EAClF,KAAK,IAAI,KAAK,IAAI,IAAI;CACvB;CACA,IAAI,MAAM,UAAU,KAAA,KAAa,EAAE,MAAM,SAAS,IAAI,MAAM,IAAI,MAAM,yCAAyC,MAAM,MAAM,oBAAoB;CAC/I,MAAM,aAAa,CAAC,GAAI,MAAM,cAAc,CAAC,CAAE;CAC/C,KAAK,MAAM,QAAQ,OAAO;EACzB,MAAM,KAAK,KAAK,YAAY;EAC5B,IAAI,CAAC,KAAK,UAAU,CAAC,WAAW,MAAM,aAAa,SAAS,OAAO,EAAE,GAAG,WAAW,KAAK;GAAE;GAAI,OAAO,gBAAgB,OAAO;EAAG,CAAC;CACjI;CACA,OAAO;EAAE;EAAO;EAAO;EAAM;CAAW;AACzC;;AAGA,SAAS,QAAQ,MAA6B,QAA4B,QAAwB;CACjG,QAAQ,MAAR;EACC,KAAK,SACJ,QAAQ,UAAU,KAAK;EACxB,KAAK,OACJ,OAAO,WAAW,KAAA,IAAY,SAAS,KAAK,IAAI,QAAQ,MAAM;EAC/D,KAAK,OACJ,OAAO,WAAW,KAAA,IAAY,SAAS,KAAK,IAAI,QAAQ,MAAM;EAC/D,KAAK,QACJ,OAAO;EACR,SACC,QAAQ,UAAU,KAAK;CACzB;AACD;;AAGA,IAAM,cAAc,UAAkB,KAAK,MAAM,QAAQ,GAAG,IAAI;;;;;;;;AAShE,IAAa,QAAb,MAAmB;CAOW;;CAL7B,UAAU;;CAEV,cAAc;CACd,OAA+B,CAAC;CAEhC,YAAY,OAA+B;EAAd,KAAA,QAAA;EAC5B,KAAK,OAAO;CACb;;CAGA,IAAI,QAA8B;EACjC,OAAO,KAAK,MAAM,SAAS;CAC5B;;CAGA,IAAI,KAAc;EACjB,OAAO,KAAK,MAAM,SAAS,UAAU;CACtC;;CAGA,QAAiC;EAChC,OAAO,KAAK,OAAO,SAAS,CAAC;CAC9B;;CAGA,SAAe;EACd,KAAK,MAAM,OAAO,KAAK,MAAM,IAAI;EACjC,KAAK,OAAO,CAAC;EACb,MAAM,QAAQ,KAAK;EACnB,IAAI,CAAC,OAAO;EACZ,MAAM,0BAAU,IAAI,IAA6F;EACjH,KAAK,MAAM,QAAQ,MAAM,OAAO;GAC/B,MAAM,UAAU,CAAC,KAAK,OAAO,CAAC,IAAI,MAAM,QAAQ,KAAK,IAAI,IAAK,KAAK,OAAkC,CAAC,KAAK,IAAmB;GAC9H,KAAK,MAAM,UAAU,SAAS;IAC7B,IAAI,QAAQ,QAAQ,IAAI,OAAO,MAAM,EAAE;IACvC,IAAI,CAAC,OAAO,QAAQ,IAAI,OAAO,MAAM,IAAK,QAAQ;KAAE,KAAK,OAAO;KAAO,MAAM,CAAC;IAAE,CAAE;IAClF,MAAM,KAAK,KAAK;KAAE;KAAM;IAAO,CAAC;GACjC;EACD;EACA,MAAM,QAAQ,KAAK;EACnB,KAAK,MAAM,EAAE,KAAK,UAAU,QAAQ,OAAO,GAC1C,KAAK,KAAK,KACT,MAAM,OAAO,GAAG,MAAM,YAAqB;GAC1C,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;IACrC,MAAM,EAAE,MAAM,WAAW,KAAK;IAE9B,IAAI,MAAM,SAAS,QAAQ,MAAM,SAAS,IAAI,kBAAkB,KAAK,IAAI,GAAG;IAC5E,IAAI;IACJ,IAAI;KACH,UAAU,OAAO,MAAM,SAAS,KAAK;IACtC,SAAS,OAAO;KACf,MAAM,OAAO,OAAO;MAAE,MAAM;MAAY,IAAI,SAAS,KAAK;KAAK,CAAC;KAChE;IACD;IACA,KAAK,KAAK,MAAM,OAAO;GACxB;EACD,CAAC,CACF;EAGD,KAAK,KAAK,KAAK,MAAM,OAAO,GAAG,gBAAgB,KAAK,OAAO,IAAI,CAAC,CAAC;CAClE;CAEA,KAAa,MAAoB,SAA6B;EAC7D,IAAI,YAAY,KAAA,KAAa,YAAY,MAAM;EAC/C,IAAI,OAAO,YAAY,UAAU,KAAK,IAAI,MAAM,SAAS,GAAG,KAAA,CAAS;OAChE,IAAI,MAAM,QAAQ,OAAO,GAAG,KAAK,MAAM,QAAQ,SAAkC,KAAK,IAAI,MAAM,KAAK,QAAQ,KAAK,UAAU,GAAG,KAAK,IAAI;OACxI;GACJ,MAAM,OAAO;GACb,KAAK,IAAI,MAAM,KAAK,QAAQ,KAAK,UAAU,GAAG,KAAK,IAAI;EACxD;CACD;;CAGA,OAAO,QAA2B;EACjC,MAAM,MAAM,KAAK,OAAO,MAAM;EAC9B,IAAI,KAAK,OAAO,IAAI,KAAK,OAAO,MAAM;EACtC,MAAM,QAAQ,KAAK,MAAM,QAAQ,IAAI,MAAM;EAC3C,OAAO,CAAC,CAAC,SAAS,CAAC,MAAM,WAAW,CAAC,MAAM;CAC5C;;CAGA,UAA6B,CAAC;;CAG9B,UAAsB;EACrB,MAAM,UAAsB,CAAC;EAC7B,KAAK,MAAM,MAAM,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,KAAK,OAAO,EAAE,GAAG,QAAQ,KAAK,EAAE;EAChF,OAAO,QAAQ,MAAM,GAAG,MAAM,IAAI,CAAC;CACpC;CAEA,IAAY,MAAoB,QAAkB,QAAgB,MAAgC;EACjG,IAAI,CAAC,OAAO,SAAS,MAAM,GAAG;EAC9B,IAAI,KAAK,MAAO,MAAM,SAAS,CAAC,KAAK,OAAO,MAAM,IAAI,EAAE,KAAK,QAAQ,YAAY,KAAK,OAAO,MAAM,IAAI;EACvG,MAAM,OAAO,KAAK,MAAM,MAAM,SAAS;EACvC,MAAM,SAAU,KAAK,OAAO,KAAK,QAAQ,CAAC;EAC1C,OAAO,UAAU,QAAQ,KAAK,MAAM,OAAO,SAAS,MAAM;EAC1D,IAAI,KAAK,UAAU,SAAS,KAAA,GAAW;GACtC,MAAM,QAAS,CAAC,KAAK,MAAM,KAAK,QAAQ,CAAC,EAAA,CAAG,YAAY,CAAC;GACzD,MAAM,QAAQ,QAAQ,KAAK,MAAM,MAAM,OAAO,MAAM;EACrD;EACA,KAAK;CACN;CAEA,KAAa,IAA0B;EACtC,MAAM,OAAO,KAAK,OAAO,KAAK,IAAI,EAAE;EACpC,IAAI,CAAC,MACJ,MAAM,IAAI,MACT,KAAK,QACF,0BAA0B,GAAG,8CAC7B,iGAAiG,GAAG,EACxG;EAED,OAAO;CACR;;CAGA,IAAI,QAAkB,IAAY,SAAS,GAAG,MAAqB;EAClE,KAAK,IAAI,KAAK,KAAK,EAAE,GAAG,QAAQ,QAAQ,IAAI;CAC7C;;CAGA,IAAI,QAAkB,IAAY,OAAe,MAAqB;EACrE,KAAK,IAAI;GAAE,GAAG,KAAK,KAAK,EAAE;GAAG,MAAM;EAAO,GAAG,QAAQ,OAAO,IAAI;CACjE;;CAGA,IAAI,QAAkB,IAAoB;EACzC,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC,CAAC,OAAO,GAAG,GAAG,WAAW;CAC5D;;CAGA,OAAO,QAAkB,IAA8C;EACtE,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC,CAAC,MAAM,GAAG,GAAG,WAAW,CAAC;CAC5D;;CAGA,KAAK,MAAc,IAAoB;EACtC,MAAM,OAAO,KAAK,KAAK,EAAE;EACzB,IAAI;EACJ,KAAK,MAAM,UAAU,KAAK,QAAQ,GAAG;GACpC,IAAI,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC,SAAS,MAAM;GAC7C,MAAM,QAAQ,KAAK,IAAI,QAAQ,EAAE;GACjC,QAAQ,KAAK,SAAS,SAAS,KAAK,SAAS,QAAS,UAAU,KAAA,IAAY,QAAQ,QAAQ,KAAK,MAAM,OAAO,KAAK,KAAM,SAAS,KAAK;EACxI;EACA,OAAO,SAAS;CACjB;;CAGA,SAAS,QAAkB,IAAqE;EAC/F,MAAM,OAAO,KAAK,MAAM,MAAM,SAAS;EACvC,OAAO;GAAE,OAAO,KAAK;GAAO,QAAQ,KAAK,KAAK,GAAG,GAAG,WAAW,CAAC;EAAE;CACnE;;CAGA,OAAO,QAAQ,OAAa;EAC3B,MAAM,QAAQ,KAAK;EACnB,IAAI,CAAC,OAAO;EACZ,MAAM,EAAE,UAAU;EAClB,MAAM,UAAU,KAAK,QAAQ;EAC7B,KAAK,MAAM,QAAQ,MAAM,OAAO;GAC/B,IAAI,CAAC,KAAK,UAAW,MAAM,SAAS,QAAQ,MAAM,SAAS,IAAI,gBAAgB,KAAK,IAAI,GAAI;GAC5F,MAAM,OAAO,KAAK,QAAQ;GAC1B,KAAK,MAAM,UAAU,SAAS;IAC7B,IAAI;IACJ,IAAI;KACH,QAAQ,KAAK,OAAO,OAAO,MAAM;IAClC,SAAS,OAAO;KACf,MAAM,OAAO,OAAO;MAAE,MAAM;MAAU,IAAI,SAAS,KAAK;KAAK,CAAC;KAC9D;IACD;IACA,IAAI,UAAU,KAAA,GAAW,KAAK,IAAI,KAAK,OAAO,OAAO;KAAE,GAAG;KAAM;IAAK,GAAG,QAAQ,OAAO,KAAA,CAAS;GACjG;EACD;EACA,MAAM,OAAO,MAAM,MAAM,SAAS;EAClC,MAAM,QAAQ,KAAK,OAAO,MAAM,MAAM,SAAS,MAAM,MAAM,QAAQ;EACnE,IAAI,SAAS,GAAG;EAChB,IAAI,CAAC,KAAK,OAAO,KAAK,QAAQ;EAE9B,IAAI,EADQ,KAAK,MAAM,WAAW,KAAK,MAAM,OAAO,KAAK,MAAM,KAAK,MAAM,SAAS,MAAM,KAAK,UAClF,EAAE,SAAS,KAAK,MAAM,KAAK,MAAM,SAAS,OAAO,MAAM,OAAO;EAC1E,KAAK,MAAM,KAAK,MAAM,IAAI;EAC1B,KAAK,MAAM,QAAQ,MAAM,OAAO;GAC/B,IAAI,CAAC,KAAK,UAAU;GACpB,MAAM,OAAQ,KAAK,KAAK,KAAK,QAAQ,CAAC;GACtC,KAAK,MAAM,UAAU,SAAS;IAC7B,MAAM,SAAU,KAAK,YAAY,CAAC;IAElC,OAAO,OAAO,SAAS,KAAK,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC;IAC3D,OAAO,KAAK,KAAK,OAAO,KAAK,GAAG,GAAG,WAAW,CAAC;GAChD;EACD;EAEA,MAAM,MAAM,KAAK,IAAI,MAAM,MAAM,aAAa,KAAK,CAAC;EACpD,IAAI,KAAK,MAAM,SAAS,KAAK;GAC5B,MAAM,QAAQ,SAAmB,KAAK,QAAQ,GAAG,MAAM,IAAI,MAAM,KAAK,MAAM,KAAK,SAAS,CAAC;GAC3F,KAAK,QAAQ,KAAK,KAAK,KAAK;GAC5B,KAAK,MAAM,SAAS,OAAO,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,OAAO,MAAM,UAAU,KAAK,MAAM,OAAO;GAC5G,KAAK,SAAS;EACf;EACA,KAAK;EACL,KAAK;CACN;;CAGA,MAAM,QAA8B,QAAkB,OAAyB;EAC9E,MAAM,QAAQ,KAAK,OAAO;EAC1B,IAAI,CAAC,OAAO,OAAO;EACnB,MAAM,WAAW,QAAS,MAAM,OAAO,aAAe,MAAM,QAAQ;EACpE,IAAI,OAAO,aAAa,YAAY,OAAO,SAAS,KAAK,OAAO,QAAQ,MAAM;EAC9E,IAAI,aAAa,QAAQ,OAAO;EAChC,IAAI,WAAW,KAAA,KAAa,aAAa,YAAY,OAAO;EAC5D,IAAI,aAAa,OAAO,OAAO,WAAW;EAC1C,OAAO,WAAW,UAAU,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC,SAAS,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC;CAC1F;;CAGA,SAAS,QAA8B,OAAwC;EAC9E,MAAM,QAAQ,KAAK;EACnB,IAAI,CAAC,OAAO,OAAO,KAAA;EACnB,MAAM,UAAU,KAAK,QAAQ,CAAC,CAAC,QAAQ,WAAW,KAAK,MAAM,QAAQ,QAAQ,KAAK,CAAC;EACnF,IAAI,CAAC,QAAQ,QAAQ,OAAO,KAAA;EAC5B,MAAM,OAAO,KAAK,MAAM,MAAM,SAAS;EACvC,MAAM,SAA+B,CAAC;EACtC,IAAI;EACJ,KAAK,MAAM,QAAQ,MAAM,OAAO;GAC/B,MAAM,MAAM,KAAK,OAAO,KAAK;GAC7B,IAAI,KAAK;IACR,MAAM,OAA+B,CAAC;IACtC,KAAK,MAAM,UAAU,SAAS,IAAI,UAAU,KAAK,KAAK,UAAU,WAAW,IAAI,OAAO;IACtF,OAAO,KAAK,MAAM;GACnB;GACA,MAAM,SAAS,KAAK,SAAS,KAAK,MAAM,KAAK,MAAM,KAAA;GACnD,IAAI,QAAQ;IACX,MAAM,OAA+C,CAAC;IACtD,KAAK,MAAM,UAAU,SAAS;KAC7B,IAAI,CAAC,OAAO,SAAS;KACrB,MAAM,OAA+B,CAAC;KACtC,KAAK,MAAM,QAAQ,OAAO,SAAS,KAAK,QAAQ,WAAW,OAAO,OAAO,CAAC,KAAK;KAC/E,KAAK,UAAU;IAChB;IACC,CAAC,UAAU,CAAC,EAAA,CAAG,KAAK,MAAM;GAC5B;EACD;EACA,OAAO;GAAE,MAAM,KAAK,MAAM;GAAM;GAAO;GAAS;GAAQ,GAAI,SAAS,EAAE,MAAM;EAAG;CACjF;;CAGA,QAAQ,QAA8B,OAA4C;EAEjF,IAAI,CADU,KAAK,OACP,OAAO,KAAA;EACnB,MAAM,OAAO,KAAK,MAAM,MAAM,SAAS;EACvC,IAAI,CAAC,KAAK,MAAM,QAAQ,OAAO,KAAA;EAC/B,MAAM,UAAU,KAAK,QAAQ,CAAC,CAAC,QAAQ,WAAW,KAAK,MAAM,QAAQ,QAAQ,KAAK,CAAC;EACnF,IAAI,CAAC,QAAQ,QAAQ,OAAO,KAAA;EAC5B,MAAM,SAAmC,CAAC;EAC1C,KAAK,MAAM,QAAQ,KAAK,MAAM;GAC7B,MAAM,OAAiC,CAAC;GACxC,KAAK,MAAM,UAAU,SAAS,IAAI,KAAK,KAAK,KAAK,CAAC,SAAS,KAAK,UAAU,KAAK,KAAK,KAAK,CAAC,OAAO,CAAC,IAAI,UAAU;GAChH,OAAO,QAAQ;EAChB;EACA,OAAO;GAAE,OAAO,KAAK,QAAQ,KAAK,MAAM;GAAU,OAAO,CAAC,GAAG,KAAK,KAAK;GAAG;EAAO;CAClF;AACD;;AAGA,SAAgB,YAAY,OAAsB;CACjD,OAAO;EACN,MAAM;EACN,OAAO;EACP,OAAO,KAAK,IAAI,KAAK,MAAM,MAAM,QAAQ,GAAG,CAAC;EAC7C,SAAS,UAAU,MAAM,MAAM,OAAO;CACvC;AACD;AAIA,IAAM,WAAW,OAAc,GAAa,MAAgB,MAAM,WAAW,GAAG,CAAC;;AAGjF,IAAM,QAAQ,WACb,WAAW,eAAe,WAAW,aAAa,WAAW,aAAa,WAAW,cAAc,WAAW;AAE/G,IAAM,YAAY,OAAc,QAAgB,WAC/C,UAAU,QAAQ,OAAO,OAAO,OAAO,OAAO,KAAK,IAAI,OAAO,QAAQ,KAAA;;;;;;AAOvE,SAAgB,YAAY,MAAkC;CAC7D,MAAM,YAAY,KAAK,aAAa,CAAC;CACrC,MAAM,WAAW,KAAK,YAAY,UAAU,EAAE,EAAE;CAChD,OAAO;EAEN,WAAW,iBAAiB;GAC3B,OAAO;GACP,UAAU;GACV,QAAQ;GACR,MAAM,CACL,QAAQ,cAAc,EAAE,YAAY;IAAE,QAAQ,KAAK;IAAO,MAAM,KAAK,IAAI;GAAG,EAAE,GAC9E,QAAQ,YAAY,EAAE,MAAM,cAAc;IAAE;IAAQ,MAAM,KAAK,IAAI;GAAG,EAAE,CACzE;EACD,CAAC;EACD,WAAW,eAAe;GACzB,OAAO;GACP,UAAU;GACV,QAAQ;GACR,UAAU;GACV,MAAM,QAAQC,aAAkB,EAAE,QAAQ,UAAU,UAAU;IAC7D,IAAI,CAAC,OAAO,QAAQ,OAAO,KAAA;IAC3B,MAAM,KAAK,SAAS,OAAO,QAAQ,MAAM;IACzC,OAAO,OAAO,KAAA,IAAY,KAAA,IAAY;KAAE,QAAQ;KAAI,MAAM,OAAO,IAAI;IAAG;GACzE,CAAC;EACF,CAAC;EACD,WAAW,aAAa;GACvB,OAAO;GACP,UAAU;GACV,QAAQ;GACR,MAAM,QAAQA,aAAkB,EAAE,QAAQ,aACzC,OAAO,UAAU,KAAK,MAAM,IAAI;IAAE,QAAQ,OAAO;IAAO,MAAM,OAAO,IAAI;GAAG,IAAI,KAAA,CACjF;EACD,CAAC;EACD,WAAW,kBAAkB;GAC5B,OAAO;GACP,UAAU;GACV,QAAQ;GACR,MAAM,QAAQ,uBAAuB,cAAc;IAAE,QAAQ,SAAS;IAAO,MAAM,SAAS,IAAI;GAAG,EAAE;EACtG,CAAC;EACD,WAAW,kBAAkB;GAC5B,OAAO;GACP,UAAU;GACV,QAAQ;GACR,MAAM,QAAQA,aAAkB,EAAE,QAAQ,UAAU,UAAU;IAC7D,IAAI,CAAC,OAAO,YAAY,OAAO,KAAA;IAC/B,MAAM,KAAK,SAAS,OAAO,QAAQ,MAAM;IACzC,OAAO,OAAO,KAAA,IAAY,KAAA,IAAY;KAAE,QAAQ;KAAI,MAAM,OAAO,IAAI;IAAG;GACzE,CAAC;EACF,CAAC;EACD,WAAW,iBAAiB;GAC3B,OAAO;GACP,UAAU;GACV,MAAM,QAAQA,aAAkB,EAAE,QAAQ,aAAc,OAAO,cAAc,KAAK,MAAM,IAAI,OAAO,QAAQ,KAAA,CAAU;EACtH,CAAC;EACD,WAAW,QAAQ;GAClB,OAAO;GACP,aAAa;GACb,UAAU;GACV,MAAM;GACN,UAAU;GACV,SAAS,OAAO,WAAW,MAAM,OAAO,MAAM,CAAC,CAAC;EACjD,CAAC;EACD,WAAW,eAAe;GACzB,OAAO;GACP,aAAa;GACb,UAAU;GACV,MAAM;GACN,SAAS,OAAO,WAAW,MAAM,OAAO,MAAM,CAAC,CAAC;EACjD,CAAC;EAED,WAAW,gBAAgB;GAC1B,OAAO;GACP,UAAU;GACV,QAAQ;GACR,MAAM,QAAQA,aAAkB,EAAE,QAAQ,UAAU,UAAU;IAC7D,IAAI,CAAC,OAAO,IAAI,SAAS,GAAG,OAAO,KAAA;IACnC,MAAM,KAAK,SAAS,OAAO,QAAQ,MAAM;IACzC,OAAO,OAAO,KAAA,IAAY,KAAA,IAAY;KAAE,QAAQ;KAAI,MAAM,OAAO,IAAI;IAAG;GACzE,CAAC;EACF,CAAC;EACD,WAAW,cAAc;GACxB,OAAO;GACP,UAAU;GACV,MAAM,QAAQA,aAAkB,EAAE,QAAQ,aAAc,OAAO,MAAM,KAAK,KAAK,MAAM,IAAI,OAAO,QAAQ,KAAA,CAAU;EACnH,CAAC;EACD,WAAW,oBAAoB;GAC9B,OAAO;GACP,UAAU;GACV,MAAM;GACN,MAAM,QAAQ,cAAc,EAAE,MAAM,aAAa;IAAE,QAAQ,KAAK;IAAO,QAAQ;IAAO,MAAM,KAAK,IAAI;GAAG,EAAE;EAC3G,CAAC;EACD,WAAW,cAAc;GACxB,OAAO;GACP,UAAU;GACV,QAAQ;GACR,MAAM,QAAQ,WAAW,EAAE,MAAM,cAAc;IAAE,QAAQ,KAAK;IAAO;IAAQ,MAAM,KAAK,IAAI;GAAG,EAAE;EAClG,CAAC;EACD,WAAW,gBAAgB;GAC1B,OAAO;GACP,UAAU;GACV,MAAM,QAAQA,aAAkB,EAAE,QAAQ,UAAU,UAAW,UAAU,MAAM,OAAO,OAAO,KAAK,CAAC,CAAC,SAAS,OAAO,QAAQ,KAAA,CAAU;EACvI,CAAC;EACD,WAAW,iBAAiB;GAC3B,OAAO;GACP,UAAU;GACV,QAAQ;GACR,MAAM,QAAQ,aAAa,EAAE,QAAQ,YAAY;IAAE,QAAQ,OAAO;IAAO,MAAM,KAAK;GAAK,EAAE;EAC5F,CAAC;EACD,WAAW,iBAAiB;GAC3B,OAAO;GACP,UAAU;GACV,QAAQ;GACR,MAAM,QAAQ,cAAc,EAAE,QAAQ,eAAe;IAAE,QAAQ,OAAO;IAAO,MAAM,QAAQ;GAAG,EAAE;EACjG,CAAC;EAED,WAAW,eAAe;GACzB,OAAO;GACP,UAAU;GACV,QAAQ;GACR,UAAU;GACV,MAAM,QAAQ,UAAU,EAAE,QAAQ,QAAQ,UAAU,UACnD,UAAU,QAAQ,OAAO,OAAO,OAAO,OAAO,KAAK,IAAI;IAAE,QAAQ,OAAO;IAAO;IAAQ,MAAM,OAAO,IAAI;GAAG,IAAI,KAAA,CAChH;EACD,CAAC;EACD,WAAW,eAAe;GACzB,OAAO;GACP,UAAU;GACV,MAAM,QAAQ,UAAU,EAAE,QAAQ,cAAc;IAAE,QAAQ,OAAO;IAAO;GAAO,EAAE;EAClF,CAAC;EACD,WAAW,WAAW;GACrB,OAAO;GACP,UAAU;GACV,QAAQ;GACR,MAAM,QAAQ,SAAS,EAAE,QAAQ,QAAQ,cAAc;IAAE,SAAS,UAAU,OAAA,CAAQ;IAAO;IAAQ,OAAO,UAAU,OAAA,CAAQ,IAAI;GAAG,EAAE;EACtI,CAAC;EAED,GAAG,UAAU,SAAS,aAAa;GAClC,WAAW,YAAY,SAAS,MAAM;IACrC,OAAO,GAAG,SAAS,KAAK;IACxB,UAAU;IACV,UAAU,SAAS,OAAO;IAC1B,MAAM,QAAQ,qBAAqB,EAAE,QAAQ,MAAM,aAAc,SAAS,SAAS,KAAK;KAAE;KAAQ;IAAO,IAAI,KAAA,CAAU;GACxH,CAAC;GACD,WAAW,SAAS,SAAS,MAAM;IAClC,OAAO,GAAG,SAAS,KAAK;IACxB,UAAU;IACV,QAAQ;IACR,MAAM,QAAQ,iBAAiB,EAAE,QAAQ,MAAM,IAAI,aAClD,KAAK,SAAS,MAAM;KAAE;KAAQ,QAAQ,SAAS,CAAC,KAAK,SAAS,MAAM,KAAK,SAAS;KAAK,MAAM;IAAG,IAAI,KAAA,CACrG;GACD,CAAC;GACD,GAAI,SAAS,SACV,CACA,WAAW,UAAU,SAAS,MAAM;IACnC,OAAO,GAAG,SAAS,KAAK;IACxB,UAAU;IACV,MAAM,QAAQ,qBAAqB,EAAE,QAAQ,MAAM,aAClD,SAAS,SAAS,MAAM,SAAS;KAAE;KAAQ,QAAQ;IAAO,IAAI,KAAA,CAC/D;GACD,CAAC,CACF,IACC,CAAC;EACL,CAAC;EACD,GAAI,WACD,CACA,WAAW,UAAU;GACpB,OAAO;GACP,aAAa,GAAG,UAAU,MAAM,aAAa,SAAS,OAAO,QAAQ,CAAC,EAAE,QAAQ,SAAS;GACzF,UAAU;GACV,MAAM,QAAQC,SAAc,EAAE,QAAQ,cAAc;IAAE;IAAQ;GAAO,EAAE;EACxE,CAAC,CACF,IACC,CAAC;EAEJ,GAAI,UAAU,SACX,CACA,WAAW,aAAa;GACvB,OAAO;GACP,UAAU;GACV,QAAQ;GACR,MAAM,QAAQ,SAAS,EAAE,MAAM,UAAU,YAAY;IAAE,QAAQ;IAAM,QAAQ;IAAM,MAAM;GAAS,EAAE;EACrG,CAAC,GACD,WAAW,YAAY;GACtB,OAAO;GACP,UAAU;GACV,QAAQ;GACR,MAAM,QAAQ,SAAS,EAAE,IAAI,UAAU,gBAAgB;IAAE,QAAQ;IAAI,QAAQ;IAAU,MAAM;GAAS,EAAE;EACzG,CAAC,CACF,IACC,CAAC;CACL;AACD;;;;;;;;;AAyBA,SAAgB,YAAY,UAA8B,CAAC,GAAe;CACzE,MAAM,EAAE,MAAM,SAAS,OAAO,MAAM,CAAC,GAAG,GAAG,UAAU;CACrD,MAAM,SAAS,MAAqC,OAAe,CAAC,CAAC,MAAM,MAAM,SAAS,SAAS,MAAM,GAAG,WAAW,GAAG,KAAK,EAAE,CAAC;CAClI,OAAO;EACN,GAAG;EACH,QAAQ,SAAS,CAAC,GAAG,YAAY,IAAI,CAAC,CAAC,QAAQ,UAAU,CAAC,QAAQ,MAAM,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,SAAS,KAAK,EAAE,CAAC,GAAG,GAAG,GAAG;CAC7H;AACD;AAYA,IAAM,OAAO,CAAC;;AAGd,SAAS,UAAU,MAA0C;CAC5D,MAAM,EAAE,UAAU;CAClB,MAAM,UAAU,MAAM,MAAM;CAC5B,IAAI,CAAC,WAAW,KAAK,aAAa,OAAO,KAAA;CACzC,MAAM,OAAO,KAAK,KAAgB,aAAa;EAAE,MAAM;EAAW,SAAS;EAAI,aAAa;EAAI,OAAO;CAAM,EAAE;CAE/G,MAAM,QAAQ,MAAM,WAAW,QAAQ,MAAM,YAAY;CACzD,MAAM,SAAS,KAAK,WAAW,KAAA,IAAY,KAAK;CAChD,MAAM,UAAU,KAAK,IAAI,KAAK,OAAO,QAAQ,MAAM,WAAW,KAAK,MAAM,QAAQ,GAAG,CAAC;CAErF,IADY,UAAU,KAAK,SAAU,MAAM,OAAO,KAAK,QAAQ,WAAW,MAAM,MAAM,YAAY,KAAK,SAC9F;EACR,KAAK,QAAQ,MAAM,MAAM,SAAS,QAAQ,KAAK;EAC/C,KAAK,OAAO,MAAM;EAClB,KAAK,UAAU,MAAM,MAAM;CAC5B;CACA,IAAI,UAAU,KAAK,SAAS,MAAM,MAAM,gBAAgB,KAAK,aAAa;EACzE,KAAK,OAAO,MAAM,MAAM,QAAQ,QAAQ,KAAK;EAC7C,KAAK,cAAc,MAAM,MAAM;CAChC;CACA,KAAK,QAAQ;CACb,OAAO;AACR;;AAGA,IAAa,YAAY,aAAa,UAAU,SAAS,UAAU,IAAI,CAAC,EAAE,KAAK;;AAG/E,IAAa,gBAAgB,aAAa,cAAc,SAAS,UAAU,IAAI,CAAC,EAAE,IAAI;;;;;;;;;AC50BtF,IAAa,eAAuB;CACnC,MAAM;CACN,OAAO;CACP,OAAO,OAAO;EACb,MAAM,QAAQ,MAAM,MAAM,OAAO,SAAS,CAAC;EAC3C,MAAM,QAAQ,OAAO,KAAK,KAAK;EAC/B,KAAK,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG;GAC5C,OAAO,aAAa;GACpB,OAAO,YAAY;GACnB,MAAM,WAA0D,CAAC;GACjE,KAAK,MAAM,QAAQ,OAAO,SAAS,QAAQ;IAAE,MAAM;IAAG,KAAK;GAAE;GAC7D,OAAO,WAAW;EACnB;EACA,KAAK,MAAM,UAAU,MAAM,OAAO,OAAO,GAAG;GAE3C,IAAI,CAAC,OAAO,SAAS,CAAC,OAAO,IAAI,SAAS,GAAG;GAC7C,MAAM,SAAS,MAAM,OAAO,OAAO,KAAK;GACxC,MAAM,EAAE,QAAQ;GAChB,IAAI,OAAO,QAAQ;IAClB,OAAO,cAAc,MAAM,MAAM,OAAO,GAAG,OAAO,MAAM;IACxD,KAAK,MAAM,QAAQ,IAAI,UAAU,IAAI,OAAO,SAAS,OAAO,OAAO,SAAS,KAAK,CAAC,QAAQ,IAAI,SAAS;GACxG,OAAO,IAAI,OAAO,SAAS,OAAO,aAAa;IAC9C,OAAO,aAAa,IAAI,kBAAkB;IAC1C,KAAK,MAAM,QAAQ,IAAI,kBAAkB,IAAI,OAAO,SAAS,OAAO,OAAO,SAAS,KAAK,CAAC,OAAO,IAAI,iBAAiB;GACvH;EACD;EAEA,KAAK,MAAM,UAAU,MAAM,MAAM,QAAQ,eAAe,GAAG;GAC1D,IAAI,OAAO,WAAY,CAAC,OAAO,SAAS,CAAC,OAAO,IAAI,SAAS,GAAI;GACjE,MAAM,SAAS,MAAM,OAAO,OAAO,KAAK;GACxC,KAAK,MAAM,QAAQ,aAAa,MAAM,CAAC,CAAE,OAAO;IAC/C,IAAI,KAAK,SAAS,QAAQ;IAC1B,MAAM,SAAqB;KAAE,KAAK,MAAM,SAAS,KAAK,KAAK,EAAE;KAAG,OAAO,OAAO;KAAO,QAAQ;IAAK;IAClG,OAAO,cAAc,MAAM,MAAM,OAAO,GAAG,OAAO,MAAM;IACxD,KAAK,MAAM,QAAQ,OAAO,IAAI,UAAU,IAAI,OAAO,SAAS,OAAO,OAAO,SAAS,KAAK,CAAC,QAAQ,OAAO,IAAI,SAAS;GACtH;EACD;EACA,MAAM,SAAS,MAAM,MAAM,IAAI,WAAW;EAC1C,KAAK,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG;GAC5C,IAAI,QAAQ;IACX,MAAM,OAAkB;KAAE,QAAQ,OAAO;KAAI,MAAM;KAAU,KAAK,OAAO;IAAU;IACnF,MAAM,MAAM,IAAI,aAAa,IAAI;IACjC,OAAO,YAAY,KAAK;IACxB,KAAK,MAAM,QAAQ,OAAO;KACzB,MAAM,OAAkB;MAAE,QAAQ,OAAO;MAAI,MAAM;MAAM,KAAK,OAAO,SAAS,KAAK,CAAC;KAAI;KACxF,MAAM,MAAM,IAAI,aAAa,IAAI;KACjC,OAAO,SAAS,KAAK,CAAC,MAAM,KAAK;IAClC;GACD;GACA,OAAO,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,WAAW,MAAM,MAAM,OAAO,GAAG,CAAC;GACjF,KAAK,MAAM,QAAQ,OAAO,OAAO,SAAS,KAAK,CAAC,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,SAAS,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC,GAAG,CAAC;EACvH;CACD;AACD;;AAGA,IAAa,WAAW,eAAeC,SAAc,SAAS,EAAE,QAAQ,UAAU,SACjF,KAAK,MAAM,MAAM,KAAK,KAAK,MAAM,MAAM,IAAI;CAAE,MAAM;CAAQ,IAAI,OAAO;CAAI,QAAQ,OAAO;AAAG,IAAI,KAAA,CACjG;;AAGA,IAAa,eAAe,eAAe,iBAAiB,aAAa,EAAE,QAAQ,MAAM,QAAQ,UAAU,SAC1G,KAAK,OAAO,OAAO,KAAK,IAAI;CAAE,MAAM;CAAY,IAAI,OAAO;CAAI;CAAM;CAAQ;AAAO,IAAI,KAAA,CACzF;;AAGA,IAAM,QAAQ,CAAC;;;;;;;AAQf,SAAgB,SAAS,MAAwC;CAChE,MAAM,OAAO,KAAK,KAAK,cAAc;EAAE,IAAI;EAAI,OAAO,CAAC;CAAyB,EAAE;CAClF,MAAM,EAAE,UAAU;CAClB,IAAI,KAAK,OAAO,MAAM,MAAM,OAAO,KAAK;CACxC,KAAK,KAAK,MAAM;CAChB,MAAM,QAAQ,MAAM,SAAS;CAC7B,MAAM,QAAoB,CAAC;CAC3B,KAAK,MAAM,UAAU,MAAM,SAAS,OAAO,GAC1C,IAAI,OAAO,SAAS,SAAS,OAAO,IAAI,UAAU,SAAS,OAAO,MAAM,KAAK;EAAE,IAAI,OAAO;EAAI,GAAG,OAAO,IAAI;EAAG,GAAG,OAAO,IAAI;CAAE,CAAC;CAEjI,KAAK,QAAQ;CACb,OAAO;AACR;;;;;;;;AC1FA,IAAa,QAAQ,gBAA0C,cAAc,EAAE,gBAAgB,CAAC,GAAG,CAAC;AAyCpG,IAAa,UAAU,gBAAyB,YAAY,EAAE,gBAAgB;CAAE,MAAM;CAAI,MAAM,CAAC;CAAG,QAAQ,CAAC;CAAG,OAAO,CAAC;AAAE,GAAG,CAAC;;;;;;;AAQ9H,IAAa,WAAb,MAAsB;CACQ;CAA7B,YAAY,MAAgC;EAAf,KAAA,OAAA;CAAgB;;CAG7C,IAAI,OAAe;EAClB,OAAO,KAAK,KAAK;CAClB;;CAGA,IAAI,OAAgC;EACnC,OAAO,KAAK,KAAK;CAClB;;;;;;CAOA,OAAO,MAAc,SAAyD,CAAC,GAAe;EAC7F,MAAM,SAAS,UAAU,KAAK,MAAM,IAAI;EACxC,IAAI,CAAC,OAAO,QAAQ,OAAO;EAC3B,OAAO,OAAO,KAAK,UAAU;GAC5B,MAAM,OAAO,EAAE,GAAG,MAAM,KAAK;GAC7B,KAAK,MAAM,SAAS,QAAQ,IAAI,KAAK,MAAM,QAAQ,KAAA,KAAa,MAAM,YAAY,KAAA,GAAW,KAAK,MAAM,MAAM,MAAM;GACpH,OAAO;IAAE,GAAG;IAAO;GAAK;EACzB,CAAC;CACF;;CAGA,IAAI,MAAuB;EAC1B,OAAO,KAAK,OAAO,MAAM,UAAU,MAAM,SAAS,IAAI,KAAK,KAAK,MAAM,MAAM,SAAS,KAAK,SAAS,IAAI;CACxG;;CAGA,MAAoC,MAAkB;EACrD,MAAM,QAAQ,KAAK,OAAO,MAAM,UAAU,MAAM,SAAS,IAAI;EAC7D,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,UAAU,KAAK,MAAM,iBAAiB,KAAK,EAAE;EACzE,OAAO;GAAE,GAAG,MAAM;GAAG,GAAG,MAAM;GAAG,QAAQ,MAAM;EAAO;CACvD;;CAGA,KAAmC,MAAkB;EACpD,MAAM,OAAO,KAAK,MAAM,MAAM,SAAS,KAAK,SAAS,IAAI;EACzD,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,UAAU,KAAK,MAAM,gBAAgB,KAAK,EAAE;EACvE,OAAO,IAAI,KAAK,KAAK,QAAQ,KAAK,KAAK;CACxC;;CAGA,IAAI,cAA0C;EAC7C,OAAO,KAAK,KAAK;CAClB;;CAGA,IAAI,UAAgC;EACnC,OAAO,KAAK,KAAK,WAAW,CAAC;CAC9B;;CAGA,IAAI,UAAgC;EACnC,OAAO,KAAK,KAAK,WAAW,CAAC;CAC9B;;CAGA,OAAO,IAAuC;EAC7C,OAAO,KAAK,KAAK,SAAS,MAAM,WAAW,OAAO,OAAO,EAAE;CAC5D;;CAGA,UAAU,MAAwC;EACjD,OAAO,KAAK,KAAK,YAAY,MAAM,UAAU,MAAM,SAAS,IAAI;CACjE;;CAGA,IAAI,SAA8B;EACjC,OAAO,KAAK,KAAK,UAAU,CAAC;CAC7B;;CAGA,IAAI,UAAgC;EACnC,OAAO,KAAK,KAAK,WAAW,CAAC;CAC9B;;CAGA,IAAI,SAA8B;EACjC,OAAO,KAAK,KAAK,UAAU,CAAC;CAC7B;;CAGA,IAAI,QAA4B;EAC/B,OAAO,KAAK,KAAK,SAAS,CAAC;CAC5B;CAEA,IAAY,QAAgB;EAC3B,OAAO,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK;CAClD;AACD;;;;;;;;ACjJA,IAAa,aAAa,gBAAyC,cAAc,EAAE,gBAAgB,CAAC,GAAG,CAAC;;;;;;AAOxG,IAAa,cAAc,YAA6C,oBAAoB,EAAE,WAAW,WAAW,CAAC;;AAGrH,IAAM,YAAY;AAElB,IAAM,WAAW,UAA8B,MAAM,IAAI,QAAQ,QAAQ,WAAW,OAAO,QAAQ,OAAO,QAAQ,OAAO,MAAM;;AAG/H,SAAS,KAAK,OAAc,MAAuB;CAClD,IAAI,CAAC,MAAM,IAAI,YAAY,YAAY,KAAK,IAAI;EAAE,GAAG,KAAK;EAAG,GAAG,KAAK;EAAG,IAAI,KAAK;EAAS,IAAI,KAAK;CAAQ,CAAC,GAC3G,MAAM,IAAI,KAAK,cAAc,mDAAmD,KAAK,KAAK,0BAA0B,EAAE,MAAM,KAAK,GAAG,CAAC;AACvI;;;;;AAMA,SAAgB,WAAW,OAAoB;CAC9C,MAAM,QAAQ,QAAQ,KAAK;CAE3B,IAAI,CAAC,MAAM,QAAQ;CACnB,MAAM,SAAS,MAAM,MAAM,UAAU;CACrC,KAAK,MAAM,QAAQ,OAAO;EACzB,MAAM,OAAO,OAAO,KAAK,SAAU,KAAK,QAAQ;EAChD,OAAO,KAAK,QAAS;EACrB,IAAI,CAAC,MAAM,KAAK,OAAO,IAAI;CAC5B;CACA,MAAM,SAAS,YAAY,MAAM;AAClC;;;;;;AAOA,SAAgB,WAAW,OAAc,MAAmC;CAC3E,OAAO,MAAM,MAAM,UAAU,CAAC,CAAC;AAChC;;;;;;;AAQA,SAAgB,QAAQ,OAAc,MAAc,MAAwB;CAC3E,MAAM,OAAO,QAAQ,KAAK,CAAC,CAAC,MAAM,WAAW,OAAO,SAAS,IAAI;CACjE,IAAI,CAAC,MAAM,OAAO;CAClB,MAAM,SAAS,MAAM,MAAM,UAAU;CACrC,IAAI,OAAO,UAAU,MAAM,OAAO;CAClC,MAAM,SAAS,YAAY;EAAE,GAAG;GAAS,OAAO;CAAK,CAAC;CACtD,IAAI,MAAM,MAAM,IAAI,eAAe,YAAY,KAAK,EAAE;MACjD,KAAK,OAAO,IAAI;CAErB,MAAM,OAAO,MAAM,MAAM,OAAO;CAChC,MAAM,SAAS,SAAS;EAAE,GAAG;EAAM,UAAU,KAAK,WAAW,CAAC,EAAA,CAAG,KAAK,WAAY,OAAO,OAAO,KAAK,KAAK;GAAE,GAAG;GAAQ;EAAK,IAAI,MAAO;CAAE,CAAC;CAC1I,MAAM,OAAO,KAAK,aAAa;EAAE;EAAM;CAAK,CAAC;CAC7C,OAAO;AACR;;;;ACnDA,IAAa,iBAAiB,QAAgC;;;;;;;AAQ9D,SAAgB,WAAW,MAA6B,OAA0C,CAAC,GAAiB;CACnH,OAAO,KAAK,KAAK,QAAQ;EACxB,MAAM,QAAQ,KAAK,IAAI;EACvB,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI;GAAE,GAAG;GAAK,SAAS,KAAK,IAAI,KAAK,IAAI,OAAO,IAAI,GAAG,GAAG,IAAI,GAAG;EAAE,IAAI;CACjI,CAAC;AACF;;;;;;AAOA,IAAa,UAAU,gBAAwC,gBAAgB,EAAE,gBAAgB,CAAC,GAAG,CAAC;;;;;;AAOtG,IAAa,iBAAiB,YAA2C,qBAAqB;;;;;;AAO9F,IAAa,cAAc,mBAAmB,cAAc;CAAE,IAAI;CAAQ,OAAO;AAAO,IAAI,OAAO,SAAS,YAAY;CACvH,MAAM,WAAW,QAAQ,IAAI,QAAQ,KAAK;AAC3C,CAAC;;;;;;;;;;;;;;ACUD,IAAa,aAAa,gBAA4B,WAAW;;;;;;AAOjE,IAAa,QAAQ,gBAAwB,cAAc,EAAE,eAAe,CAAC,EAAE,CAAC;;AAGhF,IAAa,WAAW,UAAyB,MAAM,MAAM,KAAK;;;;;;AAOlE,IAAa,aAAa,OAAc,SAAmC,QAAQ,KAAK,CAAC,CAAC,MAAM,SAAS,KAAK,SAAS,IAAI;;;;;;AAO3H,SAAgB,WAAW,OAAa,OAA2D;CAClG,OAAO,MAAM,KAAK,EAAE,QAAQ,MAAM,IAAI,GAAG,MAAM;EAC9C,MAAM,QAAS,IAAI,KAAK,IAAI,QAAQ,GAAG,CAAC,IAAK,KAAK,KAAK;EACvD,MAAM,SAAS,MAAM,IAAI,IAAI;EAC7B,OAAO;GAAE,GAAG,MAAM,IAAI,IAAI,KAAK,IAAI;GAAQ,GAAG,MAAM,IAAI,IAAI,KAAK,IAAI;GAAQ,QAAQ;EAAM;CAC5F,CAAC;AACF;;;;;;AAOA,SAAgB,UAAU,OAAc,OAAiB,OAAa,OAAiB,QAAQ,MAAM,MAAM,MAAM,OAAa;CAC7H,MAAM,MAAM,QAAQ,KAAK;CACzB,MAAM,QAAQ,MAAM,QAAQ,KAAK,SAAS,OAAO,MAAM,SAAS,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC;CACzF,MAAM,OAAa;EAAE,IAAI,IAAI,SAAS;EAAG,GAAG,MAAM;EAAG,GAAG,MAAM;EAAG;EAAO;EAAO,SAAS,CAAC;EAAG,OAAO;EAAG;EAAO,OAAO,CAAC,GAAG,KAAK;CAAE;CAC/H,MAAM,EAAE,YAAY,MAAM,MAAM;CAChC,IAAI,YAAY,KAAA,GAAW,KAAK,UAAU;CAC1C,IAAI,KAAK,IAAI;CACb,SAAS,OAAO,MAAM,OAAO,KAAK;CAClC,OAAO;AACR;;AAGA,SAAS,SAAS,OAAc,MAAY,OAAiB,OAAuB;CACnF,MAAM,SAAS,WAAW,MAAM,MAAM,MAAM;CAC5C,KAAK,UAAU,CAAC;CAChB,MAAM,SAAS,MAAM,MAAM;EAC1B,MAAM,EAAE,GAAG,GAAG,WAAW,OAAO;EAChC,MAAM,QAAQ,MAAM,MAAM,MAAM,OAAO;GAAE;GAAG;EAAE,GAAG,EAAE,OAAO,CAAC;EAC3D,MAAM,IAAI,YAAY;GAAE,MAAM,KAAK;GAAI,MAAM;IAAE,GAAG,MAAM,IAAI;IAAG,GAAG,MAAM,IAAI;GAAE;GAAG,WAAW;GAAO,WAAW;EAAK,CAAC;EACpH,KAAK,QAAQ,KAAK,MAAM,EAAE;CAC3B,CAAC;AACF;;;;;;AAOA,SAAgB,YAAY,OAAc,MAAkB;CAC3D,IAAI,CAAC,KAAK,OAAO,UAAU,KAAK,UAAU,KAAA,GAAW;CACrD,SAAS,OAAO,MAAM,KAAK,OAAO,KAAK,KAAK;CAC5C,KAAK,QAAQ;CACb,KAAK,YAAY,KAAA;CACjB,MAAM,OAAO,KAAKC,cAAmB,EAAE,KAAK,CAAC;AAC9C;;AAGA,IAAM,WAAW,OAAc,SAAe,KAAK,QAAQ,OAAO,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,KAAK;;;;;;;AAQ9F,IAAa,oBAA4B;CACxC,MAAM;CACN,OAAO;CACP,OAAO;CACP,OAAO,OAAoB;EAC1B,KAAK,MAAM,QAAQ,QAAQ,KAAK,GAAG;GAClC,IAAI,CAAC,QAAQ,OAAO,IAAI,GAAG;GAC3B,IAAI,KAAK,cAAc,KAAA,GAAW;IACjC,KAAK,YAAY,MAAM;IACvB,MAAM,OAAO,KAAKC,aAAkB,EAAE,KAAK,CAAC;GAC7C;GACA,IAAI,KAAK,YAAY,KAAA,KAAa,MAAM,OAAO,KAAK,YAAY,KAAK,SAAS;GAG9E,IADc,MAAM,QAAQ,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,KACjD,CAAA,CAAM,MAAM,WAAW,OAAO,SAAS,OAAO,UAAU,OAAO,UAAU,KAAK,KAAK,GAAG;GAC1F,YAAY,OAAO,IAAI;EACxB;CACD;AACD;;AAGA,IAAM,kBAAkB;AACxB,IAAM,QAAkB,CAAC;;AAGzB,SAAS,QAAQ,OAAc,QAAyB;CACvD,KAAK,MAAM,SAAS,OAAO,WAAW;EACrC,IAAI,MAAM,QAAQ,KAAK,MAAM,WAAW,GAAG;EAC3C,MAAM,UAAU,MAAM,SAAS,QAAQ,MAAM,EAAE;EAC/C,IAAI,QAAQ,WAAW,UAAU,GAAG,QAAQ,UAAU,MAAM,KAAK,IAAI,OAAO,MAAM;EAClF,MAAM,SAAS,QAAQ,QAAQ,QAAQ,KAAK,WAAW,KAAK,IAAI,KAAK,OAAO,SAAS,WAAW,GAAG,OAAO,QAAQ,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC;EACtI,IAAI,CAAC,QAAQ;EACb,IAAI,SAAS;EACb,KAAK,MAAM,SAAS,MAAM,QAAQ,MAAM,OAAO,IAAI,GAAG,OAAO,IAAI,GAAG,QAAQ,KAAK,GAChF,IAAI,MAAM,UAAU,UAAU,OAAO,QAAQ,KAAK,KAAK,aAAa,QAAQ,KAAK,KAAK,QAAQ;EAE/F,IAAI,SAAS,GAAG;EAChB,UAAU,OAAO,QAAQ,YAAY,OAAO;GAAE,MAAM;GAAQ,SAAS,QAAQ;EAAG,CAAC,CAAC;EAClF,OAAO;CACR;CACA,OAAO;AACR;;;;;AAMA,SAAS,UAAU,OAAc,QAAgB,IAAkB;CAClE,MAAM,SAAS,OAAO,IAAI,UAAU;CACpC,MAAM,SAAS,OAAO,IAAI,QAAQ;CAClC,MAAM,OAAO,QAAQ,KAAK,CAAC,CAAC,OAAO,OAAO;CAC1C,MAAM,IAAI,OAAO,IAAI,MAAM;CAC3B,MAAM,OAAO,KAAK,OAAO,KAAK,OAAO,IAAI;CAEzC,IAAI,OAAO,QAAQ;EAElB,IAAI,MAAM,SAAS,CAAC,OAAO,gBAAgB,CAAC,MAAM,IAAI,KAAK,KAAK,GAAG;EACnE,OAAO,SAAS;CACjB;CAEA,IAAI,OAAO,WAAW;EACrB,OAAO,KAAK,KAAK,IAAI,OAAO,KAAK,OAAO,QAAQ,kBAAkB,IAAI,OAAO,KAAK;EAClF,IAAI,KAAK,EAAE,WAAW,UAAU;EAChC,IAAI,KAAK,OAAO,OAAO,EAAE,WAAW,UAAU;GAC7C,OAAO,OAAO,QAAQ,OAAO,IAAI;GACjC;EACD;EACA,OAAO,YAAY;EACnB,OAAO,eAAe;EACtB,IAAI,KAAK,SAAS,CAAC,MAAM,IAAI,KAAK,KAAK,GAAG,KAAK,QAAQ;EACvD;CACD;CAEA,MAAM,gBAAgB;EACrB,OAAO,aAAa;EACpB,UAAU,OAAO,MAAM;EACvB,MAAM,WAAW,MAAM,IAAI,KAAK,KAAK;EACrC,IAAI,KAAK,UAAU,CAAC,YAAY,KAAK,SAAS,KAAK,IAAI,IAAI,KAAK,QAAQ,KAAK,QAAQ;EACrF,IAAI,KAAK,OAAO,KAAK;GACpB,OAAO,YAAY;GACnB,OAAO,OAAO,QAAQ,OAAO,IAAI;EAClC;CACD;CAEA,IAAI,OAAO,YAAY;EACtB,MAAM,SAAS,MAAM,IAAI,OAAO,UAAU;EAE1C,MAAM,SAAS,OAAO,KAAK,SAAU,CAAC,CAAC,UAAU,KAAK,OAAO,KAAK,IAAI,IAAI,KAAK,QAAQ;EACvF,IAAI,CAAC,UAAU,UAAU,QAAQ,OAAO,MAAM,GAAG;EACjD,IAAI,SAAS,SAAS,YAAY,OAAO,OAAO,QAAQ,QAAQ,IAAI,CAAC,CAAC,CAAC;EACvE,IAAI,WAAW,aAAa,UAAU,UAAU,OAAO,QAAQ,MAAM,GAAG;GACvE,KAAK,OAAO,QAAQ,MAAM;GAC1B,SAAS;EACV;EACA,IAAI,WAAW,eAAe,WAAW,WAAW;EACpD,OAAO,aAAa;EACpB,UAAU,OAAO,MAAM;CACxB;CAEA,KAAK,MAAM,OAAO,OAAO,MAAM,MAAM,GAAG;CACxC,MAAM,SAAS,UACd,CAAC,CAAC,SAAS,UAAU,OAAO,QAAQ,KAAK,KAAK,OAAO,OAAO,QAAQ,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,QAAQ;CACrH,IAAI,OAAO,cAAc,OAAO,MAAM;CACtC,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,OAAO,KAAA;CACjC,IAAI,CAAC,QAAQ,MAAM,MAAM,IAAI,OAAO,YAAY,CAAC,GAAG,OAAO,MAAM,IAAI,OAAO,YAAY;CACxF,IAAI,CAAC,QAAQ,MAAM,MAAM,IAAI,KAAK,KAAK,CAAC,GAAG,OAAO,MAAM,IAAI,KAAK,KAAK;CACtE,IAAI,CAAC,MAAM;EAEV,MAAM,SAAS,MAAM,IAAI,OAAO,YAAY;EAC5C,IAAI,KAAK,UAAU,UAAU,OAAO,QAAQ,MAAM,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,QAAQ,GAAG;GAChG,OAAO,YAAY;IAAE,GAAG,OAAO,IAAI;IAAG,GAAG,OAAO,IAAI;GAAE;GACtD,OAAO,OAAO,QAAQ,OAAO,SAAS;EACvC;CACD;CACA,OAAO,eAAe;CACtB,IAAI,MAAM;EACT,WAAW,OAAO,QAAQ,IAAI;EAC9B,OAAO,YAAY;EACnB,OAAO,aAAa,KAAK;EACzB,KAAK,QAAQ,KAAK;CACnB,OAAO,IAAI,OAAO,aAAa,GAAG,WAAW,YAAY,QAAQ,KAAK,OACrE;MACM;EACN,OAAO,YAAY;EACnB,QAAQ;EACR,IAAI,MAAM,SAAS,MAAM,MAAM,MAAM,SAAS,CAAC,OAAO,aAAa,CAAC,KAAK,OAAO,OAAO,SAAS;CACjG;AACD;;;;;;AAOA,IAAa,YAAuB,CACnC,WAAW;CACV,MAAM;CACN,IAAI;CACJ,IAAI,OAAO,OAAO;EACjB,IAAI,MAAM,WAAW,CAAC,MAAM,UAAU,CAAC,MAAM,OAAO,IAAI,UAAU,GAAG;EACrE,UAAU,OAAO,MAAM,QAAQ,MAAM,EAAE;EACvC,MAAM,UAAU;CACjB;AACD,CAAC,CACF;;AAGA,IAAM,QAAQ,CAAC;;;;;;;;AASf,SAAgB,SAAS,MAAwC;CAChE,MAAM,OAAO,KAAK,KAAK,cAAc;EAAE,IAAI;EAAI,OAAO,CAAC;CAAgB,EAAE;CACzE,MAAM,EAAE,UAAU;CAClB,IAAI,KAAK,OAAO,MAAM,MAAM,OAAO,KAAK;CACxC,KAAK,KAAK,MAAM;CAChB,MAAM,MAAM,QAAQ,KAAK;CACzB,MAAM,EAAE,YAAY,KAAK;CACzB,MAAM,YAAY,YAA+B,QAAQ,MAAM,OAAO,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;CACrF,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;EACpC,MAAM,OAAO,IAAI;EACjB,MAAM,QAAQ,QAAQ,QAAQ,KAAK,EAAE;EAErC,IAAI,QAAQ,KAAK,KAAK,KAAK,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,KAAK,OAAO,GAAG,QAAQ,KAAK,KAAK,EAAE;OACtF,IAAI,SAAS,KAAK,KAAK,KAAK,KAAK,GAAG,KAAK,CAAC,KAAK,SAAS,KAAK,OAAO,GAExE,QAAQ,OAAO,OAAO,CAAC;EAExB,MAAM,OAAQ,KAAK,MAAM,OAAO;GAAE,IAAI,KAAK;GAAI,GAAG,KAAK;GAAG,GAAG,KAAK;GAAG,OAAO,KAAK;GAAO,SAAS;EAAM;EACvG,KAAK,UAAU,QAAQ,SAAS,KAAK,EAAE;CACxC;CACA,KAAK,MAAM,SAAS,IAAI;CACxB,OAAO,KAAK;AACb;;;;;;;;ACzNA,IAAa,oBAA+C,OAAO,OAAO;CACzE,SAAS;CACT,cAAc;CACd,cAAc;CACd,YAAY;CACZ,WAAW;CACX,WAAW;CACX,UAAU;CACV,cAAc;CACd,eAAe;CACf,eAAe;AAChB,CAAC;;;;;;;AAeD,IAAa,mBAAyF,OAAO,OAAO;CACnH,KAAK,OAAO,OAAO;EAAE,cAAc;EAAG,eAAe;EAAG,eAAe;CAAE,CAAC;CAC1E,QAAQ,OAAO,OAAO,CAAC,CAAC;CACxB,MAAM,OAAO,OAAO;EAAE,cAAc;EAAG,eAAe;EAAG,eAAe;CAAE,CAAC;AAC5E,CAAC;AAQD,IAAM,gBAAgB;AACtB,IAAM,cAAc;;;;;AAKpB,IAAM,gBAAgB;;AAEtB,IAAM,2BAAW,IAAI,IAAI;CAAC;CAAG;CAAG;AAAC,CAAC;;AAElC,IAAM,UAAU;;;;;;AAMhB,IAAM,UAAU;AAChB,IAAM,UAAU;;AAchB,SAAS,SAAS,SAAkB,SAAyE;CAC5G,MAAM,EAAE,OAAO,UAAU;CACzB,MAAM,SAAS,IAAI,aAAa,QAAQ,KAAK;CAC7C,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAC1B,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;EAC/B,MAAM,QAAQ,QAAQ,IAAI,IAAK,IAAI,EAAG;EACtC,OAAO,IAAI,QAAQ,KAAK;EACxB,IAAI,UAAU,GAAG,OAAO;CACzB;CAED,OAAO,OAAO;EAAE;EAAO;EAAO;CAAO,IAAI,KAAA;AAC1C;;AAGA,SAAS,MAAM,WAAyB,SAAsB,MAAsB;CACnF,IAAI,QAAQ;CACZ,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,QAAQ,KAAK,IAAI,OAAO,UAAU,QAAQ,KAAK,IAAI,KAAK;CACjG,OAAO;AACR;;AAGA,IAAM,YAAY,QAAgB,UAAkB,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK,MAAM,GAAG,KAAK,GAAG,KAAK;;AAGtG,IAAM,eAAe;;AAErB,IAAM,mBAAmB;;AAUzB,IAAM,iBAAiB;;;;;AAMvB,SAAS,QAAQ,SAAkB,WAAmB,aAAqB,WAAsC,QAAwB;CACxI,MAAM,QAAQ,IAAI,MAAM,SAAS;EAAE;EAAW,gBAAgB,KAAK,IAAI,cAAc,GAAG,CAAC;CAAE,CAAC;CAC5F,MAAM,aAAa,0BAA0B;EAAE,GAAG;EAAG,GAAG;EAAG,GAAG;CAAE;CAEhE,IAAI,QAAQ,aAAa,MAAM,UAAU,CAAC,CAAC;CAC3C,MAAM,SAAS,IAAI,IAAI,OAAO,0BAA0B;CACxD,OAAO,UAAU,UAAU;CAC3B,OAAO,eAAe,UAAU;CAChC,OAAO,eAAe,UAAU;CAChC,OAAO,aAAa,UAAU;CAC9B,OAAO,YAAY,UAAU;CAC7B,OAAO,YAAY,UAAU;CAC7B,OAAO,WAAW,UAAU;CAC5B,OAAO,eAAe,UAAU;CAChC,OAAO,gBAAgB,UAAU;CACjC,OAAO,gBAAgB,UAAU;CACjC,MAAM,IAAI,2BAA2B,gBAAgB,MAAM;CAC3D,IAAI,QAAQ,MAAM;CAClB,OAAO;AACR;AAEA,IAAa,mBAAb,MAAa,iBAAuC;CAgBjC;CACT;CACA;CACA;CACA;CACS;CAET;CAES;CAEA;CAET;CAEC;CACA;CAED;CAES;CAEA;CAEA;CAvClB,UAAU;CAEV,yBAAiB,IAAI,IAAwB;CAC7C,4BAAoB,IAAI,IAAsB;;CAE9C,iBAAyB;CACzB,iBAAyB;;CAEzB,UAAkB;;CAElB,OAAe;CACf,8BAA+B,IAAI,IAAY;CAC/C,UAA2B;EAAE,GAAG;EAAG,GAAG;EAAG,GAAG;CAAE;CAE9C,YACC,SACA,SACA,WACA,OACA,OACA,aAEA,WAEA,cAEA,UAEA,OAEA,WACA,YAEA,OAEA,YAA+D,GAAG,MAAM,QAAQ,SAAS,GAAG,CAAC,GAE7F,QAEA,KACC;EAzBgB,KAAA,UAAA;EACT,KAAA,UAAA;EACA,KAAA,YAAA;EACA,KAAA,QAAA;EACA,KAAA,QAAA;EACS,KAAA,cAAA;EAET,KAAA,YAAA;EAES,KAAA,eAAA;EAEA,KAAA,WAAA;EAET,KAAA,QAAA;EAEC,KAAA,YAAA;EACA,KAAA,aAAA;EAED,KAAA,QAAA;EAES,KAAA,WAAA;EAEA,KAAA,SAAA;EAEA,KAAA,MAAA;EAEjB,KAAK,iBAAiB;CACvB;CAEA,aAAa,OAAO,SAAkB,UAAmC,CAAC,GAA8B;EACvG,MAAM,WAAW;EAEjB,MAAM,QAAQ,QAAQ,QAAQ,QAAQ;EACtC,MAAM,EACL,cAAc,IACd,WAAW,IACX,YAAY,KAEZ,eAAe,SAAS,OAAO,IAAI,GACnC,WAAW,SAAS,QAAQ,GAAG,IAAI,GACnC,WAAW,KACX,UAAU,UACV,aAAa,OACV;EACJ,MAAM,YAAuC,OAAO,OAAO;GAC1D,GAAG;GACH,GAAG,iBAAiB,OAAO,QAAQ,cAAc,WAAW,QAAQ,YAAY;GAChF,GAAI,OAAO,QAAQ,cAAc,YAAY,QAAQ;EACtD,CAAC;EACD,MAAM,aAAa;EACnB,MAAM,QAAQ,YAAY;EAC1B,MAAM,SAAgC;GACrC,IAAI;GACJ,IAAI;GACJ,UAAU;GACV,oBAAoB;GACpB,gBAAgB,KAAK,KAAK,IAAI,UAAU;GACxC,eAAe,KAAK,KAAK,KAAM,UAAU;GACzC,gBAAgB,KAAK,KAAK,cAAc,QAAQ;GAChD,wBAAwB;GACxB,iBAAiB;GACjB,iBAAiB;GACjB,kBAAkB;GAClB,sBAAsB;GACtB,uBAAuB;GACvB;EACD;EAEA,MAAM,UAAU,QAAQ,KAAA,IAAY,QAAQ;EAE5C,MAAM,YAAY;GACjB,MAAM,EAAE,WAAW,YAAY,QAAQ,QAAQ,eAAe,IAAI,QAAQ,UAAU,IAAI;GACxF,MAAM,SAAS,WAAW,SAAS,SAAS,OAAO;GACnD,OAAO;IACN,OAAO;KAAE;KAAW;KAAS;KAAQ,GAAI,UAAU,EAAE,OAAO;IAAG;IAC/D,OAAO;KAAE,MAAM,OAAO,WAAW;KAAU,SAAS,MAAM,WAAW,SAAS,CAAC;KAAG,SAAS,MAAM,WAAW,SAAS,CAAC;IAAE;GACzH;EACD;EACA,MAAM,QAAQ,IAAI;EAGlB,MAAM,OAAO,MAAM,eAAe,MAAM,OAAO,QAAQ,MAAM;EAG7D,MAAM,UAAU,UAAU,kBAAkB,OAAO,IAAI,kCAAkC;EACzF,MAAM,EAAE,SAAS,WAAW,WAAW,eAAe,gBAAgB,MAAM,OAAO;EACnF,MAAM,QAAQ,IAAI,aAAa,SAAS,EAAE,SAAS,CAAC;EACpD,MAAM,0BAA0B;GAAE,GAAG;GAAG,GAAG;GAAG,GAAG;EAAE;EACnD,IAAI,SAAS,aAAa,MAAM,aAAa;EAC7C,MAAM,QAAQ,QAAQ,SAAS,WAAW,aAAa,WAAW,CAAC,CAAC,OAAO;EAC3E,OAAO,IAAI,iBACV,SACA,SACA,WACA,OACA,OACA,aACA,WACA,cACA,UACA;GAAC;GAAS;GAAW;EAAU,GAC/B,WACA,YACA,MAAM,OACN,SAAS,GAAG,MAAM,QAAQ,cAAc,GAAG,CAAC,IAAI,KAAA,GAChD,WAAW,EAAE,QAAQ,GACrB,GACD;CACD;;;;;;;CAQA,UAAmB;EAClB,IAAI,CAAC,KAAK,KAAK,OAAO;EACtB,KAAK,MAAM;EACX,MAAM,EAAE,OAAO,UAAU,KAAK,IAAI;EAClC,IAAI;EACJ,IAAI;GACH,OAAO,gBAAgB,mBAAmB,KAAK,GAAG,KAAK,MAAM,EAA2C;EACzG,QAAQ;GACP,OAAO;EACR;EACA,MAAM,QAAQ,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,SAAS,CAAC,KAAK,cAChD,SAAS,SAAS,QACf,CACA,CACC,KACA;GACC,GAAG,SAAS,SAAS;GACrB,GAAG,SAAS,SAAS;GACrB,IAAI,SAAS,YAAY,IAAI,KAAK;GAClC,IAAI,SAAS,YAAY,IAAI,KAAK;EACnC,CACD,CACD,IACC,CAAC,CACL;EACA,MAAM,SAAS,CAAC,GAAG,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAE,CAAU;EACrF,MAAM,MAAM;GAAC,KAAK;GAAO,KAAK;GAAO,KAAK;GAAW,KAAK;EAAO;EACjE,KAAK,UAAU,KAAK;EACpB,KAAK,YAAY,KAAK;EACtB,KAAK,QAAQ;GAAC,KAAK,MAAM;GAAI,KAAK;GAAW,KAAK;EAAU;EAC5D,KAAK,QAAQ;EACb,KAAK,QAAQ,IAAI,aAAa,KAAK,SAAS,EAAE,UAAU,KAAK,SAAS,CAAC;EACvE,KAAK,MAAM,0BAA0B;GAAE,GAAG;GAAG,GAAG;GAAG,GAAG;EAAE;EACxD,IAAI,KAAK,QAAQ,aAAa,KAAK,MAAM,aAAa;EACtD,KAAK,QAAQ,QAAQ,KAAK,SAAS,KAAK,WAAW,KAAK,aAAa,KAAK,WAAW,CAAC,CAAC,KAAK,MAAM;EAClG,KAAK,UAAU,MAAM;EACrB,KAAK,OAAO,MAAM;EAClB,KAAK,MAAM,QAAQ,KAAK,KAAK,QAAQ;EAErC,KAAK,UAAU;EACf,KAAK,OAAO;EACZ,KAAK,YAAY,MAAM;EACvB,KAAK,iBAAiB;EACtB,KAAK,cAAc,IAAI;EACvB,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,KAAK,YAAY,KAAK,IAAI;EAC3D,KAAK,cAAc,KAAK;EACxB,KAAK,MAAM,CAAC,IAAI,SAAS,QAAQ,KAAK,aAAa,IAAI,IAAI;EAC3D,KAAK;EACL,OAAO;CACR;;;;;;CAOA,cAAc,OAAgC;EAC7C,IAAI,CAAC,KAAK,QAAQ;EAClB,KAAK,MAAM;EACX,MAAM,OAAO,KAAK;EAClB,MAAM,EAAE,UAAU,KAAK;EACvB,MAAM,wBAAQ,IAAI,IAAY;EAC9B,KAAK,MAAM,QAAQ,OAAO;GACzB,MAAM,KAAK,KAAK,OAAQ,OAAO,QAAS,KAAM,KAAK,WAAW,KAAK,IAAI;GACvE,MAAM,KAAK,KAAK,OAAO,KAAK,MAAM,OAAO,KAAK,IAAI,KAAM,KAAK,WAAW,KAAK,IAAI;GACjF,MAAM,IAAI,KAAK,QAAQ,EAAE;EAC1B;EAEA,KAAK,MAAM,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,KAAK,UAAU,oBAAoB,KAAK,MAAM,MAAM,KAAK,GAAG,MAAM,OAAO,KAAK,OAAO;EACzI,KAAK;CACN;;CAGA,IAAI,SAAqD;EACxD,OAAO;GAAE,cAAc,KAAK;GAAc,UAAU,KAAK;EAAS;CACnE;;CAGA,IAAI,WAAmB;EACtB,OAAO,KAAK;CACb;;;;;CAMA,OAAqB;EACpB,MAAM,QAAQ,CAAC,GAAG,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAE,CAAU;EACpF,MAAM,MAAM,KAAK;EACjB,KAAK,aAAa;EAClB,KAAK,QAAQ,QAAQ,KAAK,SAAS,KAAK,WAAW,KAAK,aAAa,KAAK,WAAW,CAAC,CAAC,KAAK,MAAM;EAClG,KAAK,OAAO,MAAM;EAClB,KAAK,MAAM,CAAC,IAAI,SAAS,OAAO,KAAK,aAAa,IAAI,IAAI;EAC1D,IAAI,QAAQ;CACb;CAEA,OAAe,GAAS;EACvB,KAAK,QAAQ,IAAI,EAAE;EACnB,KAAK,QAAQ,IAAI,KAAK,SAAS,EAAE,GAAG,EAAE,CAAC;EACvC,KAAK,QAAQ,IAAI,EAAE;EACnB,OAAO,KAAK;CACb;CAEA,SAAS,IAAY,UAAgB,QAA2B;EAC/D,IAAI,KAAK,OAAO,IAAI,EAAE,GAAG,KAAK,YAAY,EAAE;EAC5C,MAAM,QAAQ,KAAK,aAAa,UAAU,CAAC,KAAK;EAChD,MAAM,cAAc;GACnB,QAAQ,OAAO;GACf,QAAQ;GACR,UAAU,OAAO;GACjB,iBAAiB,OAAO,QAAQ;GAChC,qBAAqB,OAAO,SAAS;GACrC,uBAAuB,OAAO,SAAS;GACvC,kBAAkB,KAAK;GACvB,aAAa;GACb,uBAAuB;EACxB;EACA,IAAI,QAAQ,KAAK,MAAM,SAAS,KAAK,OAAO,KAAK,GAAG,WAAW;EAE/D,IAAI,MAAM,aAAa,GAAG;GACzB,KAAK,KAAK;GACV,QAAQ,KAAK,MAAM,SAAS,KAAK,OAAO,KAAK,GAAG,WAAW;GAC3D,IAAI,MAAM,aAAa,GAAG,MAAM,IAAI,MAAM,sCAAsC,KAAK,UAAU,0BAA0B;EAC1H;EACA,KAAK,OAAO,IAAI,IAAI;GAAE;GAAO,QAAQ,OAAO;GAAQ,UAAU;GAAO,SAAS,MAAM;GAAG,SAAS,MAAM;GAAG,OAAO;GAAO,QAAQ;EAAK,CAAC;CACtI;CAEA,YAAY,IAAkB;EAC7B,MAAM,QAAQ,KAAK,OAAO,IAAI,EAAE;EAChC,IAAI,CAAC,OAAO;EACZ,KAAK,MAAM,YAAY,MAAM,KAAK;EAClC,KAAK,OAAO,OAAO,EAAE;CACtB;CAEA,SAAS,IAAqB;EAC7B,OAAO,KAAK,OAAO,IAAI,EAAE;CAC1B;CAEA,eAAe,IAAY,QAAuB;EACjD,MAAM,QAAQ,KAAK,OAAO,IAAI,EAAE;EAChC,IAAI,CAAC,OAAO,OAAO;EACnB,MAAM,UAAU,KAAK,aAAa,QAAQ,CAAC;EAC3C,IAAI,CAAC,SAAS,OAAO;EACrB,KAAK,KAAK,KAAK;EACf,IAAI,CAAC,MAAM,UAAU,CAAC,MAAM,OAAO,MAAM,MAAM,iBAAiB,EAAE,aAAa,cAAc,CAAC;EAC9F,MAAM,SAAS;EACf,OAAO,MAAM,MAAM,kBAAkB,KAAK,OAAO,OAAO,CAAC;CAC1D;CAEA,iBAAiB,IAAkB;EAClC,MAAM,QAAQ,KAAK,OAAO,IAAI,EAAE;EAChC,IAAI,CAAC,OAAO;EACZ,IAAI,MAAM,UAAU,CAAC,MAAM,OAAO,MAAM,MAAM,iBAAiB,EAAE,aAAa,cAAc,CAAC;EAC7F,MAAM,SAAS;EACf,MAAM,MAAM,gBAAgB;CAC7B;CAEA,SAAS,IAAY,UAAsB;EAC1C,MAAM,QAAQ,KAAK,OAAO,IAAI,EAAE;EAChC,IAAI,CAAC,OAAO;EACZ,MAAM,UAAU,KAAK,aAAa,UAAU,CAAC,KAAK;EAClD,MAAM,MAAM,SAAS,KAAK,OAAO,OAAO,CAAC;EACzC,MAAM,UAAU,QAAQ;EACxB,MAAM,UAAU,QAAQ;EAExB,IAAI,MAAM,UAAU,MAAM,MAAM,IAAI,QAAQ;CAC7C;CAEA,YAAY,IAAY,UAAyB;EAChD,MAAM,QAAQ,KAAK,OAAO,IAAI,EAAE;EAChC,IAAI,CAAC,SAAS,MAAM,aAAa,UAAU;EAC3C,IAAI,CAAC,UAAU;GACd,KAAK,KAAK,KAAK;GACf;EACD;EACA,MAAM,EAAE,UAAU;EAClB,MAAM,EAAE,QAAQ;EAChB,MAAM,WAAW;EACjB,MAAM,UAAU,IAAI,SAAS,CAAC;EAC9B,MAAM,UAAU,IAAI,SAAS,CAAC;EAC9B,IAAI,MAAM,UAAU,CAAC,MAAM,OAAO,MAAM,iBAAiB,EAAE,aAAa,cAAc,CAAC;EACvF,MAAM,SAAS;EACf,MAAM,gBAAgB;EAEtB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,QAAQ,GAAG,CAAC;EAC5C,IAAI,QAAQ;CACb;;CAGA,KAAa,OAAyB;EACrC,IAAI,CAAC,MAAM,UAAU;EACrB,MAAM,WAAW;EACjB,MAAM,MAAM,IAAI,QAAQ;CACzB;CAEA,SAAS,IAAY,OAAsB;EAC1C,MAAM,QAAQ,KAAK,OAAO,IAAI,EAAE;EAChC,IAAI,CAAC,SAAS,MAAM,UAAU,OAAO;EACrC,MAAM,QAAQ;EACd,MAAM,MAAM,iBAAiB;GAC5B,aAAa,QAAQ,cAAc,MAAM,SAAS,gBAAgB;GAElE,qBAAqB,QAAQ,MAAO,MAAM,SAAS;EACpD,CAAC;CACF;CAEA,SAAS,IAAY,OAAqB;EAEzC,KAAK,OAAO,IAAI,EAAE,CAAC,EAAE,MAAM,iBAAiB;GAAE,UAAU;GAAO,iBAAiB,KAAK,IAAI,QAAQ,IAAI,OAAO;EAAE,CAAC;CAChH;CAEA,UAAU,IAAmC;EAC5C,MAAM,QAAQ,KAAK,OAAO,IAAI,EAAE;EAChC,IAAI,CAAC,OAAO,OAAO,KAAA;EACnB,MAAM,EAAE,OAAO,QAAQ,QAAQ,UAAU,UAAU;EACnD,MAAM,IAAI,MAAM,SAAS;EACzB,MAAM,IAAI,MAAM,SAAS;EACzB,OAAO;GACN,GAAG,EAAE;GACL,GAAG,EAAE;GACL,IAAI,EAAE;GACN,IAAI,EAAE;GACN;GACA,OAAO,MAAM;GACb,cAAc,MAAM;GACpB,QAAQ,UAAU;IAAE,GAAG,OAAO;IAAG,GAAG,OAAO;GAAE;GAC7C;GACA,QAAQ,WAAW;IAAE,GAAG,MAAM;IAAS,GAAG,MAAM;GAAQ,IAAI,KAAA;GAC5D;EACD;CACD;CAEA,OAAO,QAAmE;EAEzE,MAAM,MAAM,KAAK;EACjB,KAAK,YAAY,KAAK;EACtB,KAAK,QAAQ,QAAQ,KAAK,SAAS,KAAK,WAAW,KAAK,aAAa,KAAK,WAAW,CAAC,CAAC,KAAK,MAAM;EAClG,KAAK,OAAO,MAAM;EAClB,IAAI,QAAQ;EACZ,KAAK,MAAM,CAAC,IAAI,SAAS,QAAQ,KAAK,aAAa,IAAI,IAAI;CAC5D;CAEA,aAAa,IAAY,MAAuB;EAE/C,KAAK,SAAS,IAAI;GAAE,GAAG,KAAK;GAAG,GAAG,KAAK;EAAE,GAAG;GAAE,QAAQ,KAAK;GAAQ,OAAO,KAAK;EAAM,CAAC;EACtF,MAAM,QAAQ,KAAK,OAAO,IAAI,EAAE;EAChC,MAAM,EAAE,UAAU;EAGlB,MAAM,KAAK,KAAK,WAAY,KAAK,UAAU,OAAQ;EACnD,MAAM,SAAS;GAAE,GAAG,GAAG;GAAG,GAAG,KAAK,SAAS,GAAG,GAAG,GAAG,CAAC;GAAG,GAAG,GAAG;EAAE,CAAC;EACjE,MAAM,UAAU,GAAG;EACnB,MAAM,UAAU,GAAG;EACnB,IAAI,KAAK,iBAAiB,KAAA,GAAW,MAAM,iBAAiB,EAAE,iBAAiB,KAAK,aAAa,CAAC;EAClG,KAAK,SAAS,IAAI,KAAK,KAAK;EAC5B,IAAI,KAAK,QAAQ,KAAK,eAAe,IAAI,KAAK,MAAM;EACpD,IAAI,KAAK,UAAU;GAClB,KAAK,YAAY,IAAI,IAAI;GACzB;EACD;EAEA,MAAM,IAAI,QAAQ,GAAG,KAAK,EAAE;EAC5B,MAAM,IAAI,QAAQ,GAAG,KAAK,EAAE;CAC7B;CAEA,OAAO,SAAuB;EAC7B,KAAK,MAAM;EACX,KAAK,IAAI,IAAI,GAAG,KAAK,gBAAgB,KAAK;GACzC,IAAI,IAAI,KAAQ,MAAM,IAAI,MAAM,yCAAyC;GACzE,KAAK,iBAAiB,CAAC,KAAK,UAAU,OAAO,KAAK,OAAO,CAAC,CAAC;EAC5D;EACA,KAAK,UAAU;EAGf,KAAK,IAAI,IAAI,GAAG,IAAI,OAAQ,CAAC,GAAG,KAAK,OAAO,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,YAAY,SAAS,IAAI,MAAM,IAAI,WAAW,CAAC,GAAG,KAAK,KAAK,MAAM,OAAO,CAAC;CACzI;CAEA,UAAU,IAAY,KAA0B;EAC/C,MAAM,QAAQ,KAAK,OAAO,IAAI,EAAE;EAChC,IAAI,CAAC,OAAO,OAAO;EAEnB,IAAI,MAAM,UAAU;GACnB,IAAI,IAAI,MAAM;GACd,IAAI,IAAI,MAAM;GACd,IAAI,KAAK;GACT,IAAI,KAAK;GACT,IAAI,KAAK,IAAI,KAAK,MAAM;GACxB,IAAI,KAAK,IAAI,KAAK,MAAM;GACxB,OAAO;EACR;EAEA,MAAM,MAAM,MAAM,MAAM;EACxB,IAAI,IAAI,IAAI,SAAS,CAAC;EACtB,IAAI,IAAI,IAAI,SAAS,CAAC;EACtB,IAAI,KAAK,IAAI,QAAQ,CAAC;EACtB,IAAI,KAAK,IAAI,QAAQ,CAAC;EAEtB,MAAM,UAAU,IAAI;EACpB,IAAI,UAAU,GAAG;GAChB,IAAI,KAAK,IAAI,gBAAgB,CAAC;GAC9B,IAAI,KAAK,IAAI,gBAAgB,CAAC;EAC/B,OAAO;GACN,IAAI,KAAK,IAAI,cAAc,CAAC;GAC5B,IAAI,KAAK,IAAI,cAAc,CAAC;EAC7B;EACA,IAAI,UAAU,GAAG;GAChB,IAAI,KAAK,IAAI,gBAAgB,CAAC;GAC9B,IAAI,KAAK,IAAI,gBAAgB,CAAC;EAC/B,OAAO;GACN,IAAI,KAAK,IAAI;GACb,IAAI,KAAK,IAAI;EACd;EACA,OAAO;CACR;CAEA,OAAO,IAAkB;EACxB,KAAK,MAAM;EACX,IAAI,KAAK,gBAAgB;GACxB,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KACvB,IAAI,KAAK,UAAU,OAAO,KAAK,OAAO,CAAC,CAAC,UAAU;IACjD,KAAK,iBAAiB;IACtB;GACD;GAED,KAAK;EACN;EAKA,KAAK,MAAM,OAAO,EAAE;CACrB;CAEA,YAAY,KAAa,MAAqB;EAC7C,KAAK,eAAe,GAAG;EACvB,IAAI,KAAK,UAAU,QAAQ,KAAK,cAAc,OAAO;EACrD,MAAM,IAAI,KAAK,QAAQ,SAAS,KAAK,GAAG,KAAK,CAAC;EAE9C,MAAM,OAAO;GAAE,GAAG,KAAK,KAAK,KAAK;GAAa,GAAG;GAAG,GAAG,KAAK,KAAK,KAAK;EAAY;EAClF,KAAK,SAAS,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;EAC5C,MAAM,SAAS,KAAK,UAAU,eAAe;GAAE,GAAG,KAAK;GAAG;GAAG,GAAG,KAAK;EAAE,GAAG,MAAM,CAAC;EAEjF,IAAI,CAAC,OAAO,SAAS,OAAO;EAC5B,KAAK,UAAU,IAAI,KAAK,OAAO,QAAQ;EACvC,KAAK,eAAe;EACpB,OAAO;CACR;;;;;;;CAQA,cAAc,MAAqB;EAClC,IAAI,KAAK,YAAY,MAAM;EAC3B,KAAK,UAAU;EACf,IAAI,CAAC,MAAM,OAAO,KAAK,MAAM;EAG7B,IAAI,KAAK,gBAAgB;GACxB,KAAK,OAAO;GACZ,KAAK,MAAM;GACX,KAAK,iBAAiB;EACvB;CACD;;;;;;CAOA,SAAiB,GAAW,GAAW,IAAY,IAAkB;EACpE,IAAI,CAAC,KAAK,SAAS;EACnB,MAAM,UAAU,KAAK,UAAU,GAAG,GAAG,IAAI,EAAE;EAC3C,IAAI,OAAO;EACX,KAAK,MAAM,UAAU,SAAS,IAAI,CAAC,KAAK,YAAY,IAAI,MAAM,GAAG;EACjE,IAAI,KAAK,OAAO,IAAI,gBAAgB,KAAK,YAAY,OAAO,OAAO,kBAAkB,KAAK,MAAM;EAChG,KAAK,MAAM,UAAU,SAAS,KAAK,YAAY,IAAI,MAAM;CAC1D;;;;;CAMA,UAAkB,GAAW,GAAW,IAAY,IAAsB;EACzE,MAAM,EAAE,MAAM,SAAS,YAAY,KAAK;EACxC,MAAM,QAAQ,MAAM,KAAK,IAAI,IAAI,EAAE;EACnC,MAAM,KAAK,KAAK,OAAO,IAAI,QAAQ,WAAW,IAAI;EAClD,MAAM,KAAK,KAAK,OAAO,IAAI,QAAQ,WAAW,IAAI;EAClD,MAAM,KAAK,KAAK,OAAO,IAAI,QAAQ,WAAW,IAAI;EAClD,MAAM,KAAK,KAAK,OAAO,IAAI,QAAQ,WAAW,IAAI;EAClD,MAAM,UAAoB,CAAC;EAC3B,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,QAAQ,KAAK,KAAK,QAAQ,EAAE;EAChG,OAAO;CACR;;CAGA,QAAsB;EACrB,IAAI,CAAC,KAAK,MAAM;EAChB,KAAK,OAAO;EACZ,KAAK,YAAY,MAAM;EACvB,KAAK,IAAI,IAAI,GAAG,CAAC,KAAK,UAAU,OAAO,KAAK,OAAO,CAAC,CAAC,UAAU,KAC9D,IAAI,IAAI,KAAQ,MAAM,IAAI,MAAM,yCAAyC;EAE1E,KAAK,iBAAiB;CACvB;CAEA,eAAuB;EACtB,OAAO,KAAK,eAAe,KAAK,UAAU;CAC3C;CAEA,eAAe,KAAmB;EACjC,MAAM,WAAW,KAAK,UAAU,IAAI,GAAG;EACvC,IAAI,CAAC,UAAU;EACf,IAAI,KAAK,WAAW,SAAS,SAAS,OAAO;GAC5C,MAAM,EAAE,UAAU,gBAAgB;GAClC,KAAK,SAAS,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,YAAY,CAAC;EACnE;EACA,KAAK,UAAU,eAAe,QAAQ;EACtC,KAAK,UAAU,OAAO,GAAG;EACzB,KAAK,eAAe;CACrB;;;;;CAMA,iBAA+B;EAC9B,IAAI,KAAK,SAAS,KAAK;OAClB,KAAK,iBAAiB,CAAC,KAAK,UAAU,OAAO,KAAK,OAAO,CAAC,CAAC;EAChE,KAAK;CACN;CAEA,aAAa,OAAa,eAAe,GAAgB;EACxD,KAAK,MAAM;EACX,MAAM,SAAS,KAAK,MAAM,iBAAiB,KAAK,OAAO,KAAK,GAAG,EAAE,aAAa;GAAE,GAAG;GAAc,GAAG;GAAG,GAAG;EAAa,EAAE,CAAC;EAC1H,IAAI,CAAC,OAAO,WAAW,OAAO,YAAY,GAAG,OAAO;EACpD,OAAO;GAAE,GAAG,OAAO,MAAM;GAAG,GAAG,OAAO,MAAM;EAAE;CAC/C;CAEA,SAAS,MAAY,IAAyB;EAC7C,KAAK,MAAM;EACX,MAAM,QAAQ,EAAE,GAAG,KAAK,OAAO,IAAI,EAAE;EACrC,MAAM,MAAM,EAAE,GAAG,KAAK,OAAO,EAAE,EAAE;EACjC,MAAM,SAAS,KAAK,MAAM,YAAY,OAAO,GAAG;EAChD,IAAI,CAAC,OAAO,WAAW,OAAO,KAAK,WAAW,GAAG,OAAO;EACxD,OAAO,OAAO,KAAK,KAAK,OAAO;GAAE,GAAG,EAAE;GAAG,GAAG,EAAE;EAAE,EAAE;CACnD;CAEA,gBAAkC;EACjC,KAAK,MAAM;EACX,MAAM,SAAS,IAAI,iBAAiB;EACpC,MAAM,aAAa,OAAO,YAAY,KAAK,OAAO;EAClD,MAAM,YAAsB,CAAC;EAC7B,MAAM,QAAkB,CAAC;EACzB,KAAK,MAAM,aAAa,YAAY;GACnC,MAAM,SAAS,UAAU,SAAS,SAAS,YAAY,UAAU,SAAS,UAAU,QAAQ;GAC5F,IAAI,CAAC,QAAQ;GACb,KAAK,MAAM,KAAK,UAAU,UAAU,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;EACjE;EACA,OAAO,QAAQ;EACf,OAAO;GAAE,WAAW,IAAI,aAAa,SAAS;GAAG,OAAO,IAAI,aAAa,KAAK;EAAE;CACjF;CAEA,UAAgB;EACf,KAAK,MAAM,QAAQ;EACnB,KAAK,MAAM,QAAQ;EACnB,KAAK,UAAU,QAAQ;EACvB,KAAK,QAAQ,QAAQ;EACrB,KAAK,OAAO,MAAM;EAClB,KAAK,UAAU,MAAM;CACtB;AACD;;;;;;;;;;;;;;;;;;;;;AClzBA,IAAa,gBAAgB,gBAAiD,sBAAsB,EAAE,gBAAgB,CAAC,GAAG,CAAC;;;;;;AAoB3H,IAAa,YAAb,MAAa,UAAU;CAGe;CAFrC;CAEA,YAAoB,OAA2C;EAA1B,KAAA,QAAA;CAA2B;;CAGhE,aAAa,OAAO,SAAkB,OAA0B,UAAmC,CAAC,GAAuB;EAC1H,MAAM,wBAAQ,IAAI,IAAkB;EACpC,IAAI;GACH,KAAK,MAAM,QAAQ,OAAO;IACzB,MAAM,aAAa,MAAM,iBAAiB,OAAO,SAAS,OAAO;IAGjE,WAAW,cAAc,IAAI;IAC7B,MAAM,IAAI,MAAM;KAAE;KAAY,uBAAO,IAAI,IAAI;KAAG,sBAAM,IAAI,IAAI;KAAG,SAAS;KAAG,OAAO;IAAM,CAAC;GAC5F;EACD,SAAS,OAAO;GACf,KAAK,MAAM,QAAQ,MAAM,OAAO,GAAG,KAAK,WAAW,QAAQ;GAC3D,MAAM;EACP;EACA,OAAO,IAAI,UAAU,KAAK;CAC3B;;;;;CAMA,OAAO,OAAoB;EAC1B,KAAK,OAAO;EACZ,KAAK,MAAM,UAAU,MAAM,SAAS,OAAO,GAAG,KAAK,IAAI,OAAO,MAAM;EACpE,MAAM,OAAO;GACZ,MAAM,OAAO,GAAG,gBAAgB,WAAW,KAAK,IAAI,OAAO,MAAM,CAAC;GAClE,MAAM,OAAO,GAAG,aAAa,EAAE,aAAa,KAAK,KAAK,MAAM,CAAC;GAC7D,MAAM,OAAO,GAAG,gBAAgB,WAAW,KAAK,KAAK,MAAM,CAAC;EAC7D;EACA,KAAK,aAAa,KAAK,SAAS,QAAQ,IAAI,CAAC;CAC9C;;CAGA,OAAe,OAAc,MAAc,OAA0B;EACpE,MAAM,SAAS,MAAM,QAAQ,IAAI,KAAK;EACtC,IAAI,CAAC,QAAQ,OAAO;EACpB,IAAI,OAAO,WAAW,OAAO,UAAU,OAAO,SAAS,MAAM,OAAO;EACpE,KAAK,MAAM,SAAS,MAAM,QAAQ,OAAO,GAAG,IAAI,MAAM,SAAS,MAAM,OAAO,MAAM,UAAU,MAAM,IAAI,KAAK;EAC3G,OAAO;CACR;;CAGA,IAAY,OAAc,QAAsB;EAC/C,IAAI,CAAC,OAAO,eAAe,CAAC,OAAO,SAAS,CAAC,OAAO,MAAM;EAC1D,KAAK,MAAM,QAAQ,KAAK,MAAM,KAAK,GAAG,IAAI,KAAK,OAAO,OAAO,MAAM,OAAO,KAAK,GAAG,KAAK,MAAM,MAAM,OAAO,IAAI,OAAO,IAAI;CAC1H;;CAGA,KAAa,QAAsB;EAClC,IAAI,CAAC,OAAO,aAAa;EACzB,KAAK,MAAM,CAAC,MAAM,SAAS,KAAK,OAAO,IAAI,KAAK,MAAM,IAAI,OAAO,EAAE,KAAK,CAAC,KAAK,KAAK,IAAI,OAAO,EAAE,GAAG,KAAK,OAAO,MAAM,OAAO,EAAE;CAC/H;;CAGA,IAAI,MAAuB;EAC1B,OAAO,KAAK,MAAM,IAAI,IAAI;CAC3B;;CAGA,QAAQ,MAAsB;EAC7B,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,EAAE,WAAW;CACzC;CAEA,MAAM,MAAc,IAAqB;EACxC,OAAO,CAAC,CAAC,KAAK,MAAM,IAAI,IAAI,CAAC,EAAE,MAAM,IAAI,EAAE;CAC5C;;CAGA,MAAM,MAAyC;EAC9C,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,EAAE,yBAAS,IAAI,IAAI;CAC/C;;CAGA,MAAM,MAAc,IAAY,MAAY,OAAO,OAAa;EAC/D,MAAM,OAAO,KAAK,MAAM,IAAI,IAAI;EAChC,IAAI,CAAC,QAAQ,KAAK,MAAM,IAAI,EAAE,GAAG;EACjC,MAAM,OAAO;GAAE,GAAG,KAAK;GAAG,GAAG,KAAK;GAAG,IAAI,KAAK;GAAI,IAAI,KAAK;EAAG;EAC9D,KAAK,MAAM,IAAI,IAAI,IAAI;EACvB,IAAI,MAAM,KAAK,KAAK,IAAI,IAAI,IAAI;EAChC,KAAK,WAAW,YAAY,IAAI,IAAI;EACpC,KAAK;EACL,KAAK,QAAQ;CACd;;CAGA,OAAO,MAAc,IAAkB;EACtC,MAAM,OAAO,KAAK,MAAM,IAAI,IAAI;EAChC,IAAI,CAAC,MAAM,MAAM,OAAO,EAAE,GAAG;EAC7B,KAAK,KAAK,OAAO,EAAE;EACnB,KAAK,WAAW,eAAe,EAAE;EACjC,KAAK;EACL,KAAK,QAAQ;CACd;;CAGA,SAAe;EACd,KAAK,MAAM,QAAQ,KAAK,MAAM,OAAO,GAAG;GACvC,IAAI,CAAC,KAAK,OAAO;GACjB,KAAK,WAAW,OAAO,KAAK,WAAW,OAAO;GAC9C,KAAK,QAAQ;EACd;CACD;;CAGA,MAAM,MAAc,MAAY,IAAyB;EACxD,MAAM,OAAO,KAAK,MAAM,IAAI,IAAI;EAChC,IAAI,CAAC,MAAM,OAAO;EAClB,IAAI,KAAK,OAAO,KAAK,OAAO;EAC5B,OAAO,KAAK,WAAW,SAAS,MAAM,EAAE;CACzC;;CAGA,OAAwC;EACvC,MAAM,QAAyC,CAAC;EAChD,KAAK,MAAM,CAAC,MAAM,SAAS,KAAK,OAAO,MAAM,QAAQ,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,UAAU;GAAC;GAAI,KAAK;GAAG,KAAK;GAAG,KAAK;GAAI,KAAK;EAAE,CAAC;EAC9H,OAAO;CACR;;CAGA,QAAQ,OAAc,OAA8C;EACnE,KAAK,OAAO,KAAK;EACjB,KAAK,MAAM,CAAC,MAAM,cAAc,OAAO,QAAQ,KAAK,GACnD,KAAK,MAAM,CAAC,IAAI,GAAG,GAAG,IAAI,OAAO,WAAW,KAAK,MAAM,OAAO,IAAI,GAAG,IAAI;GAAE;GAAG;GAAG;GAAI;EAAG,GAAG,IAAI;EAEhG,KAAK,OAAO;CACb;;CAGA,CAAC,UAAU,OAAc,MAAiC;EACzD,KAAK,MAAM,SAAS,MAAM,QAAQ,OAAO,GAAG;GAC3C,IAAI,KAAK,OAAO,OAAO,MAAM,MAAM,EAAE,GAAG;GACxC,KAAK,MAAM,UAAU,MAAM,MAAM,QAAQ,MAAM,EAAE,GAAG,IAAI,OAAO,eAAe,OAAO,SAAS,OAAO,MAAM,MAAM;EAClH;CACD;;CAGA,KAAK,MAAyC;EAC7C,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,EAAE,wBAAQ,IAAI,IAAI;CAC9C;;CAGA,cAAc,OAAgC;EAC7C,KAAK,MAAM,QAAQ,KAAK,MAAM,OAAO,GAAG,KAAK,WAAW,cAAc,KAAK;CAC5E;;CAGA,UAAgB;EACf,KAAK,MAAM,QAAQ,KAAK,MAAM,OAAO,GAAG,KAAK,WAAW,UAAU;CACnE;CAEA,UAAgB;EACf,KAAK,OAAO;EACZ,KAAK,MAAM,QAAQ,KAAK,MAAM,OAAO,GAAG,KAAK,WAAW,QAAQ;EAChE,KAAK,MAAM,MAAM;CAClB;AACD;;AAGA,SAAS,QAAQ,OAAc,MAAc,MAAqB;CACjE,MAAM,KAAK,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE;CACtC,MAAM,KAAK,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE,IAAI;CACzC,MAAM,KAAK,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE;CACtC,MAAM,KAAK,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE,IAAI;CACzC,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI,UAAU,MAAM,IAAI,IAAK,IAAI,EAAG,GAAG,OAAO;CACtH,OAAO;AACR;;;;;;AAOA,IAAa,sBAA8B;CAC1C,MAAM;CACN,OAAO;CACP,OAAO;CACP,OAAO,OAAO;EACb,MAAM,QAAQ,MAAM;EACpB,IAAI,CAAC,OAAO;EACZ,IAAI,UAAU;EACd,MAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,MAAM,QAAQ,OAAO,CAAC,CAAC,CAAC,KAAK,WAAW,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,SAAS,MAAM,IAAI,IAAI,CAAC;EACrH,KAAK,MAAM,QAAQ,OAAO;GACzB,KAAK,MAAM,UAAU,MAAM,UAAU,OAAO,IAAI,GAAG;IAClD,IAAI,MAAM,MAAM,MAAM,OAAO,EAAE,KAAK,CAAC,QAAQ,OAAO,MAAM,OAAO,IAAI,GAAG;IACxE,MAAM,MAAM,MAAM,OAAO,IAAI,OAAO,MAAM,IAAI;IAC9C,UAAU;GACX;GACA,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG;IAC/C,MAAM,SAAS,MAAM,SAAS,IAAI,EAAE;IACpC,IAAK,QAAQ,SAAS,OAAO,QAAS,CAAC,QAAQ,OAAO,MAAM,IAAI,GAAG;IACnE,MAAM,OAAO,MAAM,EAAE;IACrB,UAAU;GACX;EACD;EACA,IAAI,CAAC,SAAS;EACd,MAAM,OAAO;EACb,MAAM,SAAS,eAAe,MAAM,KAAK,CAAC;CAC3C;AACD;;;;;;;;;ACjKA,IAAa,cAAc;;;;;;;;AAoC3B,IAAa,cAAc;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;;;;;;;;AASA,IAAa,iBAAiB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AAEA,IAAM,eAAe,IAAI,IAAY,WAAW;;;;;;AA2BhD,SAAgB,UAAU,OAAc,UAA4B,CAAC,GAAc;CAClF,MAAM,2BAAW,IAAI,IAAsB;CAC3C,MAAM,OAAO,WAAmB;EAC/B,IAAI,MAAM,SAAS,IAAI,OAAO,EAAE,MAAM,QAAQ,SAAS,IAAI,OAAO,IAAI,MAAM;EAC5E,OAAO,OAAO;CACf;CACA,MAAM,4BAAY,IAAI,IAA2B;CACjD,MAAM,cAA4B,CAAC;CACnC,MAAM,EAAE,YAAY;CAEpB,MAAM,OAAkB;EACvB,QAAA;EACA,MAAM,MAAM,SAAS;EACrB,SAAS,MAAM,SAAS;EACxB,MAAM,MAAM,SAAS;EACrB,UAAU,MAAM;EAChB,MAAM,MAAM;EACZ,QAAQ,MAAM;EACd,GAAI,MAAM,SAAS,OAAO,KAAK,EAAE,UAAU,CAAC,GAAG,MAAM,SAAS,OAAO,CAAC,EAAE;EACxE,GAAI,MAAM,WAAW,EAAE,SAAS,gBAAgB,MAAM,OAAO,EAAE;EAC/D,KAAK,MAAM,IAAI,KAAK;EACpB,WAAW,MAAM,MAAM,UAAU,GAAG,UAAU;EAC9C,QAAQ,EAAE,GAAG,MAAM,OAAO;EAC1B,GAAI,MAAM,YAAY,OAAO,KAAK,EAAE,aAAa,CAAC,GAAG,MAAM,WAAW,EAAE;EACxE,SAAS,YAAY,SAAS,MAAM,QAAQ,MAAM,SAAS,QAAQ,MAAM,MAAM,SAAS,UAAU,CAAC,CAAC;EACpG,SAAS,CAAC,GAAG,MAAM,QAAQ,OAAO,CAAC,CAAC,CAAC,KAAK,YAAY;GACrD,MAAM;IACL,IAAI,OAAO;IACX,MAAM,OAAO;IACb,MAAM,OAAO;IACb,OAAO,CAAC,GAAG,OAAO,KAAK;IACvB,SAAS,OAAO;IAChB,QAAQ,OAAO;IACf,GAAI,OAAO,SAAS,KAAA,KAAa,EAAE,MAAM,OAAO,KAAK;GACtD;GACA,WAAW,EAAE,GAAG,OAAO,UAAU;GACjC,YAAY,OAAO;GACnB,WAAW,OAAO;GAClB,GAAI,OAAO,KAAK,OAAO,QAAQ,CAAC,CAAC,SAAS,KAAK,EAAE,UAAU,gBAAgB,OAAO,QAAQ,EAAE;GAC5F,aAAa,OAAO;GACpB,UAAU,OAAO;GACjB,UAAU,CAAC,GAAG,OAAO,QAAQ;GAC7B,iBAAiB,OAAO;GACxB,aAAa,CAAC,GAAG,OAAO,WAAW;GACnC,OAAO,MAAM,OAAO,OAAO,QAAQ,mBAAmB,OAAO,IAAI;EAClE,EAAE;EACF,KAAK,MAAM,IAAI,KAAK;EACpB,YAAY,MAAM,IAAI;EACtB,UAAU,CAAC,GAAG,MAAM,SAAS,OAAO,CAAC,CAAC,CAAC,KAAK,WAAW,WAAW,OAAO,MAAM,CAAC;EAChF,UAAU,CAAC;EACX,QAAQ,CAAC,GAAG,MAAM,OAAO,KAAK,CAAC;EAC/B,gBAAgB,OAAO,YAAY,CAAC,GAAG,MAAM,cAAc,CAAC,CAAC,KAAK,CAAC,MAAM,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,KAAK,WAAW,OAAO,EAAE,CAAC,CAAC,CAAC;EACtI,aAAa,MAAM,MAAM,aAAa,aAAa;EACnD,UAAU,MAAM,SAAS,KAAK,YAAY;GACzC,IAAI,QAAQ,UAAU,IAAI,QAAQ,GAAG;GACrC,IAAI,UAAU,KAAA,GAAW;IACxB,UAAU,IAAI,QAAQ,KAAM,QAAQ,YAAY,MAAO;IACvD,YAAY,KAAK,CAAC,GAAG,QAAQ,GAAG,CAAC;GAClC;GACA,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS;GACpC,OAAO;IACN,GAAI,MAAM,MAAM,WAAW,QAAQ,IAAI;IACvC,KAAK;IACL,QAAQ,UAAU,MAAM,UAAU,QAAQ,SAAS,MAAM;GAC1D;EACD,CAAC;EACD;EACA,SAAS,MAAM,QAAQ,KAAK,YAAY;GACvC,MAAM,EAAE,QAAQ,SAAS,SAAS,GAAG,SAAS;GAC9C,OAAO;IACN,GAAI,MAAM,MAAM,SAAS;IACzB,QAAQ,IAAI,MAAM;IAClB,SAAS,QAAQ;IACjB,SAAS,UAAU,MAAM,UAAU,QAAQ,IAAI,OAAO;GACvD;EACD,CAAC;EACD,OAAO,MAAM,MAAM,KAAK,SAAS;GAChC,MAAM,EAAE,QAAQ,SAAS,QAAQ,GAAG,SAAS;GAC7C,OAAO;IACN,GAAI,MAAM,MAAM,QAAQ,KAAK,IAAI;IACjC,QAAQ,IAAI,MAAM;IAClB,SAAS,QAAQ;IACjB,QAAQ,UAAU,MAAM,UAAU,QAAQ,IAAI,MAAM;GACrD;EACD,CAAC;EACD,SAAS,MAAM,MAAM,SAAS,SAAS;EACvC,OAAO,MAAM,MAAM,OAAO,OAAO;EACjC,OAAO,MAAM,MAAM,OAAO,QAAQ,OAAO;CAC1C;CACA,MAAM,UAAmC,CAAC;CAC1C,KAAK,MAAM,UAAU,MAAM,SAAS,IAAI,OAAO,MAAM,QAAQ,OAAO,QAAQ,MAAM,OAAO,KAAK,KAAK,GAAG,UAAU,OAAO,MAAM;CAC7H,IAAI,OAAO,KAAK,OAAO,CAAC,CAAC,QAAQ,KAAK,UAAU;CAChD,KAAK,WAAW,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC,CAAC,KAAK,WAAW,WAAW,OAAO,MAAM,CAAC;CAChF,IAAI,QAAQ,WAAW,OAAO;EAI7B,MAAM,IAAI,OAAO,KAAK,UAAU;EAChC,MAAM,IAAI,OAAO,KAAK,SAAS,SAAS,UAAW,MAAM,QAAQ,CAAC,CAAC,MAAM,IAAI,MAAM,KAAK,CAAU,IAAI,CAAC,CAAE,CAAC;EAC1G,MAAM,IAAI,OAAO,KAAK,UAAU;EAChC,MAAM,MAAM;CACb;CACA,OAAO;AACR;AAEA,SAAS,WAAW,OAAc,QAA4B;CAC7D,MAAM,QAAQ,GAAG,OAAO,IAAI,GAAG,GAAG,OAAO;CACzC,MAAM,OAAmB;EAAE,IAAI,OAAO;EAAI,MAAM,OAAO,IAAI;EAAI,OAAO,OAAO;CAAM;CACnF,KAAK,MAAM,OAAO,aAAa;EAC9B,MAAM,QAAQ,OAAO;EACrB,IAAI,UAAU,KAAA,GAAW;EACzB,IAAI,QAAQ,cAAc,KAAK,aAAa,gBAAgB,OAAO,QAAQ,KAAK;OAC3E,KAAK,OAAO,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK;CAChD;CACA,MAAM,QAAQ,OAAO,SAAS,CAAC,OAAO,UAAU,OAAO,IAAI,MAAM,IAAI,MAAM,IAAI,UAAU,OAAO,EAAE,IAAI,KAAA;CACtG,IAAI,OAAO,KAAK,QAAQ;CACxB,OAAO;AACR;;AAGA,SAAS,gBAAgB,OAAc,QAAgB,OAAwC;CAC9F,MAAM,QAAiC,CAAC;CACxC,KAAK,MAAM,QAAQ,OAAO,eAAe,GAAG;EAC3C,MAAM,EAAE,OAAO;EACf,MAAM,QAAQ,OAAO,IAAI,IAAI;EAC7B,MAAM,YAAY,MAAM,SAAS,UAAU,EAAE;EAC7C,MAAM,MAAM,WAAW,OACpB,MAAM,UAAU,KAAK,OAAgB,KAAK,GAAG,GAAG,MAAM,cAAc,IAAI,IACxE,MAAM,OAAO,GAAG,MAAM,cAAc,IAAI;CAC5C;CACA,OAAO;AACR;;;;;AAMA,IAAM,SAAS,OAAgB,UAA2BC,QAAU,OAAO,OAAO,QAAQ,0CAA0C;;AAKpI,IAAa,gBAAgB,SAAkC,KAAK,QAAQ,KAAK,YAAY;CAAE,GAAG,OAAO;CAAM,WAAW,EAAE,GAAG,OAAO,UAAU;AAAE,EAAE;;;;;AAMpJ,SAAgB,aAAa,OAAc,MAAuB;CACjE,IAAI,KAAK,WAAA,GAAwB,MAAM,IAAI,UAAU,gBAAgB,KAAK,OAAO,8BAA8B,UAAU;CACzH,IAAI,KAAK,aAAa,MAAM,UAAU,MAAM,IAAI,MAAM,iBAAiB,KAAK,SAAS,qCAAqC,MAAM,UAAU;CAC1I,MAAM,EAAE,aAAa;CACrB,MAAM,OAAO,KAAK;CAClB,MAAM,SAAS,KAAK;CACpB,MAAM,IAAI,QAAQ,KAAK,GAAG;CAC1B,MAAM,iBAAiB,KAAK,SAAS;CAErC,qBAAqB,UAAU,KAAK,MAAM,cAAc,GAAG;CAC3D,OAAO,OAAO,MAAM,QAAQ,KAAK,MAAM;CACvC,KAAK,MAAM,CAAC,QAAQ,WAAW,KAAK,eAAe,CAAC,GAAG,MAAM,YAAY,IAAI,QAAQ,MAAM;CAE3F,KAAK,MAAM,SAAS,KAAK,SAAS;EACjC,MAAM,SAAS,MAAM,OAAO,MAAM,KAAK,EAAE;EACzC,OAAO,OAAO,OAAO,WAAW,MAAM,SAAS;EAC/C,OAAO,aAAa,MAAM;EAC1B,OAAO,YAAY,MAAM;EACzB,IAAI,MAAM,UAAU,OAAO,WAAW,gBAAgB,MAAM,QAAQ;EACpE,OAAO,cAAc,MAAM;EAC3B,OAAO,WAAW,MAAM;EACxB,KAAK,MAAM,CAAC,SAAS,UAAU,MAAM,UAAU,OAAO,WAAW,SAAS,KAAK;EAC/E,OAAO,kBAAkB,MAAM;EAC/B,KAAK,MAAM,WAAW,MAAM,aAAa,OAAO,YAAY,IAAI,OAAO;EACvE,OAAO,OAAO,OAAO,OAAO,QAAQ,gBAAgB,MAAM,KAAK,CAAC;CACjE;CACA,MAAM,IAAI,QAAQ,KAAK,GAAG;CAE1B,MAAM,WAAW,IAAI,IAAI,KAAK,SAAS,KAAK,UAAU,CAAC,MAAM,IAAI,WAAW,UAAU,KAAK,CAAC,CAAC,CAAC;CAE9F,MAAM,IAAI,gBAAgB,IAAI;CAC9B,KAAK,MAAM,SAAS,KAAK,UAAU;EAClC,MAAM,SAAS,WAAW,UAAU,KAAK;EACzC,MAAM,SAAS,IAAI,OAAO,IAAI,MAAM;EACpC,MAAM,MAAM,IAAI,MAAM;EAEtB,IAAI,OAAO,eAAe,OAAO,OAAO;GACvC,MAAM,QAAQ,aAAa,MAAM;GACjC,IAAI,OAAO,MAAM;IAEhB,MAAM,KAAK,YAAY,OAAO,GAAG;IACjC,MAAM,KAAK,OAAO,OAAO,KAAK,GAAG,OAAO,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,OAAO,EAAE;IACrE,IAAI,CAAC,SAAS,WAAW,MAAM,KAAK,CAAC,MAAM,IAAI,YAAY,OAAO,IAAI,OAAO,IAAI,GAChF,MAAM,IAAI,KAAK,cAAc,0CAA0C,OAAO,IAAI,GAAG,0BAA0B,EAAE,QAAQ,OAAO,GAAG,CAAC;GACtI;EACD;CACD;CACA,MAAM,IAAI,gBAAgB,KAAK;CAC/B,MAAM,YAAY,KAAK,UAAU,QAAQ,CAAC,CAAC;CAG3C,MAAM,IAAI,OAAO,KAAK,UAAU;CAChC,KAAK,MAAM,SAAS,KAAK,UAAU,IAAI,MAAM,OAAO,MAAM,IAAI,aAAa,MAAM,IAAI,MAAM,KAAK;CAChG,MAAM,IAAI,OAAO,KAAK,UAAU;CAChC,KAAK,MAAM,MAAM,KAAK,QAAQ,MAAM,OAAO,IAAI,IAAI,MAAM,SAAS,IAAI,EAAE,KAAK,KAAK,SAAS,GAAG,oBAAoB,CAAC;CACnH,KAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,KAAK,cAAc,GAC3D,MAAM,eAAe,IAAI,OAAO,IAAI,GAAG,IAAI,IAAI,IAAI,KAAK,OAAO,MAAM,SAAS,IAAI,EAAE,KAAK,KAAK,WAAW,GAAG,oBAAoB,CAAC,CAAC,CAAC;CAGpI,MAAM,UAAU,OAAiB,MAAM,SAAS,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,KAAK,UAAU,GAAG,oBAAoB;CACrH,MAAM,WAAW,OAA2B,SAAS,QAAQ,EAAE;CAC/D,MAAM,YAAY,KAAK,GAAI,gBAAgB,KAAK,WAAW,CAAkB;CAC7E,MAAM,OAAO,KAAK,YAAY,KAAK,QAAQ,IAAI,IAAI,GAAG,CAAC;CACvD,KAAK,MAAM,WAAW,KAAK,UAC1B,MAAM,SAAS,KAAK;EAAE,GAAG,gBAAgB,OAAO;EAAG,KAAK,KAAK,QAAQ;EAAM,QAAQ,cAAc,UAAU,QAAQ,SAAS,QAAQ,MAAM;CAAE,CAAC;CAE9I,KAAK,MAAM,WAAW,KAAK,SAAS;EACnC,MAAM,EAAE,QAAQ,SAAS,IAAI,SAAS,GAAG,SAAS,gBAAgB,OAAO;EACzE,MAAM,QAAQ,KAAK;GAAE,GAAG;GAAM,QAAQ,OAAO,MAAM;GAAG,SAAS,QAAQ,EAAE;GAAG,SAAS,cAAc,UAAU,IAAI,OAAO;EAAE,CAAC;CAC5H;CACA,KAAK,MAAM,QAAQ,KAAK,OAAO;EAC9B,MAAM,EAAE,QAAQ,SAAS,IAAI,QAAQ,GAAG,SAAS,gBAAgB,IAAI;EACrE,MAAM,MAAM,KAAK;GAAE,GAAG;GAAM,QAAQ,OAAO,MAAM;GAAG,SAAS,QAAQ,EAAE;GAAG,QAAQ,cAAc,UAAU,IAAI,MAAM;EAAE,CAAC;CACxH;CACA,MAAM,QAAQ,KAAK,GAAI,gBAAgB,KAAK,OAAO,CAAc;CACjE,OAAO,OAAO,MAAM,OAAO,QAAQ,gBAAgB,KAAK,KAAK,CAAC;CAG9D,MAAM,WAAW,QAAQ,OAAO,MAAM,OAAO,IAAI,aAAa,IAAI,MAAM,MAAM,aAAa,IAAI,CAAC,CAAC;CACjG,MAAM,MAAM,KAAK,GAAI,gBAAgB,KAAK,KAAK,CAAkB;CAGjE,MAAM,eAAe,KAAK,WAAW,CAAC,CAAC;CACvC,IAAI,KAAK,UAAU,MAAM,QAAQ,KAAK,QAAQ;CAC9C,IAAI,KAAK,SAAS,MAAM,UAAU,gBAAgB,KAAK,OAAO;AAC/D;AAEA,SAAS,WAAW,UAAoB,OAA2B;CAClE,MAAM,EAAE,IAAI,MAAM,OAAO,OAAO,GAAG,KAAK,GAAG,WAAW,gBAAgB,KAAK;CAC3E,MAAM,SAAS,IAAI,OAAO,IAAI,SAAS,KAAK,IAAI,GAAG,OAAO,GAAoB;CAC9E,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GACnC,IAAI,CAAC,aAAa,IAAI,GAAG,GAAG,KAAK,GAAG,KAAK,GAAG,GAAG,QAAQ,IAAI,kDAAkD;CAC9G,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAC/C,IAAI,QAAQ,cACX,KAAK,MAAM,CAAC,aAAa,UAAU,OAAO,QAAQ,OAAO,UAAqC,GAAG;EAEhG,MAAM,YAAY,SAAS,UAAU,WAAW;EAChD,OAAO,IAAI,WAAW,UAAU,OAAO,UAAU,KAAK,OAAO,QAAQ,IAAI,KAAK;CAC/E;MACM,OAAO,QAAQ,KAAK,KAAK;CAEjC,OAAO;AACR;AAEA,SAAS,KAAK,MAAqB;CAClC,MAAM,IAAI,MAAM,SAAS,MAAM;AAChC;;;;;;AAoEA,IAAa,YAAb,cAA+B,MAAM;CAG1B;CAEA;CAJV,YACC,SACA,QAEA,SACC;EACD,MAAM,OAAO;EAJJ,KAAA,SAAA;EAEA,KAAA,UAAA;EAGT,KAAK,OAAO;CACb;AACD;;;;;;AAoBA,IAAa,cAAc,UAAkC;CAAE,QAAQ,KAAK;CAAQ,MAAM,KAAK;CAAM,SAAS,KAAK,WAAW;CAAG,MAAM,KAAK;AAAK;AAEjJ,IAAM,WAAW,UAAoC,OAAO,UAAU,YAAY,OAAO,UAAU,KAAK,KAAK,SAAS;;AAGtH,IAAM,kBAAkB,aAAuB,SAAS,QAAQ,OAAO,eAAe,SAAS,QAAQ,QAAQ,SAAS;AAExH,SAAS,WAAW,QAAoB,UAA+B;CACtE,OAAO,IAAI,UACV,uCAAuC,SAAS,KAAK,KAAK,OAAO,KAAK,YAAY,SAAS,KAAK,2CAC9F,SAAS,QAAQ,QAAQ,KAAK,kEAChC,OACD;AACD;;AAGA,SAAS,cAAc,QAAoB,UAA2C;CACrF,MAAM,EAAE,WAAW;CACnB,MAAM,UAAU,OAAO,WAAW;CAClC,IAAI,CAAC,QAAQ,MAAM,GAAG,OAAO,IAAI,UAAU,gBAAgB,OAAO,MAAM,EAAE,8BAA8B,UAAU;CAClH,IAAI,CAAC,QAAQ,OAAO,GAAG,OAAO,IAAI,UAAU,iBAAiB,OAAO,OAAO,EAAE,8BAA8B,UAAU;CACrH,IAAI,OAAO,SAAS,SAAS,MAAM,OAAO,IAAI,UAAU,6BAA6B,OAAO,KAAK,UAAU,SAAS,KAAK,IAAI,MAAM;CACnI,IAAI,SAAA,GACH,OAAO,IAAI,UACV,gBAAgB,OAAO,kFACvB,OACD;CAGD,IAAI,SAAA,GAAsB,OAAO,IAAI,UAAU,gBAAgB,OAAO,qCAAkD,OAAO;CAC/H,MAAM,KAAK,SAAS;CACpB,IAAI,UAAU,IACb,OAAO,IAAI,UACV,iBAAiB,QAAQ,oBAAoB,SAAS,KAAK,mCAAmC,GAAG,iDACjG,OACD;CAED,MAAM,UAAU,SAAS,QAAQ,OAAO;CACxC,IAAI,OAAO,YAAY,YAAY,OAAO,KAAA;CAC1C,KAAK,IAAI,OAAO,SAAS,OAAO,IAAI,QACnC,IAAI,CAAC,UAAU,OACd,OAAO,IAAI,UACV,iBAAiB,QAAQ,oBAAoB,SAAS,KAAK,kCAAkC,KAAK,MAAM,OAAO,EAAE,8BACjH,OACD;AAIH;;;;;;;;AASA,SAAgB,YAAY,QAAoB,UAA2C;CAC1F,MAAM,UAAU,cAAc,QAAQ,QAAQ;CAC9C,IAAI,SAAS,OAAO;CAEpB,KADqB,OAAO,WAAW,OAAO,SAAS,eACpC,OAAO,SAAS,SAAS,QAAQ,eAAe,QAAQ,MAAM,UAAU,OAAO,WAAW,QAAQ,QAAQ;AAE9H;;;;;;;;;;AAWA,SAAgB,WAAW,MAAe,UAAoB,UAAoC,CAAC,GAAc;CAChH,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM,MAAM,IAAI,UAAU,oBAAoB,UAAU;CACjG,MAAM,SAAS;CACf,MAAM,UAAU,cAAc,QAAQ,QAAQ;CAC9C,IAAI,SAAS,MAAM;CACnB,MAAM,OAAO,OAAO,WAAW;CAC/B,MAAM,KAAK,SAAS;CACpB,IAAI,OAAO;CACX,IAAI,OAAO,IAAI;EAEd,OAAO,gBAAgB,IAAI;EAC3B,MAAM,UAAU,SAAS,QAAQ,OAAO;EACxC,IAAI,OAAO,YAAY,YAClB;OAAA,OAAO,IAAI,OAAO,QAAQ,MAAM,MAAM,EAAE,KAAK;EAAA,OAEjD,KAAK,IAAI,UAAU,MAAM,UAAU,IAAI,WAAW,OAAO,QAAS,QAAQ,CAAC,IAAI,KAAK;CAEtF;CAEA,IAAI,SAAS,MAAM,OAAO,SAAS,SAAS,QAAQ,CAAC,QAAQ,YAAY;EACxE,MAAM,SAAS,eAAe,QAAQ;EACtC,KAAK,OAAO,WAAW,aAAa,OAAO,MAAM,SAAS,IAAI,IAAI,YAAY,UAAU,MAAM,WAAW,QAAQ,QAAQ;CAC1H;CACA,MAAM,UAAU,UAAU,MAAM,QAAQ;CACxC,IAAI,SAAS;EACZ,MAAM,OAAO,OAAO,QAAQ,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,SAAS,OAAO,MAAM,MAA2B,GAAG,IAAI,KAAK,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI,GAAG;EAC5I,MAAM,IAAI,UACT,sBAAsB,SAAS,KAAK,mBAAmB,KAAK,KAAK,IAAI,EAAE,8EACvE,WACA,OACD;CACD;CAEA,OAAO;EAAE,GAAG;EAAM,QAAA;EAAqB,SAAS;EAAI,MAAM,SAAS;CAAK;AACzE;AAEA,IAAM,QAA2C;CAChD,MAAM;CACN,SAAS;CACT,MAAM;CACN,MAAM;CACN,SAAS;CACT,OAAO;CACP,WAAW;CACX,OAAO;CACP,UAAU;AACX;;;;;AAMA,SAAS,UAAU,MAAiB,UAA6C;CAChF,MAAM,UAAuB,CAAC;CAC9B,MAAM,SAAS,MAAyB,SAAkC,OAAgB;EACzF,IAAI,OAAO,OAAO,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,QAAQ,UAAU,CAAC,EAAA,CAAG,KAAK,EAAE;CACvG;CAEA,MAAM,OAAQ,KAAK,MAAM,cAAc,OAAO,CAAC;CAC/C,MAAM,WAAW,UAAoB,OAAe,SAAS,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,OAAO,KAAK,KAAK,GAAG,GAAG,GAAA,cAAgB;CAC3H,MAAM,OAAO,MAAM,QAAQ,QAAQ,OAAO,CAAC;CAC3C,MAAM,UAAU,MAAM,WAAW,QAAQ,WAAW,CAAC;CACrD,MAAM,OAAO,MAAM,QAAQ,QAAQ,OAAO,CAAC;CAC3C,MAAM,OAAO,MAAM,QAAQ,QAAQ,OAAO,CAAC;CAC3C,MAAM,UAAU,MAAM,WAAW,QAAQ,UAAU,CAAC;CACpD,MAAM,QAAQ,MAAM,UAAU,OAAO,SAAS,OAAO,IAAI,EAAE,CAAC;CAE5D,MAAM,YAAY,MAAM,cAAc,OAAO,SAAS,UAAU,EAAE,MAAM,KAAA,CAAS;CAEjF,MAAM,QAAwD;EAAE,OAAO;EAAM,WAAW;EAAS,OAAO;EAAM,OAAO;EAAM,UAAU;CAAQ;CAC7I,MAAM,cAAc,WAAoB;EACvC,KAAK,MAAM,CAAC,IAAI,UAAU,OAAO,QAAS,UAAkD,CAAC,CAAC,GAAG;GAChG,UAAU,EAAE;GACZ,MAAM,OAAO,SAAS,UAAU,EAAE,CAAC,EAAE,OAAO,KAAK;GACjD,IAAI,MAAM,KAAK,MAAM,QAAQ,OAAO,KAAK,IAAI,GAA0B,KAAK,KAAK,EAAE,QAAQ,MAAM,KAAK;EACvG;CACD;CAEA,MAAM,UAAU,WAAkC,CAAC,CAAC,UAAU,UAAU;CAExE,WAAW,KAAK,KAAK;CACrB,KAAK,MAAM,UAAU,KAAK,SAAS;EAClC,WAAW,OAAO,KAAK;EACvB,KAAK,MAAM,CAAC,OAAO,OAAO,UAAU,QAAQ,EAAE;EAC9C,KAAK,MAAM,MAAM,OAAO,aAAa,QAAQ,EAAE;CAChD;CACA,KAAK,MAAM,UAAU,CAAC,GAAG,KAAK,UAAU,GAAG,KAAK,QAAQ,GAAG;EAC1D,KAAK,OAAO,IAAI;EAChB,WAAW,OAAO,UAAU;EAC5B,KAAK,MAAM,SAAU,OAAO,aAA4C,CAAC,GAAG,QAAQ,MAAM,EAAE;EAC5F,KAAK,MAAM,YAAa,OAAO,SAAwC,CAAC,GAAG,KAAK,SAAS,EAAE;EAC3F,KAAK,MAAM,SAAU,OAAO,UAAkC,CAAC,GAAG;GACjE,MAAM,MAAM,IAAI;GAChB,KAAK,MAAM,MAAM,QAAQ;EAC1B;CACD;CACA,KAAK,MAAM,WAAW,KAAK,UAAU,IAAI,OAAO,QAAQ,MAAM,GAAG,QAAQ,QAAQ,OAAO;CACxF,KAAK,MAAM,WAAW,KAAK,SAAS,QAAQ,QAAQ,OAAO;CAC3D,KAAK,MAAM,QAAQ,KAAK,OAAO,QAAQ,KAAK,OAAO;CACnD,KAAK,MAAM,WAAW,KAAK,OAAO,KAAK,QAAQ,IAAI;CACnD,MAAM,OAAO,SAAS;CACtB,IAAI,MAAM;EACT,MAAM,SAAS,IAAI,IAAI,CAAC,GAAG,YAAY,GAAI,SAAS,UAAU,UAAU,KAAK,UAAU,CAAC,CAAE,CAAC,CAAC,KAAK,QAAQ,IAAI,EAAE,CAAC;EAChH,MAAM,YAAY,IAAI,KAAK,KAAK,aAAa,CAAC,EAAA,CAAG,KAAK,QAAQ,IAAI,EAAE,CAAC;EACrE,cAAc,KAAK,KAAK,CAAC,CAAC,QAAQ,MAAM,UAAU,OAAO,OAAO,IAAI,EAAE,CAAC,CAAC;EACxE,iBAAiB,KAAK,KAAK,CAAC,CAAC,QAAQ,MAAM,aAAa,OAAO,UAAU,IAAI,EAAE,CAAC,CAAC;CAClF;CACA,OAAO,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,IAAI,UAAU,KAAA;AACpD;;;;;;;AAUA,SAAgB,WAAW,MAAyB;CACnD,OAAO,KAAK,UAAU,OAAO,MAAM,UAAW,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,IAAI,EAAE,SAAS,OAAO,KAAK,EAAE,IAAI,KAAM;AACzI;;AAGA,SAAgB,WAAW,MAAyB;CACnD,OAAO,KAAK,MAAM,OAAO,MAAM,UAC9B,SAAS,OAAO,UAAU,YAAY,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,KAAK,OAAO,MAAM,YAAY,WAAW,OAAO,MAAM,OAAO,IAAI,KACtI;AACD;;;;;;;;AC/uBA,IAAM,eAAe;AACrB,IAAa,YAAY,gBAA2D,kBAAkB,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC;;AAExI,IAAa,SAAS,gBAAqD,eAAe,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC;;AAE5H,IAAa,UAAU,gBAAuD,gBAAgB,EAAE,gBAAgB,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC;AAClI,IAAM,OAA0B,CAAC;;;;;;AAOjC,IAAa,QAAb,MAAmB;CACW;CAA7B,YAAY,OAA+B;EAAd,KAAA,QAAA;CAAe;;CAG5C,aAAa,MAAuB;EACnC,KAAK,MAAM,UAAU,KAAK,MAAM,QAAQ,OAAO,GAAG,IAAI,OAAO,SAAS,QAAQ,CAAC,OAAO,WAAW,CAAC,OAAO,UAAU,OAAO;EAC1H,OAAO;CACR;;CAGA,QAAQ,GAAa,GAAsB;EAC1C,IAAI,MAAM,GAAG,OAAO;EACpB,MAAM,MAAM,KAAK,WAAW,GAAG,CAAC;EAChC,IAAI,KAAK,OAAO,QAAQ;EACxB,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC;EAC9B,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC;EAC9B,OAAO,CAAC,GAAG,WAAW,CAAC,GAAG,WAAW,GAAG,SAAS,GAAG;CACrD;;;;;;CAOA,YAAY,GAAa,GAAa,UAAuC;EAC5E,IAAI,MAAM,GAAG;EACb,MAAM,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,IAAI,eAAe;EAC9D,MAAM,EAAE,UAAU,KAAK,MAAM,MAAM,SAAS;EAC5C,IAAI,UAAU,MAAM,OAAO;OACtB,OAAO,MAAM;CACnB;;CAGA,WAAW,GAAa,GAAyC;EAEhE,MAAM,MAAM,KAAK,MAAM,OAAO,OAAO,UAAU;EAC/C,IAAI,CAAC,KAAK,OAAO,KAAA;EACjB,OAAO,IAAI,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,IAAI,eAAe;CACpE;;;;;CAMA,QAAQ,QAAkB,MAAoB;EAC7C,MAAM,QAAQ,KAAK,MAAM,OAAO,MAAM;EACtC,IAAI,MAAM,SAAS,MAAM;EACzB,MAAM,OAAO,MAAM;EACnB,KAAK,MAAM,IAAI,QAAQ,IAAI;EAC3B,MAAM,OAAO;EACb,KAAK,MAAM,OAAO,KAAK,aAAa;GAAE;GAAQ;GAAM,IAAI;EAAK,CAAC;CAC/D;;;;;CAMA,YAAY,MAAc,IAAY,SAAS,MAAY;EAC1D,MAAM,EAAE,UAAU,KAAK,MAAM,MAAM,MAAM;EACzC,MAAM,OAAQ,MAAM,UAAU,CAAC;EAC/B,MAAM,QAAQ,KAAK,QAAQ,EAAE;EAC7B,IAAI,UAAU,QAAQ,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;EACpD,IAAI,CAAC,UAAU,SAAS,GAAG,KAAK,OAAO,OAAO,CAAC;EAC/C,KAAK,MAAM,IAAI,QAAQ,EAAE;CAC1B;;CAGA,SAAS,MAAiC;EAEzC,OADY,KAAK,MAAM,OAAO,OAAO,OAAO,GACrC,EAAK,MAAM,SAAS;CAC5B;;;;;;CAOA,aAAa,OAAiB,YAAsB,SAAS,MAAY;EACxE,MAAM,EAAE,YAAY,KAAK,MAAM,MAAM,OAAO;EAC5C,MAAM,OAAQ,QAAQ,WAAW,CAAC;EAClC,MAAM,QAAQ,KAAK,QAAQ,UAAU;EACrC,IAAI,UAAU,QAAQ,KAAK,UAAU,YAAY,KAAK,KAAK,UAAU;EACrE,IAAI,CAAC,UAAU,SAAS,GAAG,KAAK,OAAO,OAAO,CAAC;CAChD;;CAGA,UAAU,OAAsC;EAE/C,OADY,KAAK,MAAM,OAAO,OAAO,QAAQ,GACtC,EAAK,QAAQ,UAAU;CAC/B;;;;;CAMA,MAAM,QAAkB,YAAsB,MAAqD;EAClG,IAAI,KAAK,YAAY,KAAA,GAAW,KAAK,aAAa,QAAQ,YAAY,KAAK,OAAO;EAClF,IAAI,KAAK,WAAW,KAAA,GAAW,KAAK,YAAY,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,OAAO,UAAU,CAAC,CAAC,MAAM,KAAK,MAAM;CAChI;;;;;CAMA,WAAW,QAAkB,QAAyB;EACrD,OAAO,KAAK,MAAM,MAAM,WAAW,KAAK,OAAO,QAAQ,MAAM;CAC9D;;CAGA,OAAO,GAAa,GAAsB;EACzC,IAAI,MAAM,GAAG,OAAO;EACpB,MAAM,MAAM,KAAK,WAAW,GAAG,CAAC;EAChC,IAAI,KAAK,OAAO,QAAQ;EACxB,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC;EAC9B,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC;EAC9B,OAAO,CAAC,GAAG,WAAW,CAAC,GAAG,WAAW,GAAG,SAAS,GAAG;CACrD;AACD;;;;;;;;;;;;;AC/HA,IAAa,SAAiC;CAAC;CAAY;CAAU;CAAQ;CAAW;AAAS;;AAGjG,IAAM,gBAA6B;;AAGnC,IAAM,YAAY;;;;;;;;AAoBlB,IAAa,YAAb,MAAuB;CACtB,QAAmC,CAAC;CACpC,UAA4B,CAAC;CAC7B,0BAA2B,IAAI,IAAoB;;CAEnD,YAAY;CAEZ,YAAY,SAAmB;EAC9B,KAAK,MAAM,UAAU,SAAS;GAC7B,KAAK,MAAM,MAAM;GACjB,KAAK,MAAM,KAAK,MAAM;EACvB;EACA,KAAK,UAAU,MAAM,KAAK,KAAK,CAAC,CAAC,QAAQ,WAAW,CAAC,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC;CAC/E;;CAGA,IAAI,UAA6B;EAChC,OAAO,KAAK;CACb;;CAGA,IAAI,QAAsB;EACzB,KAAK,MAAM,MAAM;EACjB,KAAK,MAAM,KAAK,MAAM;EACtB,KAAK,UAAU,MAAM,KAAK,KAAK,CAAC,CAAC,QAAQ,WAAW,CAAC,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC;CAC/E;;CAGA,OAAO,MAAuB;EAC7B,MAAM,QAAQ,KAAK,MAAM,WAAW,WAAW,OAAO,SAAS,IAAI;EACnE,IAAI,QAAQ,GAAG,OAAO;EACtB,KAAK,MAAM,OAAO,OAAO,CAAC;EAC1B,KAAK,UAAU,MAAM,KAAK,KAAK,CAAC,CAAC,QAAQ,WAAW,CAAC,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC;EAC9E,KAAK,QAAQ,OAAO,IAAI;EACxB,OAAO;CACR;;CAGA,IAAI,OAAoB;EACvB,MAAM,EAAE,MAAM,OAAO;EACrB,KAAK,MAAM,UAAU,KAAK,SAAS;GAClC,MAAM,QAAQ,OAAO,SAAS;GAC9B,MAAM,MAAM,UAAU,KAAK,OAAO,WAAW,OAAO,UAAU,KAAK;GACnE,IAAI,CAAC,KAAK,WAAW;IACpB,IAAI,KAAK,KAAK,OAAO,QAAQ,OAAO,KAAK,KAAK;IAC9C;GACD;GACA,MAAM,QAAQ,YAAY,IAAI;GAC9B,IAAI,KAAK,KAAK,OAAO,QAAQ,OAAO,KAAK,KAAK;GAC9C,MAAM,OAAO,MAAM,YAAY,IAAI,IAAI,QAAQ;GAC/C,MAAM,SAAS,KAAK,QAAQ,IAAI,OAAO,IAAI;GAC3C,KAAK,QAAQ,IAAI,OAAO,MAAM,WAAW,KAAA,IAAY,OAAO,UAAU,OAAO,UAAU,SAAS;EACjG;CACD;;CAGA,OAAe,QAAgB,OAAc,IAAkB;EAC9D,IAAI;GACH,OAAO,SAAS,OAAO,EAAE;GACzB,IAAI,OAAO,MAAM,QAAQ,QAAQ,OAAO,EAAE;EAC3C,SAAS,OAAO;GACf,MAAM,OAAO,OAAO;IAAE,MAAM;IAAU,IAAI,OAAO;GAAK,CAAC;GACvD,KAAK,QAAQ,OAAO,IAAI;EACzB;CACD;CAEA,sBAAuB,IAAI,IAAY;;CAGvC,QAAQ,MAAoB;EAC3B,KAAK,IAAI,IAAI,IAAI;EACjB,KAAK,UAAU,KAAK,QAAQ,QAAQ,WAAW,OAAO,SAAS,IAAI;CACpE;;CAGA,SAAyB;EACxB,OAAO,KAAK,QAAQ,SAAS,WAAW;GACvC,MAAM,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI;GACvC,OAAO,OAAO,KAAA,IAAY,CAAC,IAAI,CAAC;IAAE,MAAM,OAAO;IAAM,OAAO,OAAO,SAAS;IAAe;GAAG,CAAC;EAChG,CAAC;CACF;CAEA,MAAc,QAAsB;EACnC,IAAI,KAAK,MAAM,MAAM,UAAU,MAAM,SAAS,OAAO,IAAI,GAAG,MAAM,IAAI,MAAM,6BAA6B,OAAO,KAAK,UAAU;EAC/H,IAAI,CAAC,OAAO,UAAU,CAAC,OAAO,MAAM,MAAM,IAAI,MAAM,WAAW,OAAO,KAAK,8CAA8C;EACzH,IAAI,OAAO,UAAU,KAAA,MAAc,CAAC,OAAO,UAAU,OAAO,KAAK,KAAK,OAAO,QAAQ,IACpF,MAAM,IAAI,MAAM,WAAW,OAAO,KAAK,eAAe,OAAO,MAAM,iDAAiD;CACtH;AACD;;AAGA,SAAS,QAAQ,QAAgB,OAAc,IAAkB;CAChE,MAAM,OAAO,OAAO;CACpB,MAAM,EAAE,SAAS;CACjB,IAAI,SAAS,KAAA,KAAa,SAAS,UAClC,KAAK,MAAM,UAAU,MAAM,OAAO,OAAO,GAAG,KAAK,KAAK,QAAQ,OAAO,QAAQ,EAAE;MACzE,IAAI,OAAO,SAAS,YACrB;OAAA,MAAM,UAAU,MAAM,OAAO,OAAO,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG,KAAK,KAAK,QAAQ,OAAO,QAAQ,EAAE;CAAA,OAExG,KAAK,MAAM,UAAU,MAAM,MAAM,QAAQ,IAAI,GAAG,KAAK,KAAK,QAAQ,OAAO,QAAQ,EAAE;AAErF;;;;;;AAeA,SAAgB,MAAyB,SAAmB;CAC3D,MAAM,WAAW,WAAc,OAAO,QAAQ,OAAO,SAAS,aAAa;CAC3E,MAAM,SAAS,IAAI,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO,MAAM,MAAM,CAAC,CAAC;CAErE,MAAM,QAAQ,IAAI,IAAe,QAAQ,KAAK,WAAW,CAAC,wBAAQ,IAAI,IAAI,CAAC,CAAC,CAAC;CAC7E,MAAM,QAAQ,OAAU,SAAY;EACnC,IAAI,QAAQ,KAAK,IAAI,QAAQ,IAAI,GAChC,MAAM,IAAI,MAAM,WAAW,MAAM,KAAK,uBAAuB,KAAK,KAAK,6BAA6B,MAAM,SAAS,cAAc,EAAE;EACpI,MAAM,IAAI,IAAI,CAAC,CAAE,IAAI,KAAK;CAC3B;CACA,KAAK,MAAM,UAAU,SAAS;EAC7B,KAAK,MAAM,QAAQ,OAAO,UAAU,CAAC,GAAG,IAAI,OAAO,IAAI,IAAI,GAAG,KAAK,QAAQ,OAAO,IAAI,IAAI,CAAE;EAC5F,KAAK,MAAM,QAAQ,OAAO,SAAS,CAAC,GAAG,IAAI,OAAO,IAAI,IAAI,GAAG,KAAK,OAAO,IAAI,IAAI,GAAI,MAAM;CAC5F;CAEA,MAAM,SAAc,CAAC;CACrB,MAAM,uBAAO,IAAI,IAAO;CAExB,MAAM,UAAU,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC;CACnE,OAAO,QAAQ,QAAQ;EACtB,MAAM,QAAQ,QAAQ,WAAW,WAAW,CAAC,GAAG,MAAM,IAAI,MAAM,CAAE,CAAC,CAAC,OAAO,UAAU,KAAK,IAAI,KAAK,CAAC,CAAC;EACrG,IAAI,QAAQ,GAAG,MAAM,IAAI,MAAM,4CAA4C,QAAQ,KAAK,WAAW,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,GAAG;EAC5H,MAAM,CAAC,QAAQ,QAAQ,OAAO,OAAO,CAAC;EACtC,KAAK,IAAI,IAAI;EACb,OAAO,KAAK,IAAI;CACjB;CACA,OAAO;AACR;;;;;;;;;;;;;ACrIA,IAAa,gBAAgB,gBAA8C,kBAAkB,EAAE,gBAAgB,CAAC,GAAG,CAAC;;;;;AAMpH,IAAa,mBAAmB,gBAAyC,yBAAyB,EAAE,gBAAgB,CAAC,GAAG,CAAC;;;;;;;;AASzH,IAAa,YAAb,MAAuB;CAIO;;CAF7B,wBAAyB,IAAI,IAA8B;CAE3D,YAAY,OAA+B;EAAd,KAAA,QAAA;CAAe;;;;;;;;;;;CAY5C,KAAuC,QAAkB,UAAuB,CAAC,GAAsB;EACtG,MAAM,EAAE,OAAO,QAAQ,GAAG,UAAU;EAEpC,MAAM,UAAqB;GAAE,GAAG,KAAK;GAAU,GAAG;EAAM;EAExD,MAAM,QAAQ,UAAU,KAAK,SAAS,MAAM;EAC5C,MAAM,MAAM,OAAO,UAAU,WAAW,KAAK,MAAM,KAAK,IAAI;EAC5D,IAAI,OAAO,UAAU,YAAY,CAAC,KAAK,MAAM,IAAI,MAAM,uBAAuB,MAAM,0DAA0D;EAC9I,IAAI,KAAK,MAAM,IAAI,MAAM,GAAG,KAAK,OAAO,MAAM;EAC9C,MAAM,SAAS,KAAK,OAAO,QAAQ,KAAK,OAAO;EAC/C,KAAK,MAAM,UAAU,MAAM;EAC3B,KAAK,MAAM,IAAI,QAAQ,MAAM;EAC7B,KAAK,MAAM,SAAS,eAAe;GAClC,GAAG,KAAK,MAAM,MAAM,aAAa;IAChC,SAAS;IAAE,GAAI,OAAO,EAAE,OAAO,IAAI,GAAG;IAAI,SAAS,OAAO,SAAS,KAAK,OAAO,MAAM;GAAE;EACzF,CAAC;EACD,OAAO;CACR;;;;;;;CAQA,IAAI,WAAoE;EACvE,OAAO,KAAK,MAAM,OAAO,IAAI,gBAAgB,IAAK,KAAK,MAAM,MAAM,gBAAgB,IAAsD,CAAC;CAC3I;CAEA,IAAI,SAAS,UAAyD;EACrE,KAAK,MAAM,SAAS,kBAAkB,EAAE,GAAG,SAAS,CAAC;CACtD;;CAGA,OAAO,QAA2B;EACjC,MAAM,SAAS,KAAK,MAAM,IAAI,MAAM;EACpC,IAAI,KAAK,MAAM,OAAO,IAAI,aAAa,KAAK,UAAU,KAAK,MAAM,MAAM,aAAa,GAAG;GACtF,MAAM,GAAG,SAAS,OAAO,GAAG,SAAS,KAAK,MAAM,MAAM,aAAa;GACnE,KAAK,MAAM,SAAS,eAAe,IAAI;EACxC;EACA,IAAI,CAAC,QAAQ,OAAO;EACpB,KAAK,MAAM,OAAO,MAAM;EACxB,KAAK,MAAM,aAAa,OAAO,IAAI;EACnC,OAAO,QAAQ;EACf,OAAO;CACR;;CAGA,IAAI,QAA8C;EACjD,OAAO,KAAK,MAAM,IAAI,MAAM;CAC7B;;CAGA,OAAmB;EAClB,OAAO,CAAC,GAAG,KAAK,MAAM,KAAK,CAAC;CAC7B;;;;;;CAOA,KAAK,QAAkB,MAAc,MAAyB;EAC7D,MAAM,WAAW,KAAK,IAAI,MAAM,CAAC,EAAE;EACnC,IAAI,CAAC,UAAU,MAAM,OAAO;EAC5B,SAAS,KAAK,MAAM,MAAM,KAAK,MAAM,IAAI;EACzC,OAAO;CACR;;CAGA,MAAM,QAA2B;EAChC,OAAO,KAAK,UAAU,QAAQ,IAAI;CACnC;;CAGA,OAAO,QAA2B;EACjC,OAAO,KAAK,UAAU,QAAQ,KAAK;CACpC;CAEA,UAAkB,QAAkB,QAA0B;EAC7D,MAAM,WAAW,KAAK,IAAI,MAAM,CAAC,EAAE;EACnC,IAAI,CAAC,YAAY,EAAE,YAAY,WAAW,OAAO;EACjD,SAAS,SAAS;EAClB,OAAO;CACR;;CAGA,OAAe,QAAkB,KAA2B,SAAoC;EAC/F,MAAM,OAAO,KAAK,MAAM,SAAS;EACjC,MAAM,QAAQ,OAAO,MAAM,SAAS;EACpC,IAAI,CAAC,OACJ,MAAM,IAAI,MACT,aAAa,MAAM,GAAG,+CAA+C,OAAO,uGAC7E;EACD,IAAI,CAAC,MAAM,MAAM,MAAM,IAAI,MAAM,cAAc,MAAM,GAAG,0FAA0F;EAClJ,OAAO,MAAM,KAAK,KAAK,OAAO,QAAQ,OAAO;CAC9C;;;;;;CAOA,SAAiB,QAAsC;EACtD,MAAM,SAAS,KAAK,MAAM,IAAI,OAAO,MAAM;EAC3C,MAAM,MAAM,QAAQ,eAAe,aAAc,OAAO,MAAM,KAAyC,KAAA;EACvG,IAAI,OAAO,OAAO,QAAQ,YAAY,OAAO,IAAI,UAAU,UAAU,OAAO,IAAI;EAChF,MAAM,KAAK,KAAK,MAAM,SAAS,QAAQ;EACvC,MAAM,OAAO,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,EAAE;EAC7C,QAAQ,SAAS,KAAA,IAAY,IAAI,QAAQ,KAAK,EAAE,QAAQ,KAAA,MAAc,IAAI,UAAU;CACrF;;CAGA,MAAM,IAAkC;EACvC,OAAO,KAAK,MAAM,SAAS,QAAQ,QAAQ,MAAM,UAAU,MAAM,OAAO,EAAE;CAC3E;;;;;;CAOA,UAAgB;EACf,IAAI,CAAC,KAAK,MAAM,OAAO,IAAI,aAAa,GAAG;EAC3C,KAAK,MAAM,CAAC,IAAI,SAAS,OAAO,QAAQ,KAAK,MAAM,MAAM,aAAa,CAAC,GAAG;GACzE,MAAM,SAAS,OAAO,EAAE;GACxB,IAAI,KAAK,MAAM,IAAI,MAAM,GAAG;GAC5B,MAAM,MAAM,KAAK,UAAU,KAAA,IAAY,KAAA,IAAY,KAAK,MAAM,KAAK,KAAK;GACxE,IAAI,KAAK,UAAU,KAAA,KAAa,CAAC,KAAK;IACrC,KAAK,MAAM,IAAI,KACd,MACA,6BAA6B,KAAK,MAAM,cAAc,OAAO,6EAC7D;KACC;KACA,OAAO,KAAK;IACb,CACD;IACA;GACD;GACA,MAAM,SAAS,KAAK,OAAO,QAAQ,KAAK,KAAK,OAAoB;GACjE,KAAK,MAAM,UAAU,MAAM;GAC3B,KAAK,MAAM,IAAI,QAAQ,MAAM;EAC9B;CACD;AACD;;;;;AAMA,SAAS,OAAO,SAAoB,OAAc,QAA2C;CAC5F,MAAM,EAAE,MAAM,YAAY,WAAW,OAAO;CAC5C,IAAI,QAAQ,QACX,MAAM,IAAI,MACT,MACA,eAAe,QAAQ,KAAK,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,6BAA6B,OAAO,oCAC/F;EACC;EACA;CACD,CACD;CACD,OAAO;AACR;;;;;;;;AC3KA,IAAa,eAAe;;;;;;;AAQ5B,IAAa,iBAAsD;CAClE;EAAE,IAAI;EAAU,MAAM;EAAS,MAAM;EAAU,SAAS;EAAG,KAAK;EAAG,KAAK;EAAI,MAAM;EAAK,MAAM;CAA6C;CAC1I;EACC,IAAI;EACJ,MAAM;EACN,MAAM;EACN,SAAS;EACT,KAAK;EACL,KAAK;EACL,MAAM;EACN,MAAM;CACP;CACA;EACC,IAAI;EACJ,MAAM;EACN,MAAM;EACN,SAAS;EACT,SAAS;GACR;IAAE,OAAO;IAAS,OAAO;GAAgB;GACzC;IAAE,OAAO;IAAS,OAAO;GAA0B;GACnD;IAAE,OAAO;IAAY,OAAO;GAA2B;EACxD;EACA,MAAM;CACP;CACA;EAAE,IAAI;EAAS,MAAM;EAAsB,MAAM;EAAU,MAAM;CAAyB;AAC3F;;;;;;;AAQA,IAAa,WAAW,gBAA8C,iBAAiB,EAAE,gBAAgB,CAAC,GAAG,CAAC;;AAG9G,IAAa,QAAQ,gBAAyB,sBAAsB,EAAE,eAAe,MAAM,CAAC;;;;;;AAO5F,IAAa,WAAW,YAA2E,iBAAiB,EAAE,WAAW,WAAW,CAAC;;;;;;AAO7I,IAAa,YAAY,YAA+C,kBAAkB,EAAE,WAAW,WAAW,CAAC;;;;;;AAOnH,IAAa,iBAAiB,OAAuB,gBAAgB;;;;;;AAOrE,IAAa,cAAc,UAAiC,OAAO,OAAO,MAAM,MAAM,QAAQ,CAAC;;;;;;AAO/F,IAAa,aAAa,OAAc,OAAyC,MAAM,MAAM,QAAQ,CAAC,CAAC;;;;;;AAOvG,SAAgB,aAAa,OAAc,IAAY,OAAiC;CACvF,MAAM,QAAQ,MAAM,MAAM,QAAQ,CAAC,CAAC;CACpC,IAAI,CAAC,OAAO,OAAO;CACnB,MAAM,OAAO,MAAM;CACnB,MAAM,QAAQ;CACd,MAAM,KAAK;CACX,MAAM,WAAW;CACjB,MAAM,OAAO,KAAK,UAAU;EAAE;EAAI;EAAO;CAAK,CAAC;CAC/C,OAAO;AACR;;AAiBA,SAAS,aAAa,OAA+B;CACpD,MAAM,OAAO,MAAM;CACnB,MAAM,QAAQ,OAAO,KAAK,UAAU,YAAY,KAAK,QAAQ,IAAI,KAAK,QAAQ,KAAA;CAC9E,OAAO;EACN,IAAI,MAAM,QAAQ,WAAW,MAAM;EACnC,MAAM,MAAM;EACZ,IAAI;GAAE,GAAG,MAAM;GAAG,GAAG,MAAM;EAAE;EAC7B,QAAQ,KAAK;EACb,MAAM,KAAK;EACX,WAAW,KAAK;EAChB;CACD;AACD;;AAGA,SAAS,MAAM,OAAc,SAA+B;CAC3D,MAAM,QAAQ,MAAM,MAAM,QAAQ;CAClC,MAAM,SAAS,MAAM,IAAI,OAAO,QAAQ,QAAA,WAAsB,cAAc,CAAC,CAAC,IAAI,YAAY;CAC9F,KAAK,MAAM,SAAS,CAAC,GAAI,QAAQ,UAAU,CAAC,GAAI,GAAG,MAAM,GACxD,MAAM,MAAM,QAAQ;EACnB,IAAI,MAAM;EACV,GAAI,MAAM,QAAQ,EAAE,MAAM,MAAM,KAAK;EACrC,GAAG,MAAM,GAAG;EACZ,GAAG,MAAM,GAAG;EACZ,QAAQ,MAAM,UAAU;EACxB,MAAM,KAAK,IAAI,MAAM,QAAQ,IAAI,EAAG;EACpC,WAAW,MAAM,aAAa;EAC9B,OAAO,MAAM,SAAS;EACtB,IAAI;EACJ,UAAU;CACX;CAED,MAAM,SAAS,OAAO,IAAI;AAC3B;;AAGA,SAAS,OAAO,OAAc,OAA6B;CAC1D,MAAM,KAAK,cAAc,MAAM,EAAE;CACjC,IAAI,CAAC,MAAM,MAAM,IAAI,EAAE,GAAG;EACzB,MAAM,OAAgB;GAAE;GAAI,OAAO;IAAE,MAAM;IAAU,GAAG,MAAM;IAAG,GAAG,MAAM;IAAG,QAAQ,MAAM;GAAO;EAAE;EACpG,MAAM,MAAM,IAAI,IAAI;CACrB;CACA,OAAO;AACR;;AAGA,IAAM,2BAAW,IAAI,IAAiD;;AAGtE,SAAS,MAAM,OAAc,IAAkB;CAC9C,KAAK,MAAM,SAAS,OAAO,OAAO,MAAM,MAAM,QAAQ,CAAC,GAAG;EACzD,SAAS,MAAM;EACf,KAAK,MAAM,UAAU,MAAM,MAAM,OAAO,OAAO,OAAO,KAAK,CAAC,GAAG;GAC9D,IAAI,CAAC,OAAO,SAAS,OAAO,UAAU,OAAO,IAAI,SAAS,QAAQ;GAClE,MAAM,SAAS,MAAM,OAAO,OAAO,KAAK;GACxC,IAAI,OAAO,SAAS;GACpB,MAAM,OAAO,SAAS,IAAI,OAAO,IAAI;GACrC,IAAI,MAAM,KAAK;QACV,SAAS,IAAI,OAAO,MAAM;IAAE,OAAO;IAAG,QAAQ,OAAO;GAAM,CAAC;EAClE;EAEA,IAAI,CAAC,SAAS,MAAM;EACpB,IAAI;EACJ,IAAI,SAAS,SAAS,GAAG;GACxB,MAAM,CAAC,MAAM,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC;GACnC,QAAQ;IAAE;IAAM,QAAQ,KAAK;GAAO;EACrC,OAAO,IAAI,MAAM,cAAc,SAAS;GACvC,IAAI,MAAM,WAAW,KAAK,MAAM,OAAO,MAAM;IAC5C,MAAM,WAAW;IACjB,MAAM,KAAK;IACX,MAAM,OAAO,KAAK,WAAW;KAAE,IAAI,MAAM;KAAI,IAAI;IAAK,CAAC;GACxD;GACA;EACD,OAAO,IAAI,MAAM,cAAc,YAAY;GAC1C,IAAI;GACJ,IAAI,MAAM;GACV,KAAK,MAAM,SAAS,UACnB,IAAI,CAAC,QAAQ,MAAM,EAAE,CAAC,QAAQ,KAAK,EAAE,CAAC,OAAO;IAC5C,OAAO;IACP,MAAM;GACP,OAAO,IAAI,MAAM,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,OAAO,MAAM;GAEpD,IAAI,CAAC,QAAQ,KAAK;GAClB,QAAQ;IAAE,MAAM,KAAK;IAAI,QAAQ,KAAK,EAAE,CAAC;GAAO;EACjD,OAAO;EACP,MAAM,OAAO,KAAK,MAAM;EACxB,MAAM,YAAY,MAAM,UAAU,OAAO,OAAO,MAAM,OAAO,MAAM,KAAK,CAAC,CAAC;EAE1E,IAAI,MAAM,SAAS,WAAW;GAC7B,IAAI,MAAM,WAAW,GAAG,MAAM,WAAW,KAAK,IAAI,GAAG,MAAM,WAAW,IAAI;GAC1E,IAAI,MAAM,aAAa,KAAK,MAAM,OAAO,MAAM;IAC9C,MAAM,KAAK;IACX,MAAM,OAAO,KAAK,WAAW;KAAE,IAAI,MAAM;KAAI,IAAI;IAAK,CAAC;GACxD;GACA;EACD;EAEA,IAAI,MAAM,OAAO,QAAQ,MAAM,OAAO,MAAM,MAAM;GACjD,MAAM,WAAW,KAAK,IAAI,GAAG,MAAM,WAAW,IAAI;GAClD,IAAI,MAAM,aAAa,GAAG,MAAM,KAAK;GACrC;EACD;EACA,IAAI,MAAM,OAAO,MAAM;GACtB,MAAM,KAAK,MAAM;GACjB,MAAM,OAAO,KAAK,WAAW;IAAE,IAAI,MAAM;IAAI,IAAI,MAAM;GAAK,CAAC;EAC9D;EACA,MAAM,WAAW,KAAK,IAAI,GAAG,MAAM,WAAW,IAAI;EAClD,IAAI,MAAM,WAAW,GAAG;EACxB,MAAM,OAAO,MAAM;EACnB,MAAM,QAAQ,MAAM;EACpB,MAAM,KAAK;EACX,MAAM,WAAW;EACjB,MAAM,OAAO,KAAK,UAAU;GAAE,IAAI,MAAM;GAAI,OAAO,MAAM;GAAQ;EAAK,CAAC;CACxE;AACD;;;;;;;;;;AAWA,SAAgB,YAAY,UAA0B,CAAC,GAAa;CACnE,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,SAAS,CAAC,CAAC;CAWxD,OAAO;EACN,IAAI;EACJ;EACA,YAAY,CAAC,UAAU,KAAK;EAC5B,QAAQ,CAAC,UAAU,SAAS;EAC5B,SAAS,CAAC;GAbV,MAAM;GACN,OAAO;GACP;GACA,OAAO,OAAO;IACb,IAAI,CAAC,MAAM,MAAM,KAAK,GAAG,MAAM,OAAO,OAAO;IAC7C,MAAM,OAAO,QAAQ,MAAM,QAAQ;GACpC;EAOU,CAAM;EAEhB,SAAS,WAAW,EAAE,UAAU,WAAW,KAAK,EAAE;CACnD;AACD;;;;ACxSA,IAAM,SAAS,QAAe,WAAmB,WAAmB,OAAO,UAAU,CAAC,OAAO,IAAI;;;;;;AAOjG,SAAgB,QAAQ,OAAc,UAAkB,QAAgB,UAAuB,CAAC,GAAY;CAC3G,IAAI,MAAM,WAAW,SAAS,OAAO,OAAO,KAAK,GAAG,OAAO;CAC3D,IAAI,OAAO,MAAM,OAAO,SAAS,QAAQ,SAAS,KAAM,OAAO;CAC/D,OAAO,cAAc,OAAO,UAAU,MAAM,MAAM,QAAQ,UAAU,MAAA,CAAO,OAAO,UAAU,MAAM;AACnG;;;;;;AAOA,SAAgB,QAAQ,UAAuB,CAAC,GAAc;CAC7D,OAAO,CACN,WAAW;EACV,MAAM;EACN,IAAI,QAAQ,MAAM;EAClB,IAAI,OAAO,OAAO;GACjB,IAAI,MAAM,WAAW,CAAC,MAAM,SAAS;GACrC,IAAI,QAAQ,OAAO,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG,MAAM,UAAU;EAC5E;CACD,CAAC,CACF;AACD;;AAsBA,IAAa,UAAU,gBAAsE,YAAY,EAAE,gBAAgB,CAAC,GAAG,CAAC;;;;;;;AAQhI,SAAgB,WAAW,OAAc,QAAwD;CAEhG,OADY,MAAM,MAAM,OACjB,CAAA,CAAI,WAAW;EAAE,UAAU;EAAG,QAAQ;CAAE;AAChD;;AAGA,IAAM,eAAe,QAAe,SAAiB,KAAK,UAAU,CAAC,KAAK,IAAI;;;;;;;;;AAU9E,SAAgB,aAAa,UAA0B,CAAC,GAAa;CACpE,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,OAAO,QAAQ,cAAc;CACnC,MAAM,QAAQ,WAAW;EACxB,MAAM;EACN,IAAI;EACJ,IAAI,OAAO,OAAO;GACjB,MAAM,EAAE,QAAQ,WAAW;GAC3B,IAAI,CAAC,UAAU,WAAW,UAAU,CAAC,OAAO,OAAO,MAAM,GAAG;GAC5D,MAAM,MAAM,MAAM,MAAM,OAAO;GAC/B,MAAM,SAAS,OAAO;GACtB,MAAM,OAAQ,IAAI,YAAY;IAAE,UAAU;IAAG,QAAQ;GAAE;GACvD,IAAI,MAAM,WAAW,QAAQ,OAAO,KAAK,GAAG;IAC3C,KAAK;IACL;GACD;GACA,IAAI,CAAC,MAAM,UAAU,QAAQ,OAAO,KAAK,GAAG;GAC5C,KAAK;GACL,MAAM,QAAQ;GAEd,MAAM,QAAQ,QAAQ,OAAO,MAAM,IAAI;GACvC,IAAI,SAAS,GAAG;GAChB,MAAM,QAAQ,MAAM,MAAM,OAAO;GACjC,MAAM,SAAmB,CAAC;GAE1B,KAAK,MAAM,QAAQ,MAAM,MAAM,KAAK,SAAS,GAAG;IAC/C,MAAM,QAAQ,OAAO,IAAI;IACzB,IAAI,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC,MAAM,WAAW,KAAK,OAAO,OAAO,KAAK,GAAG;IAC1E,IAAI,MAAM,SAAS,WAAW,OAAO,IAAI,GAAG;IAC5C,IAAI,OAAO,KAAK,KAAK,OAAO,GAAG,KAAK,QAAQ,OAAO,OAAO,KAAK,IAAI;GACpE;GACA,KAAK,MAAM,QAAQ,QAAQ,QAAQ,OAAO,MAAM,QAAQ,OAAO,QAAQ,MAAM;EAC9E;CACD,CAAC;CACD,OAAO;EACN,IAAI;EACJ;EACA,YAAY,CAAC,OAAO;EACpB,OAAO,CAAC,GAAI,QAAQ,SAAS,QAAQ,CAAC,IAAI,QAAQ,QAAQ,IAAI,GAAI,KAAK;CACxE;AACD;;;;;;;;ACpHA,IAAa,gBAAgB;;;;;;AAO7B,IAAa,iBAAiB;;;;;;AAO9B,IAAa,sBAAkD,CAC9D;CAAE,IAAI;CAAU,MAAM;CAAU,MAAM;CAAU,SAAS;CAAG,MAAM;AAA6B,GAC/F;CAAE,IAAI;CAAQ,MAAM;CAAQ,MAAM;CAAQ,MAAM;AAAkE,CACnH;;;;;;;AAQA,IAAa,oBAAoB;CAChC,IAAI;CACJ,MAAM;CACN,QAAQ;CACR,MAAM;CACN,MAAM;CACN,OAAO;EAAC;EAAM;EAAM;CAAI;CACxB,QAAQ;CACR,OAAA;AACD;;AA2BA,IAAM,UAAU,OAA2B,YAA2C;CACrF,MAAM,KAAK,QAAQ,MAAM;CACzB,OAAO,OAAO,OAAO,WAAW,MAAM,MAAM,SAAS,KAAK,OAAO,EAAE,IAAI,OAAO,OAAO,WAAW,MAAM,MAAM,SAAS,KAAK,SAAS,EAAE,IAAI,KAAA;AAC1I;;AAGA,SAAS,MAAM,MAAe,IAA6B;CAC1D,MAAM,QAAQ,KAAK,OAAO;CAC1B,MAAM,OAAO,KAAK,OAAO,KAAK,OAAO,SAAS;CAC9C,IAAI,CAAC,SAAS,CAAC,MAAM,OAAO,KAAA;CAC5B,MAAM,KAAK,MAAM,GAAG,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC;CAC/C,MAAM,KAAK,MAAM,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,CAAC;CAC7C,IAAI,KAAK,IAAI,IAAI,EAAE,IAAA,GAAoB,OAAO,KAAA;CAC9C,OAAO,MAAM,KAAK,IAAI;AACvB;;;;;;AAOA,SAAgB,SAAS,KAA2E;CACnG,MAAM,wBAAQ,IAAI,IAAkB;CACpC,KAAK,MAAM,WAAW,UAAU,KAAK,aAAa,GAAG;EACpD,MAAM,OAAO,OAAO,IAAI,OAAO,OAAO;EACtC,IAAI,CAAC,MAAM;EACX,IAAI,OAAO,MAAM,IAAI,KAAK,EAAE;EAC5B,IAAI,CAAC,MAAM,MAAM,IAAI,KAAK,IAAK,OAAO;GAAE,MAAM,KAAK;GAAM,QAAQ,KAAK;GAAQ,MAAM,CAAC,KAAA,GAAW,KAAA,CAAS;EAAE,CAAE;EAC7G,MAAM,MAAM,MAAM,MAAM,OAAO;EAC/B,IAAI,QAAQ,KAAA,GAAW;EACvB,KAAK,KAAK,OAAO;GAAE;GAAS,QAAQ,OAAO,QAAQ,MAAM,UAAU,CAAC;GAAG,IAAI;IAAE,GAAG,QAAQ;IAAG,GAAG,QAAQ;GAAE;EAAE;CAC3G;CACA,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC;AAC1B;;;;;;AAOA,IAAa,WAAW,UAAyB,SAAS;CAAE,OAAO,MAAM,IAAI;CAAO,MAAM,MAAM,IAAI;AAAK,CAAC;;;;;;;AAQ1G,SAAgB,WAAW,KAA4B;CACtD,MAAM,WAAyB,CAAC;CAChC,MAAM,UAAU,WAAmB,IAAI,QAAQ,MAAM,SAAS,KAAK,OAAO,MAAM,CAAC,EAAE,QAAQ;CAC3F,KAAK,MAAM,WAAW,UAAU,KAAK,aAAa,GAAG;EACpD,MAAM,OAAO,OAAO,IAAI,OAAO,OAAO;EACtC,MAAM,QAAQ;GAAE,OAAO,QAAQ;GAAI,MAAM;EAAc;EACvD,IAAI,CAAC,MACJ,SAAS,KAAK;GAAE,SAAS;GAAyD,OAAO;GAAM,MAAM;GAAiB,IAAI;GAAS;EAAM,CAAC;OACtI,IAAI,MAAM,MAAM,OAAO,MAAM,KAAA,GACjC,SAAS,KAAK;GAAE,SAAS,iBAAiB,KAAK,KAAK;GAA4B,OAAO;GAAM,MAAM;GAAiB,IAAI;GAAS;EAAM,CAAC;CAC1I;CACA,KAAK,MAAM,QAAQ,SAAS,GAAG,GAAG;EACjC,MAAM,OAAO,IAAI,MAAM,MAAM,SAAS,KAAK,SAAS,KAAK,IAAI;EAC7D,MAAM,QAAQ,EAAE,MAAM,KAAK,GAAG;EAC9B,MAAM,CAAC,OAAO,QAAQ,KAAK;EAC3B,IAAI,CAAC,SAAS,CAAC,MAAM;GACpB,MAAM,UAAU,CAAC,QAAQ,KAAK,OAAO,KAAK,KAAK,OAAO,KAAK,OAAO,SAAS;GAC3E,SAAS,KAAK;IACb,SAAS,aAAa,KAAK,KAAK;IAChC,OAAO;IACP,MAAM;IACN,IAAI;IACJ;GACD,CAAC;EACF,OAAO,IAAI,OAAO,MAAM,MAAM,MAAM,OAAO,KAAK,MAAM,GACrD,SAAS,KAAK;GAAE,SAAS,aAAa,KAAK,KAAK;GAAmC,OAAO;GAAM,MAAM;GAAe,IAAI,MAAM;GAAI;EAAM,CAAC;CAC5I;CACA,OAAO;AACR;;;;;;AAiEA,IAAa,aAAa,gBAA0F,cAAc;;AAGlI,IAAa,aAAa,gBAAyF,eAAe,EACjI,gBAAgB;CAAE,SAAS;CAAO,OAAO,CAAC;AAAE,GAC7C,CAAC;;;;;;;AAQD,SAAgB,YAAY,OAAc,MAAgB,SAAyD;CAClH,MAAM,EAAE,OAAO,QAAQ,UAAU;CACjC,MAAM,IAAI,KAAK;CAMf,OAAO;EAJN,GAAG,MAAc,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK;EACxD,GAAG,MAAc,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM;EACzD,GAAG,MAAc,SAAS,IAAI,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE;CAE9E,CAAA,CAAM,QAAQ,SAAS,MAAM,SAAS,MAAM,IAAI,IAAI,CAAC;AAC7D;;AAGA,SAAS,YAAY,OAAc,QAAgB,MAAY,MAA+B;CAC7F,MAAM,MAAM,KAAK,OAAO,SAAS,IAAI,KAAK,OAAO,SAAS,IAAI;CAC9D,IAAI;CACJ,IAAI,eAAe;CACnB,KAAK,MAAM,UAAU,MAAM,SAAS,OAAO,GAAG;EAC7C,IAAI,CAAC,OAAO,SAAS,CAAC,OAAO,eAAe,CAAC,MAAM,WAAW,OAAO,OAAO,OAAO,KAAK,GAAG;EAC3F,MAAM,IAAI,OAAO,OAAO,KAAK,GAAG;EAChC,IAAI,IAAI,cAAc;GACrB,eAAe;GACf,OAAO;EACR;CACD;CACA,OAAO,OAAO;EAAE,GAAG,KAAK,IAAI;EAAG,GAAG,KAAK,IAAI;CAAE,IAAI;AAClD;;;;;;;;AASA,SAAgB,SAAS,OAAc,SAAiB,SAA0C;CACjG,KAAK,MAAM,QAAQ,QAAQ,KAAK,GAAG;EAClC,MAAM,OAAO,KAAK,KAAK,EAAE,EAAE,QAAQ,OAAO,UAAU,IAAI,KAAK,KAAK,EAAE,EAAE,QAAQ,OAAO,UAAU,IAAI,KAAA;EACnG,IAAI,SAAS,KAAA,GAAW;EACxB,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,QAAQ,MAAM,MAAM,UAAU;EACpC,MAAM,UAAU,MAAM,MAAM,YAAY,KAAK;EAC7C,MAAM,MAAM,WAAW;EACvB,MAAM,OAAiB;GAAE;GAAQ;GAAM;GAAM,QAAQ,IAAI;EAAO;EAChE,IAAI,CAAC,QAAQ,QAAQ,CAAC,QAAQ,SAAS,MAAM,IAAI,MAAM,+EAA+E;EACtI,MAAM,QAAQ,QAAQ,OAAO,QAAQ,KAAK,OAAO,IAAI,IAAI,YAAY,OAAO,MAAM,QAAQ,OAAQ;EAElG,MAAM,OAAO,KAAK,OAAO,SAAS,IAAI,IAAI,KAAK,OAAO,SAAS,MAAM,IAAI;EACzE,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,GAAG,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,KAAK;EAC9D,MAAM,QAAQ;GAAE,IAAI,KAAK,IAAI,IAAI,GAAG,KAAK;GAAQ,IAAI,KAAK,IAAI,IAAI,GAAG,KAAK;EAAO;EACjF,MAAM,QAAQ,MAAM,KAAK,MAAM,MAAM;GACpC,MAAM,MAAM,KAAK,MAAM,IAAI,CAAC;GAC5B,MAAM,OAAQ,IAAI,IAAK;GACvB,MAAM,KAAK;IAAE,GAAG,IAAI,GAAG,IAAI,MAAM,IAAI,MAAM,MAAM,MAAM,IAAI,OAAO;IAAK,GAAG,IAAI,GAAG,IAAI,MAAM,IAAI,MAAM,MAAM,MAAM,IAAI,OAAO;GAAI;GAChI,MAAM,OAAO,MAAM,MAAM,MAAM,IAAI,QAAQ,IAAI,EAAE,QAAQ,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;GAClF,KAAK,IAAI,YAAY;IAAE,MAAM,KAAK;IAAM;GAAK,CAAC;GAC9C,OAAO;EACR,CAAC;EACD,IAAI,CAAC,MAAM,QAAQ,OAAO;EAC1B,UAAU,OAAO,OAAO,MAAM,MAAM,OAAO;EAC3C,OAAO;CACR;CACA,OAAO,CAAC;AACT;;AAGA,SAAS,UAAU,OAAc,OAAiB,MAAY,MAAa,SAAsC;CAChH,MAAM,WAAW,MAAM,KAAK,SAAS,KAAK,EAAE;CAC5C,MAAM,SAAS,MAAM,EAAE,CAAC;CACxB,MAAM,MAAM;EAAE,MAAM;EAAS;EAAQ;EAAU,OAAO;GAAE,MAAM;GAAc,MAAM,KAAK;GAAM,SAAS,SAAS,IAAI,SAAS;EAAQ;CAAE,CAAC;CACvI,MAAM,QAAQ,QAAQ,QAAQ,YAAA,CAAa,OAAO,MAAM,IAAI,MAAM,IAAI;CACtE,IAAI,MAAM,MAAM,MAAM;EAAE,MAAM;EAAS;EAAQ;EAAU,OAAO;GAAE,MAAM;GAAc,OAAO;EAAK;EAAG,OAAO;CAAK,CAAC;AACnH;;AAGA,SAAS,QAAQ,MAAY,IAAkB;CAC9C,IAAI,OAAO;CACX,MAAM,EAAE,WAAW;CACnB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACvC,MAAM,IAAI,OAAO,IAAI;EACrB,MAAM,KAAK,OAAO,EAAE,CAAC,IAAI,EAAE;EAC3B,MAAM,KAAK,OAAO,EAAE,CAAC,IAAI,EAAE;EAC3B,MAAM,SAAS,KAAK,KAAK,KAAK;EAC9B,MAAM,IAAI,SAAS,IAAI,KAAK,IAAI,KAAK,MAAM,GAAG,IAAI,EAAE,KAAK,MAAM,GAAG,IAAI,EAAE,KAAK,MAAM,QAAQ,CAAC,GAAG,CAAC,IAAI;EACpG,OAAO,KAAK,IAAI,MAAM,MAAM,GAAG,KAAK,EAAE,IAAI,KAAK,IAAI,GAAG,KAAK,EAAE,IAAI,KAAK,EAAE,CAAC;CAC1E;CACA,OAAO;AACR;;;;;;AAOA,IAAa,aAAa,OAAc,YAA4B,MAAM,MAAM,UAAU,CAAC,CAAC,MAAM,YAAY;;;;;;;;AAS9G,SAAgB,UAAU,SAAiC;CAE1D,IAAI,CAAC,QAAQ,QAAQ,EAAE,QAAQ,SAAS,SAAS,QAAQ,QAAQ,SAChE,MAAM,IAAI,MAAM,mGAAmG;CACpH,IAAI,QAAQ,UAAU,KAAA,GAAW,MAAM,IAAI,MAAM,6FAA6F;CAC9I,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,UAAU,YAAiC,eAAe,OAAO,SAAS;EAC/E,IAAI,MAAM,WAAW,MAAM,SAAS,OAAO,KAAK,SAAS,OAAO;CACjE,CAAC;CAED,MAAM,QAAgB;EACrB,MAAM;EACN,OAAO;EACP,OAAO,OAAO;GACb,MAAM,QAAQ,MAAM,MAAM,UAAU;GACpC,IAAI,MAAM,SAAS;GACnB,MAAM,UAAU;GAChB,KAAK,MAAM,QAAQ,QAAQ,KAAK,GAC/B,KAAK,MAAM,OAAO,KAAK,MAAM,IAAI,KAAK,MAAM,OAAO,MAAM,OAAO,SAAS;IAAE,OAAO;IAAW,MAAM,EAAE,SAAS,IAAI,QAAQ,GAAG;GAAE,CAAC;EAElI;CACD;CACA,MAAM,EAAE,OAAO,WAAW,YAAY,WAAW,OAAO;CACxD,OAAO;EACN,IAAI;EACJ;EACA,YAAY;GAAC;GAAY;GAAY;EAAU;EAC/C,QAAQ,CAAC,OAAO;EAChB,SAAS,CAAC,OAAO,GAAG,OAAO;EAC3B;EACA;EACA,GAAI,QAAQ,UAAU,SAAS,EAAE,SAAS,YAAY,QAAQ,QAAQ,KAAK,CAAC,EAAE;EAE9E,QAAQ,WAAW,EAAE,QAAQ,EAAE,KAAK,OAAO,SAAU,SAAS,QAAQ,KAAK,IAAI,UAAU,IAAI,IAAI,MAAM,OAAO,GAAG,OAAO,IAAI,EAAG,EAAE;EACjI,QAAQ,QAAQ,WAAW,GAAG;CAC/B;AACD;;;;;;;AAUA,IAAa,aAAa,gBAAgC,kBAAkB;;AAG5E,IAAM,WAAW,OAAc,QAAgB,UAC9C,OAAO,eAAe,CAAC,CAAC,OAAO,IAAI,SAAS,UAAU,EAAE,SAAS,QAAQ,KAAK,CAAC,CAAC,OAAO,MAAM;;AAG9F,IAAM,WAAW,UAChB,OAAO,UAAU,YAAY,QAAQ,WAAW,OAAO,IAAI,OAAO,QAAQ;;;;;;;AAQ3E,SAAgB,YAAY,OAA0D;CACrF,OAAO;EACN,MAAM;EACN,OAAO;EACP,OAAO;EACP,OAAO,OAAO;GACb,IAAI,MAAM,WAAW,MAAM;GAC3B,MAAM,2BAAW,IAAI,IAAY;GACjC,KAAK,MAAM,UAAU,MAAM,SAAS,OAAO,GAAG,IAAI,OAAO,SAAS,MAAM,OAAO,MAAM,GAAG,SAAS,IAAI,MAAM,OAAO,OAAO,KAAK,CAAC,CAAC,IAAI;GACpI,MAAM,wBAAQ,IAAI,IAAY;GAC9B,KAAK,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG;IAC5C,IAAI,OAAO,WAAW,OAAO,QAAQ;IACrC,IAAI,SAAS,IAAI,OAAO,IAAI,GAAG,OAAO,cAAc;IACpD,IAAI,CAAC,OAAO,aAAa;IACzB,MAAM,IAAI,OAAO,IAAI;IACrB,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,KAAK,CAAC,OAAO,UAAU,OAAO,OAAO,OAAO,EAAE;GAC5E;GACA,IAAI,MAAM,OAAO,KAAK,SAAS,SAAS,GAAG;GAC3C,MAAM,CAAC,UAAU;GACjB,MAAM,SAAS;GACf,MAAM,OAAO,KAAK,UAAU,EAAE,OAAO,CAAC;EACvC;CACD;AACD;;AAGA,SAAS,WAAW,SAAuB;CAC1C,MAAM,SAAS,QAAQ,YAAY,OAAc,WAAmB,QAAQ,OAAO,QAAQ,QAAQ,KAAK;CACxG,MAAM,QAAQ,QAAQ,cAAc;CACpC,MAAM,cAAc,OAAc,WAAmB;EACpD,MAAM,SAAS,OAAO,IAAI,UAAU;EACpC,OAAO,CAAC,CAAC,UAAU,MAAM,OAAO,OAAO,MAAM;CAC9C;CACA,MAAM,cAAc,WAAW;EAC9B,MAAM;EACN,IAAI;EACJ,IAAI,OAAO,OAAO;GACjB,IAAI,CAAC,OAAO,OAAO,MAAM,QAAQ,GAAG;GACpC,IAAI,MAAM,OAAO,IAAI,QAAQ,WAAW,OAAO,MAAM,MAAM,GAAG,MAAM,SAAS;QACxE,IAAI,MAAM,OAAO,IAAI,UAAU,GAAG,MAAM,SAAS;EACvD;CACD,CAAC;CACD,MAAM,UAAU,QAAQ,gBAAgB,QAAQ,KAAA,IAAY;EAAE,QAAQ;EAAG,OAAO;EAAK,OAAO;EAAI,GAAG,QAAQ;CAAY;CAEvH,MAAM,cAAc,eAAe;EAClC,IAAI;EACJ,OAAO;EACP,IAAI,OAAO,EAAE,QAAQ,UAAU;GAC9B,IAAI,CAAC,QAAQ,SAAS,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,MAAM,WAAW,OAAO,OAAO,OAAO,KAAK,GAAG;GAC7G,OAAO,IAAI,YAAY,EAAE,IAAI,MAAM,KAAK,CAAC;GACzC,IAAI,SAAS;IACZ,MAAM,QAAQ,MAAM,MAAM,UAAU;IACpC,MAAM,SAAmB,CAAC;IAC1B,KAAK,MAAM,UAAU,MAAM,QAAQ,MAAM,OAAO,IAAI,GAAG,OAAO,IAAI,GAAG,QAAQ,MAAM,GAAG;KACrF,MAAM,OAAO,OAAO,IAAI,UAAU;KAClC,IAAI,CAAC,QAAQ,CAAC,OAAO,SAAS,KAAK,OAAO,WAAW,OAAO,MAAM,CAAC,MAAM,UAAU,OAAO,OAAO,OAAO,KAAK,GAAG;KAChH,IAAI,CAAC,MAAM,YAAY,QAAQ,MAAM,OAAO,OAAO,KAAK,CAAC,CAAC,IAAI,GAAG;KACjE,KAAK,QAAQ;MAAE,QAAQ,OAAO;MAAI,OAAO,MAAM,OAAO,QAAQ;KAAM;KACpE,OAAO,KAAK,MAAM;KAClB,IAAI,EAAE,MAAM,YAAY,CAAC,EAAA,CAAG,SAAS,OAAO,EAAE,GAAG,MAAM,QAAQ,KAAK,OAAO,EAAE;IAC9E;IACA,KAAK,MAAM,SAAS,IAAI,IAAI,OAAO,KAAK,WAAW,OAAO,KAAK,CAAC,GAAG;KAClE,MAAM,WAAW,OAAO,QAAQ,WAAW,OAAO,UAAU,KAAK,CAAC,CAAC,KAAK,WAAW,OAAO,EAAE;KAC5F,MAAM,MAAM;MAAE,MAAM;MAAS,QAAQ;MAAO;MAAU,OAAO;OAAE,MAAM;OAAU,QAAQ,OAAO;MAAG;KAAE,CAAC;IACrG;GACD;GACA,KAAK,MAAM,SAAS,MAAM,QAAQ,MAAM,OAAO,IAAI,GAAG,OAAO,IAAI,GAAG,EAAE,GAAG;IACxE,IAAI,CAAC,MAAM,SAAS,CAAC,MAAM,IAAI,QAAQ,KAAK,CAAC,OAAO,OAAO,KAAK,KAAK,CAAC,MAAM,UAAU,MAAM,OAAO,OAAO,KAAK,GAAG;IAClH,MAAM,QAAQ,MAAM,MAAM,OAAO,iBAAiB,OAAO,KAAK,IAAI,MAAM,IAAI;IAC5E,IAAI,MAAM,MAAM,IAAI,IAAI,OAAO,IAAI,GAAG,MAAM,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,OAAO;IAC3E,IAAI,MAAM,IAAI,QAAQ,CAAC,CAAE,eAAe,OAAO,MAAM,CAAC,MAAM,YAAY,QAAQ,MAAM,OAAO,MAAM,KAAK,CAAC,CAAC,IAAI,GAAG;IACjH,UAAU,OAAO,KAAK;IACtB,WAAW,OAAO,OAAO,MAAM;IAC/B,MAAM,IAAI,QAAQ,CAAC,CAAE,aAAa,OAAO;GAC1C;EACD;CACD,CAAC;CA2BD,OAAO;EAAE,OAAO,CAAC,WAAW;EAAG,WAAW,CAAC,WAAW;EAAG,SAAS,CAAC;GAxBlE,MAAM;GACN,OAAO;GACP,OAAO,OAAO;IACb,MAAM,QAAQ,MAAM,MAAM,UAAU;IACpC,IAAI,CAAC,WAAW,CAAC,MAAM,SAAS,QAAQ;IACxC,MAAM,QAAQ,QAAQ,KAAK;IAC3B,MAAM,UAAU,MAAM,QAAQ,QAAQ,OAAO;KAC5C,MAAM,SAAS,MAAM,IAAI,EAAE;KAC3B,MAAM,OAAO,QAAQ,IAAI,UAAU;KACnC,IAAI,CAAC,QAAQ,SAAS,CAAC,MAAM,OAAO,OAAO;KAC3C,MAAM,OAAO,MAAM,MAAM,SAAS,KAAK,SAAS,KAAK,IAAI;KACzD,MAAM,SAAS,MAAM,IAAI,KAAK,MAAM,MAAM;KAM1C,IAAI,EAJH,MAAM,OAAO,KAAK,MAAM,SACxB,CAAC,QAAQ,SACT,CAAC,MAAM,YAAY,QAAQ,MAAM,OAAO,OAAO,KAAK,CAAC,CAAC,IAAI,KACzD,CAAC,CAAC,QAAQ,QAAQ,MAAM,OAAO,GAAG,IAAI,QAAQ,QACrC,OAAO;KAClB,KAAK,QAAQ,KAAA;KACb,IAAI,MAAM,UAAU,OAAO,CAAC,MAAM,GAAG,MAAM,KAAK,MAAM,OAAO;KAC7D,OAAO;IACR,CAAC;GACF;EAEkE,CAAI;CAAE;AAC1E;;;;;;;;AC3cA,IAAa,SAAS,gBAAwD,aAAa,EAAE,WAAW,WAAW,CAAC;;AAGpH,IAAa,UAAU,gBACtB,gBACA,EACC,gBAAgB;CAAE,OAAO,CAAC;CAAG,QAAQ,CAAC;AAAE,GACzC,CACD;;;;;;AAOA,IAAa,YAAY,YAAgG,kBAAkB,EAC1I,WAAW,WACZ,CAAC;;AAGD,SAAS,UAAU,OAAwB;CAC1C,KAAK,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG,IAAI,OAAO,SAAS,OAAO,OAAO;CAC/E,OAAA;AACD;;AAGA,SAAS,QAAQ,OAAc,MAAmB,GAAW,GAA+B;CAC3F,IAAI,CAAC,MAAM,SAAS,MAAM,IAAI,KAAK,IAAI,GAAG,OAAO,KAAA;CACjD,MAAM,SAAS,MAAM,MAAM,KAAK,MAAM,UAAU,KAAK,GAAG;EAAE;EAAG;CAAE,CAAC;CAChE,IAAI,KAAK,WAAW,KAAA,KAAa,OAAO,IAAI,OAAO,GAAG,OAAO,IAAI,OAAO,CAAC,CAAE,SAAS,KAAK;CACzF,OAAO;AACR;;;;;;;AAQA,SAAgB,WAAW,KAOX;CACf,OAAO;EACN,IAAI,IAAI;EACR,MAAM,IAAI,QAAQ;EAClB,MAAM;EACN,QAAQ,KAAK,IAAI,IAAI,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI;EACrD,WAAW,IAAI;EACf,OAAO,EAAE,QAAQ,EAAE;EACnB,OAAO;EACP,UAAU;GAAE,MAAM,IAAI;GAAM,QAAQ,IAAI,UAAU;GAAK,OAAO,IAAI,SAAS;EAAE;CAC9E;AACD;;;;;;;;AASA,SAAgB,SAAS,KAK0C;CAClE,OAAO;EACN,IAAI,IAAI;EACR,MAAM,IAAI,QAAQ;EAClB,MAAM;EACN,QAAQ;EACR,OAAO;GAAE,QAAQ;GAAG,WAAW;EAAE;EACjC,OAAO;EACP,cAAc;EACd,SAAS;EACT,MAAM;GAAE,MAAM,IAAI;GAAM,QAAQ,IAAI,UAAU;EAAG;CAClD;AACD;;;;;;;AAQA,SAAgB,YAAY,UAA0B,CAAC,GAAa;CACnE,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,UAAU,QAAQ,aAAa,QAAe,SAAiB,CAAC,KAAK,eAAe,CAAC,KAAK,cAAc,KAAK,SAAS,CAAC,KAAK,IAAI,MAAM;CAE5I,MAAM,YAAY,WAAW;EAC5B,MAAM;EACN,IAAI;EACJ,IAAI,OAAO,OAAO;GACjB,MAAM,EAAE,QAAQ,MAAM,WAAW;GACjC,MAAM,QAAQ,MAAM,MAAM,OAAO;GACjC,IAAI,KAAK,eAAe,QAAQ,QAAQ;IACvC,MAAM,OAAO,OAAO,QAAQ,WAAW,aAAa,QAAQ,OAAO,OAAO,IAAI,IAAI,QAAQ;IAC1F,MAAM,OAAO,OAAO,SAAS,WAAW,EAAE,MAAM,KAAK,IAAI;IAEzD,IAAI,MAAM,MAAM,OAAO,KAAK,MAAM;KAAE,GAAG;KAAM,GAAG,KAAK,IAAI;KAAG,GAAG,KAAK,IAAI;IAAE;GAC3E,OAAO,IAAI,CAAC,KAAK,eAAe,CAAC,KAAK,cAAc,QAAQ,OAAO;IAClE,MAAM,OAAO,QAAQ,MAAM,OAAO,MAAM,MAAM;IAC9C,MAAM,OAAO,QAAQ,QAAQ,OAAO,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC;IAChE,IAAI,CAAC,MAAM;IAEX,MAAM,OAAQ,KAAK,IAA0D;IAC7E,MAAM,OAAO,MAAM,QAAQ,MAAM,SAAS,UAAU,EAAE,EAAE,MAAM;IAC9D,KAAK,IAAI,QAAQ;KAAE;KAAM,QAAQ,KAAK,UAAU,MAAM,UAAU;IAAG,CAAC;IACpE,MAAM,MAAM,KAAK,KAAK,EAAE;GACzB;EACD;CACD,CAAC;CACD,MAAM,aAAa,WAAW;EAC7B,MAAM;EACN,IAAI;EACJ,IAAI,OAAO,QAAQ;GAClB,MAAM,QAAQ,MAAM,MAAM,OAAO;GACjC,MAAM,SAAS,MAAM,OAAO,OAAO;GACnC,IAAI,CAAC,QAAQ;GACb,OAAO,MAAM,OAAO,OAAO;GAC3B,QAAQ,OAAO,QAAQ,OAAO,GAAG,OAAO,CAAC;EAC1C;CACD,CAAC;CACD,MAAM,OAAiB,CAAC;CA0BxB,OAAO;EACN,IAAI;EACJ;EACA,YAAY,CAAC,SAAS,MAAM;EAC5B,QAAQ,CAAC,SAAS;EAClB,OAAO,CAAC,WAAW,UAAU;EAC7B,SAAS,CAAC;GA9BV,MAAM;GACN,OAAO,OAAc;IACpB,MAAM,QAAQ,MAAM,MAAM,OAAO;IACjC,IAAI,CAAC,MAAM,MAAM,QAAQ;IACzB,MAAM,QAAQ,MAAM,MAAM,QAAQ,OAAO;KACxC,MAAM,OAAO,MAAM,IAAI,EAAE;KACzB,MAAM,QAAQ,MAAM,IAAI,MAAM;KAC9B,IAAI,CAAC,MAAM,SAAS,CAAC,OAAO,OAAO;KACnC,KAAK,MAAM,QAAQ,CAAC,GAAG,MAAM,QAAQ,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,IAAI,CAAC,GAAG;MACjF,IAAI,MAAM,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,CAAC,QAAQ,OAAO,MAAM,IAAI,GAAG;MACrE,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI;MACjC,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI;MACjC,MAAM,SAAS,QAAQ,KAAK,IAAI;MAChC,IAAI,KAAK,KAAK,KAAK,KAAK,SAAS,QAAQ;MACzC,MAAM,EAAE,MAAM,WAAW;MACzB,KAAK,MAAM,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,MAAM,MAAM;MACrD,MAAM,OAAO,KAAK,WAAW;OAAE,MAAM,KAAK;OAAI,IAAI,KAAK;OAAI,QAAQ,KAAK;OAAO;OAAM;MAAO,CAAC;MAC7F,MAAM,KAAK,MAAM,MAAM,OAAO,OAAO;MACrC,OAAO;KACR;KACA,OAAO;IACR,CAAC;GACF;EAQU,CAAM;CACjB;AACD;;;;;;;;;AC9KA,IAAa,UAAgC;CAC5C;EACC,IAAI;EACJ,MAAM;EACN,aAAa;EACb,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,UAAU;EACV,UAAU;CACX;CACA;EACC,IAAI;EACJ,MAAM;EACN,aAAa;EACb,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,UAAU;EACV,UAAU;CACX;CACA;EACC,IAAI;EACJ,MAAM;EACN,aAAa;EACb,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,UAAU;EACV,UAAU;CACX;CACA;EACC,IAAI;EACJ,MAAM;EACN,aAAa;EACb,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,UAAU;EACV,UAAU;CACX;AACD;;;;;;AAOA,IAAa,iBAAiB;;;;;;AAO9B,IAAa,SAAS,gBAAwB,eAAe,EAAE,WAAW,QAAQ,CAAC;;;;;;;AAQnF,SAAgB,SAAS,QAAgB,UAAgC,SAAoB;CAC5F,MAAM,KAAK,OAAO,IAAI,MAAM,KAAA;CAC5B,OAAO,QAAQ,MAAM,QAAQ,IAAI,OAAO,EAAE,KAAK,QAAQ,MAAM,QAAQ,IAAI,OAAA,YAAqB,KAAK,QAAQ;AAC5G;;;;;;;AAQA,IAAa,gBAAgB,cAAc,UAAU;CAAE,UAAU;CAAK,QAAQ;AAAO,IAAI,OAAO,QAAQ,YAAY;CACnH,MAAM,KAAK,QAAQ;CACnB,KAAK,MAAM,UAAU,MAAM,OAAO,QAAQ,QAAQ,QAAQ,GAAG;EAC5D,MAAM,MAAM,OAAO,IAAI,MAAM;EAC7B,IAAI,OAAA,cAAuB,OAAO,OAAO,MAAM;OAC1C,OAAO,IAAI,QAAQ,EAAE;EAE1B,IAAI,QAAQ,MAAM,OAAO,IAAI,QAAQ,GAAG;GACvC,OAAO,IAAI,QAAQ,CAAC,CAAE,aAAa;GACnC,OAAO,IAAI,QAAQ,CAAC,CAAE,eAAe;GACrC,UAAU,OAAO,MAAM;EACxB;CACD;AACD,CAAC;;AAGD,SAAS,MAAM,OAAc,QAAkB,UAAuC;CACrF,MAAM,MAAgB,CAAC;CACvB,KAAK,MAAM,MAAM,UAAU;EAC1B,MAAM,SAAS,MAAM,IAAI,EAAE;EAC3B,IAAI,QAAQ,SAAS,OAAO,UAAU,QAAQ,IAAI,KAAK,MAAM;CAC9D;CACA,OAAO;AACR;;;;;;;;;AAoBA,SAAgB,YAAY,UAA0B,CAAC,GAAa;CACnE,MAAM,UAAU,QAAQ,WAAW;CACnC,IAAI,CAAC,QAAQ,QAAQ,MAAM,IAAI,MAAM,6CAA6C;;CAGlF,MAAM,gBAAgB,WAAW;EAChC,MAAM;EACN,IAAI;EACJ,IAAI,OAAO,OAAO;GACjB,IAAI,CAAC,MAAM,WAAW,MAAM,SAAS;GACrC,MAAM,EAAE,UAAU,WAAW;GAC7B,MAAM,MAAM,SAAS,UAAU,OAAO;GACtC,IAAI,IAAI,YAAY,SAAS,IAAI,QAAQ;GACzC,MAAM,SAAS,SAAS,IAAI,QAAQ;GACpC,MAAM,UAAU,CAAC,CAAC,WAAW,OAAO,eAAe,OAAO,MAAM,OAAO,iBAAiB,OAAO;GAC/F,IAAI,IAAI,YAAY,QAAQ;IAC3B,MAAM,UAAU,IAAI,YAAY;IAChC;GACD;GAGA,IAAI,IAAI,YAAY,UAAW,CAAC,IAAI,UAAU,SAAU;IACvD,MAAM,WAAW,CAAC,CAAC,UAAU,OAAO,QAAQ,KAAK,OAAO,gBAAgB,OAAO;IAC/E,MAAM,QAAQ,aAAa,OAAO,UAAU,MAAM,KAAK,OAAO,cAAc,kBAAkB,MAAM,WAAW,cAAc;IAC7H,IAAI,aAAa,UAAU,MAAM,IAAI,OAAO,MAAM,UAAU;GAC7D;EACD;CACD,CAAC;;CAGD,MAAM,WAAW,WAAW;EAC3B,MAAM;EACN,IAAI;EACJ,IAAI,QAAQ,OAAO;GAClB,MAAM,EAAE,WAAW;GACnB,MAAM,SAAS,OAAO,IAAI,QAAQ;GAClC,IAAI,CAAC,QAAQ,SAAS,OAAO,YAAY;GACzC,IAAI,SAAS,QAAQ,OAAO,CAAC,CAAC,aAAa,QAAQ,OAAO,QAAQ;EACnE;CACD,CAAC;CAED,OAAO;EACN,IAAI;EACJ;EACA,YAAY,CAAC,MAAM;EACnB,UAAU,CAAC,aAAa;EACxB,OAAO,CAAC,eAAe,QAAQ;CAChC;AACD;;;;;;;;ACvKA,IAAa,kBAA4C;CACxD;EAAE,MAAM;EAAW,IAAI;EAAI,OAAO,EAAE,SAAS;GAAE,cAAc;GAAK,QAAQ;EAAI,EAAE;CAAE;CAClF;EAAE,MAAM;EAAS,IAAI;EAAK,OAAO,EAAE,SAAS;GAAE,cAAc;GAAK,QAAQ;EAAI,EAAE;CAAE;CACjF;EAAE,MAAM;EAAU,IAAI;EAAK,OAAO,EAAE,SAAS;GAAE,cAAc;GAAK,QAAQ;EAAI,EAAE;CAAE;AACnF;;;;;;AAqBA,IAAa,YAAY,gBAAgC,kBAAkB,EAAE,WAAW,WAAW,CAAC;;;;;;AAOpG,IAAa,WAAW,YAA4D,iBAAiB,EAAE,WAAW,WAAW,CAAC;;;;;;AAO9H,SAAgB,OAAO,QAAgB,QAAkC,iBAA4C;CACpH,MAAM,OAAO,OAAO,IAAI,SAAS,CAAC,EAAE,QAAQ;CAC5C,OAAO,OAAO,IAAI,MAAM,OAAO,KAAK,KAAA;AACrC;;;;;;;;AASA,SAAgB,eAAe,OAAc,QAAgB,IAAY,QAAkC,iBAAyB;CACnI,MAAM,MAAM,OAAO,IAAI,SAAS,KAAK;EAAE,IAAI;EAAG,MAAM;CAAE;CACtD,MAAM,OAAuB;EAAE,IAAI,IAAI,KAAK,KAAK,IAAI,GAAG,EAAE;EAAG,MAAM,IAAI;CAAK;CAC5E,OAAO,KAAK,OAAO,MAAM,UAAU,KAAK,MAAM,MAAM,KAAK,KAAK,CAAC,IAAI;EAClE,KAAK;EACL,MAAM,OAAO,KAAK,UAAU;GAAE,QAAQ,OAAO;GAAI,MAAM,KAAK;GAAM,MAAM,MAAM,KAAK,OAAO,EAAE,CAAC;EAAK,CAAC;CACpG;CACA,OAAO,IAAI,WAAW,IAAI;CAC1B,IAAI,KAAK,SAAS,IAAI,MAAM,gBAAgB,OAAO,MAAM;CACzD,OAAO,KAAK;AACb;;;;;;;AAQA,SAAgB,cAAc,UAA4B,CAAC,GAAa;CACvE,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,QAAQ,QAAQ,WAAW,QAAe,WAAmB,CAAC,OAAO,IAAI,SAAS,KAAK,CAAC,OAAO,eAAe,OAAO;CAC3H,MAAM,YAAY,WAAW;EAC5B,MAAM;EACN,IAAI;EACJ,IAAI,OAAO,OAAO;GACjB,MAAM,EAAE,QAAQ,MAAM,WAAW;GACjC,IAAI,CAAC,UAAU,CAAC,MAAM,WAAW,OAAO,OAAO,KAAK,KAAK,KAAK,CAAC,MAAM,OAAO,MAAM,GAAG;GACrF,MAAM,QAAQ,QAAQ,QAAQ,QAAQ,MAAM,OAAO,MAAM,MAAM,IAAI,QAAQ,OAAO,IAAI;GACtF,IAAI,QAAQ,GAAG,eAAe,OAAO,QAAQ,OAAO,KAAK;EAC1D;CACD,CAAC;CACD,MAAM,YAAY,WAAW;EAC5B,MAAM;EACN,IAAI;EACJ,IAAI,QAAQ,OAAO;GAClB,MAAM,OAAO,OAAO,MAAM,QAAQ,KAAK;GACvC,IAAI,MAAM,OAAO,MAAM,IAAI,KAAK,KAAK;EACtC;CACD,CAAC;CACD,OAAO;EACN,IAAI;EACJ;EACA,YAAY,CAAC,SAAS;EACtB,QAAQ,CAAC,QAAQ;EACjB,OAAO,CAAC,WAAW,SAAS;CAC7B;AACD;;;;;;;AC9FA,IAAM,MAAqC,CAAC;;;;;;AAO5C,SAAgB,kBAAkB,GAAG,YAAyC;CAC7E,KAAK,MAAM,aAAa,YAAY,IAAI,CAAC,IAAI,MAAM,SAAS,KAAK,OAAO,UAAU,EAAE,GAAG,IAAI,KAAK,SAAS;AAC1G;;;;;;;AAQA,SAAgB,iBAAyD;CACxE,OAAO;EACNC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACA,GAAG;CACJ;AACD"}
|