@adatechnology/game-weapons-three 0.1.1 → 0.3.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../../game-weapons/src/data/calibers.json","../../game-weapons/src/data/weapons.json","../../game-weapons/src/locale.ts","../../game-weapons/src/rng.ts","../../game-weapons/src/weapon.ts","../../game-weapons/src/arsenal.ts","../src/audio.ts","../src/props.ts","../src/fx.ts","../src/area.ts"],"sourcesContent":["/**\n * @adatechnology/game-weapons-three: the three.js side of @adatechnology/game-weapons. Low-poly weapon models, the weapon in the hands with\n * fire and reload motion, ejected casings and dropped magazines, synthesized sounds, and the weapons test area as a `TestableModule`\n * (any host of @adatechnology/game-contracts, like the test room, loads it with `loadModule`).\n */\nexport { createWeaponsTestModule, weaponsLayout, WEAPON_ITEM_PREFIX, COUNTER_ITEM_ID } from './area'\nexport type { WeaponsTestModuleOptions } from './area'\nexport { createWeaponFx } from './fx'\nexport type { WeaponFx, WeaponFxOptions } from './fx'\nexport { createWeaponAudio } from './audio'\nexport type { WeaponAudio } from './audio'\nexport { buildWeaponModel, buildProp, weaponProp, BODY_ACTIONS } from './props'\nexport type { WeaponProp } from './props'\n","[\n {\n \"id\": \"22lr\",\n \"label\": \".22 LR\",\n \"diameter\": 5.7,\n \"bulletGrams\": 2.6,\n \"muzzleSpeed\": 350,\n \"dragPer100m\": 0.15,\n \"kind\": \"rimfire\"\n },\n {\n \"id\": \"9x19\",\n \"label\": \"9×19 mm\",\n \"diameter\": 9,\n \"bulletGrams\": 7.5,\n \"muzzleSpeed\": 365,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"38spl\",\n \"label\": \".38 Special\",\n \"diameter\": 9.1,\n \"bulletGrams\": 10.2,\n \"muzzleSpeed\": 247,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"357mag\",\n \"label\": \".357 Magnum\",\n \"diameter\": 9.1,\n \"bulletGrams\": 10.2,\n \"muzzleSpeed\": 396,\n \"dragPer100m\": 0.18,\n \"kind\": \"hp\"\n },\n {\n \"id\": \"40sw\",\n \"label\": \".40 S&W\",\n \"diameter\": 10.2,\n \"bulletGrams\": 11.7,\n \"muzzleSpeed\": 310,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"45acp\",\n \"label\": \".45 ACP\",\n \"diameter\": 11.5,\n \"bulletGrams\": 14.9,\n \"muzzleSpeed\": 254,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"380acp\",\n \"label\": \".380 ACP\",\n \"diameter\": 9,\n \"bulletGrams\": 6.2,\n \"muzzleSpeed\": 295,\n \"dragPer100m\": 0.22,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"5_56x45\",\n \"label\": \"5.56×45 mm\",\n \"diameter\": 5.7,\n \"bulletGrams\": 4,\n \"muzzleSpeed\": 935,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"7_62x39\",\n \"label\": \"7.62×39 mm\",\n \"diameter\": 7.9,\n \"bulletGrams\": 8,\n \"muzzleSpeed\": 725,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"7_62x51\",\n \"label\": \"7.62×51 mm (.308)\",\n \"diameter\": 7.8,\n \"bulletGrams\": 9.7,\n \"muzzleSpeed\": 850,\n \"dragPer100m\": 0.08,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"338lapua\",\n \"label\": \".338 Lapua Magnum\",\n \"diameter\": 8.6,\n \"bulletGrams\": 16.2,\n \"muzzleSpeed\": 903,\n \"dragPer100m\": 0.06,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"50bmg\",\n \"label\": \".50 BMG\",\n \"diameter\": 12.7,\n \"bulletGrams\": 42,\n \"muzzleSpeed\": 925,\n \"dragPer100m\": 0.05,\n \"kind\": \"ap\"\n },\n {\n \"id\": \"12ga_00buck\",\n \"label\": \"12 ga 00 buck\",\n \"diameter\": 8.4,\n \"bulletGrams\": 3.5,\n \"muzzleSpeed\": 414,\n \"pellets\": 9,\n \"dragPer100m\": 0.45,\n \"kind\": \"buck\"\n },\n {\n \"id\": \"12ga_slug\",\n \"label\": \"12 ga slug\",\n \"diameter\": 18.5,\n \"bulletGrams\": 28,\n \"muzzleSpeed\": 463,\n \"dragPer100m\": 0.3,\n \"kind\": \"slug\"\n },\n {\n \"id\": \"12ga_birdshot\",\n \"label\": \"12 ga birdshot\",\n \"diameter\": 2.4,\n \"bulletGrams\": 0.2,\n \"muzzleSpeed\": 400,\n \"pellets\": 90,\n \"dragPer100m\": 0.6,\n \"kind\": \"birdshot\"\n },\n {\n \"id\": \"20ga_buck\",\n \"label\": \"20 ga buck\",\n \"diameter\": 6.9,\n \"bulletGrams\": 1.3,\n \"muzzleSpeed\": 400,\n \"pellets\": 20,\n \"dragPer100m\": 0.5,\n \"kind\": \"buck\"\n },\n {\n \"id\": \"arrow\",\n \"label\": \"Arrow (compound bow)\",\n \"diameter\": 7,\n \"bulletGrams\": 25,\n \"muzzleSpeed\": 90,\n \"dragPer100m\": 0.12,\n \"kind\": \"arrow\"\n },\n {\n \"id\": \"crossbow_bolt\",\n \"label\": \"Crossbow bolt\",\n \"diameter\": 8,\n \"bulletGrams\": 20,\n \"muzzleSpeed\": 122,\n \"dragPer100m\": 0.12,\n \"kind\": \"bolt\"\n }\n]\n","[\n {\n \"id\": \"hand\",\n \"name\": \"Hand\",\n \"category\": \"hand\",\n \"action\": {\n \"kind\": \"hand\",\n \"reach\": 2\n },\n \"mass\": 0,\n \"tags\": [\n \"grab\"\n ]\n },\n {\n \"id\": \"kick\",\n \"name\": \"Kick\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 250,\n \"radius\": 0.08,\n \"reach\": 1.1,\n \"rpm\": 60,\n \"noise\": 8\n },\n \"mass\": 0\n },\n {\n \"id\": \"shove\",\n \"name\": \"Shove\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 80,\n \"radius\": 0.1,\n \"reach\": 1.5,\n \"rpm\": 90,\n \"noise\": 5\n },\n \"mass\": 0\n },\n {\n \"id\": \"pistol_9mm\",\n \"name\": \"9 mm service pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 15,\n \"reload\": 2,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.2,\n 0.4\n ],\n \"range\": 50,\n \"noise\": 150\n },\n \"mass\": 0.9,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"pistol_45\",\n \"name\": \".45 ACP pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 280,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 8,\n \"reload\": 2.2,\n \"barrel\": 1,\n \"spreadDeg\": 1.1,\n \"bloomDeg\": 0.8,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.8,\n 0.6\n ],\n \"range\": 50,\n \"noise\": 160\n },\n \"mass\": 1.1,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"pistol_22\",\n \"name\": \".22 LR pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 360,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 1.8,\n \"barrel\": 1,\n \"spreadDeg\": 0.9,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.5,\n 0.2\n ],\n \"range\": 40,\n \"noise\": 90\n },\n \"mass\": 0.7,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"revolver_357\",\n \"name\": \".357 Magnum revolver\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"357mag\",\n \"rpm\": 150,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 4,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 1,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3,\n 0.9\n ],\n \"range\": 60,\n \"noise\": 220\n },\n \"mass\": 1.2,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"revolver_38\",\n \"name\": \".38 Special revolver\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"38spl\",\n \"rpm\": 160,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 3.8,\n \"barrel\": 0.95,\n \"spreadDeg\": 0.9,\n \"bloomDeg\": 0.7,\n \"recoveryDegPerS\": 3.5,\n \"recoil\": [\n 1.6,\n 0.5\n ],\n \"range\": 45,\n \"noise\": 170\n },\n \"mass\": 0.9,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"smg_9mm\",\n \"name\": \"9 mm submachine gun\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 800,\n \"modes\": [\n \"auto\",\n \"burst\",\n \"semi\"\n ],\n \"burst\": 3,\n \"magazine\": 30,\n \"reload\": 2.4,\n \"barrel\": 1.1,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.9,\n 0.5\n ],\n \"range\": 80,\n \"noise\": 180\n },\n \"mass\": 2.6,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"carbine_22\",\n \"name\": \".22 LR carbine\",\n \"category\": \"carbine\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 2.2,\n \"barrel\": 1.4,\n \"spreadDeg\": 0.5,\n \"bloomDeg\": 0.15,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.4,\n 0.15\n ],\n \"range\": 80,\n \"noise\": 100\n },\n \"mass\": 2.4,\n \"tags\": [\n \"small_game\"\n ]\n },\n {\n \"id\": \"rifle_5_56\",\n \"name\": \"5.56 mm assault rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\",\n \"burst\",\n \"semi\"\n ],\n \"burst\": 3,\n \"magazine\": 30,\n \"reload\": 2.5,\n \"barrel\": 1,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1,\n 0.6\n ],\n \"range\": 400,\n \"noise\": 300\n },\n \"mass\": 3.4,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"rifle_7_62x39\",\n \"name\": \"7.62×39 mm assault rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x39\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.8,\n \"barrel\": 1,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.5,\n 0.8\n ],\n \"range\": 350,\n \"noise\": 320\n },\n \"mass\": 3.8,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"rifle_bolt_308\",\n \"name\": \".308 bolt-action rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 40,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 3.5,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3,\n 0.5\n ],\n \"range\": 800,\n \"noise\": 350\n },\n \"mass\": 4,\n \"tags\": [\n \"hunting\"\n ]\n },\n {\n \"id\": \"sniper_338\",\n \"name\": \".338 Lapua sniper rifle\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"338lapua\",\n \"rpm\": 35,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 4,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 4.5,\n 0.7\n ],\n \"range\": 1500,\n \"noise\": 450\n },\n \"mass\": 6.5,\n \"tags\": [\n \"long_range\"\n ]\n },\n {\n \"id\": \"anti_materiel_50\",\n \"name\": \".50 BMG anti-materiel rifle\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"50bmg\",\n \"rpm\": 30,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 4.5,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.15,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 7,\n 1.2\n ],\n \"range\": 1800,\n \"noise\": 600\n },\n \"mass\": 12.5,\n \"tags\": [\n \"long_range\",\n \"heavy\"\n ]\n },\n {\n \"id\": \"shotgun_pump_12\",\n \"name\": \"12 gauge pump-action shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 60,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 6,\n \"reload\": 0.6,\n \"perRound\": true,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 4,\n 1\n ],\n \"range\": 40,\n \"noise\": 400\n },\n \"mass\": 3.2,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"shotgun_double_12\",\n \"name\": \"12 gauge double-barrel shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"break\"\n ],\n \"magazine\": 2,\n \"reload\": 3.5,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 4.5,\n 1.2\n ],\n \"range\": 35,\n \"noise\": 400\n },\n \"mass\": 3,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"shotgun_semi_12\",\n \"name\": \"12 gauge semi-automatic shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 180,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 5,\n \"reload\": 0.7,\n \"perRound\": true,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.4,\n 1\n ],\n \"range\": 40,\n \"noise\": 400\n },\n \"mass\": 3.4,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"bow_compound\",\n \"name\": \"Compound bow\",\n \"category\": \"bow\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"arrow\",\n \"rpm\": 20,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 1,\n \"reload\": 1.5,\n \"barrel\": 1,\n \"spreadDeg\": 0.4,\n \"bloomDeg\": 0.4,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 0.3,\n 0.1\n ],\n \"range\": 60,\n \"noise\": 20\n },\n \"mass\": 1.8,\n \"tags\": [\n \"silent\"\n ]\n },\n {\n \"id\": \"crossbow\",\n \"name\": \"Crossbow\",\n \"category\": \"crossbow\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"crossbow_bolt\",\n \"rpm\": 8,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 1,\n \"reload\": 4,\n \"barrel\": 1,\n \"spreadDeg\": 0.3,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 0.5,\n 0.1\n ],\n \"range\": 70,\n \"noise\": 25\n },\n \"mass\": 3,\n \"tags\": [\n \"silent\"\n ]\n },\n {\n \"id\": \"hammer\",\n \"name\": \"Hammer\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 60,\n \"radius\": 0.08,\n \"reach\": 0.7,\n \"rpm\": 70,\n \"noise\": 6\n },\n \"mass\": 1\n },\n {\n \"id\": \"sledgehammer\",\n \"name\": \"Sledgehammer\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 300,\n \"radius\": 0.15,\n \"reach\": 1.1,\n \"rpm\": 30,\n \"noise\": 8\n },\n \"mass\": 5.5,\n \"tags\": [\n \"heavy\"\n ]\n },\n {\n \"id\": \"baseball_bat\",\n \"name\": \"Baseball bat\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 150,\n \"radius\": 0.1,\n \"reach\": 1,\n \"rpm\": 60,\n \"noise\": 7\n },\n \"mass\": 0.9\n },\n {\n \"id\": \"crowbar\",\n \"name\": \"Crowbar\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 120,\n \"radius\": 0.08,\n \"reach\": 0.9,\n \"rpm\": 60,\n \"noise\": 7\n },\n \"mass\": 2,\n \"tags\": [\n \"pry\"\n ]\n },\n {\n \"id\": \"machete\",\n \"name\": \"Machete\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 140,\n \"radius\": 0.06,\n \"reach\": 0.8,\n \"rpm\": 80,\n \"noise\": 6\n },\n \"mass\": 0.8\n },\n {\n \"id\": \"axe\",\n \"name\": \"Axe\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 250,\n \"radius\": 0.08,\n \"reach\": 0.9,\n \"rpm\": 45,\n \"noise\": 8\n },\n \"mass\": 1.6\n },\n {\n \"id\": \"knife\",\n \"name\": \"Knife\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 40,\n \"radius\": 0.03,\n \"reach\": 0.4,\n \"rpm\": 100,\n \"noise\": 5\n },\n \"mass\": 0.2\n },\n {\n \"id\": \"fists\",\n \"name\": \"Fists\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 25,\n \"radius\": 0.1,\n \"reach\": 0.6,\n \"rpm\": 120,\n \"noise\": 5\n },\n \"mass\": 0\n },\n {\n \"id\": \"lighter\",\n \"name\": \"Lighter\",\n \"category\": \"flame\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 400,\n \"radius\": 0.03,\n \"range\": 0.15,\n \"fuelPerSecond\": 0.02,\n \"fuel\": 60,\n \"noise\": 0\n },\n \"mass\": 0.05,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"flamethrower\",\n \"name\": \"Flamethrower\",\n \"category\": \"flame\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 900,\n \"radius\": 0.6,\n \"range\": 6,\n \"fuelPerSecond\": 1,\n \"fuel\": 20,\n \"cone\": true,\n \"noise\": 20\n },\n \"mass\": 15,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"molotov\",\n \"name\": \"Molotov cocktail\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"energy\": 500,\n \"radius\": 1.5,\n \"fuse\": 0,\n \"throwSpeed\": 12,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 1.5,\n \"seconds\": 12\n },\n \"noise\": 60\n },\n \"mass\": 0.8,\n \"tags\": [\n \"fire\",\n \"improvised\"\n ]\n },\n {\n \"id\": \"cutting_torch\",\n \"name\": \"Oxy-fuel cutting torch\",\n \"category\": \"heat\",\n \"action\": {\n \"kind\": \"heat\",\n \"temperature\": 3000,\n \"radius\": 0.02,\n \"range\": 0.25,\n \"fuelPerSecond\": 0.05,\n \"fuel\": 30,\n \"noise\": 15\n },\n \"mass\": 4,\n \"tags\": [\n \"fire\",\n \"cutting\"\n ]\n },\n {\n \"id\": \"blowtorch\",\n \"name\": \"Blowtorch\",\n \"category\": \"heat\",\n \"action\": {\n \"kind\": \"heat\",\n \"temperature\": 1300,\n \"radius\": 0.04,\n \"range\": 0.3,\n \"fuelPerSecond\": 0.04,\n \"fuel\": 30,\n \"noise\": 10\n },\n \"mass\": 0.6,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"frag_grenade\",\n \"name\": \"Fragmentation grenade\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"energy\": 200000,\n \"radius\": 6,\n \"fuse\": 4,\n \"throwSpeed\": 15,\n \"noise\": 400\n },\n \"mass\": 0.45,\n \"tags\": [\n \"explosive\"\n ]\n },\n {\n \"id\": \"pipe_bomb\",\n \"name\": \"Pipe bomb\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"energy\": 100000,\n \"radius\": 4,\n \"fuse\": 3,\n \"throwSpeed\": 13,\n \"noise\": 350\n },\n \"mass\": 0.7,\n \"tags\": [\n \"explosive\",\n \"improvised\"\n ]\n },\n {\n \"id\": \"screwdriver\",\n \"name\": \"Screwdriver\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"screwdriver\",\n \"reach\": 0.5,\n \"noise\": 5\n },\n \"mass\": 0.15\n },\n {\n \"id\": \"wrench\",\n \"name\": \"Wrench\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"wrench\",\n \"reach\": 0.6,\n \"noise\": 6\n },\n \"mass\": 0.5\n },\n {\n \"id\": \"pry_bar\",\n \"name\": \"Pry bar\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"pry_bar\",\n \"reach\": 0.8,\n \"noise\": 8\n },\n \"mass\": 0.8\n },\n {\n \"id\": \"hacksaw\",\n \"name\": \"Hacksaw\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"saw\",\n \"reach\": 0.7,\n \"noise\": 10\n },\n \"mass\": 0.6\n },\n {\n \"id\": \"utility_knife\",\n \"name\": \"Utility knife\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"knife\",\n \"reach\": 0.3,\n \"noise\": 3\n },\n \"mass\": 0.1\n },\n {\n \"id\": \"claw_hammer\",\n \"name\": \"Claw hammer\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"hammer\",\n \"reach\": 0.5,\n \"noise\": 8\n },\n \"mass\": 0.7\n },\n {\n \"id\": \"extinguisher\",\n \"name\": \"Fire extinguisher\",\n \"category\": \"extinguisher\",\n \"action\": {\n \"kind\": \"extinguisher\",\n \"range\": 4,\n \"coolC\": 300,\n \"charge\": 12,\n \"noise\": 25\n },\n \"mass\": 5,\n \"tags\": [\n \"safety\"\n ]\n }\n]\n","/** Locales shipped with the package. Unknown locales fall back to `en`. */\nexport type WeaponsLocale = 'en' | 'pt-BR'\n\nexport interface WeaponsStrings {\n /** Display name of each weapon id. */\n weapons: Record<string, string>\n /** Display name of each fire mode. */\n modes: Record<string, string>\n /** Display name of each weapon category. */\n categories: Record<string, string>\n}\n\nconst modesEn = { single: 'single action', semi: 'semi-automatic', burst: 'burst', auto: 'automatic', pump: 'pump action', bolt: 'bolt action', lever: 'lever action', break: 'break action' }\nconst categoriesEn = {\n pistol: 'pistol', revolver: 'revolver', smg: 'submachine gun', rifle: 'rifle', carbine: 'carbine', sniper: 'sniper rifle', shotgun: 'shotgun',\n bow: 'bow', crossbow: 'crossbow', melee_blunt: 'blunt melee', melee_blade: 'bladed melee', flame: 'flame', heat: 'heat', throwable: 'throwable',\n tool: 'tool', extinguisher: 'extinguisher', hand: 'hand',\n}\n\nexport const locales: Record<WeaponsLocale, WeaponsStrings> = {\n en: {\n weapons: {\n hand: 'Hand', kick: 'Kick', shove: 'Shove', pistol_9mm: '9 mm service pistol', pistol_45: '.45 ACP pistol', pistol_22: '.22 LR pistol', revolver_357: '.357 Magnum revolver',\n revolver_38: '.38 Special revolver', smg_9mm: '9 mm submachine gun', carbine_22: '.22 LR carbine', rifle_5_56: '5.56 mm assault rifle',\n rifle_7_62x39: '7.62×39 mm assault rifle', rifle_bolt_308: '.308 bolt-action rifle', sniper_338: '.338 Lapua sniper rifle',\n anti_materiel_50: '.50 BMG anti-materiel rifle', shotgun_pump_12: '12 gauge pump-action shotgun', shotgun_double_12: '12 gauge double-barrel shotgun',\n shotgun_semi_12: '12 gauge semi-automatic shotgun', bow_compound: 'Compound bow', crossbow: 'Crossbow', hammer: 'Hammer', sledgehammer: 'Sledgehammer',\n baseball_bat: 'Baseball bat', crowbar: 'Crowbar', machete: 'Machete', axe: 'Axe', knife: 'Knife', fists: 'Fists', lighter: 'Lighter',\n flamethrower: 'Flamethrower', molotov: 'Molotov cocktail', cutting_torch: 'Oxy-fuel cutting torch', blowtorch: 'Blowtorch',\n frag_grenade: 'Fragmentation grenade', pipe_bomb: 'Pipe bomb', screwdriver: 'Screwdriver', wrench: 'Wrench', pry_bar: 'Pry bar', hacksaw: 'Hacksaw',\n utility_knife: 'Utility knife', claw_hammer: 'Claw hammer', extinguisher: 'Fire extinguisher',\n },\n modes: modesEn,\n categories: categoriesEn,\n },\n 'pt-BR': {\n weapons: {\n hand: 'mão', kick: 'chute', shove: 'empurrão', pistol_9mm: 'pistola 9 mm', pistol_45: 'pistola .45', pistol_22: 'pistola .22', revolver_357: 'revólver .357', revolver_38: 'revólver .38',\n smg_9mm: 'submetralhadora 9 mm', carbine_22: 'carabina .22', rifle_5_56: 'fuzil 5,56', rifle_7_62x39: 'fuzil 7,62×39', rifle_bolt_308: 'fuzil de ferrolho .308',\n sniper_338: 'fuzil de precisão .338', anti_materiel_50: 'fuzil antimaterial .50', shotgun_pump_12: 'espingarda de repetição calibre 12',\n shotgun_double_12: 'espingarda de dois canos calibre 12', shotgun_semi_12: 'espingarda semiautomática calibre 12', bow_compound: 'arco composto',\n crossbow: 'besta', hammer: 'martelo', sledgehammer: 'marreta', baseball_bat: 'taco de beisebol', crowbar: 'pé de cabra', machete: 'facão', axe: 'machado',\n knife: 'faca', fists: 'punhos', lighter: 'isqueiro', flamethrower: 'lança-chamas', molotov: 'coquetel molotov', cutting_torch: 'maçarico de corte',\n blowtorch: 'maçarico', frag_grenade: 'granada de fragmentação', pipe_bomb: 'bomba caseira', screwdriver: 'chave de fenda', wrench: 'chave inglesa',\n pry_bar: 'alavanca', hacksaw: 'serra de arco', utility_knife: 'estilete', claw_hammer: 'martelo de unha', extinguisher: 'extintor',\n },\n modes: { single: 'tiro único', semi: 'semiautomático', burst: 'rajada', auto: 'automático', pump: 'repetição', bolt: 'ferrolho', lever: 'alavanca', break: 'basculante' },\n categories: {\n pistol: 'pistola', revolver: 'revólver', smg: 'submetralhadora', rifle: 'fuzil', carbine: 'carabina', sniper: 'fuzil de precisão', shotgun: 'espingarda',\n bow: 'arco', crossbow: 'besta', melee_blunt: 'corpo a corpo contundente', melee_blade: 'corpo a corpo cortante', flame: 'chama', heat: 'calor',\n throwable: 'arremessável', tool: 'ferramenta', extinguisher: 'extintor', hand: 'mão',\n },\n },\n}\n\nexport const resolveStrings = (locale: string | undefined): WeaponsStrings => locales[(locale as WeaponsLocale) ?? 'en'] ?? locales.en\n","import type { Vec3 } from './types'\n\n/** Deterministic mulberry32 generator; returns floats in [0, 1). */\nexport const createRng = (seed: number): (() => number) => {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) >>> 0\n let t = a\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\nexport const normalize = (v: Vec3): Vec3 => {\n const l = Math.hypot(v[0], v[1], v[2])\n return l > 1e-12 ? [v[0] / l, v[1] / l, v[2] / l] : [0, 0, -1]\n}\n\nconst cross = (a: Vec3, b: Vec3): Vec3 => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]\n\n/** Uniform direction inside a cone of half-angle `deg` around the unit vector `dir` (uniform over the solid angle). */\nexport const sampleCone = (dir: Vec3, deg: number, rng: () => number): Vec3 => {\n if (deg <= 0) return dir\n const cosMax = Math.cos((deg * Math.PI) / 180)\n const cosT = 1 - rng() * (1 - cosMax)\n const sinT = Math.sqrt(Math.max(0, 1 - cosT * cosT))\n const phi = rng() * Math.PI * 2\n const helper: Vec3 = Math.abs(dir[1]) < 0.9 ? [0, 1, 0] : [1, 0, 0]\n const u = normalize(cross(helper, dir))\n const v = cross(dir, u)\n const cx = Math.cos(phi) * sinT\n const cy = Math.sin(phi) * sinT\n return normalize([\n u[0] * cx + v[0] * cy + dir[0] * cosT,\n u[1] * cx + v[1] * cy + dir[1] * cosT,\n u[2] * cx + v[2] * cy + dir[2] * cosT,\n ])\n}\n","import { createRng, normalize, sampleCone } from './rng'\nimport type {\n CaliberDef,\n FireMode,\n Shot,\n TriggerResult,\n Use,\n Vec3,\n WeaponAction,\n WeaponDef,\n WeaponState,\n} from './types'\n\nconst EPS = 1e-9\nconst DEFAULT_THROWABLES = 3\n/** Total spread (base + bloom) never exceeds this many times the base spread. */\nexport const BLOOM_CAP = 4\n/** Fraction of the throw speed added upwards so a throw arcs. */\nconst THROW_LIFT = 0.15\n\n/** Muzzle energy in joules of ONE projectile (a bullet, or one pellet): 0.5 × mass × speed², speed scaled by the barrel factor. */\nexport const muzzleEnergy = (caliber: CaliberDef, barrel = 1): number => {\n const v = caliber.muzzleSpeed * barrel\n return 0.5 * (caliber.bulletGrams / 1000) * v * v\n}\n\nexport interface WeaponStateInit {\n def: WeaponDef\n caliber: CaliberDef | null\n seed: number\n reserve?: number\n}\n\nconst result = (status: TriggerResult['status'], extra: Partial<TriggerResult> = {}): TriggerResult => ({\n shots: [],\n uses: [],\n status,\n recoil: [0, 0],\n noise: 0,\n ...extra,\n})\n\n/** Runtime of one weapon. See `WeaponState` for the contract. */\nexport class WeaponRuntime implements WeaponState {\n readonly def: WeaponDef\n readonly caliber: CaliberDef | null\n reserve: number\n mode: FireMode\n private _ammo: number\n private readonly _capacity: number\n private readonly action: WeaponAction\n private readonly rng: () => number\n private readonly initialReserve: number\n\n private clock = 0\n /** Time already advanced by the other of update / trigger in the same frame (so calling both does not count `dt` twice). */\n private pend: { src: 'update' | 'trigger'; amt: number } | null = null\n private readyAt = 0\n private latched = false\n\n private _reloading = false\n private reloadEnd = 0\n\n /** Bloom degrees at `extraClock`. */\n private extra = 0\n private extraClock = 0\n\n constructor(init: WeaponStateInit) {\n this.def = init.def\n this.caliber = init.caliber\n this.action = init.def.action\n this.rng = createRng(init.seed)\n const a = this.action\n this.mode = a.kind === 'firearm' ? a.modes[0] ?? 'single' : 'single'\n switch (a.kind) {\n case 'firearm':\n this._capacity = a.magazine\n break\n case 'flame':\n case 'heat':\n this._capacity = a.fuel\n break\n case 'extinguisher':\n this._capacity = a.charge\n break\n case 'throwable':\n this._capacity = a.count ?? DEFAULT_THROWABLES\n break\n default:\n this._capacity = 0\n }\n this._ammo = this._capacity\n this.initialReserve = init.reserve ?? (a.kind === 'firearm' ? a.magazine * 3 : 0)\n this.reserve = this.initialReserve\n }\n\n get ammo(): number {\n return this._ammo\n }\n get capacity(): number {\n return this._capacity\n }\n get reloading(): boolean {\n return this._reloading\n }\n get spread(): number {\n if (this.action.kind !== 'firearm') return 0\n return this.action.spreadDeg + this.extraAt(this.clock)\n }\n\n private extraAt(t: number): number {\n if (this.action.kind !== 'firearm') return 0\n const rec = this.action.recoveryDegPerS ?? 4\n return Math.max(0, this.extra - rec * Math.max(0, t - this.extraClock))\n }\n\n // --- time -----------------------------------------------------------------------------------------------------------------------\n\n update(dt: number): void {\n const d = Math.max(0, dt)\n let eff = d\n if (this.pend && this.pend.src === 'trigger') {\n eff = Math.max(0, d - this.pend.amt)\n this.pend = null\n } else {\n this.pend = { src: 'update', amt: d }\n }\n this.clock += eff\n this.settle(this.clock)\n }\n\n /** Complete the reload steps that finish at or before `t`. */\n private settle(t: number): void {\n const a = this.action\n if (a.kind !== 'firearm') return\n while (this._reloading && this.reloadEnd <= t + EPS) {\n if (a.perRound) {\n if (this.reserve > 0 && this._ammo < this._capacity) {\n this._ammo += 1\n this.reserve -= 1\n }\n if (this._ammo >= this._capacity || this.reserve <= 0) this._reloading = false\n else this.reloadEnd += a.reload\n } else {\n const take = Math.min(this._capacity - this._ammo, this.reserve)\n this._ammo += take\n this.reserve -= take\n this._reloading = false\n }\n }\n }\n\n // --- commands -------------------------------------------------------------------------------------------------------------------\n\n release(): void {\n this.latched = false\n }\n\n reload(): boolean {\n const a = this.action\n if (a.kind === 'throwable') {\n if (this._ammo >= this._capacity || this.reserve <= 0) return false\n this._ammo += 1\n this.reserve -= 1\n return true\n }\n if (a.kind !== 'firearm' || this._reloading) return false\n if (this._ammo >= this._capacity || this.reserve <= 0) return false\n this._reloading = true\n this.reloadEnd = this.clock + a.reload\n return true\n }\n\n cycleMode(): FireMode {\n if (this.action.kind !== 'firearm') return this.mode\n const modes = this.action.modes\n const i = modes.indexOf(this.mode)\n this.mode = modes[(i + 1) % modes.length] ?? this.mode\n return this.mode\n }\n\n refill(): void {\n this._ammo = this._capacity\n this.reserve = this.initialReserve\n this._reloading = false\n this.readyAt = this.clock\n this.latched = false\n this.extra = 0\n }\n\n // --- trigger --------------------------------------------------------------------------------------------------------------------\n\n trigger(origin: Vec3, direction: Vec3, dt: number, held = false, source?: string): TriggerResult {\n const d = Math.max(0, dt)\n let overlap = 0\n if (this.pend && this.pend.src === 'update') {\n overlap = Math.min(this.pend.amt, d)\n this.pend = null\n } else {\n this.pend = { src: 'trigger', amt: d }\n }\n const start = this.clock - overlap\n const end = start + d\n this.settle(start)\n\n const dir = normalize(direction)\n let res: TriggerResult\n const a = this.action\n switch (a.kind) {\n case 'firearm':\n res = this.fireFirearm(a, origin, dir, start, end, held, source)\n break\n case 'melee':\n res = this.fireMelee(a, origin, dir, start, end)\n break\n case 'flame':\n case 'heat':\n res = this.fireFuel(a, origin, dir, d)\n break\n case 'extinguisher':\n res = this.fireExtinguisher(a, origin, dir, d)\n break\n case 'throwable':\n res = this.fireThrowable(a, origin, dir, held)\n break\n case 'tool':\n res = d > 0 ? result('ok', { uses: [{ kind: 'tool', tool: a.tool, reach: a.reach, duration: d, origin, direction: dir }], noise: a.noise }) : result('ok')\n break\n case 'hand':\n res = this.oncePerPull(held)\n ? result('ok', { uses: [{ kind: 'hand', reach: a.reach, origin, direction: dir }] })\n : result('cooldown')\n break\n }\n this.clock = Math.max(this.clock, end)\n this.settle(this.clock)\n return res\n }\n\n /** Semi-style gating: a held trigger that already fired does nothing until `release()` or a new pull (`held` false). */\n private oncePerPull(held: boolean): boolean {\n if (!held) this.latched = false\n if (this.latched) return false\n this.latched = true\n return true\n }\n\n private fireFirearm(a: Extract<WeaponAction, { kind: 'firearm' }>, origin: Vec3, dir: Vec3, start: number, end: number, held: boolean, source?: string): TriggerResult {\n if (this._reloading) {\n if (a.perRound && this._ammo > 0) this._reloading = false // a tube reload is interrupted by the trigger\n else return result('reloading')\n }\n const auto = this.mode === 'auto'\n if (!auto && !this.oncePerPull(held)) return result('cooldown')\n if (this._ammo <= 0) return result('empty')\n\n const iv = 60 / a.rpm\n const t0 = Math.max(start, this.readyAt)\n if (t0 > end + EPS) return result('cooldown')\n\n const res = result('ok')\n const fire = (t: number): void => {\n this.fireOne(a, origin, dir, t, res, source)\n }\n if (auto) {\n for (let t = t0, n = 0; this._ammo > 0 && (n === 0 ? t <= end + EPS : t < end - EPS); t += iv, n++) fire(t)\n } else if (this.mode === 'burst') {\n const count = Math.min(a.burst ?? 3, this._ammo)\n for (let k = 0; k < count; k++) fire(t0 + k * iv)\n } else {\n fire(t0)\n }\n return res\n }\n\n private fireOne(a: Extract<WeaponAction, { kind: 'firearm' }>, origin: Vec3, dir: Vec3, t: number, res: TriggerResult, source?: string): void {\n const cal = this.caliber as CaliberDef\n const barrel = a.barrel ?? 1\n const speed = cal.muzzleSpeed * barrel\n const energy = muzzleEnergy(cal, barrel)\n const drag = cal.dragPer100m ?? 0.1\n const energyAt = (distance: number): number => {\n const f = Math.pow(1 - drag, Math.max(0, distance) / 100)\n return energy * f * f\n }\n const bloomNow = this.extraAt(t)\n const spread = a.spreadDeg + bloomNow\n const aim = sampleCone(dir, spread, this.rng)\n const pellets = cal.pellets ?? 1\n const pelletSpread = pellets > 1 ? a.pelletSpreadDeg ?? 3 : 0\n for (let p = 0; p < pellets; p++) {\n const shot: Shot = {\n origin: [origin[0], origin[1], origin[2]],\n direction: sampleCone(aim, pelletSpread, this.rng),\n energy,\n caliber: cal.diameter,\n caliberId: cal.id,\n speed,\n energyAt,\n pellet: p,\n weapon: this.def.id,\n }\n if (source !== undefined) shot.source = source\n res.shots.push(shot)\n }\n this._ammo -= 1\n this.readyAt = t + 60 / a.rpm\n this.extra = Math.min(bloomNow + (a.bloomDeg ?? 0), a.spreadDeg * (BLOOM_CAP - 1))\n this.extraClock = t\n res.recoil = [res.recoil[0] + a.recoil[0], res.recoil[1] + (this.rng() * 2 - 1) * a.recoil[1]]\n res.noise = a.noise\n }\n\n private fireMelee(a: Extract<WeaponAction, { kind: 'melee' }>, origin: Vec3, dir: Vec3, start: number, end: number): TriggerResult {\n const t0 = Math.max(start, this.readyAt)\n if (t0 > end + EPS) return result('cooldown')\n this.readyAt = t0 + 60 / a.rpm\n const use: Use = { kind: 'melee', damage: a.damage, energy: a.energy, radius: a.radius, reach: a.reach, origin, direction: dir }\n return result('ok', { uses: [use], noise: a.noise })\n }\n\n private fireFuel(a: Extract<WeaponAction, { kind: 'flame' | 'heat' }>, origin: Vec3, dir: Vec3, dt: number): TriggerResult {\n if (this._ammo <= EPS) return result('no_fuel')\n if (dt <= 0) return result('ok')\n const need = a.fuelPerSecond * dt\n let duration = dt\n if (need > this._ammo) {\n duration = dt * (this._ammo / need)\n this._ammo = 0\n } else {\n this._ammo -= need\n }\n const use: Use =\n a.kind === 'flame'\n ? { kind: 'flame', temperature: a.temperature, radius: a.radius, range: a.range, cone: a.cone ?? false, duration, origin, direction: dir }\n : { kind: 'heat', temperature: a.temperature, radius: a.radius, range: a.range, duration, origin, direction: dir }\n return result('ok', { uses: [use], noise: a.noise })\n }\n\n private fireExtinguisher(a: Extract<WeaponAction, { kind: 'extinguisher' }>, origin: Vec3, dir: Vec3, dt: number): TriggerResult {\n if (this._ammo <= EPS) return result('no_fuel')\n if (dt <= 0) return result('ok')\n const duration = Math.min(dt, this._ammo)\n this._ammo -= duration\n return result('ok', { uses: [{ kind: 'extinguish', range: a.range, coolC: a.coolC, duration, origin, direction: dir }], noise: a.noise })\n }\n\n private fireThrowable(a: Extract<WeaponAction, { kind: 'throwable' }>, origin: Vec3, dir: Vec3, held: boolean): TriggerResult {\n if (!this.oncePerPull(held)) return result('cooldown')\n if (this._ammo <= 0) return result('empty')\n this._ammo -= 1\n const velocity: Vec3 = [dir[0] * a.throwSpeed, dir[1] * a.throwSpeed + a.throwSpeed * THROW_LIFT, dir[2] * a.throwSpeed]\n const use: Use = { kind: 'throw', energy: a.energy, radius: a.radius, fuse: a.fuse, velocity, origin }\n if (a.fire) use.fire = { ...a.fire }\n return result('ok', { uses: [use], noise: a.noise })\n }\n}\n","import calibersJson from './data/calibers.json'\nimport weaponsJson from './data/weapons.json'\nimport { resolveStrings } from './locale'\nimport type { Arsenal, ArsenalOptions, CaliberDef, CaliberId, WeaponCategory, WeaponDef, WeaponId, WeaponState } from './types'\nimport { muzzleEnergy, WeaponRuntime } from './weapon'\n\nexport const CALIBERS = calibersJson as unknown as CaliberDef[]\nexport const WEAPONS = weaponsJson as unknown as WeaponDef[]\n\n/** A reasonable starting kit for a test room or a sandbox. */\nexport const DEFAULT_LOADOUT: WeaponId[] = [\n 'hand', 'kick', 'shove', 'pistol_9mm', 'revolver_357', 'shotgun_pump_12', 'rifle_5_56', 'rifle_bolt_308', 'hammer', 'axe', 'machete', 'utility_knife', 'crowbar', 'lighter', 'flamethrower',\n 'cutting_torch', 'molotov', 'frag_grenade', 'screwdriver', 'wrench', 'pry_bar', 'hacksaw', 'extinguisher',\n]\n\nexport { muzzleEnergy }\n\n/** Create an arsenal: the built-in calibres and weapons merged (by id) with the ones in `options`. */\nexport const createArsenal = (options: ArsenalOptions = {}): Arsenal => {\n const calibers = new Map<CaliberId, CaliberDef>()\n for (const c of [...CALIBERS, ...(options.calibers ?? [])]) calibers.set(c.id, c)\n const weapons = new Map<WeaponId, WeaponDef>()\n for (const w of [...WEAPONS, ...(options.weapons ?? [])]) weapons.set(w.id, w)\n const strings = resolveStrings(options.locale)\n const baseSeed = options.seed ?? 1\n let counter = 0\n\n const create = (id: WeaponId, opts: { seed?: number; reserve?: number } = {}): WeaponState => {\n const def = weapons.get(id)\n if (!def) throw new Error(`game-weapons: unknown weapon \"${id}\"`)\n let caliber: CaliberDef | null = null\n if (def.action.kind === 'firearm') {\n caliber = calibers.get(def.action.caliber) ?? null\n if (!caliber) throw new Error(`game-weapons: weapon \"${id}\" uses unknown calibre \"${def.action.caliber}\"`)\n }\n counter += 1\n const seed = opts.seed ?? (baseSeed + Math.imul(counter, 0x9e3779b1)) >>> 0\n return new WeaponRuntime({ def, caliber, seed, reserve: opts.reserve })\n }\n\n return {\n calibers,\n weapons,\n create,\n muzzleEnergy(caliber, barrel = 1) {\n const c = calibers.get(caliber)\n if (!c) throw new Error(`game-weapons: unknown calibre \"${caliber}\"`)\n return muzzleEnergy(c, barrel)\n },\n name(id) {\n const w = weapons.get(id)\n if (w) return strings.weapons[id] ?? w.name ?? id\n return strings.modes[id] ?? strings.categories[id] ?? calibers.get(id)?.label ?? id\n },\n list(category?: WeaponCategory) {\n const all = [...weapons.values()]\n return category ? all.filter((w) => w.category === category) : all\n },\n }\n}\n","// Weapon sounds synthesized with WebAudio: no sound files, so the kit stays offline and small. Every call is a no-op where there is no\n// AudioContext (tests, workers), and the context is only created on the first sound, which comes from a click or a key (browsers allow it).\n\n/** Sounds the weapon presentation plays. */\nexport interface WeaponAudio {\n /** A shot: louder and longer the more muzzle energy (joules). */\n shot(energyJ: number, category: string): void\n /** Dry click of an empty weapon. */\n click(): void\n /** Magazine out, or the first shell in. */\n reloadStart(category: string): void\n /** Magazine seated and the action racked. */\n reloadEnd(category: string): void\n /** The pump or lever cycling after a shot. */\n cycle(): void\n /** A casing bouncing on the floor. */\n clink(): void\n /** A magazine landing on the floor. */\n thud(): void\n /** Master volume, 0 to 1. */\n setVolume(volume: number): void\n dispose(): void\n}\n\ntype AudioContextCtor = new () => AudioContext\n\nconst NOISE_SECONDS = 0.6\n\nexport function createWeaponAudio(volume = 0.6): WeaponAudio {\n const Ctor = (globalThis as { AudioContext?: AudioContextCtor; webkitAudioContext?: AudioContextCtor }).AudioContext ?? (globalThis as { webkitAudioContext?: AudioContextCtor }).webkitAudioContext\n let ctx: AudioContext | null = null\n let master: GainNode | null = null\n let noise: AudioBuffer | null = null\n let level = volume\n\n const ready = (): AudioContext | null => {\n if (!Ctor) return null\n if (!ctx) {\n ctx = new Ctor()\n master = ctx.createGain()\n master.gain.value = level\n master.connect(ctx.destination)\n noise = ctx.createBuffer(1, Math.floor(ctx.sampleRate * NOISE_SECONDS), ctx.sampleRate)\n const data = noise.getChannelData(0)\n for (let i = 0; i < data.length; i++) data[i] = Math.random() * 2 - 1\n }\n if (ctx.state === 'suspended') void ctx.resume()\n return ctx\n }\n\n // a filtered noise burst with a fast attack and an exponential tail\n const burst = (options: { at?: number; seconds: number; gain: number; filter: BiquadFilterType; frequency: number; q?: number }): void => {\n const audio = ready()\n if (!audio || !noise || !master) return\n const start = audio.currentTime + (options.at ?? 0)\n const source = audio.createBufferSource()\n source.buffer = noise\n const filter = audio.createBiquadFilter()\n filter.type = options.filter\n filter.frequency.value = options.frequency\n filter.Q.value = options.q ?? 0.8\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(options.gain, start + 0.004)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + options.seconds)\n source.connect(filter).connect(gain).connect(master)\n source.start(start)\n source.stop(start + options.seconds + 0.05)\n }\n\n const tone = (options: { at?: number; seconds: number; gain: number; frequency: number; to?: number; type?: OscillatorType }): void => {\n const audio = ready()\n if (!audio || !master) return\n const start = audio.currentTime + (options.at ?? 0)\n const osc = audio.createOscillator()\n osc.type = options.type ?? 'sine'\n osc.frequency.setValueAtTime(options.frequency, start)\n if (options.to) osc.frequency.exponentialRampToValueAtTime(options.to, start + options.seconds)\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(options.gain, start + 0.003)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + options.seconds)\n osc.connect(gain).connect(master)\n osc.start(start)\n osc.stop(start + options.seconds + 0.05)\n }\n\n const metal = (at: number, frequency: number, gain: number): void => {\n burst({ at, seconds: 0.05, gain, filter: 'highpass', frequency, q: 2 })\n tone({ at, seconds: 0.04, gain: gain * 0.6, frequency: frequency * 0.6, type: 'square' })\n }\n\n return {\n shot(energyJ, category) {\n // 200 J (.22) to 15 000 J (.50 BMG) mapped to 0..1\n const k = Math.min(1, Math.max(0, Math.log10(Math.max(energyJ, 50) / 50) / 2.5))\n const shotgun = category === 'shotgun'\n burst({ seconds: 0.12 + k * 0.35 + (shotgun ? 0.1 : 0), gain: 0.5 + k * 0.5, filter: 'lowpass', frequency: 4200 - k * 2600 })\n burst({ seconds: 0.03, gain: 0.6, filter: 'highpass', frequency: 3000 })\n tone({ seconds: 0.14 + k * 0.2, gain: 0.35 + k * 0.4, frequency: 140 - k * 70, to: 40 })\n },\n click() {\n metal(0, 2600, 0.25)\n },\n reloadStart(category) {\n metal(0, 1500, 0.35)\n if (category !== 'shotgun' && category !== 'revolver') metal(0.12, 900, 0.2)\n },\n reloadEnd(category) {\n metal(0, 1100, 0.45)\n if (category !== 'revolver') metal(0.18, 1900, 0.4)\n },\n cycle() {\n metal(0.22, 900, 0.35)\n metal(0.36, 1300, 0.35)\n },\n clink() {\n const f = 3200 + Math.random() * 2000\n tone({ seconds: 0.09, gain: 0.12, frequency: f })\n tone({ seconds: 0.06, gain: 0.06, frequency: f * 2.7 })\n },\n thud() {\n burst({ seconds: 0.09, gain: 0.35, filter: 'lowpass', frequency: 380 })\n },\n setVolume(next) {\n level = Math.max(0, Math.min(1, next))\n if (master) master.gain.value = level\n },\n dispose() {\n void ctx?.close()\n ctx = null\n master = null\n noise = null\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, JointSpec, PartSpec, Vec3 } from '@adatechnology/game-contracts'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\n\n/** A low-poly prop: its destruction spec (box parts only) and one colour per part. */\nexport interface WeaponProp {\n spec: DestructibleSpec\n colors: Record<string, number>\n}\n\ntype Extra = Partial<Omit<PartSpec, 'id' | 'material' | 'shape' | 'position'>>\nconst box = (id: string, material: string, size: Vec3, position: Vec3, extra: Extra = {}): PartSpec => ({ id, material, shape: { kind: 'box', size }, position, ...extra })\nconst joint = (a: string, b: string, kind: JointSpec['kind']): JointSpec => ({ a, b, kind })\n\n// A grip and a body lying flat end to end, long axis along +x, the muzzle or head at +x. One thickness for both parts so the prop lies flat,\n// and the parts touch without overlapping: overlapping parts are pushed apart by the physics and the prop slides away.\nconst handled = (name: string, handle: [string, Vec3], head: [string, Vec3]): WeaponProp => {\n const [handleMaterial, rawHandle] = handle\n const [headMaterial, rawHead] = head\n const thickness = Math.max(rawHandle[1], rawHead[1])\n const handleSize: Vec3 = [rawHandle[0], thickness, rawHandle[2]]\n const headSize: Vec3 = [rawHead[0], thickness, rawHead[2]]\n const shift = (handleSize[0] - headSize[0]) / 2\n return {\n spec: {\n name,\n parts: [box('handle', handleMaterial, handleSize, [-handleSize[0] / 2 + shift, thickness / 2, 0]), box('head', headMaterial, headSize, [headSize[0] / 2 + shift, thickness / 2, 0])],\n joints: [joint('handle', 'head', 'screw')],\n tags: ['weapon'],\n },\n colors: { handle: handleMaterial === 'steel' ? 0x3a3d42 : handleMaterial === 'plastic' ? 0x2b2d30 : 0x7a5530, head: headMaterial === 'steel' ? 0x8f969e : headMaterial === 'copper' ? 0xb87333 : 0x6b4a2a },\n }\n}\nconst solid = (name: string, material: string, size: Vec3, color: number): WeaponProp => ({\n spec: { name, parts: [box('body', material, size, [0, size[1] / 2, 0])], joints: [], tags: ['weapon'] },\n colors: { body: color },\n})\n\nconst SHAPES: Record<string, (name: string, id: string) => WeaponProp> = {\n pistol: (n) => handled(n, ['plastic', [0.06, 0.03, 0.11]], ['steel', [0.2, 0.03, 0.04]]),\n revolver: (n) => handled(n, ['wood_soft', [0.06, 0.035, 0.11]], ['steel', [0.24, 0.04, 0.05]]),\n smg: (n) => handled(n, ['plastic', [0.2, 0.05, 0.14]], ['steel', [0.45, 0.05, 0.06]]),\n carbine: (n) => handled(n, ['wood_soft', [0.35, 0.05, 0.12]], ['steel', [0.6, 0.04, 0.05]]),\n rifle: (n) => handled(n, ['wood_soft', [0.35, 0.06, 0.13]], ['steel', [0.75, 0.05, 0.07]]),\n sniper: (n) => handled(n, ['plastic', [0.4, 0.06, 0.14]], ['steel', [0.95, 0.06, 0.08]]),\n shotgun: (n) => handled(n, ['wood_soft', [0.38, 0.06, 0.13]], ['steel', [0.7, 0.05, 0.06]]),\n bow: (n) => solid(n, 'wood_soft', [0.95, 0.03, 0.22], 0x5a3d22),\n crossbow: (n) => handled(n, ['wood_soft', [0.6, 0.06, 0.08]], ['steel', [0.12, 0.04, 0.26]]),\n melee_blunt: (n, id) =>\n id === 'baseball_bat'\n ? solid(n, 'wood_soft', [0.84, 0.06, 0.06], 0xb08550)\n : handled(n, ['wood_soft', [id === 'sledgehammer' ? 0.8 : 0.32, 0.03, 0.03]], ['steel', id === 'sledgehammer' ? [0.08, 0.08, 0.2] : [0.06, 0.04, 0.12]]),\n melee_blade: (n, id) => handled(n, ['wood_soft', [0.13, 0.03, 0.03]], ['steel', id === 'axe' ? [0.5, 0.03, 0.16] : id === 'knife' ? [0.16, 0.01, 0.03] : [0.45, 0.01, 0.05]]),\n tool: (n) => handled(n, ['plastic', [0.12, 0.025, 0.03]], ['steel', [0.16, 0.02, 0.03]]),\n flame: (n, id) => (id === 'flamethrower' ? handled(n, ['steel', [0.3, 0.14, 0.14]], ['steel', [0.6, 0.05, 0.05]]) : solid(n, 'plastic', [0.08, 0.02, 0.04], 0xd9482b)),\n heat: (n) => handled(n, ['steel', [0.2, 0.08, 0.08]], ['copper', [0.25, 0.03, 0.03]]),\n throwable: (n, id) => (id === 'molotov' ? solid(n, 'glass', [0.25, 0.07, 0.07], 0x7fd6b0) : solid(n, 'steel', [id === 'pipe_bomb' ? 0.25 : 0.1, 0.06, 0.06], 0x4c5a3a)),\n extinguisher: (n) => solid(n, 'steel', [0.5, 0.15, 0.15], 0xc0392b),\n}\n\n/** Body actions of the arsenal: nothing to hold or lay on a counter. */\nexport const BODY_ACTIONS: ReadonlySet<string> = new Set(['hand', 'kick', 'shove', 'fists'])\n\n// Real weights from the arsenal data: solid steel boxes would weigh several times more, go past a carry limit and stop being props.\nconst withMass = (prop: WeaponProp, kg: number): WeaponProp => {\n const volumes = prop.spec.parts.map((part) => (part.shape.kind === 'box' ? part.shape.size[0] * part.shape.size[1] * part.shape.size[2] : 0))\n const total = volumes.reduce((sum, volume) => sum + volume, 0) || 1\n return { ...prop, spec: { ...prop.spec, parts: prop.spec.parts.map((part, index) => ({ ...part, mass: (kg * volumes[index]) / total })) } }\n}\n\n/** The prop of a weapon: low-poly parts by category, the real mass of the weapon spread over them. */\nexport function weaponProp(def: Pick<WeaponDef, 'id' | 'category' | 'mass'>, name = def.id): WeaponProp {\n const shape = SHAPES[def.category] ?? SHAPES.tool\n return withMass(shape(name, def.id), def.mass)\n}\n\n/** One mesh per box part, named after the part (what destruction renderers bind to), in a group with its origin on the floor. */\nexport function buildProp(THREE: typeof THREE_NS, prop: WeaponProp): THREE_NS.Group {\n const group = new THREE.Group()\n group.name = prop.spec.name ?? 'weapon'\n for (const part of prop.spec.parts) {\n if (part.shape.kind !== 'box') continue\n const [w, h, d] = part.shape.size\n const material = new THREE.MeshStandardMaterial({ color: prop.colors[part.id] ?? 0x777777, roughness: 0.6, metalness: part.material === 'steel' ? 0.6 : 0.05 })\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), material)\n mesh.name = part.id\n mesh.position.set(part.position[0], part.position[1], part.position[2])\n mesh.castShadow = true\n mesh.receiveShadow = true\n group.add(mesh)\n }\n return group\n}\n\n/** The model of a weapon for the hands or a shelf: the same prop the counters show. */\nexport function buildWeaponModel(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id' | 'category' | 'mass'>): THREE_NS.Group {\n return buildProp(THREE, weaponProp(def))\n}\n","import type * as THREE_NS from 'three'\nimport type { HostEvent, HostTool } from '@adatechnology/game-contracts'\nimport type { Arsenal, WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponAudio } from './audio'\nimport { BODY_ACTIONS, buildWeaponModel } from './props'\n\nexport interface WeaponFxOptions {\n THREE: typeof THREE_NS\n scene: THREE_NS.Scene\n camera: THREE_NS.Camera\n arsenal: Arsenal\n /** Height things rest on at (x, z): casings and magazines land there. */\n groundAt: (x: number, z: number) => number\n /** Sounds (`createWeaponAudio`); null or absent: silent. */\n audio?: WeaponAudio | null\n}\n\n/** The weapon in the hands, its fire and reload motion, ejected casings and dropped magazines, and their sounds. */\nexport interface WeaponFx {\n /** Feed every tool event of the host, with the tool as it is after the event. */\n handle(event: HostEvent, tool: HostTool): void\n update(dt: number): void\n /** Weapon shown in the hands, or null. */\n readonly inHand: string | null\n /** Casings and magazines currently on the floor or in the air. */\n readonly casings: number\n readonly magazines: number\n dispose(): void\n}\n\n/** Weapons that throw the spent case out on every shot. Revolvers keep them in the cylinder; break-actions open on reload. */\nconst EJECTS_ON_SHOT = new Set(['pistol', 'smg', 'carbine', 'rifle', 'sniper', 'shotgun'])\n/** Weapons whose reload drops a magazine. */\nconst DROPS_MAGAZINE = new Set(['pistol', 'smg', 'carbine', 'rifle', 'sniper'])\n/** Manual actions that cycle (pump, bolt) after each shot: the sound of the cycle. */\nconst CYCLES = new Set(['shotgun_pump_12', 'rifle_bolt_308'])\nconst MAX_CASINGS = 120\nconst MAX_MAGAZINES = 12\nconst LIFETIME_S = 25\nconst HAND_OFFSET: [number, number, number] = [0.2, -0.2, -0.42]\nconst GRAVITY = 9.81\n\ninterface Body {\n mesh: THREE_NS.Mesh\n velocity: THREE_NS.Vector3\n spin: THREE_NS.Vector3\n radius: number\n age: number\n resting: boolean\n bounces: number\n kind: 'casing' | 'magazine'\n}\n\nexport function createWeaponFx(options: WeaponFxOptions): WeaponFx {\n const { THREE, scene, camera, arsenal, groundAt } = options\n const audio = options.audio ?? null\n const bodies: Body[] = []\n const brass = new THREE.MeshStandardMaterial({ color: 0xc9a24a, metalness: 0.8, roughness: 0.35 })\n const shell = new THREE.MeshStandardMaterial({ color: 0xa8322b, roughness: 0.6 })\n const steel = new THREE.MeshStandardMaterial({ color: 0x2f3237, metalness: 0.5, roughness: 0.5 })\n const hand = new THREE.Group()\n hand.name = 'weapon-in-hand'\n scene.add(hand)\n let model: THREE_NS.Object3D | null = null\n let inHand: string | null = null\n let def: WeaponDef | null = null\n let kick = 0\n let dip = 0\n let reloading = false\n const v = new THREE.Vector3()\n const q = new THREE.Quaternion()\n const pointForward = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2)\n\n const equip = (weapon: string): void => {\n if (model) hand.remove(model)\n model = null\n inHand = null\n def = arsenal.weapons.get(weapon) ?? null\n if (!def || BODY_ACTIONS.has(def.id)) return\n model = buildWeaponModel(THREE, def)\n const length = new THREE.Box3().setFromObject(model).getSize(v).x\n // long guns are drawn smaller so they do not fill the view\n model.scale.setScalar(length > 0.8 ? 0.55 : length > 0.4 ? 0.75 : 1)\n model.quaternion.copy(pointForward)\n hand.add(model)\n inHand = def.id\n }\n\n // a point on the gun in camera space, turned into the world\n const handPoint = (x: number, y: number, z: number, out: THREE_NS.Vector3): THREE_NS.Vector3 =>\n out.set(HAND_OFFSET[0] + x, HAND_OFFSET[1] + y, HAND_OFFSET[2] + z).applyQuaternion(camera.quaternion).add(camera.position)\n\n const throwBody = (kind: Body['kind'], mesh: THREE_NS.Mesh, from: THREE_NS.Vector3, velocity: THREE_NS.Vector3, radius: number): void => {\n const limit = kind === 'casing' ? MAX_CASINGS : MAX_MAGAZINES\n const same = bodies.filter((b) => b.kind === kind)\n if (same.length >= limit) removeBody(same[0])\n mesh.position.copy(from)\n mesh.castShadow = true\n scene.add(mesh)\n bodies.push({ mesh, velocity, spin: new THREE.Vector3(Math.random() * 20 - 10, Math.random() * 30 - 15, Math.random() * 20 - 10), radius, age: 0, resting: false, bounces: 0, kind })\n }\n\n const ejectCasing = (caliberMm: number, isShell: boolean, downward: boolean): void => {\n const radius = isShell ? 0.0105 : Math.max(0.003, (caliberMm / 1000) * 0.6)\n const length = isShell ? 0.068 : Math.min(0.07, Math.max(0.015, (caliberMm / 1000) * 2.6))\n const mesh = new THREE.Mesh(new THREE.CylinderGeometry(radius, radius, length, 8), isShell ? shell : brass)\n mesh.name = 'casing'\n const from = handPoint(0.03, 0.03, 0.05, new THREE.Vector3())\n const right = new THREE.Vector3(1, 0, 0).applyQuaternion(camera.quaternion)\n const up = new THREE.Vector3(0, 1, 0)\n const velocity = downward\n ? up.clone().multiplyScalar(-0.5).addScaledVector(right, (Math.random() - 0.5) * 0.4)\n : right.multiplyScalar(1.6 + Math.random() * 0.8).addScaledVector(up, 1.4 + Math.random() * 0.8)\n throwBody('casing', mesh, from, velocity, radius)\n }\n\n const dropMagazine = (category: string): void => {\n const long = category === 'rifle' || category === 'sniper' || category === 'carbine'\n const size: [number, number, number] = long ? [0.03, 0.17, 0.07] : [0.025, 0.11, 0.035]\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(...size), steel)\n mesh.name = 'magazine'\n const from = handPoint(0, -0.06, 0, new THREE.Vector3())\n throwBody('magazine', mesh, from, new THREE.Vector3(0, -0.4, 0), size[1] / 2)\n audio?.reloadStart(category)\n }\n\n const caliberOf = (weapon: WeaponDef): number => {\n if (weapon.action.kind !== 'firearm') return 9\n return arsenal.calibers.get(weapon.action.caliber)?.diameter ?? 9\n }\n\n function removeBody(body: Body): void {\n body.mesh.removeFromParent()\n body.mesh.geometry.dispose()\n bodies.splice(bodies.indexOf(body), 1)\n }\n\n const onShot = (weapon: WeaponDef): void => {\n kick = 1\n const caliber = weapon.action.kind === 'firearm' ? arsenal.calibers.get(weapon.action.caliber) : undefined\n const energy = caliber ? 0.5 * (caliber.bulletGrams / 1000) * caliber.muzzleSpeed ** 2 * (caliber.pellets ?? 1) : 300\n audio?.shot(energy, weapon.category)\n if (CYCLES.has(weapon.id)) audio?.cycle()\n if (EJECTS_ON_SHOT.has(weapon.category) && weapon.id !== 'shotgun_double_12') ejectCasing(caliberOf(weapon), weapon.category === 'shotgun', false)\n }\n\n const onReloadStart = (weapon: WeaponDef, tool: HostTool): void => {\n if (DROPS_MAGAZINE.has(weapon.category)) dropMagazine(weapon.category)\n else audio?.reloadStart(weapon.category)\n // revolvers and break-action shotguns dump their spent cases when opened\n if (weapon.category === 'revolver' || weapon.id === 'shotgun_double_12') {\n const spent = Math.max(1, tool.capacity - tool.ammo)\n for (let i = 0; i < spent; i++) ejectCasing(caliberOf(weapon), weapon.category === 'shotgun', true)\n }\n }\n\n const stepBody = (body: Body, dt: number): void => {\n body.age += dt\n if (body.resting) return\n body.velocity.y -= GRAVITY * dt\n body.mesh.position.addScaledVector(body.velocity, dt)\n body.mesh.rotation.x += body.spin.x * dt\n body.mesh.rotation.y += body.spin.y * dt\n body.mesh.rotation.z += body.spin.z * dt\n const floor = groundAt(body.mesh.position.x, body.mesh.position.z) + body.radius\n if (body.mesh.position.y > floor) return\n body.mesh.position.y = floor\n if (Math.abs(body.velocity.y) > 0.7 && body.bounces < 4) {\n body.bounces++\n body.velocity.y = -body.velocity.y * 0.35\n body.velocity.x *= 0.55\n body.velocity.z *= 0.55\n body.spin.multiplyScalar(0.5)\n if (body.kind === 'casing') audio?.clink()\n else audio?.thud()\n return\n }\n if (body.kind === 'magazine' && body.bounces === 0) audio?.thud()\n body.resting = true\n body.mesh.rotation.x = Math.PI / 2\n body.mesh.rotation.z = 0\n }\n\n return {\n handle(event, tool) {\n const weapon = arsenal.weapons.get(event.weapon)\n if (event.type === 'tool') equip(event.weapon)\n if (!weapon) return\n if (event.type === 'shot') onShot(weapon)\n else if (event.type === 'empty') audio?.click()\n else if (event.type === 'reload' && event.phase === 'start') onReloadStart(weapon, tool)\n else if (event.type === 'reload' && event.phase === 'end') audio?.reloadEnd(weapon.category)\n reloading = tool.reloading\n },\n update(dt) {\n kick *= Math.exp(-dt * 14)\n dip += ((reloading ? 1 : 0) - dip) * Math.min(1, dt * 8)\n if (inHand) {\n handPoint(0, -0.12 * dip, 0.05 * kick, hand.position)\n q.setFromEuler(new THREE.Euler(0.14 * kick - 0.25 * dip, 0, 0.6 * dip))\n hand.quaternion.copy(camera.quaternion).multiply(q)\n }\n for (const body of [...bodies]) {\n stepBody(body, dt)\n if (body.age > LIFETIME_S) removeBody(body)\n }\n },\n get inHand() {\n return inHand\n },\n get casings() {\n return bodies.filter((b) => b.kind === 'casing').length\n },\n get magazines() {\n return bodies.filter((b) => b.kind === 'magazine').length\n },\n dispose() {\n for (const body of [...bodies]) removeBody(body)\n hand.removeFromParent()\n brass.dispose()\n shell.dispose()\n steel.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { AreaPlacement, DestructibleSpec, ModuleArea, TestableItem, TestableModule, Vec3 } from '@adatechnology/game-contracts'\nimport { createArsenal } from '@adatechnology/game-weapons'\nimport type { Arsenal } from '@adatechnology/game-weapons'\nimport { createWeaponAudio } from './audio'\nimport type { WeaponAudio } from './audio'\nimport { createWeaponFx } from './fx'\nimport type { WeaponFx } from './fx'\nimport { BODY_ACTIONS, buildProp, weaponProp } from './props'\nimport type { WeaponProp } from './props'\n\nexport interface WeaponsTestModuleOptions {\n /** `en` or `pt-BR` (default). */\n locale?: string\n /** The arsenal to lay out (default `createArsenal` with the locale). */\n arsenal?: Arsenal\n /** Play sounds (default true; silent anyway where there is no AudioContext). */\n sound?: boolean\n}\n\n/** Prefix of the item ids of the weapon props (`weapon_pistol_9mm`). */\nexport const WEAPON_ITEM_PREFIX = 'weapon_'\n// must not start with WEAPON_ITEM_PREFIX: hosts and tests tell the props apart by it\nexport const COUNTER_ITEM_ID = 'counter_weapons'\n\nconst COUNTER = { length: 4.8, depth: 1.6, height: 0.9 }\nconst COUNTER_X = [-6.5, -9, -11.5]\nconst COUNTER_Z = -1\n// props closer than this to a counter end have nothing next to them on one side\nconst END_MARGIN = 0.6\nconst SLOT_GAP = 0.3\n// targets in front of the brick wall of the room, at shooting distances\nconst TARGETS: Array<{ id: string; at: Vec3 }> = [\n { id: 'target_steel_plate', at: [-1.5, 0, -7] },\n { id: 'target_plywood', at: [0, 0, -7] },\n { id: 'target_concrete', at: [1.5, 0, -7] },\n]\n\nconst TEXT: Record<string, { group: string; name: string; counter: string; targets: Record<string, string>; reloadStart: string; reloadEnd: string }> = {\n en: {\n group: 'Weapons',\n name: 'Weapons area',\n counter: 'Weapon counter',\n targets: { target_steel_plate: 'Steel plate target', target_plywood: 'Plywood target', target_concrete: 'Concrete block target' },\n reloadStart: 'Reload started: {weapon} ({ammo}/{capacity})',\n reloadEnd: 'Reload done: {weapon} ({ammo}/{capacity})',\n },\n 'pt-BR': {\n group: 'Armas',\n name: 'Área de armas',\n counter: 'Balcão de armas',\n targets: { target_steel_plate: 'Alvo: chapa de aço', target_plywood: 'Alvo: compensado', target_concrete: 'Alvo: bloco de concreto' },\n reloadStart: 'Recarga iniciada: {weapon} ({ammo}/{capacity})',\n reloadEnd: 'Recarga completa: {weapon} ({ammo}/{capacity})',\n },\n}\nconst textOf = (locale: string): (typeof TEXT)['en'] => TEXT[locale] ?? TEXT.en\nconst fill = (template: string, vars: Record<string, string | number>): string => template.replace(/\\{(\\w+)\\}/g, (_, key: string) => String(vars[key] ?? ''))\n\nconst counterProp = (name: string): WeaponProp => {\n const { length, depth, height } = COUNTER\n return {\n spec: {\n name,\n parts: [\n { id: 'top', material: 'wood_soft', shape: { kind: 'box', size: [depth, 0.05, length] }, position: [0, height - 0.025, 0] },\n { id: 'side_a', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, -length / 2 + 0.05], anchored: true },\n { id: 'side_b', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, length / 2 - 0.05], anchored: true },\n ],\n joints: [\n { a: 'top', b: 'side_a', kind: 'screw' },\n { a: 'top', b: 'side_b', kind: 'screw' },\n ],\n tags: ['furniture'],\n },\n colors: { top: 0x8a5a30, side_a: 0x6b4426, side_b: 0x6b4426 },\n }\n}\n\nconst targetProp = (id: string, name: string): WeaponProp => {\n const face: Record<string, [string, Vec3, number]> = {\n target_steel_plate: ['steel', [0.5, 0.5, 0.01], 0xb5bcc4],\n target_plywood: ['plywood', [0.6, 0.8, 0.018], 0xc9a26b],\n target_concrete: ['concrete', [0.4, 0.2, 0.2], 0x9a9a94],\n }\n const [material, size, color] = face[id]\n const spec: DestructibleSpec = {\n name,\n parts: [\n { id: 'post', material: 'steel', shape: { kind: 'box', size: [0.05, 1.1, 0.05] }, position: [0, 0.55, -0.05], anchored: true },\n { id: 'face', material, shape: { kind: 'box', size }, position: [0, 1.1 + size[1] / 2, 0] },\n ],\n joints: [{ a: 'post', b: 'face', kind: 'bolt' }],\n tags: ['target'],\n }\n return { spec, colors: { post: 0x3a3d42, face: color } }\n}\n\nconst asItem = (id: string, name: string, prop: WeaponProp, extra: Partial<TestableItem> = {}): TestableItem => ({\n id,\n name,\n build: (THREE: unknown) => buildProp(THREE as typeof THREE_NS, prop),\n spec: prop.spec,\n ...extra,\n})\n\n/** Where the counters go and where each weapon lies on them: three counters on the free left side of the room, props across them. */\nexport function weaponsLayout(weaponItemIds: string[]): AreaPlacement[] {\n const perCounter = Math.floor((COUNTER.length - 2 * END_MARGIN) / SLOT_GAP) + 1\n const counters = COUNTER_X.slice(0, Math.max(1, Math.ceil(weaponItemIds.length / perCounter)))\n const placements: AreaPlacement[] = counters.map((x) => ({ item: COUNTER_ITEM_ID, position: [x, 0, COUNTER_Z], surface: { halfSize: [COUNTER.depth / 2, COUNTER.length / 2], height: COUNTER.height } }))\n weaponItemIds.forEach((item, index) => {\n const x = counters[Math.min(counters.length - 1, Math.floor(index / perCounter))]\n const z = COUNTER_Z - COUNTER.length / 2 + END_MARGIN + (index % perCounter) * SLOT_GAP\n // long props side by side overlap in the gentle piece separation of the renderer: asleep, they stay until grabbed\n placements.push({ item, position: [x, COUNTER.height + 0.01, z], asleep: true })\n })\n for (const target of TARGETS) placements.push({ item: target.id, position: target.at })\n return placements\n}\n\n/**\n * The weapons test area as a `TestableModule` of @adatechnology/game-contracts: one prop per weapon of the arsenal on counters (aim at one and\n * press H to equip it), targets at shooting distance, and, through `attach`, the weapon in the hands with its fire and reload motion,\n * ejected casings, dropped magazines and sounds, driven by the host's tool events.\n */\nexport function createWeaponsTestModule(options: WeaponsTestModuleOptions = {}): TestableModule & { readonly audio: WeaponAudio | null; readonly fx: WeaponFx | null } {\n const locale = options.locale ?? 'pt-BR'\n const arsenal = options.arsenal ?? createArsenal({ locale })\n const text = textOf(locale)\n const audio = options.sound === false ? null : createWeaponAudio()\n const weaponDefs = [...arsenal.weapons.values()].filter((def) => !BODY_ACTIONS.has(def.id))\n const weaponIds = weaponDefs.map((def) => `${WEAPON_ITEM_PREFIX}${def.id}`)\n let fx: WeaponFx | null = null\n return {\n id: 'weapons_area',\n name: text.name,\n group: text.group,\n audio,\n get fx() {\n return fx\n },\n items: () => [\n ...weaponDefs.map((def) => asItem(`${WEAPON_ITEM_PREFIX}${def.id}`, arsenal.name(def.id), weaponProp(def, arsenal.name(def.id)), { weapon: def.id, movable: true })),\n asItem(COUNTER_ITEM_ID, text.counter, counterProp(text.counter), { movable: false }),\n ...TARGETS.map((target) => asItem(target.id, text.targets[target.id], targetProp(target.id, text.targets[target.id]), { movable: false })),\n ],\n area: (): ModuleArea => ({ placements: weaponsLayout(weaponIds), view: { eye: [-3.4, 1.7, 2.6], target: [-9, 0.9, -1.2] } }),\n attach(host) {\n const created = createWeaponFx({\n THREE: host.THREE as typeof THREE_NS,\n scene: host.scene as THREE_NS.Scene,\n camera: host.camera as THREE_NS.Camera,\n arsenal,\n groundAt: host.groundAt,\n audio,\n })\n fx = created\n const offEvents = host.on((event) => {\n const tool = host.tool()\n created.handle(event, tool)\n if (event.type === 'reload') host.log(fill(event.phase === 'start' ? text.reloadStart : text.reloadEnd, { weapon: arsenal.name(event.weapon), ammo: tool.ammo, capacity: tool.capacity }), { weapon: event.weapon, phase: event.phase })\n })\n const offFrame = host.onFrame((dt) => created.update(dt))\n created.handle({ type: 'tool', weapon: host.tool().weapon }, host.tool())\n return () => {\n offEvents()\n offFrame()\n created.dispose()\n audio?.dispose()\n fx = null\n }\n },\n }\n}\n"],"mappings":"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Z,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;UACA;QACF;QACA,OAAS;QACT,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QAC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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../../game-weapons/src/rng.ts","../../game-weapons/src/data/attachments.json","../../game-weapons/src/data/archetypes.json","../../game-weapons/src/data/calibers.json","../../game-weapons/src/data/explosives.json","../../game-weapons/src/data/explosive-weapons.json","../../game-weapons/src/data/firearms.json","../../game-weapons/src/data/launchers.json","../../game-weapons/src/attachments.ts","../../game-weapons/src/check-arsenal.ts","../../game-weapons/src/merge.ts","../../game-weapons/src/locale.ts","../../game-weapons/src/fuse.ts","../../game-weapons/src/registry.ts","../../game-weapons/src/rules.ts","../../game-weapons/src/vec.ts","../../game-weapons/src/explosive-body.ts","../../game-weapons/src/explosive-use.ts","../../game-weapons/src/heat.ts","../../game-weapons/src/reload-stages.ts","../../game-weapons/src/reload.ts","../../game-weapons/src/faults.ts","../../game-weapons/src/fire.ts","../../game-weapons/src/attachment-effects.ts","../../game-weapons/src/weapon-shared.ts","../../game-weapons/src/weapon-core.ts","../../game-weapons/src/weapon-commands.ts","../../game-weapons/src/weapon-attachments.ts","../../game-weapons/src/weapon-firearm.ts","../../game-weapons/src/weapon.ts","../../game-weapons/src/arsenal.ts","../../game-weapons/src/explosive-effect.ts","../src/attachments-key.ts","../src/accessory-bench.ts","../src/accessory-text.ts","../src/audio/mechanical-sounds.ts","../src/audio/shot-sound.ts","../src/audio.ts","../src/fx/layers.ts","../src/laser-raycast.ts","../src/merge-by-material.ts","../src/data/models.json","../src/models/rounded-box.ts","../src/models/kit.ts","../src/models/break-action.ts","../src/models/attachments/mount-frames.ts","../src/models/details.ts","../src/models/bullpup.ts","../src/models/launcher-flame.ts","../src/models/launcher-rounds.ts","../src/models/launcher-rocket.ts","../src/models/launcher.ts","../src/models/m134.ts","../src/models/m2.ts","../src/models/p90.ts","../src/models/part-registry.ts","../src/models/pistol-slide.ts","../src/models/pistol-style.ts","../src/models/pistol.ts","../src/models/revolver.ts","../src/models/attachments/muzzle-brake.ts","../src/models/capture.ts","../src/models/attachments/bipod.ts","../src/models/rifle-fittings.ts","../src/models/rifle-forend.ts","../src/models/attachments/belt-box.ts","../src/models/attachments/drum.ts","../src/models/helical-magazine.ts","../src/models/rifle-controls.ts","../src/models/rifle-stock.ts","../src/models/rifle.ts","../src/models/index.ts","../src/models/attachments/tripod.ts","../src/props.ts","../src/box-fx.ts","../../game-contracts/src/impact.ts","../../game-contracts/src/spec.ts","../../game-contracts/src/weapons.ts","../../game-contracts/src/animation.ts","../../game-contracts/src/tool-animation.ts","../../game-contracts/src/bench.ts","../src/animation/clip-builder.ts","../src/animation/accessory-clips.ts","../src/animation/magazine-clips.ts","../src/animation/context.ts","../src/animation/cycle-clips.ts","../src/animation/reload-clips.ts","../src/animation/shot-clips.ts","../src/animation/clip-set.ts","../src/audio/host-events.ts","../../game-interactables-three/src/effects.ts","../../game-interactables-three/src/cord.ts","../../game-interactables-three/src/types.ts","../../game-interactables-three/src/pose.ts","../../game-interactables-three/src/merge.ts","../../game-interactables-three/src/mesh.ts","../../game-interactables-three/src/mirrors.ts","../../game-interactables-three/src/screen.ts","../../game-interactables-three/src/sway.ts","../../game-interactables-three/src/adapter.ts","../src/models/attachments/ammo-backpack.ts","../src/models/attachments/foregrip.ts","../src/models/attachments/laser.ts","../src/models/attachments/light.ts","../src/models/attachments/magazine.ts","../src/models/attachments/muzzle-device.ts","../src/models/attachments/optic.ts","../src/models/attachments/sling.ts","../src/models/attachments/suppressor.ts","../src/models/attachments/ugl.ts","../src/models/attachments/registry.ts","../src/models/attachments/fit.ts","../src/models/attachments/rig-underbarrel.ts","../src/models/rig-stock.ts","../src/models/condition.ts","../src/models/cartridge.ts","../src/fx/effects.ts","../src/fx/heavy.ts","../src/fx/particles.ts","../src/fx/rig.ts","../src/fx/session.ts","../src/fx/viewmodel-events.ts","../src/fx/viewmodel.ts","../src/fx.ts","../src/world-explosives.ts","../src/area.ts"],"sourcesContent":["/**\n * @adatechnology/game-weapons-three: the three.js side of @adatechnology/game-weapons. Low-poly weapon models, the weapon in the hands with\n * fire and reload motion, ejected casings and dropped magazines, synthesized sounds, and the weapons test area as a `TestableModule`\n * (any host of @adatechnology/game-contracts, like the test room, loads it with `loadModule`).\n */\nexport { createWeaponsTestModule, weaponsLayout, WEAPON_ITEM_PREFIX, COUNTER_ITEM_ID, MOUNTED_M134_ITEM_ID } from './area'\nexport type { WeaponsTestModuleOptions } from './area'\nexport { WORLD_EXPLOSIVE_IDS, WORLD_EXPLOSIVE_PREFIX, worldExplosiveItem } from './world-explosives'\nexport { createWeaponFx } from './fx'\nexport type { FxLayers, WeaponFx, WeaponFxOptions } from './fx'\nexport {\n createWeaponAudio,\n computeShotSound,\n mechanicalSoundOf,\n MECHANICAL_SOUNDS,\n GAME_SOUND_CLASSES,\n GAME_DISTANCE_CURVE,\n DEFAULT_ENERGY_CURVE,\n CLASS_REFERENCE_ENERGY,\n} from './audio'\nexport type {\n WeaponAudio,\n WeaponAudioOptions,\n ShotExtras,\n ShotSound,\n ShotSoundInput,\n ShotSoundOptions,\n ShotSoundClass,\n SoundClassDef,\n DistanceCurve,\n EnergyCurve,\n MechanicalSoundId,\n SoundStep,\n} from './audio'\nexport { buildWeaponModel, buildProp, weaponProp, BODY_ACTIONS } from './props'\nexport type { WeaponProp } from './props'\nexport { MODEL_ENTRIES, ARCHETYPE_MODELS, buildWeaponModelById, hasWeaponModel } from './models'\nexport type { ModelEntry, ModelFamily, ModelOptions, ModelParts, WeaponModel } from './models'\nexport { buildCartridge, buildCasing, buildRound, cartridgeShape } from './models/cartridge'\nexport { applyCondition } from './models/condition'\nexport { partRegistry } from './models/part-registry'\nexport { buildToolClips } from './animation/clip-set'\nexport type { ClipContext } from './animation/context'\nexport type { CartridgeShape } from './models/cartridge'\nexport { modelKit } from './models/kit'\nexport type { ModelKit, ModelMaterials } from './models/kit'\nexport { fitAttachmentModels } from './models/attachments/fit'\nexport type { AttachmentRig, FitAttachmentOptions } from './models/attachments/fit'\nexport { ATTACHMENT_MODELS } from './models/attachments/registry'\nexport { mountFrame, deriveFrames } from './models/attachments/mount-frames'\nexport type { MountFrame } from './models/attachments/mount-frames'\nexport type { AttachmentBuildContext, AttachmentModel, AttachmentModelBuilder, AttachmentModelRegistry, LaserRaycast } from './models/attachments/types'\nexport { rigUnderbarrel } from './models/attachments/rig-underbarrel'\nexport { rigStock } from './models/rig-stock'\n","import type { Vec3 } from './types'\n\n/** Deterministic mulberry32 generator; returns floats in [0, 1). */\nexport const createRng = (seed: number): (() => number) => {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) >>> 0\n let t = a\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\nexport const normalize = (v: Vec3): Vec3 => {\n const l = Math.hypot(v[0], v[1], v[2])\n return l > 1e-12 ? [v[0] / l, v[1] / l, v[2] / l] : [0, 0, -1]\n}\n\nconst cross = (a: Vec3, b: Vec3): Vec3 => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]\n\n/** Uniform direction inside a cone of half-angle `deg` around the unit vector `dir` (uniform over the solid angle). */\nexport const sampleCone = (dir: Vec3, deg: number, rng: () => number): Vec3 => {\n if (deg <= 0) return dir\n const cosMax = Math.cos((deg * Math.PI) / 180)\n const cosT = 1 - rng() * (1 - cosMax)\n const sinT = Math.sqrt(Math.max(0, 1 - cosT * cosT))\n const phi = rng() * Math.PI * 2\n const helper: Vec3 = Math.abs(dir[1]) < 0.9 ? [0, 1, 0] : [1, 0, 0]\n const u = normalize(cross(helper, dir))\n const v = cross(dir, u)\n const cx = Math.cos(phi) * sinT\n const cy = Math.sin(phi) * sinT\n return normalize([\n u[0] * cx + v[0] * cy + dir[0] * cosT,\n u[1] * cx + v[1] * cy + dir[1] * cosT,\n u[2] * cx + v[2] * cy + dir[2] * cosT,\n ])\n}\n","[\n {\n \"id\": \"suppressor\",\n \"name\": \"Suppressor\",\n \"kind\": \"suppressor\",\n \"mounts\": [\n \"muzzle\"\n ],\n \"interfaces\": [\n \"thread_1/2x28\",\n \"thread_5/8x24\",\n \"thread_14x1lh\",\n \"thread_24x1.5\",\n \"hk_3lug\"\n ],\n \"mass\": 0.45,\n \"install\": \"tool\",\n \"model\": \"suppressor\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"calibers\": {\n \"maxDiameter\": 12.7,\n \"maxEnergy\": 6500\n },\n \"dims\": {\n \"length\": 0.2,\n \"diameter\": 0.045\n },\n \"removable\": true,\n \"effects\": [\n {\n \"stat\": \"noise\",\n \"mul\": 0.4\n },\n {\n \"stat\": \"noise\",\n \"mul\": 0.625,\n \"when\": \"subsonic\"\n },\n {\n \"stat\": \"muzzleSpeed\",\n \"mul\": 0.97468\n },\n {\n \"stat\": \"heatPerShot\",\n \"mul\": 1.5\n }\n ]\n },\n {\n \"id\": \"oil_filter_suppressor\",\n \"name\": \"Improvised oil filter suppressor\",\n \"kind\": \"suppressor\",\n \"mounts\": [\n \"muzzle\"\n ],\n \"interfaces\": [\n \"thread_1/2x28\",\n \"thread_5/8x24\",\n \"thread_14x1lh\",\n \"thread_24x1.5\",\n \"hk_3lug\"\n ],\n \"mass\": 0.35,\n \"install\": \"tool\",\n \"model\": \"oil_filter_suppressor\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"calibers\": {\n \"maxDiameter\": 9,\n \"maxEnergy\": 2500\n },\n \"dims\": {\n \"length\": 0.17,\n \"diameter\": 0.07\n },\n \"durability\": {\n \"shots\": [\n 30,\n 60\n ]\n },\n \"effects\": [\n {\n \"stat\": \"noise\",\n \"mul\": 0.6\n },\n {\n \"stat\": \"heatPerShot\",\n \"mul\": 1.5\n }\n ]\n },\n {\n \"id\": \"muzzle_brake\",\n \"name\": \"Muzzle brake\",\n \"kind\": \"muzzle_device\",\n \"mounts\": [\n \"muzzle\"\n ],\n \"interfaces\": [\n \"thread_1/2x28\",\n \"thread_5/8x24\",\n \"thread_14x1lh\",\n \"thread_24x1.5\",\n \"hk_3lug\",\n \"fixed_muzzle_device\"\n ],\n \"mass\": 0.15,\n \"install\": \"tool\",\n \"model\": \"muzzle_brake\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"effects\": [\n {\n \"stat\": \"recoilVertical\",\n \"mul\": 0.75\n },\n {\n \"stat\": \"recoilHorizontal\",\n \"mul\": 0.75\n },\n {\n \"stat\": \"noise\",\n \"mul\": 1.1\n }\n ]\n },\n {\n \"id\": \"muzzle_brake_heavy\",\n \"name\": \"Heavy muzzle brake\",\n \"kind\": \"muzzle_device\",\n \"mounts\": [\n \"muzzle\"\n ],\n \"interfaces\": [\n \"thread_1/2x28\",\n \"thread_5/8x24\",\n \"thread_14x1lh\",\n \"thread_24x1.5\",\n \"hk_3lug\",\n \"fixed_muzzle_device\"\n ],\n \"mass\": 0.35,\n \"install\": \"tool\",\n \"model\": \"muzzle_brake_heavy\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"effects\": [\n {\n \"stat\": \"recoilVertical\",\n \"mul\": 0.75\n },\n {\n \"stat\": \"recoilHorizontal\",\n \"mul\": 0.75\n },\n {\n \"stat\": \"noise\",\n \"mul\": 1.1\n }\n ]\n },\n {\n \"id\": \"compensator\",\n \"name\": \"Compensator\",\n \"kind\": \"muzzle_device\",\n \"mounts\": [\n \"muzzle\"\n ],\n \"interfaces\": [\n \"thread_1/2x28\",\n \"thread_5/8x24\",\n \"thread_14x1lh\",\n \"thread_24x1.5\",\n \"hk_3lug\",\n \"fixed_muzzle_device\"\n ],\n \"mass\": 0.1,\n \"install\": \"tool\",\n \"model\": \"compensator\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"effects\": [\n {\n \"stat\": \"recoilVertical\",\n \"mul\": 0.75\n },\n {\n \"stat\": \"recoilHorizontal\",\n \"mul\": 0.75\n },\n {\n \"stat\": \"noise\",\n \"mul\": 1.1\n }\n ]\n },\n {\n \"id\": \"red_dot\",\n \"name\": \"Red dot sight\",\n \"kind\": \"optic\",\n \"mounts\": [\n \"rail_top\",\n \"rail_left\"\n ],\n \"interfaces\": [\n \"picatinny\",\n \"ak_side\"\n ],\n \"mass\": 0.15,\n \"install\": \"tool\",\n \"model\": \"red_dot\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"optic\": {\n \"zoom\": [\n 1,\n 1\n ],\n \"reticle\": \"dot\"\n },\n \"effects\": [\n {\n \"stat\": \"aim\",\n \"mul\": 0.8\n }\n ]\n },\n {\n \"id\": \"holographic_sight\",\n \"name\": \"Holographic sight\",\n \"kind\": \"optic\",\n \"mounts\": [\n \"rail_top\",\n \"rail_left\"\n ],\n \"interfaces\": [\n \"picatinny\",\n \"ak_side\"\n ],\n \"mass\": 0.3,\n \"install\": \"tool\",\n \"model\": \"holographic_sight\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"optic\": {\n \"zoom\": [\n 1,\n 1\n ],\n \"reticle\": \"holo\"\n },\n \"effects\": [\n {\n \"stat\": \"aim\",\n \"mul\": 0.8\n }\n ]\n },\n {\n \"id\": \"acog_4x\",\n \"name\": \"ACOG 4x\",\n \"kind\": \"optic\",\n \"mounts\": [\n \"rail_top\",\n \"rail_left\"\n ],\n \"interfaces\": [\n \"picatinny\",\n \"ak_side\"\n ],\n \"mass\": 0.4,\n \"install\": \"tool\",\n \"model\": \"acog_4x\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"optic\": {\n \"zoom\": [\n 4,\n 4\n ],\n \"reticle\": \"chevron\"\n },\n \"effects\": [\n {\n \"stat\": \"aim\",\n \"mul\": 1.1\n }\n ]\n },\n {\n \"id\": \"scope_3_9x\",\n \"name\": \"Rifle scope 3-9x\",\n \"kind\": \"optic\",\n \"mounts\": [\n \"rail_top\",\n \"rail_left\"\n ],\n \"interfaces\": [\n \"picatinny\",\n \"ak_side\",\n \"dovetail\"\n ],\n \"mass\": 0.6,\n \"install\": \"tool\",\n \"model\": \"scope_3_9x\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"optic\": {\n \"zoom\": [\n 3,\n 9\n ],\n \"reticle\": \"duplex\"\n },\n \"effects\": [\n {\n \"stat\": \"aim\",\n \"mul\": 1.15\n }\n ]\n },\n {\n \"id\": \"scope_6_24x\",\n \"name\": \"Rifle scope 6-24x\",\n \"kind\": \"optic\",\n \"mounts\": [\n \"rail_top\",\n \"rail_left\"\n ],\n \"interfaces\": [\n \"picatinny\",\n \"ak_side\",\n \"dovetail\"\n ],\n \"mass\": 1.1,\n \"install\": \"tool\",\n \"model\": \"scope_6_24x\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"optic\": {\n \"zoom\": [\n 6,\n 24\n ],\n \"reticle\": \"mildot\"\n },\n \"effects\": [\n {\n \"stat\": \"aim\",\n \"mul\": 1.25\n }\n ]\n },\n {\n \"id\": \"night_vision_scope\",\n \"name\": \"Night vision scope\",\n \"kind\": \"optic\",\n \"mounts\": [\n \"rail_top\",\n \"rail_left\"\n ],\n \"interfaces\": [\n \"picatinny\",\n \"ak_side\",\n \"dovetail\"\n ],\n \"mass\": 0.9,\n \"install\": \"tool\",\n \"model\": \"night_vision_scope\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"optic\": {\n \"zoom\": [\n 1,\n 4\n ],\n \"reticle\": \"duplex\",\n \"vision\": \"night\",\n \"batteryHours\": 40\n },\n \"effects\": [\n {\n \"stat\": \"aim\",\n \"mul\": 1.2\n }\n ]\n },\n {\n \"id\": \"thermal_scope\",\n \"name\": \"Thermal scope\",\n \"kind\": \"optic\",\n \"mounts\": [\n \"rail_top\",\n \"rail_left\"\n ],\n \"interfaces\": [\n \"picatinny\",\n \"ak_side\",\n \"dovetail\"\n ],\n \"mass\": 1.2,\n \"install\": \"tool\",\n \"model\": \"thermal_scope\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"optic\": {\n \"zoom\": [\n 1,\n 4\n ],\n \"reticle\": \"duplex\",\n \"vision\": \"thermal\",\n \"batteryHours\": 8\n },\n \"effects\": [\n {\n \"stat\": \"aim\",\n \"mul\": 1.2\n }\n ]\n },\n {\n \"id\": \"integral_optic_1_5x\",\n \"name\": \"Integral 1.5x optic of the AUG\",\n \"kind\": \"optic\",\n \"mounts\": [\n \"rail_top\"\n ],\n \"interfaces\": [\n \"integral\",\n \"pso_1_side\"\n ],\n \"mass\": 0.2,\n \"install\": \"bench\",\n \"model\": \"integral_optic_1_5x\",\n \"sources\": [\n \"gallery\",\n \"reference\"\n ],\n \"optic\": {\n \"zoom\": [\n 1.5,\n 1.5\n ],\n \"reticle\": \"duplex\"\n },\n \"removable\": false,\n \"effects\": []\n },\n {\n \"id\": \"pso_1\",\n \"name\": \"PSO-1 scope\",\n \"kind\": \"optic\",\n \"mounts\": [\n \"rail_top\"\n ],\n \"interfaces\": [\n \"integral\",\n \"pso_1_side\"\n ],\n \"mass\": 0.6,\n \"install\": \"bench\",\n \"model\": \"pso_1\",\n \"sources\": [\n \"gallery\",\n \"reference\"\n ],\n \"optic\": {\n \"zoom\": [\n 4,\n 4\n ],\n \"reticle\": \"chevron\"\n },\n \"removable\": false,\n \"effects\": []\n },\n {\n \"id\": \"fixed_scope_10x\",\n \"name\": \"Fixed 10x scope of the M24\",\n \"kind\": \"optic\",\n \"mounts\": [\n \"rail_top\"\n ],\n \"interfaces\": [\n \"integral\",\n \"pso_1_side\"\n ],\n \"mass\": 0.8,\n \"install\": \"bench\",\n \"model\": \"fixed_scope_10x\",\n \"sources\": [\n \"gallery\",\n \"reference\"\n ],\n \"optic\": {\n \"zoom\": [\n 10,\n 10\n ],\n \"reticle\": \"mildot\"\n },\n \"removable\": false,\n \"effects\": []\n },\n {\n \"id\": \"vertical_grip\",\n \"name\": \"Vertical foregrip\",\n \"kind\": \"grip\",\n \"mounts\": [\n \"rail_bottom\"\n ],\n \"interfaces\": [\n \"picatinny\",\n \"mlok\"\n ],\n \"mass\": 0.15,\n \"install\": \"field\",\n \"model\": \"vertical_grip\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"dims\": {\n \"length\": 0.1\n },\n \"effects\": [\n {\n \"stat\": \"recoilVertical\",\n \"mul\": 0.85\n }\n ]\n },\n {\n \"id\": \"bipod\",\n \"name\": \"Bipod\",\n \"kind\": \"bipod\",\n \"mounts\": [\n \"rail_bottom\"\n ],\n \"interfaces\": [\n \"picatinny\",\n \"bipod_stud\"\n ],\n \"mass\": 0.4,\n \"install\": \"field\",\n \"model\": \"bipod\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"derived\"\n ],\n \"effects\": [\n {\n \"stat\": \"recoilVertical\",\n \"mul\": 0.4,\n \"when\": \"supported\"\n },\n {\n \"stat\": \"recoilHorizontal\",\n \"mul\": 0.4,\n \"when\": \"supported\"\n }\n ]\n },\n {\n \"id\": \"m203\",\n \"name\": \"M203 grenade launcher\",\n \"kind\": \"underbarrel\",\n \"mounts\": [\n \"underbarrel\"\n ],\n \"interfaces\": [\n \"m203\"\n ],\n \"mass\": 1.36,\n \"install\": \"bench\",\n \"model\": \"m203\",\n \"sources\": [\n \"arsenal\",\n \"reference\"\n ],\n \"blocks\": [\n \"rail_bottom\"\n ],\n \"categories\": [\n \"rifle\",\n \"carbine\",\n \"dmr\"\n ],\n \"launcher\": \"m203\",\n \"dims\": {\n \"length\": 0.38\n },\n \"effects\": []\n },\n {\n \"id\": \"gp_25\",\n \"name\": \"GP-25 grenade launcher\",\n \"kind\": \"underbarrel\",\n \"mounts\": [\n \"underbarrel\"\n ],\n \"interfaces\": [\n \"gp25\"\n ],\n \"mass\": 1.5,\n \"install\": \"bench\",\n \"model\": \"gp_25\",\n \"sources\": [\n \"reference\"\n ],\n \"blocks\": [\n \"rail_bottom\"\n ],\n \"categories\": [\n \"rifle\",\n \"carbine\",\n \"dmr\"\n ],\n \"launcher\": \"gp_25\",\n \"dims\": {\n \"length\": 0.323\n },\n \"effects\": []\n },\n {\n \"id\": \"ag36\",\n \"name\": \"AG36 grenade launcher\",\n \"kind\": \"underbarrel\",\n \"mounts\": [\n \"underbarrel\"\n ],\n \"interfaces\": [\n \"ag36\"\n ],\n \"mass\": 1.5,\n \"install\": \"bench\",\n \"model\": \"ag36\",\n \"sources\": [\n \"reference\"\n ],\n \"blocks\": [\n \"rail_bottom\"\n ],\n \"categories\": [\n \"rifle\",\n \"carbine\",\n \"dmr\"\n ],\n \"launcher\": \"ag36\",\n \"dims\": {\n \"length\": 0.35\n },\n \"effects\": []\n },\n {\n \"id\": \"weapon_light\",\n \"name\": \"Weapon light\",\n \"kind\": \"light\",\n \"mounts\": [\n \"rail_left\",\n \"rail_right\",\n \"rail_bottom\"\n ],\n \"interfaces\": [\n \"picatinny\",\n \"mlok\"\n ],\n \"mass\": 0.12,\n \"install\": \"field\",\n \"model\": \"weapon_light\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"light\": {\n \"coneDeg\": 30,\n \"range\": 60,\n \"visibleFrom\": 40,\n \"batteryHours\": 20\n },\n \"dims\": {\n \"length\": 0.1,\n \"diameter\": 0.03\n },\n \"effects\": []\n },\n {\n \"id\": \"laser_sight\",\n \"name\": \"Laser sight\",\n \"kind\": \"laser\",\n \"mounts\": [\n \"rail_left\",\n \"rail_right\",\n \"rail_bottom\"\n ],\n \"interfaces\": [\n \"picatinny\",\n \"mlok\"\n ],\n \"mass\": 0.1,\n \"install\": \"field\",\n \"model\": \"laser_sight\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"laser\": {\n \"color\": 16711680,\n \"range\": 120,\n \"visibleFrom\": 30\n },\n \"dims\": {\n \"length\": 0.08,\n \"diameter\": 0.025\n },\n \"effects\": [\n {\n \"stat\": \"hipSpreadExcess\",\n \"mul\": 0.5,\n \"when\": \"hip\"\n }\n ]\n },\n {\n \"id\": \"extended_magazine\",\n \"name\": \"Extended magazine\",\n \"kind\": \"magazine\",\n \"mounts\": [\n \"magazine\"\n ],\n \"interfaces\": [\n \"mag_box\",\n \"mag_curved\",\n \"mag_pistol\"\n ],\n \"mass\": 0.15,\n \"install\": \"field\",\n \"model\": \"extended_magazine\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"categories\": [\n \"pistol\",\n \"smg\",\n \"rifle\",\n \"carbine\",\n \"dmr\",\n \"machine_gun\"\n ],\n \"effects\": [\n {\n \"stat\": \"capacity\",\n \"mul\": 1.5\n },\n {\n \"stat\": \"reload\",\n \"mul\": 1.15\n }\n ]\n },\n {\n \"id\": \"drum_magazine\",\n \"name\": \"Drum magazine\",\n \"kind\": \"magazine\",\n \"mounts\": [\n \"magazine\"\n ],\n \"interfaces\": [\n \"mag_box\",\n \"mag_curved\"\n ],\n \"mass\": 1.2,\n \"install\": \"field\",\n \"model\": \"drum_magazine\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"categories\": [\n \"smg\",\n \"rifle\",\n \"carbine\",\n \"dmr\",\n \"machine_gun\"\n ],\n \"effects\": [\n {\n \"stat\": \"capacity\",\n \"set\": 75\n },\n {\n \"stat\": \"faultChance\",\n \"mul\": 1.5\n },\n {\n \"stat\": \"reload\",\n \"mul\": 1.3\n }\n ]\n },\n {\n \"id\": \"dual_coupler\",\n \"name\": \"Dual magazine coupler\",\n \"kind\": \"magazine\",\n \"mounts\": [\n \"magazine\"\n ],\n \"interfaces\": [\n \"mag_box\",\n \"mag_curved\"\n ],\n \"mass\": 0.1,\n \"install\": \"field\",\n \"model\": \"dual_coupler\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"secondReload\": true,\n \"categories\": [\n \"smg\",\n \"rifle\",\n \"carbine\",\n \"dmr\",\n \"machine_gun\"\n ],\n \"effects\": [\n {\n \"stat\": \"reload\",\n \"mul\": 0.5\n }\n ]\n },\n {\n \"id\": \"sawn_off_barrel\",\n \"name\": \"Sawn-off barrel\",\n \"kind\": \"barrel\",\n \"mounts\": [\n \"barrel\"\n ],\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"mass\": -0.4,\n \"install\": \"bench\",\n \"model\": \"sawn_off_barrel\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"categories\": [\n \"shotgun\"\n ],\n \"effects\": [\n {\n \"stat\": \"spread\",\n \"mul\": 1.6\n },\n {\n \"stat\": \"range\",\n \"mul\": 0.6\n },\n {\n \"stat\": \"draw\",\n \"mul\": 0.8\n }\n ]\n },\n {\n \"id\": \"long_barrel\",\n \"name\": \"Long barrel\",\n \"kind\": \"barrel\",\n \"mounts\": [\n \"barrel\"\n ],\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"mass\": 0.4,\n \"install\": \"bench\",\n \"model\": \"long_barrel\",\n \"sources\": [\n \"arsenal\",\n \"derived\"\n ],\n \"categories\": [\n \"shotgun\"\n ],\n \"effects\": [\n {\n \"stat\": \"range\",\n \"mul\": 1.2\n },\n {\n \"stat\": \"muzzleSpeed\",\n \"mul\": 1.03\n }\n ]\n },\n {\n \"id\": \"sling\",\n \"name\": \"Sling\",\n \"kind\": \"sling\",\n \"mounts\": [\n \"sling\"\n ],\n \"interfaces\": [\n \"swivel\"\n ],\n \"mass\": 0.15,\n \"install\": \"field\",\n \"model\": \"sling\",\n \"sources\": [\n \"derived\"\n ],\n \"stowable\": true,\n \"categories\": [\n \"smg\",\n \"rifle\",\n \"carbine\",\n \"sniper\",\n \"dmr\",\n \"hunting\",\n \"machine_gun\",\n \"shotgun\"\n ],\n \"effects\": [\n {\n \"stat\": \"draw\",\n \"mul\": 0.85\n }\n ]\n },\n {\n \"id\": \"ammo_backpack\",\n \"name\": \"Ammunition backpack\",\n \"kind\": \"feed\",\n \"mounts\": [\n \"feed\"\n ],\n \"interfaces\": [\n \"belt\"\n ],\n \"mass\": 1.5,\n \"install\": \"field\",\n \"model\": \"ammo_backpack\",\n \"sources\": [\n \"derived\"\n ],\n \"carry\": \"back\",\n \"categories\": [\n \"machine_gun\",\n \"rifle\"\n ],\n \"effects\": [\n {\n \"stat\": \"capacity\",\n \"set\": 500\n }\n ]\n },\n {\n \"id\": \"tripod\",\n \"name\": \"Tripod mount\",\n \"kind\": \"mount\",\n \"mounts\": [\n \"underbarrel\"\n ],\n \"interfaces\": [\n \"tripod\"\n ],\n \"mass\": 6,\n \"install\": \"bench\",\n \"model\": \"tripod\",\n \"sources\": [\n \"derived\"\n ],\n \"categories\": [\n \"machine_gun\"\n ],\n \"effects\": [\n {\n \"stat\": \"recoilVertical\",\n \"mul\": 0.4\n },\n {\n \"stat\": \"recoilHorizontal\",\n \"mul\": 0.4\n },\n {\n \"stat\": \"spread\",\n \"mul\": 0.7\n }\n ]\n },\n {\n \"id\": \"integral_suppressor\",\n \"name\": \"Integral suppressor\",\n \"kind\": \"suppressor\",\n \"mounts\": [\n \"muzzle\"\n ],\n \"interfaces\": [\n \"integral\"\n ],\n \"mass\": 0.45,\n \"install\": \"bench\",\n \"model\": \"integral_suppressor\",\n \"sources\": [\n \"reference\",\n \"derived\"\n ],\n \"dims\": {\n \"length\": 0.2,\n \"diameter\": 0.045\n },\n \"removable\": false,\n \"effects\": [\n {\n \"stat\": \"noise\",\n \"mul\": 0.4\n },\n {\n \"stat\": \"noise\",\n \"mul\": 0.625,\n \"when\": \"subsonic\"\n },\n {\n \"stat\": \"muzzleSpeed\",\n \"mul\": 0.97468\n },\n {\n \"stat\": \"heatPerShot\",\n \"mul\": 1.5\n }\n ]\n },\n {\n \"id\": \"integral_optic_3x\",\n \"name\": \"Integral 3x optic of the G36\",\n \"kind\": \"optic\",\n \"mounts\": [\n \"rail_top\"\n ],\n \"interfaces\": [\n \"integral\"\n ],\n \"mass\": 0.3,\n \"install\": \"bench\",\n \"model\": \"integral_optic_3x\",\n \"sources\": [\n \"reference\",\n \"derived\"\n ],\n \"optic\": {\n \"zoom\": [\n 3,\n 3\n ],\n \"reticle\": \"duplex\"\n },\n \"removable\": false,\n \"effects\": []\n }\n]\n","[\n {\n \"id\": \"hand\",\n \"name\": \"Hand\",\n \"category\": \"hand\",\n \"action\": {\n \"kind\": \"hand\",\n \"reach\": 2\n },\n \"mass\": 0,\n \"tags\": [\n \"grab\"\n ]\n },\n {\n \"id\": \"kick\",\n \"name\": \"Kick\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 250,\n \"radius\": 0.08,\n \"reach\": 1.1,\n \"rpm\": 60,\n \"noise\": 8\n },\n \"mass\": 0\n },\n {\n \"id\": \"shove\",\n \"name\": \"Shove\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 80,\n \"radius\": 0.1,\n \"reach\": 1.5,\n \"rpm\": 90,\n \"noise\": 5\n },\n \"mass\": 0\n },\n {\n \"id\": \"pistol_9mm\",\n \"name\": \"9 mm service pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 15,\n \"reload\": 2,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.2,\n 0.4\n ],\n \"range\": 50\n },\n \"mass\": 0.9,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"pistol_45\",\n \"name\": \".45 ACP pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 280,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 8,\n \"reload\": 2.2,\n \"barrel\": 1,\n \"spreadDeg\": 1.1,\n \"bloomDeg\": 0.8,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.8,\n 0.6\n ],\n \"range\": 50\n },\n \"mass\": 1.1,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"pistol_22\",\n \"name\": \".22 LR pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 360,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 1.8,\n \"barrel\": 1,\n \"spreadDeg\": 0.9,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.5,\n 0.2\n ],\n \"range\": 40\n },\n \"mass\": 0.7,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"revolver_357\",\n \"name\": \".357 Magnum revolver\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"357mag\",\n \"rpm\": 150,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 4,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 1,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3,\n 0.9\n ],\n \"range\": 60\n },\n \"mass\": 1.2,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"revolver_38\",\n \"name\": \".38 Special revolver\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"38spl\",\n \"rpm\": 160,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 3.8,\n \"barrel\": 0.95,\n \"spreadDeg\": 0.9,\n \"bloomDeg\": 0.7,\n \"recoveryDegPerS\": 3.5,\n \"recoil\": [\n 1.6,\n 0.5\n ],\n \"range\": 45\n },\n \"mass\": 0.9,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"smg_9mm\",\n \"name\": \"9 mm submachine gun\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 800,\n \"modes\": [\n \"auto\",\n \"burst\",\n \"semi\"\n ],\n \"burst\": 3,\n \"magazine\": 30,\n \"reload\": 2.4,\n \"barrel\": 1.1,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.9,\n 0.5\n ],\n \"range\": 80\n },\n \"mass\": 2.6,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"carbine_22\",\n \"name\": \".22 LR carbine\",\n \"category\": \"carbine\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 2.2,\n \"barrel\": 1.4,\n \"spreadDeg\": 0.5,\n \"bloomDeg\": 0.15,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.4,\n 0.15\n ],\n \"range\": 80\n },\n \"mass\": 2.4,\n \"tags\": [\n \"small_game\"\n ]\n },\n {\n \"id\": \"rifle_5_56\",\n \"name\": \"5.56 mm assault rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\",\n \"burst\",\n \"semi\"\n ],\n \"burst\": 3,\n \"magazine\": 30,\n \"reload\": 2.5,\n \"barrel\": 1,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1,\n 0.6\n ],\n \"range\": 400\n },\n \"mass\": 3.4,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"rifle_7_62x39\",\n \"name\": \"7.62×39 mm assault rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x39\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.8,\n \"barrel\": 1,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.5,\n 0.8\n ],\n \"range\": 350\n },\n \"mass\": 3.8,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"rifle_bolt_308\",\n \"name\": \".308 bolt-action rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 40,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 3.5,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3,\n 0.5\n ],\n \"range\": 800\n },\n \"mass\": 4,\n \"tags\": [\n \"hunting\"\n ]\n },\n {\n \"id\": \"sniper_338\",\n \"name\": \".338 Lapua sniper rifle\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"338lapua\",\n \"rpm\": 35,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 4,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 4.5,\n 0.7\n ],\n \"range\": 1500\n },\n \"mass\": 6.5,\n \"tags\": [\n \"long_range\"\n ]\n },\n {\n \"id\": \"anti_materiel_50\",\n \"name\": \".50 BMG anti-materiel rifle\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"50bmg\",\n \"rpm\": 30,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 4.5,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.15,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 7,\n 1.2\n ],\n \"range\": 1800\n },\n \"mass\": 12.5,\n \"tags\": [\n \"long_range\",\n \"heavy\"\n ]\n },\n {\n \"id\": \"shotgun_pump_12\",\n \"name\": \"12 gauge pump-action shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 60,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 6,\n \"reload\": 0.6,\n \"perRound\": true,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 4,\n 1\n ],\n \"range\": 40\n },\n \"mass\": 3.2,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"shotgun_double_12\",\n \"name\": \"12 gauge double-barrel shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"break\"\n ],\n \"magazine\": 2,\n \"reload\": 3.5,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 4.5,\n 1.2\n ],\n \"range\": 35\n },\n \"mass\": 3,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"shotgun_semi_12\",\n \"name\": \"12 gauge semi-automatic shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 180,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 5,\n \"reload\": 0.7,\n \"perRound\": true,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.4,\n 1\n ],\n \"range\": 40\n },\n \"mass\": 3.4,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"bow_compound\",\n \"name\": \"Compound bow\",\n \"category\": \"bow\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"arrow\",\n \"rpm\": 20,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 1,\n \"reload\": 1.5,\n \"barrel\": 1,\n \"spreadDeg\": 0.4,\n \"bloomDeg\": 0.4,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 0.3,\n 0.1\n ],\n \"range\": 60\n },\n \"mass\": 1.8,\n \"tags\": [\n \"silent\"\n ]\n },\n {\n \"id\": \"crossbow\",\n \"name\": \"Crossbow\",\n \"category\": \"crossbow\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"crossbow_bolt\",\n \"rpm\": 8,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 1,\n \"reload\": 4,\n \"barrel\": 1,\n \"spreadDeg\": 0.3,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 0.5,\n 0.1\n ],\n \"range\": 70\n },\n \"mass\": 3,\n \"tags\": [\n \"silent\"\n ]\n },\n {\n \"id\": \"hammer\",\n \"name\": \"Hammer\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 60,\n \"radius\": 0.08,\n \"reach\": 0.7,\n \"rpm\": 70,\n \"noise\": 6\n },\n \"mass\": 1\n },\n {\n \"id\": \"sledgehammer\",\n \"name\": \"Sledgehammer\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 300,\n \"radius\": 0.15,\n \"reach\": 1.1,\n \"rpm\": 30,\n \"noise\": 8\n },\n \"mass\": 5.5,\n \"tags\": [\n \"heavy\"\n ]\n },\n {\n \"id\": \"baseball_bat\",\n \"name\": \"Baseball bat\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 150,\n \"radius\": 0.1,\n \"reach\": 1,\n \"rpm\": 60,\n \"noise\": 7\n },\n \"mass\": 0.9\n },\n {\n \"id\": \"crowbar\",\n \"name\": \"Crowbar\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 120,\n \"radius\": 0.08,\n \"reach\": 0.9,\n \"rpm\": 60,\n \"noise\": 7\n },\n \"mass\": 2,\n \"tags\": [\n \"pry\"\n ]\n },\n {\n \"id\": \"machete\",\n \"name\": \"Machete\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 140,\n \"radius\": 0.06,\n \"reach\": 0.8,\n \"rpm\": 80,\n \"noise\": 6\n },\n \"mass\": 0.8\n },\n {\n \"id\": \"axe\",\n \"name\": \"Axe\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 250,\n \"radius\": 0.08,\n \"reach\": 0.9,\n \"rpm\": 45,\n \"noise\": 8\n },\n \"mass\": 1.6\n },\n {\n \"id\": \"knife\",\n \"name\": \"Knife\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 40,\n \"radius\": 0.03,\n \"reach\": 0.4,\n \"rpm\": 100,\n \"noise\": 5\n },\n \"mass\": 0.2\n },\n {\n \"id\": \"fists\",\n \"name\": \"Fists\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 25,\n \"radius\": 0.1,\n \"reach\": 0.6,\n \"rpm\": 120,\n \"noise\": 5\n },\n \"mass\": 0\n },\n {\n \"id\": \"lighter\",\n \"name\": \"Lighter\",\n \"category\": \"flame\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 400,\n \"radius\": 0.03,\n \"range\": 0.15,\n \"fuelPerSecond\": 0.02,\n \"fuel\": 60,\n \"noise\": 0\n },\n \"mass\": 0.05,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"flamethrower\",\n \"name\": \"Flamethrower\",\n \"category\": \"flame\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 900,\n \"radius\": 0.6,\n \"range\": 6,\n \"fuelPerSecond\": 1,\n \"fuel\": 20,\n \"cone\": true,\n \"noise\": 20\n },\n \"mass\": 15,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"molotov\",\n \"name\": \"Molotov cocktail\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"molotov\",\n \"energy\": 500,\n \"radius\": 1.5,\n \"fuse\": 0,\n \"throwSpeed\": 12,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 1.5,\n \"seconds\": 12\n },\n \"noise\": 40\n },\n \"mass\": 0.8,\n \"tags\": [\n \"fire\",\n \"improvised\"\n ]\n },\n {\n \"id\": \"cutting_torch\",\n \"name\": \"Oxy-fuel cutting torch\",\n \"category\": \"heat\",\n \"action\": {\n \"kind\": \"heat\",\n \"temperature\": 3000,\n \"radius\": 0.02,\n \"range\": 0.25,\n \"fuelPerSecond\": 0.05,\n \"fuel\": 30,\n \"noise\": 15\n },\n \"mass\": 4,\n \"tags\": [\n \"fire\",\n \"cutting\"\n ]\n },\n {\n \"id\": \"blowtorch\",\n \"name\": \"Blowtorch\",\n \"category\": \"heat\",\n \"action\": {\n \"kind\": \"heat\",\n \"temperature\": 1300,\n \"radius\": 0.04,\n \"range\": 0.3,\n \"fuelPerSecond\": 0.04,\n \"fuel\": 30,\n \"noise\": 10\n },\n \"mass\": 0.6,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"frag_grenade\",\n \"name\": \"Fragmentation grenade\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"m67\",\n \"energy\": 200000,\n \"radius\": 5,\n \"fuse\": 4,\n \"throwSpeed\": 15,\n \"noise\": 500\n },\n \"mass\": 0.45,\n \"tags\": [\n \"explosive\"\n ]\n },\n {\n \"id\": \"pipe_bomb\",\n \"name\": \"Pipe bomb\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"pipe_bomb\",\n \"energy\": 43200,\n \"radius\": 3,\n \"fuse\": 3,\n \"throwSpeed\": 13,\n \"noise\": 450\n },\n \"mass\": 0.7,\n \"tags\": [\n \"explosive\",\n \"improvised\"\n ]\n },\n {\n \"id\": \"screwdriver\",\n \"name\": \"Screwdriver\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"screwdriver\",\n \"reach\": 0.5,\n \"noise\": 5\n },\n \"mass\": 0.15\n },\n {\n \"id\": \"wrench\",\n \"name\": \"Wrench\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"wrench\",\n \"reach\": 0.6,\n \"noise\": 6\n },\n \"mass\": 0.5\n },\n {\n \"id\": \"pry_bar\",\n \"name\": \"Pry bar\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"pry_bar\",\n \"reach\": 0.8,\n \"noise\": 8\n },\n \"mass\": 0.8\n },\n {\n \"id\": \"hacksaw\",\n \"name\": \"Hacksaw\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"saw\",\n \"reach\": 0.7,\n \"noise\": 10\n },\n \"mass\": 0.6\n },\n {\n \"id\": \"utility_knife\",\n \"name\": \"Utility knife\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"knife\",\n \"reach\": 0.3,\n \"noise\": 3\n },\n \"mass\": 0.1\n },\n {\n \"id\": \"claw_hammer\",\n \"name\": \"Claw hammer\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"hammer\",\n \"reach\": 0.5,\n \"noise\": 8\n },\n \"mass\": 0.7\n },\n {\n \"id\": \"extinguisher\",\n \"name\": \"Fire extinguisher\",\n \"category\": \"extinguisher\",\n \"action\": {\n \"kind\": \"extinguisher\",\n \"range\": 4,\n \"coolC\": 300,\n \"charge\": 12,\n \"noise\": 25\n },\n \"mass\": 5,\n \"tags\": [\n \"safety\"\n ]\n }\n]\n","[\n {\n \"id\": \"22lr\",\n \"label\": \".22 LR\",\n \"diameter\": 5.7,\n \"bulletGrams\": 2.6,\n \"muzzleSpeed\": 350,\n \"dragPer100m\": 0.15,\n \"kind\": \"rimfire\",\n \"noise\": 60,\n \"caseType\": \"tiny\",\n \"rim\": \"rimfire\",\n \"cartridge\": {\n \"caseDiameter\": 5.7,\n \"overallLength\": 25.4,\n \"caseLength\": 15.6,\n \"projectileDiameter\": 5.7\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"380acp\",\n \"label\": \".380 ACP\",\n \"diameter\": 9,\n \"bulletGrams\": 6.2,\n \"muzzleSpeed\": 295,\n \"dragPer100m\": 0.22,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"rim\": \"rimless\",\n \"cartridge\": {\n \"caseDiameter\": 9.5,\n \"overallLength\": 25,\n \"caseLength\": 17.3,\n \"projectileDiameter\": 9\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"9x18\",\n \"label\": \"9×18 mm Makarov\",\n \"diameter\": 9.3,\n \"bulletGrams\": 6.1,\n \"muzzleSpeed\": 315,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"rim\": \"rimless\",\n \"cartridge\": {\n \"caseDiameter\": 9.9,\n \"overallLength\": 25.3,\n \"caseLength\": 18,\n \"projectileDiameter\": 9.3\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"9x19\",\n \"label\": \"9×19 mm\",\n \"diameter\": 9,\n \"bulletGrams\": 7.5,\n \"muzzleSpeed\": 365,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"cartridge\": {\n \"caseDiameter\": 9.9,\n \"overallLength\": 29.7,\n \"caseLength\": 19.15,\n \"projectileDiameter\": 9\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"40sw\",\n \"label\": \".40 S&W\",\n \"diameter\": 10.2,\n \"bulletGrams\": 11.7,\n \"muzzleSpeed\": 310,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"cartridge\": {\n \"caseDiameter\": 10.8,\n \"overallLength\": 28.6,\n \"caseLength\": 21.6,\n \"projectileDiameter\": 10.2\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"45acp\",\n \"label\": \".45 ACP\",\n \"diameter\": 11.5,\n \"bulletGrams\": 14.9,\n \"muzzleSpeed\": 254,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"cartridge\": {\n \"caseDiameter\": 12,\n \"overallLength\": 32.4,\n \"caseLength\": 22.8,\n \"projectileDiameter\": 11.5\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"5_7x28\",\n \"label\": \"5.7×28 mm\",\n \"diameter\": 5.7,\n \"bulletGrams\": 2,\n \"muzzleSpeed\": 715,\n \"dragPer100m\": 0.12,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"rim\": \"rimless\",\n \"cartridge\": {\n \"caseDiameter\": 7.9,\n \"overallLength\": 40.5,\n \"caseLength\": 28.9,\n \"projectileDiameter\": 5.7\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"38spl\",\n \"label\": \".38 Special\",\n \"diameter\": 9.1,\n \"bulletGrams\": 10.2,\n \"muzzleSpeed\": 247,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"rim\": \"rimmed\",\n \"cartridge\": {\n \"caseDiameter\": 9.6,\n \"overallLength\": 39.4,\n \"caseLength\": 29.3,\n \"projectileDiameter\": 9.1\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"357mag\",\n \"label\": \".357 Magnum\",\n \"diameter\": 9.1,\n \"bulletGrams\": 10.2,\n \"muzzleSpeed\": 396,\n \"dragPer100m\": 0.18,\n \"kind\": \"hp\",\n \"noise\": 300,\n \"caseType\": \"pistol\",\n \"rim\": \"rimmed\",\n \"cartridge\": {\n \"caseDiameter\": 9.6,\n \"overallLength\": 40,\n \"caseLength\": 33,\n \"projectileDiameter\": 9.1\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"44mag\",\n \"label\": \".44 Magnum\",\n \"diameter\": 10.9,\n \"bulletGrams\": 15.6,\n \"muzzleSpeed\": 440,\n \"dragPer100m\": 0.18,\n \"kind\": \"fmj\",\n \"noise\": 420,\n \"caseType\": \"pistol\",\n \"rim\": \"rimmed\",\n \"cartridge\": {\n \"caseDiameter\": 11.6,\n \"overallLength\": 40.9,\n \"caseLength\": 32.6,\n \"projectileDiameter\": 10.9\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"50ae\",\n \"label\": \".50 AE\",\n \"diameter\": 12.7,\n \"bulletGrams\": 19.4,\n \"muzzleSpeed\": 470,\n \"dragPer100m\": 0.18,\n \"kind\": \"fmj\",\n \"noise\": 420,\n \"caseType\": \"pistol\",\n \"cartridge\": {\n \"caseDiameter\": 13.9,\n \"overallLength\": 40.9,\n \"caseLength\": 32.6,\n \"projectileDiameter\": 12.7\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"12ga_00buck\",\n \"label\": \"12 ga 00 buck\",\n \"diameter\": 8.4,\n \"bulletGrams\": 3.5,\n \"muzzleSpeed\": 414,\n \"pellets\": 9,\n \"dragPer100m\": 0.45,\n \"kind\": \"buck\",\n \"noise\": 350,\n \"caseType\": \"shell\",\n \"rim\": \"shell\",\n \"cartridge\": {\n \"caseDiameter\": 20,\n \"overallLength\": 70,\n \"caseLength\": 70,\n \"projectileDiameter\": 18.5\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"12ga_slug\",\n \"label\": \"12 ga slug\",\n \"diameter\": 18.5,\n \"bulletGrams\": 28,\n \"muzzleSpeed\": 463,\n \"dragPer100m\": 0.3,\n \"kind\": \"slug\",\n \"noise\": 350,\n \"caseType\": \"shell\",\n \"rim\": \"shell\",\n \"cartridge\": {\n \"caseDiameter\": 20,\n \"overallLength\": 70,\n \"caseLength\": 70,\n \"projectileDiameter\": 18.5\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"12ga_birdshot\",\n \"label\": \"12 ga birdshot\",\n \"diameter\": 2.4,\n \"bulletGrams\": 0.2,\n \"muzzleSpeed\": 400,\n \"pellets\": 90,\n \"dragPer100m\": 0.6,\n \"kind\": \"birdshot\",\n \"noise\": 350,\n \"caseType\": \"shell\",\n \"rim\": \"shell\",\n \"cartridge\": {\n \"caseDiameter\": 20,\n \"overallLength\": 70,\n \"caseLength\": 70,\n \"projectileDiameter\": 18.5\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"20ga_buck\",\n \"label\": \"20 ga buck\",\n \"diameter\": 6.9,\n \"bulletGrams\": 1.3,\n \"muzzleSpeed\": 400,\n \"pellets\": 20,\n \"dragPer100m\": 0.5,\n \"kind\": \"buck\",\n \"noise\": 350,\n \"caseType\": \"shell\",\n \"rim\": \"shell\",\n \"sources\": [\n \"sdk\",\n \"derived\"\n ]\n },\n {\n \"id\": \"5_56x45\",\n \"label\": \"5.56×45 mm\",\n \"diameter\": 5.7,\n \"bulletGrams\": 4,\n \"muzzleSpeed\": 935,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\",\n \"noise\": 300,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 9.6,\n \"overallLength\": 57.4,\n \"caseLength\": 44.7,\n \"projectileDiameter\": 5.7\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"5_45x39\",\n \"label\": \"5.45×39 mm\",\n \"diameter\": 5.6,\n \"bulletGrams\": 3.4,\n \"muzzleSpeed\": 900,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\",\n \"noise\": 300,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 10,\n \"overallLength\": 57,\n \"caseLength\": 39.8,\n \"projectileDiameter\": 5.6\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"7_62x39\",\n \"label\": \"7.62×39 mm\",\n \"diameter\": 7.9,\n \"bulletGrams\": 8,\n \"muzzleSpeed\": 725,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\",\n \"noise\": 300,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 11.3,\n \"overallLength\": 56,\n \"caseLength\": 38.7,\n \"projectileDiameter\": 7.9\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"30_30\",\n \"label\": \".30-30 Winchester\",\n \"diameter\": 7.8,\n \"bulletGrams\": 9.7,\n \"muzzleSpeed\": 670,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\",\n \"noise\": 300,\n \"caseType\": \"rifle\",\n \"rim\": \"rimmed\",\n \"cartridge\": {\n \"caseDiameter\": 10.7,\n \"overallLength\": 64.8,\n \"caseLength\": 51.8,\n \"projectileDiameter\": 7.8\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"7_62x51\",\n \"label\": \"7.62×51 mm (.308)\",\n \"diameter\": 7.8,\n \"bulletGrams\": 9.7,\n \"muzzleSpeed\": 850,\n \"dragPer100m\": 0.08,\n \"kind\": \"fmj\",\n \"noise\": 420,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 12,\n \"overallLength\": 71.1,\n \"caseLength\": 51.2,\n \"projectileDiameter\": 7.8\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"7_62x54r\",\n \"label\": \"7.62×54R\",\n \"diameter\": 7.9,\n \"bulletGrams\": 9.6,\n \"muzzleSpeed\": 865,\n \"dragPer100m\": 0.08,\n \"kind\": \"fmj\",\n \"noise\": 420,\n \"caseType\": \"rifle\",\n \"rim\": \"rimmed\",\n \"cartridge\": {\n \"caseDiameter\": 12.4,\n \"overallLength\": 77.2,\n \"caseLength\": 53.7,\n \"projectileDiameter\": 7.9\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"30_06\",\n \"label\": \".30-06 Springfield\",\n \"diameter\": 7.8,\n \"bulletGrams\": 9.7,\n \"muzzleSpeed\": 880,\n \"dragPer100m\": 0.08,\n \"kind\": \"fmj\",\n \"noise\": 420,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 12,\n \"overallLength\": 84.8,\n \"caseLength\": 63.3,\n \"projectileDiameter\": 7.8\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"300wm\",\n \"label\": \".300 Winchester Magnum\",\n \"diameter\": 7.8,\n \"bulletGrams\": 11.7,\n \"muzzleSpeed\": 900,\n \"dragPer100m\": 0.07,\n \"kind\": \"fmj\",\n \"noise\": 600,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 13,\n \"overallLength\": 84.8,\n \"caseLength\": 66.5,\n \"projectileDiameter\": 7.8\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"338lapua\",\n \"label\": \".338 Lapua Magnum\",\n \"diameter\": 8.6,\n \"bulletGrams\": 16.2,\n \"muzzleSpeed\": 903,\n \"dragPer100m\": 0.06,\n \"kind\": \"fmj\",\n \"noise\": 600,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 14.9,\n \"overallLength\": 93.5,\n \"caseLength\": 69.2,\n \"projectileDiameter\": 8.6\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"408cheytac\",\n \"label\": \".408 CheyTac\",\n \"diameter\": 10.4,\n \"bulletGrams\": 27.2,\n \"muzzleSpeed\": 900,\n \"dragPer100m\": 0.05,\n \"kind\": \"fmj\",\n \"noise\": 600,\n \"caseType\": \"big\",\n \"cartridge\": {\n \"caseDiameter\": 16,\n \"overallLength\": 115.6,\n \"caseLength\": 77,\n \"projectileDiameter\": 10.36\n },\n \"sources\": [\n \"reference\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"50bmg\",\n \"label\": \".50 BMG\",\n \"diameter\": 12.7,\n \"bulletGrams\": 42,\n \"muzzleSpeed\": 925,\n \"dragPer100m\": 0.05,\n \"kind\": \"ap\",\n \"noise\": 600,\n \"caseType\": \"big\",\n \"cartridge\": {\n \"caseDiameter\": 20.4,\n \"overallLength\": 138,\n \"caseLength\": 99,\n \"projectileDiameter\": 12.7\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"arrow\",\n \"label\": \"Arrow (compound bow)\",\n \"diameter\": 7,\n \"bulletGrams\": 25,\n \"muzzleSpeed\": 90,\n \"dragPer100m\": 0.12,\n \"kind\": \"arrow\",\n \"noise\": 20,\n \"sources\": [\n \"sdk\"\n ]\n },\n {\n \"id\": \"crossbow_bolt\",\n \"label\": \"Crossbow bolt\",\n \"diameter\": 8,\n \"bulletGrams\": 20,\n \"muzzleSpeed\": 122,\n \"dragPer100m\": 0.12,\n \"kind\": \"bolt\",\n \"noise\": 25,\n \"sources\": [\n \"sdk\"\n ]\n },\n {\n \"id\": \"4_6x30\",\n \"label\": \"4.6×30 mm\",\n \"diameter\": 4.65,\n \"bulletGrams\": 2,\n \"muzzleSpeed\": 735,\n \"dragPer100m\": 0.12,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"rim\": \"rimless\",\n \"cartridge\": {\n \"caseDiameter\": 8,\n \"overallLength\": 38.5,\n \"caseLength\": 30.5,\n \"projectileDiameter\": 4.65\n },\n \"sources\": [\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"32acp\",\n \"label\": \".32 ACP\",\n \"diameter\": 7.94,\n \"bulletGrams\": 4.6,\n \"muzzleSpeed\": 276,\n \"dragPer100m\": 0.22,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"rim\": \"rimmed\",\n \"cartridge\": {\n \"caseDiameter\": 9.1,\n \"overallLength\": 25,\n \"caseLength\": 17.3,\n \"projectileDiameter\": 7.94\n },\n \"sources\": [\n \"reference\",\n \"derived\"\n ]\n }\n]\n","[\n {\n \"id\": \"m67\",\n \"name\": \"M67 fragmentation grenade\",\n \"kind\": \"fragmentation\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 15,\n \"energy\": 200000,\n \"destructionLevel\": 2,\n \"noise\": 500,\n \"fuse\": 4,\n \"triggers\": [\n \"timer\"\n ],\n \"mass\": 0.4,\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"game\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"molotov\",\n \"name\": \"Molotov cocktail\",\n \"kind\": \"incendiary\",\n \"lethalRadius\": 0,\n \"injuryRadius\": 4,\n \"energy\": 500,\n \"destructionLevel\": 0,\n \"noise\": 40,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 4,\n \"seconds\": 9\n },\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"game\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"pipe_bomb\",\n \"name\": \"Pipe bomb\",\n \"kind\": \"fragmentation\",\n \"lethalRadius\": 3,\n \"injuryRadius\": 10,\n \"energy\": 43200,\n \"destructionLevel\": 2,\n \"noise\": 450,\n \"fuse\": 3,\n \"triggers\": [\n \"timer\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"propane_p13\",\n \"name\": \"P13 propane cylinder\",\n \"kind\": \"fuel\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 14,\n \"energy\": 200000,\n \"destructionLevel\": 2,\n \"noise\": 550,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 1.4,\n \"seconds\": 7\n },\n \"triggers\": [\n \"shot\",\n \"fire\",\n \"explosion\"\n ],\n \"chain\": {\n \"shot\": 1.4,\n \"fire\": 1.4,\n \"explosion\": [\n 0.25,\n 0.6\n ]\n },\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"game\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"dynamite\",\n \"name\": \"Dynamite\",\n \"kind\": \"blast\",\n \"lethalRadius\": 4,\n \"injuryRadius\": 12,\n \"energy\": 102400,\n \"destructionLevel\": 3,\n \"noise\": 600,\n \"fuseLength\": 0.03,\n \"burnRate\": 131,\n \"burnTolerance\": 0.1,\n \"triggers\": [\n \"timer\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\",\n \"reference\"\n ]\n },\n {\n \"id\": \"c4\",\n \"name\": \"C4 charge\",\n \"kind\": \"blast\",\n \"lethalRadius\": 6,\n \"injuryRadius\": 18,\n \"energy\": 345600,\n \"destructionLevel\": 3,\n \"noise\": 700,\n \"triggers\": [\n \"remote\"\n ],\n \"mass\": 0.57,\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"claymore\",\n \"name\": \"Claymore mine\",\n \"kind\": \"directional\",\n \"lethalRadius\": 15,\n \"injuryRadius\": 50,\n \"cone\": {\n \"halfAngleDeg\": 30,\n \"length\": 50\n },\n \"energy\": 102400,\n \"destructionLevel\": 1,\n \"noise\": 500,\n \"triggers\": [\n \"wire\"\n ],\n \"tripwire\": {\n \"length\": 10,\n \"angleDeg\": 0,\n \"height\": 0.15\n },\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"flashbang\",\n \"name\": \"Flashbang\",\n \"kind\": \"flash\",\n \"lethalRadius\": 0,\n \"injuryRadius\": 10,\n \"energy\": 0,\n \"destructionLevel\": 0,\n \"noise\": 400,\n \"fuseRange\": [\n 1,\n 2.3\n ],\n \"stunSeconds\": 4,\n \"triggers\": [\n \"timer\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\",\n \"reference\"\n ]\n },\n {\n \"id\": \"m79_40mm\",\n \"name\": \"40 mm grenade\",\n \"kind\": \"fragmentation\",\n \"lethalRadius\": 4,\n \"injuryRadius\": 12,\n \"energy\": 102400,\n \"destructionLevel\": 2,\n \"noise\": 450,\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"m72_66mm\",\n \"name\": \"66 mm HEAT rocket\",\n \"kind\": \"shaped_charge\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 15,\n \"energy\": 200000,\n \"destructionLevel\": 3,\n \"noise\": 700,\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"at4_84mm\",\n \"name\": \"84 mm HEAT rocket\",\n \"kind\": \"shaped_charge\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 16,\n \"energy\": 200000,\n \"destructionLevel\": 3,\n \"noise\": 750,\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"pg7v\",\n \"name\": \"PG-7V rocket\",\n \"kind\": \"shaped_charge\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 16,\n \"energy\": 200000,\n \"destructionLevel\": 3,\n \"noise\": 750,\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"carl_gustaf_84mm\",\n \"name\": \"84 mm HE/HEAT round\",\n \"kind\": \"shaped_charge\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 16,\n \"energy\": 200000,\n \"destructionLevel\": 3,\n \"noise\": 750,\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"lab\",\n \"gallery\",\n \"derived\"\n ]\n },\n {\n \"id\": \"fuel_barrel\",\n \"name\": \"Fuel barrel\",\n \"kind\": \"fuel\",\n \"lethalRadius\": 4,\n \"injuryRadius\": 12,\n \"energy\": 102400,\n \"destructionLevel\": 2,\n \"noise\": 550,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 2,\n \"seconds\": 12\n },\n \"triggers\": [\n \"shot\",\n \"fire\",\n \"explosion\"\n ],\n \"chain\": {\n \"shot\": 1.2,\n \"fire\": 1.2,\n \"explosion\": [\n 0.2,\n 0.4\n ]\n },\n \"sources\": [\n \"lab\",\n \"game\",\n \"derived\"\n ]\n },\n {\n \"id\": \"car_fuel_tank\",\n \"name\": \"Car fuel tank\",\n \"kind\": \"fuel\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 14,\n \"energy\": 200000,\n \"destructionLevel\": 2,\n \"noise\": 550,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 2.2,\n \"seconds\": 30\n },\n \"triggers\": [\n \"shot\",\n \"fire\",\n \"explosion\"\n ],\n \"chain\": {\n \"shot\": [\n 3,\n 8\n ],\n \"fire\": [\n 3,\n 8\n ],\n \"explosion\": 0.6,\n \"shotDamageFraction\": 0.5\n },\n \"sources\": [\n \"lab\",\n \"game\",\n \"derived\"\n ]\n },\n {\n \"id\": \"fuel_pump\",\n \"name\": \"Fuel pump\",\n \"kind\": \"fuel\",\n \"lethalRadius\": 4,\n \"injuryRadius\": 12,\n \"energy\": 102400,\n \"destructionLevel\": 3,\n \"noise\": 700,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 1.1,\n \"seconds\": 14\n },\n \"triggers\": [\n \"shot\",\n \"fire\",\n \"explosion\"\n ],\n \"chain\": {\n \"shot\": 1,\n \"fire\": 1,\n \"explosion\": 0.4\n },\n \"sources\": [\n \"lab\",\n \"derived\"\n ]\n },\n {\n \"id\": \"fuel_station_tank\",\n \"name\": \"Fuel station tank\",\n \"kind\": \"fuel\",\n \"lethalRadius\": 12,\n \"injuryRadius\": 30,\n \"energy\": 2764800,\n \"destructionLevel\": 3,\n \"noise\": 700,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 3.2,\n \"seconds\": 20\n },\n \"triggers\": [\n \"fire\",\n \"explosion\"\n ],\n \"chain\": {\n \"fire\": 2,\n \"explosion\": 2\n },\n \"sources\": [\n \"lab\",\n \"derived\"\n ]\n },\n {\n \"id\": \"vog_25\",\n \"name\": \"VOG-25 40 mm grenade\",\n \"kind\": \"fragmentation\",\n \"lethalRadius\": 4,\n \"injuryRadius\": 12,\n \"energy\": 102400,\n \"destructionLevel\": 2,\n \"noise\": 450,\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"lab\",\n \"derived\"\n ]\n }\n]\n","[\n {\n \"id\": \"flashbang\",\n \"name\": \"Flashbang\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"flashbang\",\n \"energy\": 0,\n \"radius\": 0,\n \"fuse\": 0,\n \"throwSpeed\": 15,\n \"noise\": 0\n },\n \"mass\": 0.23,\n \"tags\": [\n \"explosive\"\n ],\n \"archetype\": \"frag_grenade\",\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"dynamite\",\n \"name\": \"Dynamite\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"dynamite\",\n \"energy\": 0,\n \"radius\": 0,\n \"fuse\": 0,\n \"throwSpeed\": 15,\n \"noise\": 0\n },\n \"mass\": 0.5,\n \"tags\": [\n \"explosive\"\n ],\n \"archetype\": \"frag_grenade\",\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"c4\",\n \"name\": \"C4 charge\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"c4\",\n \"energy\": 0,\n \"radius\": 0,\n \"fuse\": 0,\n \"throwSpeed\": 0,\n \"noise\": 0\n },\n \"mass\": 0.57,\n \"tags\": [\n \"explosive\",\n \"placed\"\n ],\n \"archetype\": \"frag_grenade\",\n \"sources\": [\n \"arsenal\",\n \"lab\"\n ]\n },\n {\n \"id\": \"claymore\",\n \"name\": \"Claymore mine\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"claymore\",\n \"energy\": 0,\n \"radius\": 0,\n \"fuse\": 0,\n \"throwSpeed\": 0,\n \"noise\": 0\n },\n \"mass\": 1.6,\n \"tags\": [\n \"explosive\",\n \"placed\"\n ],\n \"archetype\": \"frag_grenade\",\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"reference\"\n ]\n }\n]\n","[\n {\n \"id\": \"glock_17\",\n \"name\": \"Glock 17\",\n \"maker\": \"Glock\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 17,\n \"reload\": 1.8,\n \"muzzleSpeed\": 375,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.63,\n 0.54\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.7,\n \"moa\": 4\n },\n \"mass\": 0.7,\n \"dimensions\": {\n \"length\": 0.202,\n \"barrel\": 0.114,\n \"emptyMass\": 0.63\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"glock_18\",\n \"name\": \"Glock 18\",\n \"maker\": \"Glock\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 1200,\n \"modes\": [\n \"semi\",\n \"auto\"\n ],\n \"magazine\": 17,\n \"magazineOptions\": [\n 33\n ],\n \"reload\": 1.8,\n \"muzzleSpeed\": 375,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.63,\n 0.54\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.9,\n \"moa\": 4\n },\n \"mass\": 0.7,\n \"dimensions\": {\n \"length\": 0.202,\n \"barrel\": 0.114,\n \"emptyMass\": 0.62\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"glock_19\",\n \"name\": \"Glock 19\",\n \"maker\": \"Glock\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 15,\n \"reload\": 1.7,\n \"muzzleSpeed\": 360,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.75,\n 0.58\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.7,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.7,\n \"moa\": 4\n },\n \"mass\": 0.6,\n \"dimensions\": {\n \"length\": 0.185,\n \"barrel\": 0.102,\n \"emptyMass\": 0.6\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"taurus_g2c\",\n \"name\": \"Taurus G2C\",\n \"maker\": \"Taurus\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 12,\n \"reload\": 1.7,\n \"muzzleSpeed\": 340,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.56,\n 0.52\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.7,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.5,\n \"moa\": 5\n },\n \"mass\": 0.6,\n \"dimensions\": {\n \"length\": 0.159,\n \"barrel\": 0.081,\n \"emptyMass\": 0.62\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"taurus_ts9\",\n \"name\": \"Taurus TS9\",\n \"maker\": \"Taurus\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 17,\n \"reload\": 1.8,\n \"muzzleSpeed\": 360,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.5,\n 0.5\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.2,\n \"moa\": 4\n },\n \"mass\": 0.7,\n \"dimensions\": {\n \"length\": 0.194,\n \"barrel\": 0.104,\n \"emptyMass\": 0.68\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"beretta_92fs\",\n \"name\": \"Beretta 92FS\",\n \"maker\": \"Beretta\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 15,\n \"reload\": 1.9,\n \"muzzleSpeed\": 381,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.24,\n 0.41\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.9,\n \"moa\": 3\n },\n \"mass\": 0.95,\n \"dimensions\": {\n \"length\": 0.217,\n \"barrel\": 0.125,\n \"emptyMass\": 0.95\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"sig_sauer_p226\",\n \"name\": \"SIG Sauer P226\",\n \"maker\": \"SIG Sauer\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 15,\n \"reload\": 1.9,\n \"muzzleSpeed\": 350,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.03,\n 0.34\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.8,\n \"moa\": 3\n },\n \"mass\": 0.96,\n \"dimensions\": {\n \"length\": 0.196,\n \"barrel\": 0.112,\n \"emptyMass\": 0.96\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"cz_75\",\n \"name\": \"CZ 75\",\n \"maker\": \"CZ\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 16,\n \"reload\": 1.9,\n \"muzzleSpeed\": 370,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.11,\n 0.37\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.9,\n \"moa\": 3\n },\n \"mass\": 1,\n \"dimensions\": {\n \"length\": 0.206,\n \"barrel\": 0.12,\n \"emptyMass\": 1\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"taurus_pt100\",\n \"name\": \"Taurus PT100\",\n \"maker\": \"Taurus\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"40sw\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 11,\n \"reload\": 1.9,\n \"muzzleSpeed\": 300,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.14,\n 0.38\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.2,\n \"moa\": 4\n },\n \"mass\": 1,\n \"dimensions\": {\n \"length\": 0.216,\n \"barrel\": 0.127,\n \"emptyMass\": 1\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"colt_m1911\",\n \"name\": \"Colt M1911\",\n \"maker\": \"Colt\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 7,\n \"reload\": 1.8,\n \"muzzleSpeed\": 253,\n \"spreadDeg\": 1.1,\n \"bloomDeg\": 0.8,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.79,\n 0.6\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.1,\n \"moa\": 3\n },\n \"mass\": 1.1,\n \"dimensions\": {\n \"length\": 0.216,\n \"barrel\": 0.127,\n \"emptyMass\": 1.1\n },\n \"archetype\": \"pistol_45\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"makarov_pm\",\n \"name\": \"Makarov PM\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x18\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 8,\n \"reload\": 1.7,\n \"muzzleSpeed\": 315,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 0.9,\n 0.3\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.7,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.8,\n \"moa\": 5\n },\n \"mass\": 0.73,\n \"dimensions\": {\n \"length\": 0.161,\n \"barrel\": 0.094,\n \"emptyMass\": 0.73\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"fn_five_seven\",\n \"name\": \"FN Five-seveN\",\n \"maker\": \"FN\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_7x28\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 1.8,\n \"muzzleSpeed\": 650,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.5,\n 0.5\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.9,\n \"moa\": 3\n },\n \"mass\": 0.61,\n \"dimensions\": {\n \"length\": 0.208,\n \"barrel\": 0.122,\n \"emptyMass\": 0.61\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"desert_eagle_mark_xix\",\n \"name\": \"Desert Eagle Mark XIX\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"50ae\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 7,\n \"reload\": 2,\n \"muzzleSpeed\": 470,\n \"spreadDeg\": 1.1,\n \"bloomDeg\": 0.8,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 4.41,\n 1.47\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.8,\n \"moa\": 3\n },\n \"mass\": 2,\n \"dimensions\": {\n \"length\": 0.27,\n \"barrel\": 0.152,\n \"emptyMass\": 1.99\n },\n \"archetype\": \"pistol_45\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"taurus_82\",\n \"name\": \"Taurus 82\",\n \"maker\": \"Taurus\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"38spl\",\n \"rpm\": 150,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 2.2,\n \"muzzleSpeed\": 260,\n \"spreadDeg\": 0.9,\n \"bloomDeg\": 0.7,\n \"recoveryDegPerS\": 3.5,\n \"recoil\": [\n 1.96,\n 0.61\n ],\n \"range\": 45,\n \"family\": \"revolver\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.2,\n \"perRound\": 1,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 0.9,\n \"dimensions\": {\n \"length\": 0.24,\n \"barrel\": 0.102,\n \"emptyMass\": 0.95\n },\n \"archetype\": \"revolver_38\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [],\n \"fitted\": []\n },\n {\n \"id\": \"sw_686\",\n \"name\": \"S&W 686\",\n \"maker\": \"S&W\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"357mag\",\n \"rpm\": 150,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 7,\n \"reload\": 2.4,\n \"muzzleSpeed\": 430,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 1,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3.21,\n 0.96\n ],\n \"range\": 60,\n \"family\": \"revolver\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"perRound\": 1,\n \"clear\": 1.2\n },\n \"moa\": 3,\n \"acceptsCalibers\": [\n \"38spl\"\n ]\n },\n \"mass\": 1.2,\n \"dimensions\": {\n \"length\": 0.244,\n \"barrel\": 0.102,\n \"emptyMass\": 1.14\n },\n \"archetype\": \"revolver_357\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [],\n \"fitted\": []\n },\n {\n \"id\": \"sw_model_29\",\n \"name\": \"S&W Model 29\",\n \"maker\": \"S&W\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"44mag\",\n \"rpm\": 150,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 2.6,\n \"muzzleSpeed\": 440,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 1,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 4.4,\n 1.32\n ],\n \"range\": 60,\n \"family\": \"revolver\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"perRound\": 1,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 1.4,\n \"dimensions\": {\n \"length\": 0.302,\n \"barrel\": 0.165,\n \"emptyMass\": 1.4\n },\n \"archetype\": \"revolver_357\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [],\n \"fitted\": []\n },\n {\n \"id\": \"hk_mp5a3\",\n \"name\": \"HK MP5A3\",\n \"maker\": \"HK\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 800,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.6,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.8,\n 0.44\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 2.9,\n \"dimensions\": {\n \"length\": 0.7,\n \"barrel\": 0.225,\n \"emptyMass\": 2.54,\n \"lengthCollapsed\": 0.55\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"hk_3lug\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_curved\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"taurus_smt9\",\n \"name\": \"Taurus SMT9\",\n \"maker\": \"Taurus\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.5,\n \"muzzleSpeed\": 380,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.78,\n 0.43\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.5,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 2.7,\n \"dimensions\": {\n \"length\": 0.66,\n \"barrel\": 0.2,\n \"emptyMass\": 2.5,\n \"lengthCollapsed\": 0.45\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"hk_ump_45\",\n \"name\": \"HK UMP-45\",\n \"maker\": \"HK\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 25,\n \"reload\": 2.7,\n \"muzzleSpeed\": 285,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 1.02,\n 0.57\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 2.3,\n \"dimensions\": {\n \"length\": 0.69,\n \"barrel\": 0.2,\n \"emptyMass\": 2.3,\n \"lengthCollapsed\": 0.45\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_5/8x24\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"right\"\n }\n },\n {\n \"id\": \"uzi\",\n \"name\": \"Uzi\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 32,\n \"reload\": 2.4,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.66,\n 0.37\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"clear\": 1.2\n },\n \"moa\": 6\n },\n \"mass\": 3.5,\n \"dimensions\": {\n \"length\": 0.65,\n \"barrel\": 0.26,\n \"emptyMass\": 3.5,\n \"lengthCollapsed\": 0.47\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"under\"\n }\n },\n {\n \"id\": \"fn_p90\",\n \"name\": \"FN P90\",\n \"maker\": \"FN\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_7x28\",\n \"rpm\": 900,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 50,\n \"reload\": 3,\n \"muzzleSpeed\": 715,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.76,\n 0.42\n ],\n \"range\": 80,\n \"family\": \"top_magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 2.6,\n \"dimensions\": {\n \"length\": 0.5,\n \"barrel\": 0.264,\n \"emptyMass\": 2.6\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"kriss_vector\",\n \"name\": \"Kriss Vector\",\n \"maker\": \"Kriss\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 1100,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 25,\n \"reload\": 2.5,\n \"muzzleSpeed\": 290,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.9,\n 0.5\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.5,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 2.7,\n \"dimensions\": {\n \"length\": 0.622,\n \"barrel\": 0.14,\n \"emptyMass\": 2.7,\n \"lengthCollapsed\": 0.406\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"red_dot\",\n \"mount\": \"rail_top\"\n }\n ],\n \"stock\": {\n \"kind\": \"fold_retract\",\n \"foldAxis\": \"right\"\n }\n },\n {\n \"id\": \"thompson_m1a1\",\n \"name\": \"Thompson M1A1\",\n \"maker\": \"Thompson\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 700,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.9,\n \"muzzleSpeed\": 285,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.49,\n 0.27\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.9,\n \"clear\": 1.2\n },\n \"moa\": 5\n },\n \"mass\": 4.8,\n \"dimensions\": {\n \"length\": 0.813,\n \"barrel\": 0.267,\n \"emptyMass\": 4.8\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"cz_scorpion_evo_3\",\n \"name\": \"CZ Scorpion EVO 3\",\n \"maker\": \"CZ\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 1150,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.4,\n \"muzzleSpeed\": 370,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.71,\n 0.39\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 2.8,\n \"dimensions\": {\n \"length\": 0.67,\n \"barrel\": 0.196,\n \"emptyMass\": 2.77,\n \"lengthCollapsed\": 0.41\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"red_dot\",\n \"mount\": \"rail_top\"\n }\n ],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"right\"\n }\n },\n {\n \"id\": \"mac_10\",\n \"name\": \"MAC-10\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 1090,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.2,\n \"muzzleSpeed\": 280,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.81,\n 0.45\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.2,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.4,\n \"moa\": 8\n },\n \"mass\": 2.8,\n \"dimensions\": {\n \"length\": 0.548,\n \"barrel\": 0.146,\n \"emptyMass\": 2.84,\n \"lengthCollapsed\": 0.296\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"fixed_muzzle_device\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"muzzle_brake_heavy\",\n \"mount\": \"muzzle\"\n }\n ],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"remington_870\",\n \"name\": \"Remington 870\",\n \"maker\": \"Remington\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 6,\n \"chamber\": 1,\n \"reload\": 0.55,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.32,\n 0.83\n ],\n \"range\": 40,\n \"family\": \"pump\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.55,\n \"perRound\": 0.55,\n \"cycle\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 60\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 0.99,\n \"barrel\": 0.47,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"barrel\",\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"mossberg_500\",\n \"name\": \"Mossberg 500\",\n \"maker\": \"Mossberg\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 5,\n \"chamber\": 1,\n \"reload\": 0.55,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.73,\n 0.93\n ],\n \"range\": 40,\n \"family\": \"pump\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.55,\n \"perRound\": 0.55,\n \"cycle\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 60\n },\n \"mass\": 3.2,\n \"dimensions\": {\n \"length\": 0.99,\n \"barrel\": 0.47,\n \"emptyMass\": 3.2\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"barrel\",\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"cbc_pump_military_3_0\",\n \"name\": \"CBC Pump Military 3.0\",\n \"maker\": \"CBC\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 7,\n \"chamber\": 1,\n \"reload\": 0.6,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.41,\n 0.85\n ],\n \"range\": 40,\n \"family\": \"pump\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.6,\n \"perRound\": 0.6,\n \"cycle\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 60\n },\n \"mass\": 3.5,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.48,\n \"emptyMass\": 3.4\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"barrel\",\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"benelli_m4\",\n \"name\": \"Benelli M4\",\n \"maker\": \"Benelli\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 180,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 7,\n \"chamber\": 1,\n \"reload\": 0.5,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 2.84,\n 0.84\n ],\n \"range\": 40,\n \"family\": \"tube_semi\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.5,\n \"perRound\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 60\n },\n \"mass\": 3.8,\n \"dimensions\": {\n \"length\": 1.01,\n \"barrel\": 0.47,\n \"emptyMass\": 3.82,\n \"lengthCollapsed\": 0.889\n },\n \"archetype\": \"shotgun_semi_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"barrel\",\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"red_dot\",\n \"mount\": \"rail_top\"\n }\n ],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"franchi_spas_12\",\n \"name\": \"Franchi SPAS-12\",\n \"maker\": \"Franchi\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"pump\",\n \"semi\"\n ],\n \"magazine\": 8,\n \"chamber\": 1,\n \"reload\": 0.55,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 2.72,\n 0.68\n ],\n \"range\": 40,\n \"family\": \"pump\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.55,\n \"perRound\": 0.55,\n \"cycle\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 55\n },\n \"mass\": 4.4,\n \"dimensions\": {\n \"length\": 1.041,\n \"barrel\": 0.546,\n \"emptyMass\": 4.4,\n \"lengthCollapsed\": 0.82\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"barrel\",\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"over\"\n }\n },\n {\n \"id\": \"kel_tec_ksg\",\n \"name\": \"Kel-Tec KSG\",\n \"maker\": \"Kel-Tec\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 14,\n \"chamber\": 1,\n \"tubes\": 2,\n \"reload\": 0.55,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.85,\n 0.96\n ],\n \"range\": 40,\n \"family\": \"pump\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.55,\n \"perRound\": 0.55,\n \"cycle\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 60\n },\n \"mass\": 3.1,\n \"dimensions\": {\n \"length\": 0.66,\n \"barrel\": 0.47,\n \"emptyMass\": 3.1\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"barrel\",\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"saiga_12\",\n \"name\": \"Saiga-12\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 180,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 8,\n \"magazineOptions\": [\n 20\n ],\n \"reload\": 2.8,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3,\n 0.88\n ],\n \"range\": 40,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.3,\n \"patternCm\": 65\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.43,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"shotgun_semi_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"barrel\",\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"aa_12\",\n \"name\": \"AA-12\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 300,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 8,\n \"magazineOptions\": [\n 20\n ],\n \"reload\": 3,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 2.08,\n 0.61\n ],\n \"range\": 40,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3,\n \"clear\": 1.2\n },\n \"patternCm\": 65\n },\n \"mass\": 5.2,\n \"dimensions\": {\n \"length\": 0.966,\n \"barrel\": 0.457,\n \"emptyMass\": 5.2\n },\n \"archetype\": \"shotgun_semi_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_drum\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"barrel\",\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"boito_double_barrel\",\n \"name\": \"Boito double-barrel\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 180,\n \"modes\": [\n \"break\",\n \"volley\"\n ],\n \"magazine\": 2,\n \"reload\": 2,\n \"muzzleSpeed\": 410,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 4.14,\n 1.1\n ],\n \"range\": 35,\n \"family\": \"break\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2,\n \"clear\": 1.2\n },\n \"patternCm\": 45\n },\n \"mass\": 3.2,\n \"dimensions\": {\n \"length\": 1.13,\n \"barrel\": 0.71,\n \"emptyMass\": 3.2\n },\n \"archetype\": \"shotgun_double_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"barrel\",\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"ak_47\",\n \"name\": \"AK-47\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x39\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.6,\n \"muzzleSpeed\": 715,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.29,\n 0.69\n ],\n \"range\": 350,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"reloadEmpty\": 3.4,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.4,\n \"moa\": 4\n },\n \"mass\": 4.3,\n \"dimensions\": {\n \"length\": 0.88,\n \"barrel\": 0.415,\n \"emptyMass\": 4.3\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_14x1lh\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"ak_side\"\n ],\n \"sources\": [\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"underbarrel\",\n \"interfaces\": [\n \"gp25\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_curved\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"akm\",\n \"name\": \"AKM\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x39\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.6,\n \"muzzleSpeed\": 715,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.54,\n 0.82\n ],\n \"range\": 350,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"reloadEmpty\": 3.4,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.45,\n \"moa\": 4\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 0.88,\n \"barrel\": 0.415,\n \"emptyMass\": 3.1\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_14x1lh\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"ak_side\"\n ],\n \"sources\": [\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"underbarrel\",\n \"interfaces\": [\n \"gp25\"\n ],\n \"sources\": [\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_curved\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"ak_74\",\n \"name\": \"AK-74\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_45x39\",\n \"rpm\": 650,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.6,\n \"muzzleSpeed\": 900,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.81,\n 0.49\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"reloadEmpty\": 3.4,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 3.3,\n \"dimensions\": {\n \"length\": 0.943,\n \"barrel\": 0.415,\n \"emptyMass\": 3.3\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_24x1.5\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"underbarrel\",\n \"interfaces\": [\n \"gp25\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_curved\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"muzzle_brake\",\n \"mount\": \"muzzle\"\n }\n ]\n },\n {\n \"id\": \"ak_12\",\n \"name\": \"AK-12\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_45x39\",\n \"rpm\": 700,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.5,\n \"muzzleSpeed\": 880,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.73,\n 0.44\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.5,\n \"reloadEmpty\": 3.3,\n \"clear\": 1.2\n },\n \"moa\": 2.5\n },\n \"mass\": 3.5,\n \"dimensions\": {\n \"length\": 0.945,\n \"barrel\": 0.415,\n \"emptyMass\": 3.5,\n \"lengthCollapsed\": 0.725\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_24x1.5\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"underbarrel\",\n \"interfaces\": [\n \"gp25\"\n ],\n \"sources\": [\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_curved\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"muzzle_brake\",\n \"mount\": \"muzzle\"\n },\n {\n \"id\": \"red_dot\",\n \"mount\": \"rail_top\"\n }\n ],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"imbel_ia2\",\n \"name\": \"IMBEL IA2\",\n \"maker\": \"IMBEL\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 700,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.4,\n \"muzzleSpeed\": 860,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.85,\n 0.51\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"reloadEmpty\": 3.1,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 3.4,\n \"dimensions\": {\n \"length\": 0.85,\n \"barrel\": 0.33,\n \"emptyMass\": 3.4,\n \"lengthCollapsed\": 0.6\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_1/2x28\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"right\"\n }\n },\n {\n \"id\": \"taurus_t4\",\n \"name\": \"Taurus T4\",\n \"maker\": \"Taurus\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.4,\n \"muzzleSpeed\": 880,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1,\n 0.6\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"reloadEmpty\": 3.1,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 3,\n \"dimensions\": {\n \"length\": 0.84,\n \"barrel\": 0.368,\n \"emptyMass\": 3,\n \"lengthCollapsed\": 0.767\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_1/2x28\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"red_dot\",\n \"mount\": \"rail_top\"\n }\n ],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"colt_m4a1\",\n \"name\": \"Colt M4A1\",\n \"maker\": \"Colt\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 800,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.3,\n \"muzzleSpeed\": 880,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1,\n 0.6\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.3,\n \"reloadEmpty\": 3,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 3,\n \"dimensions\": {\n \"length\": 0.84,\n \"barrel\": 0.368,\n \"emptyMass\": 2.9,\n \"lengthCollapsed\": 0.757\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_1/2x28\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\",\n \"mlok\"\n ],\n \"sources\": [\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\",\n \"mlok\"\n ],\n \"sources\": [\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\",\n \"mlok\"\n ],\n \"sources\": [\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\",\n \"mlok\"\n ],\n \"sources\": [\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"underbarrel\",\n \"interfaces\": [\n \"m203\"\n ],\n \"sources\": [\n \"arsenal\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"acog_4x\",\n \"mount\": \"rail_top\"\n }\n ],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"colt_m16a2\",\n \"name\": \"Colt M16A2\",\n \"maker\": \"Colt\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 800,\n \"modes\": [\n \"semi\",\n \"burst\"\n ],\n \"burst\": 3,\n \"magazine\": 30,\n \"reload\": 2.4,\n \"muzzleSpeed\": 948,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1.03,\n 0.62\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"reloadEmpty\": 3.1,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 3.4,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.508,\n \"emptyMass\": 3.4\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_1/2x28\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"underbarrel\",\n \"interfaces\": [\n \"m203\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"hk416\",\n \"name\": \"HK416\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 850,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.3,\n \"muzzleSpeed\": 880,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.86,\n 0.52\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.3,\n \"reloadEmpty\": 3,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 3.5,\n \"dimensions\": {\n \"length\": 0.9,\n \"barrel\": 0.368,\n \"emptyMass\": 3.5,\n \"lengthCollapsed\": 0.8\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_1/2x28\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"underbarrel\",\n \"interfaces\": [\n \"ag36\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"red_dot\",\n \"mount\": \"rail_top\"\n }\n ],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"steyr_aug_a1\",\n \"name\": \"Steyr AUG A1\",\n \"maker\": \"Steyr\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 680,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.8,\n \"muzzleSpeed\": 970,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1.02,\n 0.61\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.8,\n \"reloadEmpty\": 3.4,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 0.79,\n \"barrel\": 0.508,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"integral\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"integral_optic_1_5x\",\n \"mount\": \"rail_top\",\n \"integral\": true\n }\n ]\n },\n {\n \"id\": \"fn_fal\",\n \"name\": \"FN FAL\",\n \"maker\": \"FN\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 650,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 2.7,\n \"muzzleSpeed\": 840,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 2.16,\n 1.15\n ],\n \"range\": 350,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"reloadEmpty\": 3.5,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 4.3,\n \"dimensions\": {\n \"length\": 1.09,\n \"barrel\": 0.533,\n \"emptyMass\": 4.3\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"fixed_muzzle_device\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"muzzle_brake\",\n \"mount\": \"muzzle\"\n }\n ]\n },\n {\n \"id\": \"hk_g3a3\",\n \"name\": \"HK G3A3\",\n \"maker\": \"HK\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 550,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 2.7,\n \"muzzleSpeed\": 800,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.91,\n 1.02\n ],\n \"range\": 350,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"reloadEmpty\": 3.6,\n \"clear\": 1.2\n },\n \"moa\": 2.5\n },\n \"mass\": 4.4,\n \"dimensions\": {\n \"length\": 1.025,\n \"barrel\": 0.45,\n \"emptyMass\": 4.4\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"sks\",\n \"name\": \"SKS\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x39\",\n \"rpm\": 120,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 2.2,\n \"muzzleSpeed\": 735,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.54,\n 0.82\n ],\n \"range\": 350,\n \"family\": \"top_load_semi\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.2,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 3.8,\n \"dimensions\": {\n \"length\": 1.02,\n \"barrel\": 0.52,\n \"emptyMass\": 3.85\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"m14_ebr\",\n \"name\": \"M14 EBR\",\n \"category\": \"dmr\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 120,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 2.8,\n \"muzzleSpeed\": 850,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.13,\n 0.36\n ],\n \"range\": 800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.8,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 5.1,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.457,\n \"emptyMass\": 5.1,\n \"lengthCollapsed\": 0.81\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"scope_3_9x\",\n \"mount\": \"rail_top\"\n }\n ],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"svd_dragunov\",\n \"name\": \"SVD Dragunov\",\n \"category\": \"dmr\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x54r\",\n \"rpm\": 120,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 2.9,\n \"muzzleSpeed\": 830,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.39,\n 0.4\n ],\n \"range\": 800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.9,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 4.3,\n \"dimensions\": {\n \"length\": 1.225,\n \"barrel\": 0.62,\n \"emptyMass\": 4.3\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"fixed_muzzle_device\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"pso_1_side\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"muzzle_brake\",\n \"mount\": \"muzzle\"\n },\n {\n \"id\": \"pso_1\",\n \"mount\": \"rail_top\",\n \"integral\": true\n }\n ]\n },\n {\n \"id\": \"fn_scar_h\",\n \"name\": \"FN SCAR-H\",\n \"maker\": \"FN\",\n \"category\": \"dmr\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 2.6,\n \"muzzleSpeed\": 770,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.48,\n 0.41\n ],\n \"range\": 800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 0.965,\n \"barrel\": 0.4,\n \"emptyMass\": 3.6,\n \"lengthCollapsed\": 0.71\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_5/8x24\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"acog_4x\",\n \"mount\": \"rail_top\"\n }\n ],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"right\"\n }\n },\n {\n \"id\": \"knights_sr_25_mk11\",\n \"name\": \"Knight's SR-25 (Mk 11)\",\n \"maker\": \"Knight's\",\n \"category\": \"dmr\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 120,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 2.7,\n \"muzzleSpeed\": 800,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.14,\n 0.36\n ],\n \"range\": 800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"clear\": 1.2\n },\n \"moa\": 1\n },\n \"mass\": 4.5,\n \"dimensions\": {\n \"length\": 1.156,\n \"barrel\": 0.508,\n \"emptyMass\": 4.5\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\",\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"scope_3_9x\",\n \"mount\": \"rail_top\"\n },\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ]\n },\n {\n \"id\": \"hk_psg_1\",\n \"name\": \"HK PSG-1\",\n \"maker\": \"HK\",\n \"category\": \"dmr\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 120,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 5,\n \"magazineOptions\": [\n 20\n ],\n \"reload\": 2.7,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 1.51,\n 0.25\n ],\n \"range\": 800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"reloadEmpty\": 3.6,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.7\n },\n \"mass\": 7.2,\n \"dimensions\": {\n \"length\": 1.208,\n \"barrel\": 0.65,\n \"emptyMass\": 7.2\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"dovetail\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"scope_3_9x\",\n \"mount\": \"rail_top\"\n }\n ]\n },\n {\n \"id\": \"steyr_ssg_69\",\n \"name\": \"Steyr SSG 69\",\n \"maker\": \"Steyr\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 0.7,\n \"perRound\": true,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.79,\n 0.47\n ],\n \"range\": 800,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.7,\n \"perRound\": 0.7,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.6\n },\n \"mass\": 3.9,\n \"dimensions\": {\n \"length\": 1.14,\n \"barrel\": 0.65,\n \"emptyMass\": 3.9\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"dovetail\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"scope_3_9x\",\n \"mount\": \"rail_top\"\n }\n ]\n },\n {\n \"id\": \"barrett_mrad\",\n \"name\": \"Barrett MRAD\",\n \"maker\": \"Barrett\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"338lapua\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 10,\n \"reload\": 3.2,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 3.85,\n 0.6\n ],\n \"range\": 1500,\n \"family\": \"bolt_magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3.2,\n \"cycle\": 0.82,\n \"clear\": 1.2\n }\n },\n \"mass\": 6.9,\n \"dimensions\": {\n \"length\": 1.26,\n \"barrel\": 0.686,\n \"emptyMass\": 6.9,\n \"lengthCollapsed\": 1.055\n },\n \"archetype\": \"sniper_338\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"fixed_muzzle_device\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\",\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"muzzle_brake\",\n \"mount\": \"muzzle\"\n },\n {\n \"id\": \"scope_3_9x\",\n \"mount\": \"rail_top\"\n },\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"right\"\n }\n },\n {\n \"id\": \"cheytac_m200\",\n \"name\": \"CheyTac M200\",\n \"maker\": \"CheyTac\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"408cheytac\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 7,\n \"reload\": 3.2,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 3.16,\n 0.49\n ],\n \"range\": 1500,\n \"family\": \"bolt_magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3.2,\n \"cycle\": 0.82,\n \"clear\": 1.2\n }\n },\n \"mass\": 14,\n \"dimensions\": {\n \"length\": 1.397,\n \"barrel\": 0.737,\n \"emptyMass\": 14,\n \"lengthCollapsed\": 1.187\n },\n \"archetype\": \"sniper_338\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"fixed_muzzle_device\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"dovetail\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"muzzle_brake\",\n \"mount\": \"muzzle\"\n },\n {\n \"id\": \"scope_6_24x\",\n \"mount\": \"rail_top\"\n },\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"remington_700\",\n \"name\": \"Remington 700\",\n \"maker\": \"Remington\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 4,\n \"reload\": 0.7,\n \"perRound\": true,\n \"muzzleSpeed\": 790,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.35,\n 0.39\n ],\n \"range\": 800,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.7,\n \"perRound\": 0.7,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 1\n },\n \"mass\": 4,\n \"dimensions\": {\n \"length\": 1.1,\n \"barrel\": 0.61,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"dovetail\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"scope_3_9x\",\n \"mount\": \"rail_top\"\n }\n ]\n },\n {\n \"id\": \"m24_sws\",\n \"name\": \"M24 SWS\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 0.7,\n \"perRound\": true,\n \"muzzleSpeed\": 790,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 1.74,\n 0.29\n ],\n \"range\": 800,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.7,\n \"perRound\": 0.7,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 0.75\n },\n \"mass\": 5.4,\n \"dimensions\": {\n \"length\": 1.092,\n \"barrel\": 0.61,\n \"emptyMass\": 5.4\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"integral\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n },\n {\n \"id\": \"fixed_scope_10x\",\n \"mount\": \"rail_top\",\n \"integral\": true\n }\n ]\n },\n {\n \"id\": \"mosin_nagant_91_30\",\n \"name\": \"Mosin-Nagant 91/30\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x54r\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 2.4,\n \"muzzleSpeed\": 865,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.79,\n 0.46\n ],\n \"range\": 800,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 2.5\n },\n \"mass\": 4,\n \"dimensions\": {\n \"length\": 1.232,\n \"barrel\": 0.73,\n \"emptyMass\": 4\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"accuracy_awm\",\n \"name\": \"Accuracy AWM\",\n \"maker\": \"Accuracy\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"338lapua\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 3.2,\n \"muzzleSpeed\": 936,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 4.13,\n 0.64\n ],\n \"range\": 1500,\n \"family\": \"bolt_magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3.2,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 0.5\n },\n \"mass\": 6.9,\n \"dimensions\": {\n \"length\": 1.23,\n \"barrel\": 0.686,\n \"emptyMass\": 6.9\n },\n \"archetype\": \"sniper_338\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"fixed_muzzle_device\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"dovetail\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"muzzle_brake\",\n \"mount\": \"muzzle\"\n },\n {\n \"id\": \"scope_3_9x\",\n \"mount\": \"rail_top\"\n },\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ]\n },\n {\n \"id\": \"sako_trg_42\",\n \"name\": \"Sako TRG-42\",\n \"maker\": \"Sako\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"338lapua\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 3,\n \"muzzleSpeed\": 900,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 5.17,\n 0.8\n ],\n \"range\": 1500,\n \"family\": \"bolt_magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 0.5\n },\n \"mass\": 5.1,\n \"dimensions\": {\n \"length\": 1.2,\n \"barrel\": 0.69,\n \"emptyMass\": 5.1\n },\n \"archetype\": \"sniper_338\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"fixed_muzzle_device\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"dovetail\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"muzzle_brake\",\n \"mount\": \"muzzle\"\n },\n {\n \"id\": \"scope_3_9x\",\n \"mount\": \"rail_top\"\n },\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ]\n },\n {\n \"id\": \"barrett_m82a1\",\n \"name\": \"Barrett M82A1\",\n \"maker\": \"Barrett\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"50bmg\",\n \"rpm\": 30,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 4,\n \"muzzleSpeed\": 853,\n \"spreadDeg\": 0.15,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 4.82,\n 0.83\n ],\n \"range\": 1800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 4,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 14,\n \"dimensions\": {\n \"length\": 1.448,\n \"barrel\": 0.737,\n \"emptyMass\": 14\n },\n \"archetype\": \"anti_materiel_50\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"fixed_muzzle_device\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"dovetail\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"muzzle_brake_heavy\",\n \"mount\": \"muzzle\"\n },\n {\n \"id\": \"scope_3_9x\",\n \"mount\": \"rail_top\"\n },\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ]\n },\n {\n \"id\": \"ruger_10_22\",\n \"name\": \"Ruger 10/22\",\n \"maker\": \"Ruger\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"magazineOptions\": [\n 25\n ],\n \"reload\": 1.9,\n \"muzzleSpeed\": 380,\n \"spreadDeg\": 0.5,\n \"bloomDeg\": 0.15,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.25,\n 0.09\n ],\n \"range\": 80,\n \"family\": \"top_load_semi\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 2.3,\n \"dimensions\": {\n \"length\": 0.94,\n \"barrel\": 0.47,\n \"emptyMass\": 2.3\n },\n \"archetype\": \"carbine_22\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"cbc_7022\",\n \"name\": \"CBC 7022\",\n \"maker\": \"CBC\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 1.9,\n \"muzzleSpeed\": 380,\n \"spreadDeg\": 0.5,\n \"bloomDeg\": 0.15,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.29,\n 0.11\n ],\n \"range\": 80,\n \"family\": \"top_load_semi\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 2,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.53,\n \"emptyMass\": 2\n },\n \"archetype\": \"carbine_22\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"cbc_122\",\n \"name\": \"CBC 122\",\n \"maker\": \"CBC\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 10,\n \"reload\": 1.9,\n \"muzzleSpeed\": 380,\n \"spreadDeg\": 0.5,\n \"bloomDeg\": 0.15,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.24,\n 0.09\n ],\n \"range\": 80,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 2.4,\n \"dimensions\": {\n \"length\": 1.03,\n \"barrel\": 0.59,\n \"emptyMass\": 2.4\n },\n \"archetype\": \"carbine_22\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"winchester_1894\",\n \"name\": \"Winchester 1894\",\n \"maker\": \"Winchester\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"30_30\",\n \"rpm\": 109.09,\n \"modes\": [\n \"lever\"\n ],\n \"magazine\": 7,\n \"reload\": 0.6,\n \"perRound\": true,\n \"muzzleSpeed\": 670,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.25,\n 0.38\n ],\n \"range\": 800,\n \"family\": \"lever\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.6,\n \"perRound\": 0.6,\n \"cycle\": 0.55,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 3,\n \"dimensions\": {\n \"length\": 0.965,\n \"barrel\": 0.508,\n \"emptyMass\": 3\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"rossi_puma\",\n \"name\": \"Rossi Puma\",\n \"maker\": \"Rossi\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"357mag\",\n \"rpm\": 109.09,\n \"modes\": [\n \"lever\"\n ],\n \"magazine\": 10,\n \"reload\": 0.5,\n \"perRound\": true,\n \"muzzleSpeed\": 500,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 1.47,\n 0.24\n ],\n \"range\": 800,\n \"family\": \"lever\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.5,\n \"perRound\": 0.5,\n \"cycle\": 0.55,\n \"clear\": 1.2\n },\n \"moa\": 3,\n \"acceptsCalibers\": [\n \"38spl\"\n ]\n },\n \"mass\": 2.7,\n \"dimensions\": {\n \"length\": 0.95,\n \"barrel\": 0.508,\n \"emptyMass\": 2.7\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"hunting_rifle_30_06\",\n \"name\": \".30-06 hunting rifle\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"30_06\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 4,\n \"reload\": 0.7,\n \"perRound\": true,\n \"muzzleSpeed\": 880,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3.24,\n 0.54\n ],\n \"range\": 800,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.7,\n \"perRound\": 0.7,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 1.1,\n \"barrel\": 0.56,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"dovetail\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"scope_3_9x\",\n \"mount\": \"rail_top\"\n }\n ]\n },\n {\n \"id\": \"fn_minimi\",\n \"name\": \"FN Minimi\",\n \"maker\": \"FN\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 850,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 200,\n \"reload\": 7.5,\n \"muzzleSpeed\": 915,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.46,\n 0.28\n ],\n \"range\": 400,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 7.5,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 7.1,\n \"dimensions\": {\n \"length\": 1.04,\n \"barrel\": 0.465,\n \"emptyMass\": 7.1\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"feed\",\n \"interfaces\": [\n \"belt\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ]\n },\n {\n \"id\": \"pkm\",\n \"name\": \"PKM\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x54r\",\n \"rpm\": 650,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 100,\n \"reload\": 8,\n \"muzzleSpeed\": 825,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.18,\n 0.63\n ],\n \"range\": 350,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 8,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 7.5,\n \"dimensions\": {\n \"length\": 1.173,\n \"barrel\": 0.658,\n \"emptyMass\": 7.5\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"feed\",\n \"interfaces\": [\n \"belt\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ]\n },\n {\n \"id\": \"m60\",\n \"name\": \"M60\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 550,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 100,\n \"reload\": 8.5,\n \"muzzleSpeed\": 853,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 0.91,\n 0.49\n ],\n \"range\": 350,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 8.5,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.3,\n \"moa\": 4\n },\n \"mass\": 10.5,\n \"dimensions\": {\n \"length\": 1.105,\n \"barrel\": 0.56,\n \"emptyMass\": 10.5\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"feed\",\n \"interfaces\": [\n \"belt\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ]\n },\n {\n \"id\": \"browning_m2\",\n \"name\": \"Browning M2 .50\",\n \"maker\": \"Browning\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"50bmg\",\n \"rpm\": 550,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 100,\n \"reload\": 10,\n \"muzzleSpeed\": 890,\n \"spreadDeg\": 0.15,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 1.93,\n 0.33\n ],\n \"range\": 1800,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 10,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 38,\n \"dimensions\": {\n \"length\": 1.65,\n \"barrel\": 1.14,\n \"emptyMass\": 38\n },\n \"archetype\": \"anti_materiel_50\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"underbarrel\",\n \"interfaces\": [\n \"tripod\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"feed\",\n \"interfaces\": [\n \"belt\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"tripod\",\n \"mount\": \"underbarrel\",\n \"integral\": true\n }\n ]\n },\n {\n \"id\": \"remington_700_300wm\",\n \"name\": \"Remington 700 (.300 WM)\",\n \"maker\": \"Remington\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"300wm\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 3,\n \"reload\": 0.7,\n \"perRound\": true,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 4.76,\n 0.74\n ],\n \"range\": 1500,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.7,\n \"perRound\": 0.7,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 1\n },\n \"mass\": 4,\n \"dimensions\": {\n \"length\": 1.1,\n \"barrel\": 0.61,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"sniper_338\",\n \"variantOf\": \"remington_700\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\",\n \"derived\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"dovetail\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"scope_3_9x\",\n \"mount\": \"rail_top\"\n }\n ]\n },\n {\n \"id\": \"m79\",\n \"name\": \"M79 grenade launcher\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"m79_40mm\",\n \"magazine\": 1,\n \"reload\": 2,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2,\n \"clear\": 1.2\n },\n \"family\": \"break\",\n \"speed\": 76,\n \"minArmDistance\": 10,\n \"backblast\": 0,\n \"recoil\": [\n 4.5,\n 1.2\n ]\n },\n \"mass\": 2.93,\n \"dimensions\": {\n \"length\": 0.73,\n \"barrel\": 0.356,\n \"emptyMass\": 2.7\n },\n \"archetype\": \"shotgun_double_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"hk_mp5sd3\",\n \"name\": \"HK MP5SD3\",\n \"maker\": \"HK\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 700,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.6,\n \"muzzleSpeed\": 285,\n \"noise\": 37.5,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.35,\n 0.19\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"clear\": 1.2\n }\n },\n \"mass\": 3.4,\n \"dimensions\": {\n \"length\": 0.805,\n \"barrel\": 0.146,\n \"emptyMass\": 3.4,\n \"lengthCollapsed\": 0.61\n },\n \"archetype\": \"smg_9mm\",\n \"variantOf\": \"hk_mp5a3\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"integral\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_curved\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"integral_suppressor\",\n \"mount\": \"muzzle\",\n \"integral\": true\n }\n ],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"fn_parafal\",\n \"name\": \"FN ParaFAL\",\n \"maker\": \"FN\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 650,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 2.7,\n \"muzzleSpeed\": 840,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 2.32,\n 1.24\n ],\n \"range\": 350,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"reloadEmpty\": 3.5,\n \"clear\": 1.2\n }\n },\n \"mass\": 4,\n \"dimensions\": {\n \"length\": 1.02,\n \"barrel\": 0.44,\n \"emptyMass\": 4,\n \"lengthCollapsed\": 0.77\n },\n \"archetype\": \"rifle_7_62x39\",\n \"variantOf\": \"fn_fal\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"fixed_muzzle_device\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"muzzle_brake\",\n \"mount\": \"muzzle\"\n }\n ],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"right\"\n }\n },\n {\n \"id\": \"taurus_t4_civil\",\n \"name\": \"Taurus T4 (civil)\",\n \"maker\": \"Taurus\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 120,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.4,\n \"muzzleSpeed\": 880,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1,\n 0.6\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"reloadEmpty\": 3.1,\n \"clear\": 1.2\n }\n },\n \"mass\": 3,\n \"dimensions\": {\n \"length\": 0.878,\n \"barrel\": 0.406,\n \"emptyMass\": 3,\n \"lengthCollapsed\": 0.805\n },\n \"archetype\": \"rifle_5_56\",\n \"variantOf\": \"taurus_t4\",\n \"sources\": [\n \"derived\",\n \"reference\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_1/2x28\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"red_dot\",\n \"mount\": \"rail_top\"\n }\n ],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"taurus_th380\",\n \"name\": \"Taurus TH380\",\n \"maker\": \"Taurus\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"380acp\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 12,\n \"chamber\": 1,\n \"reload\": 1.7,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.06,\n 0.35\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.7,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.5\n },\n \"mass\": 0.55,\n \"dimensions\": {\n \"length\": 0.165,\n \"barrel\": 0.09,\n \"emptyMass\": 0.55\n },\n \"archetype\": \"pistol_9mm\",\n \"variantOf\": \"taurus_g2c\",\n \"sources\": [\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_pistol\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"mossberg_500_cruiser\",\n \"name\": \"Mossberg 500 Cruiser\",\n \"maker\": \"Mossberg\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 5,\n \"chamber\": 1,\n \"reload\": 0.55,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 4.43,\n 1.11\n ],\n \"range\": 40,\n \"family\": \"pump\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.55,\n \"perRound\": 0.55,\n \"cycle\": 0.5,\n \"clear\": 1.2\n }\n },\n \"mass\": 2.7,\n \"dimensions\": {\n \"length\": 0.72,\n \"barrel\": 0.47,\n \"emptyMass\": 2.7\n },\n \"archetype\": \"shotgun_pump_12\",\n \"variantOf\": \"mossberg_500\",\n \"sources\": [\n \"derived\",\n \"reference\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"barrel\",\n \"interfaces\": [\n \"barrel_swap\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"hk_mp5k\",\n \"name\": \"HK MP5K\",\n \"maker\": \"HK\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 900,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"magazineOptions\": [\n 15\n ],\n \"reload\": 2.6,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 1.16,\n 0.65\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"clear\": 1.2\n }\n },\n \"mass\": 2,\n \"dimensions\": {\n \"length\": 0.325,\n \"barrel\": 0.115,\n \"emptyMass\": 2\n },\n \"archetype\": \"smg_9mm\",\n \"variantOf\": \"hk_mp5a3\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"hk_3lug\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_curved\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n },\n {\n \"id\": \"hk_ump9\",\n \"name\": \"HK UMP9\",\n \"maker\": \"HK\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 700,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.7,\n \"muzzleSpeed\": 380,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.91,\n 0.51\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"clear\": 1.2\n }\n },\n \"mass\": 2.3,\n \"dimensions\": {\n \"length\": 0.69,\n \"barrel\": 0.2,\n \"emptyMass\": 2.3,\n \"lengthCollapsed\": 0.45\n },\n \"archetype\": \"smg_9mm\",\n \"variantOf\": \"hk_ump_45\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_curved\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"right\"\n }\n },\n {\n \"id\": \"mini_uzi\",\n \"name\": \"Mini Uzi\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 950,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 20,\n \"magazineOptions\": [\n 25,\n 32\n ],\n \"reload\": 2.4,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.86,\n 0.48\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"clear\": 1.2\n }\n },\n \"mass\": 2.7,\n \"dimensions\": {\n \"length\": 0.6,\n \"barrel\": 0.197,\n \"emptyMass\": 2.7,\n \"lengthCollapsed\": 0.36\n },\n \"archetype\": \"smg_9mm\",\n \"variantOf\": \"uzi\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"under\"\n }\n },\n {\n \"id\": \"hk_mp7a1\",\n \"name\": \"HK MP7A1\",\n \"maker\": \"HK\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"4_6x30\",\n \"rpm\": 950,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 40,\n \"magazineOptions\": [\n 20,\n 30\n ],\n \"reload\": 2.6,\n \"muzzleSpeed\": 735,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 1.1,\n 0.61\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"clear\": 1.2\n }\n },\n \"mass\": 1.9,\n \"dimensions\": {\n \"length\": 0.638,\n \"barrel\": 0.18,\n \"emptyMass\": 1.9,\n \"lengthCollapsed\": 0.415\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"hk_g36\",\n \"name\": \"HK G36\",\n \"maker\": \"HK\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"magazineOptions\": [\n 100\n ],\n \"reload\": 2.3,\n \"muzzleSpeed\": 920,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.91,\n 0.54\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.3,\n \"reloadEmpty\": 3,\n \"clear\": 1.2\n }\n },\n \"mass\": 3.63,\n \"dimensions\": {\n \"length\": 0.999,\n \"barrel\": 0.48,\n \"emptyMass\": 3.63,\n \"lengthCollapsed\": 0.758\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"integral\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"integral_optic_3x\",\n \"mount\": \"rail_top\",\n \"integral\": true\n }\n ],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"left\"\n }\n },\n {\n \"id\": \"hk_g36k\",\n \"name\": \"HK G36K\",\n \"maker\": \"HK\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"magazineOptions\": [\n 100\n ],\n \"reload\": 2.3,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1.03,\n 0.62\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.3,\n \"reloadEmpty\": 3,\n \"clear\": 1.2\n }\n },\n \"mass\": 3.3,\n \"dimensions\": {\n \"length\": 0.86,\n \"barrel\": 0.318,\n \"emptyMass\": 3.3,\n \"lengthCollapsed\": 0.615\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"integral\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"integral_optic_3x\",\n \"mount\": \"rail_top\",\n \"integral\": true\n }\n ],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"left\"\n }\n },\n {\n \"id\": \"hk_g36c\",\n \"name\": \"HK G36C\",\n \"maker\": \"HK\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"magazineOptions\": [\n 100\n ],\n \"reload\": 2.3,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1.21,\n 0.72\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.3,\n \"reloadEmpty\": 3,\n \"clear\": 1.2\n }\n },\n \"mass\": 2.82,\n \"dimensions\": {\n \"length\": 0.72,\n \"barrel\": 0.228,\n \"emptyMass\": 2.82,\n \"lengthCollapsed\": 0.5\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"left\"\n }\n },\n {\n \"id\": \"fn_m249\",\n \"name\": \"FN M249\",\n \"maker\": \"FN\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 850,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 200,\n \"magazineOptions\": [\n 30\n ],\n \"reload\": 7.5,\n \"muzzleSpeed\": 915,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.46,\n 0.28\n ],\n \"range\": 400,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 7.5,\n \"clear\": 1.2\n }\n },\n \"mass\": 7.1,\n \"dimensions\": {\n \"length\": 1.04,\n \"barrel\": 0.465,\n \"emptyMass\": 7.1\n },\n \"archetype\": \"rifle_5_56\",\n \"variantOf\": \"fn_minimi\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"feed\",\n \"interfaces\": [\n \"belt\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ]\n },\n {\n \"id\": \"fn_minimi_para\",\n \"name\": \"FN Minimi Para\",\n \"maker\": \"FN\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 850,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 200,\n \"magazineOptions\": [\n 30\n ],\n \"reload\": 7.5,\n \"muzzleSpeed\": 915,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.46,\n 0.28\n ],\n \"range\": 400,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 7.5,\n \"clear\": 1.2\n }\n },\n \"mass\": 7.1,\n \"dimensions\": {\n \"length\": 0.893,\n \"barrel\": 0.349,\n \"emptyMass\": 7.1,\n \"lengthCollapsed\": 0.766\n },\n \"archetype\": \"rifle_5_56\",\n \"variantOf\": \"fn_minimi\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"feed\",\n \"interfaces\": [\n \"belt\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"fn_mag\",\n \"name\": \"FN MAG\",\n \"maker\": \"FN\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 100,\n \"reload\": 8.5,\n \"muzzleSpeed\": 840,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 0.79,\n 0.42\n ],\n \"range\": 350,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 8.5,\n \"clear\": 1.2\n }\n },\n \"mass\": 11.79,\n \"dimensions\": {\n \"length\": 1.263,\n \"barrel\": 0.63,\n \"emptyMass\": 11.79\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"feed\",\n \"interfaces\": [\n \"belt\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ]\n },\n {\n \"id\": \"rpk\",\n \"name\": \"RPK\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x39\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 40,\n \"magazineOptions\": [\n 75\n ],\n \"reload\": 2.6,\n \"muzzleSpeed\": 745,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.25,\n 0.67\n ],\n \"range\": 350,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"reloadEmpty\": 3.4,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.4\n },\n \"mass\": 4.8,\n \"dimensions\": {\n \"length\": 1.04,\n \"barrel\": 0.59,\n \"emptyMass\": 4.8\n },\n \"archetype\": \"rifle_7_62x39\",\n \"variantOf\": \"ak_47\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"muzzle\",\n \"interfaces\": [\n \"thread_14x1lh\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_curved\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ]\n },\n {\n \"id\": \"sig_mpx\",\n \"name\": \"SIG MPX\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 850,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"magazineOptions\": [\n 20,\n 35\n ],\n \"reload\": 2.6,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.72,\n 0.4\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"clear\": 1.2\n }\n },\n \"mass\": 2.7,\n \"dimensions\": {\n \"length\": 0.61,\n \"barrel\": 0.203,\n \"emptyMass\": 2.7,\n \"lengthCollapsed\": 0.425\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_top\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_left\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_right\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"picatinny\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_box\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"retract\"\n }\n },\n {\n \"id\": \"mg3\",\n \"name\": \"MG3\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 1100,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 100,\n \"reload\": 8.5,\n \"muzzleSpeed\": 820,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 0.77,\n 0.41\n ],\n \"range\": 350,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 8.5,\n \"clear\": 1.2\n }\n },\n \"mass\": 11.5,\n \"dimensions\": {\n \"length\": 1.225,\n \"barrel\": 0.565,\n \"emptyMass\": 11.5\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"rail_bottom\",\n \"interfaces\": [\n \"bipod_stud\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"feed\",\n \"interfaces\": [\n \"belt\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [\n {\n \"id\": \"bipod\",\n \"mount\": \"rail_bottom\"\n }\n ]\n },\n {\n \"id\": \"pp19_bizon\",\n \"name\": \"PP-19 Bizon\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x18\",\n \"rpm\": 680,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 64,\n \"reload\": 2.5,\n \"muzzleSpeed\": 320,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.58,\n 0.32\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.5,\n \"clear\": 1.2\n }\n },\n \"mass\": 2.1,\n \"dimensions\": {\n \"length\": 0.66,\n \"barrel\": 0.195,\n \"emptyMass\": 2.1,\n \"lengthCollapsed\": 0.425\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_helical\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"left\"\n }\n },\n {\n \"id\": \"vz61\",\n \"name\": \"vz. 61 Škorpion\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"32acp\",\n \"rpm\": 850,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 20,\n \"magazineOptions\": [\n 10\n ],\n \"reload\": 2.4,\n \"muzzleSpeed\": 320,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.7,\n 0.39\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"clear\": 1.2\n }\n },\n \"mass\": 1.3,\n \"dimensions\": {\n \"length\": 0.517,\n \"barrel\": 0.115,\n \"emptyMass\": 1.3,\n \"lengthCollapsed\": 0.27\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"magazine\",\n \"interfaces\": [\n \"mag_curved\"\n ],\n \"sources\": [\n \"gallery\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": [],\n \"stock\": {\n \"kind\": \"fold\",\n \"foldAxis\": \"over\"\n }\n },\n {\n \"id\": \"m134\",\n \"name\": \"M134 Minigun\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 3000,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 200,\n \"reload\": 8.5,\n \"muzzleSpeed\": 853,\n \"spin\": {\n \"upSeconds\": 0.5,\n \"holdSeconds\": 1\n },\n \"rpmRange\": [\n 2000,\n 6000\n ],\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 0.25,\n 0.13\n ],\n \"range\": 350,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 8.5,\n \"clear\": 1.2\n }\n },\n \"mass\": 39,\n \"dimensions\": {\n \"length\": 0.801,\n \"barrel\": 0.559,\n \"emptyMass\": 39\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"reference\",\n \"derived\",\n \"sdk\"\n ],\n \"mounts\": [\n {\n \"kind\": \"underbarrel\",\n \"interfaces\": [\n \"tripod\"\n ],\n \"sources\": [\n \"reference\"\n ]\n },\n {\n \"kind\": \"sling\",\n \"interfaces\": [\n \"swivel\"\n ],\n \"sources\": [\n \"derived\"\n ]\n },\n {\n \"kind\": \"feed\",\n \"interfaces\": [\n \"belt\"\n ],\n \"sources\": [\n \"derived\"\n ]\n }\n ],\n \"fitted\": []\n }\n]\n","[\n {\n \"id\": \"rpg_7\",\n \"name\": \"RPG-7\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"pg7v\",\n \"magazine\": 1,\n \"reload\": 4.5,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 4.5,\n \"clear\": 1.2\n },\n \"family\": \"rocket\",\n \"speed\": 117,\n \"minArmDistance\": 10,\n \"backblast\": 5,\n \"backblastHalfAngleDeg\": 19,\n \"recoil\": [\n 4,\n 1\n ]\n },\n \"mass\": 6.3,\n \"dimensions\": {\n \"length\": 0.95,\n \"barrel\": 0.95,\n \"emptyMass\": 6.3\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"m72_law\",\n \"name\": \"M72 LAW\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"m72_66mm\",\n \"magazine\": 1,\n \"reload\": 1.15,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.15,\n \"clear\": 1.2\n },\n \"family\": \"rocket\",\n \"disposable\": true,\n \"speed\": 145,\n \"minArmDistance\": 10,\n \"backblast\": 5,\n \"backblastHalfAngleDeg\": 19,\n \"recoil\": [\n 2.75,\n 0.69\n ]\n },\n \"mass\": 2.5,\n \"dimensions\": {\n \"length\": 0.881,\n \"barrel\": 0.881,\n \"emptyMass\": 2.5\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"at4\",\n \"name\": \"AT4\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"at4_84mm\",\n \"magazine\": 1,\n \"reload\": 1.15,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.15,\n \"clear\": 1.2\n },\n \"family\": \"rocket\",\n \"disposable\": true,\n \"speed\": 285,\n \"minArmDistance\": 10,\n \"backblast\": 5,\n \"backblastHalfAngleDeg\": 19,\n \"recoil\": [\n 3.25,\n 0.81\n ]\n },\n \"mass\": 6.7,\n \"dimensions\": {\n \"length\": 1.02,\n \"barrel\": 1.02,\n \"emptyMass\": 6.7\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"carl_gustaf_m4\",\n \"name\": \"Carl Gustaf M4\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"carl_gustaf_84mm\",\n \"magazine\": 1,\n \"reload\": 1.05,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.05,\n \"clear\": 1.2\n },\n \"family\": \"rocket\",\n \"speed\": 255,\n \"minArmDistance\": 10,\n \"backblast\": 5,\n \"backblastHalfAngleDeg\": 19,\n \"recoil\": [\n 3.5,\n 0.87\n ]\n },\n \"mass\": 6.6,\n \"dimensions\": {\n \"length\": 0.95,\n \"barrel\": 0.95,\n \"emptyMass\": 6.6\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"m2_flamethrower\",\n \"name\": \"M2 flamethrower\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 900,\n \"radius\": 0.6,\n \"range\": 6,\n \"fuelPerSecond\": 1,\n \"fuel\": 9,\n \"cone\": true,\n \"noise\": 20,\n \"family\": \"flame\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.1,\n \"clear\": 1.2\n }\n },\n \"mass\": 32,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.62,\n \"emptyMass\": 32\n },\n \"archetype\": \"flamethrower\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ]\n },\n {\n \"id\": \"improvised_flamethrower\",\n \"name\": \"Improvised flamethrower\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 900,\n \"radius\": 0.6,\n \"range\": 3.6,\n \"fuelPerSecond\": 1,\n \"fuel\": 5,\n \"cone\": true,\n \"noise\": 20,\n \"family\": \"flame\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.1,\n \"clear\": 1.2\n }\n },\n \"mass\": 6,\n \"dimensions\": {\n \"length\": 0.8,\n \"barrel\": 0.66,\n \"emptyMass\": 6\n },\n \"archetype\": \"flamethrower\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ]\n },\n {\n \"id\": \"m203\",\n \"name\": \"M203 grenade launcher\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"m79_40mm\",\n \"magazine\": 1,\n \"reload\": 2,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2,\n \"clear\": 1.2\n },\n \"family\": \"underbarrel\",\n \"speed\": 76,\n \"minArmDistance\": 10,\n \"backblast\": 0,\n \"recoil\": [\n 4.5,\n 1.2\n ]\n },\n \"mass\": 1.59,\n \"dimensions\": {\n \"length\": 0.38,\n \"barrel\": 0.305,\n \"emptyMass\": 1.36\n },\n \"archetype\": \"shotgun_double_12\",\n \"tags\": [\n \"underbarrel\"\n ],\n \"sources\": [\n \"arsenal\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"gp_25\",\n \"name\": \"GP-25 grenade launcher\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"vog_25\",\n \"magazine\": 1,\n \"reload\": 2,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2,\n \"clear\": 1.2\n },\n \"family\": \"underbarrel\",\n \"speed\": 76,\n \"minArmDistance\": 10,\n \"backblast\": 0,\n \"recoil\": [\n 4.5,\n 1.2\n ]\n },\n \"mass\": 1.73,\n \"dimensions\": {\n \"length\": 0.323,\n \"barrel\": 0.26,\n \"emptyMass\": 1.5\n },\n \"archetype\": \"shotgun_double_12\",\n \"tags\": [\n \"underbarrel\"\n ],\n \"sources\": [\n \"arsenal\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"ag36\",\n \"name\": \"AG36 grenade launcher\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"m79_40mm\",\n \"magazine\": 1,\n \"reload\": 2,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2,\n \"clear\": 1.2\n },\n \"family\": \"underbarrel\",\n \"speed\": 76,\n \"minArmDistance\": 10,\n \"backblast\": 0,\n \"recoil\": [\n 4.5,\n 1.2\n ]\n },\n \"mass\": 1.73,\n \"dimensions\": {\n \"length\": 0.35,\n \"barrel\": 0.28,\n \"emptyMass\": 1.5\n },\n \"archetype\": \"shotgun_double_12\",\n \"tags\": [\n \"underbarrel\"\n ],\n \"sources\": [\n \"arsenal\",\n \"reference\",\n \"derived\"\n ]\n }\n]\n","import type { AttachmentDef, AttachmentInstall, FittedAttachment, MountDef, MountKind } from './attachment-types'\nimport type { CaliberDef, WeaponDef } from './types'\n\nexport type FitRefusal = 'no_mount' | 'interface' | 'caliber' | 'category' | 'occupied' | 'blocked' | 'rejected'\n\nexport type CanFit = { readonly ok: true; readonly mount: MountKind } | { readonly ok: false; readonly reason: FitRefusal }\n\n/** What a game adds to the rule: false keeps the accessory off the weapon whatever the mounts say. */\nexport type IsCompatible = (def: WeaponDef, attachment: AttachmentDef, fitted: readonly FittedAttachment[]) => boolean\n\nexport interface CanFitContext {\n readonly caliber: CaliberDef | null\n readonly catalogue: ReadonlyMap<string, AttachmentDef>\n readonly isCompatible?: IsCompatible\n}\n\nconst INSTALL_RANK: Readonly<Record<AttachmentInstall, number>> = { field: 0, tool: 1, bench: 2 }\n\n/** Whether what is at hand (`field`: the hands, `tool`: a tool, `bench`: a bench) is enough to put the accessory on or take it off. */\nexport const canInstallWith = (available: AttachmentInstall, needed: AttachmentInstall): boolean => INSTALL_RANK[available] >= INSTALL_RANK[needed]\n\nconst muzzleEnergyOf = (def: WeaponDef, caliber: CaliberDef): number => {\n const speed = def.action.kind === 'firearm' ? def.action.muzzleSpeed ?? caliber.muzzleSpeed * (def.action.barrel ?? 1) : caliber.muzzleSpeed\n return 0.5 * (caliber.bulletGrams / 1000) * speed * speed\n}\n\nconst caliberRefusal = (def: WeaponDef, attachment: AttachmentDef, caliber: CaliberDef | null): boolean => {\n const limit = attachment.calibers\n if (!limit) return false\n if (!caliber) return true\n if (limit.ids && !limit.ids.includes(caliber.id)) return true\n if (limit.maxDiameter !== undefined && caliber.diameter > limit.maxDiameter) return true\n return limit.maxEnergy !== undefined && muzzleEnergyOf(def, caliber) > limit.maxEnergy\n}\n\nconst candidatesOf = (def: WeaponDef, attachment: AttachmentDef, mount?: MountKind): MountDef[] =>\n (def.mounts ?? []).filter((place) => attachment.mounts.includes(place.kind) && (mount === undefined || place.kind === mount))\n\nconst isBlocked = (place: MountKind, attachment: AttachmentDef, fitted: readonly FittedAttachment[], catalogue: ReadonlyMap<string, AttachmentDef>): boolean => {\n if (fitted.some((part) => catalogue.get(part.id)?.blocks?.includes(place))) return true\n return fitted.some((part) => attachment.blocks?.includes(part.mount))\n}\n\n/**\n * Whether the accessory goes on the weapon, and where. Order of the checks: a place of its kind (`no_mount`), an interface the place takes\n * (`interface`), the calibre limits of a suppressor (`caliber`), the weapon categories (`category`), the place being free (`occupied`),\n * something else covering it (`blocked`), then the game's own `isCompatible` (`rejected`).\n */\nexport const canFit = (def: WeaponDef, attachment: AttachmentDef, fitted: readonly FittedAttachment[], context: CanFitContext, mount?: MountKind): CanFit => {\n const places = candidatesOf(def, attachment, mount)\n if (places.length === 0) return { ok: false, reason: 'no_mount' }\n const matching = places.filter((place) => place.interfaces.some((name) => attachment.interfaces.includes(name)))\n if (matching.length === 0) return { ok: false, reason: 'interface' }\n if (caliberRefusal(def, attachment, context.caliber)) return { ok: false, reason: 'caliber' }\n if (attachment.categories && !attachment.categories.includes(def.category)) return { ok: false, reason: 'category' }\n const free = matching.filter((place) => !fitted.some((part) => part.mount === place.kind))\n if (free.length === 0) return { ok: false, reason: 'occupied' }\n const open = free.filter((place) => !isBlocked(place.kind, attachment, fitted, context.catalogue))\n const place = open[0]\n if (!place) return { ok: false, reason: 'blocked' }\n if (context.isCompatible && !context.isCompatible(def, attachment, fitted)) return { ok: false, reason: 'rejected' }\n return { ok: true, mount: place.kind }\n}\n","import type { AttachmentDef, AttachmentId } from './attachment-types'\nimport type { CaliberDef, CaliberId, ExplosiveDef, ExplosiveId, FirearmAction, WeaponDef, WeaponId, WeaponRules } from './types'\n\nexport interface ArsenalParts {\n readonly weapons: ReadonlyMap<WeaponId, WeaponDef>\n readonly calibers: ReadonlyMap<CaliberId, CaliberDef>\n readonly explosives: ReadonlyMap<ExplosiveId, ExplosiveDef>\n readonly attachments?: ReadonlyMap<AttachmentId, AttachmentDef>\n /** When given, the default condition and ammunition quality must be ones the rules define. */\n readonly rules?: Pick<WeaponRules, 'conditions' | 'defaultCondition' | 'ammoQualities' | 'defaultAmmoQuality'>\n}\n\n/** Ids that appear more than once in a list a game passed in. */\nexport const findDuplicateIds = (kind: string, entries: readonly { readonly id: string }[] | undefined): string[] => {\n const seen = new Set<string>()\n const problems: string[] = []\n for (const { id } of entries ?? []) {\n if (seen.has(id)) problems.push(`${kind} \"${id}\" is listed more than once`)\n seen.add(id)\n }\n return problems\n}\n\nconst checkRotary = (id: string, action: FirearmAction): string[] => {\n const problems: string[] = []\n const { rpm, rpmRange, spin } = action\n if (rpmRange && !(rpmRange[0] > 0 && rpmRange[0] <= rpmRange[1])) problems.push(`weapon \"${id}\" has an empty rate range ${rpmRange[0]}-${rpmRange[1]} rpm`)\n if (rpmRange && (rpm < rpmRange[0] || rpm > rpmRange[1])) problems.push(`weapon \"${id}\" fires at ${rpm} rpm, outside its range ${rpmRange[0]}-${rpmRange[1]}`)\n if (spin && !(spin.upSeconds >= 0 && spin.holdSeconds >= 0)) problems.push(`weapon \"${id}\" has a negative spin time`)\n return problems\n}\n\nconst checkFirearm = (def: WeaponDef, calibers: ArsenalParts['calibers']): string[] => {\n if (def.action.kind !== 'firearm') return []\n const problems: string[] = []\n for (const caliber of [def.action.caliber, ...(def.action.acceptsCalibers ?? [])]) {\n if (!calibers.has(caliber)) problems.push(`weapon \"${def.id}\" uses unknown calibre \"${caliber}\"`)\n }\n if (def.action.modes.length === 0) problems.push(`weapon \"${def.id}\" has no fire modes`)\n if (!(def.action.rpm > 0)) problems.push(`weapon \"${def.id}\" has a rate of fire of ${def.action.rpm} rpm`)\n if (!(def.action.reload > 0)) problems.push(`weapon \"${def.id}\" has a reload time of ${def.action.reload} s`)\n problems.push(...checkRotary(def.id, def.action))\n return problems\n}\n\nconst checkTimings = (def: WeaponDef): string[] => {\n const timings = 'timings' in def.action ? def.action.timings : undefined\n return Object.entries(timings ?? {})\n .filter(([, seconds]) => typeof seconds === 'number' && !(seconds > 0))\n .map(([name, seconds]) => `weapon \"${def.id}\" has a ${name} time of ${seconds} s`)\n}\n\nconst checkExplosiveReference = (def: WeaponDef, explosives: ArsenalParts['explosives']): string[] => {\n const id = def.action.kind === 'launcher' ? def.action.projectile : def.action.kind === 'throwable' ? def.action.explosive : undefined\n return id !== undefined && !explosives.has(id) ? [`weapon \"${def.id}\" uses unknown explosive \"${id}\"`] : []\n}\n\nconst checkExplosiveNumbers = (explosive: ExplosiveDef): string[] => {\n const problems: string[] = []\n const [low, high] = explosive.fuseRange ?? [1, 1]\n if (!(low > 0 && high >= low)) problems.push(`explosive \"${explosive.id}\" has a fuse range of ${low} to ${high} s`)\n if (explosive.fuseLength !== undefined && !(explosive.fuseLength > 0)) problems.push(`explosive \"${explosive.id}\" has a fuse length of ${explosive.fuseLength} m`)\n if (explosive.burnRate !== undefined && !(explosive.burnRate > 0)) problems.push(`explosive \"${explosive.id}\" has a burn rate of ${explosive.burnRate} s/m`)\n if (explosive.burnTolerance !== undefined && !(explosive.burnTolerance >= 0 && explosive.burnTolerance < 1)) problems.push(`explosive \"${explosive.id}\" has a burn tolerance of ${explosive.burnTolerance}`)\n if (explosive.tripwire && !(explosive.tripwire.length > 0)) problems.push(`explosive \"${explosive.id}\" has a trip wire of ${explosive.tripwire.length} m`)\n return problems\n}\n\nconst STATS: ReadonlySet<string> = new Set(['noise', 'spread', 'hipSpreadExcess', 'recoilVertical', 'recoilHorizontal', 'range', 'muzzleSpeed', 'mass', 'capacity', 'reload', 'reloadEmpty', 'draw', 'aim', 'faultChance', 'heatPerShot'])\nconst INSTALLS: ReadonlySet<string> = new Set(['field', 'tool', 'bench'])\n\nconst checkAttachment = (attachment: AttachmentDef, weapons: ArsenalParts['weapons']): string[] => {\n const problems: string[] = []\n if (attachment.launcher !== undefined && weapons.get(attachment.launcher)?.action.kind !== 'launcher') problems.push(`attachment \"${attachment.id}\" names \"${attachment.launcher}\" as its launcher, which is not a launcher weapon`)\n const label = `attachment \"${attachment.id}\"`\n if (!INSTALLS.has(attachment.install)) problems.push(`${label} installs \"${attachment.install}\"`)\n if (attachment.mounts.length === 0) problems.push(`${label} has no mount`)\n if (attachment.interfaces.length === 0) problems.push(`${label} has no interface`)\n for (const effect of attachment.effects) {\n if (!STATS.has(effect.stat)) problems.push(`${label} changes the unknown stat \"${effect.stat}\"`)\n if (effect.mul !== undefined && !(effect.mul > 0)) problems.push(`${label} multiplies ${effect.stat} by ${effect.mul}`)\n }\n return problems\n}\n\nconst checkFitted = (def: WeaponDef, attachments: ArsenalParts['attachments']): string[] => {\n if (!attachments) return []\n return (def.fitted ?? []).flatMap((part) => {\n const problems: string[] = []\n if (!attachments.has(part.id)) problems.push(`weapon \"${def.id}\" is fitted with unknown attachment \"${part.id}\"`)\n if (!(def.mounts ?? []).some((mount) => mount.kind === part.mount)) problems.push(`weapon \"${def.id}\" has \"${part.id}\" on \"${part.mount}\", which it has no mount for`)\n return problems\n })\n}\n\nconst checkRuleDefaults = (rules: ArsenalParts['rules']): string[] => {\n if (!rules) return []\n const problems: string[] = []\n if (!rules.conditions.some((condition) => condition.id === rules.defaultCondition)) problems.push(`the default condition \"${rules.defaultCondition}\" is not one of the conditions`)\n if (!rules.ammoQualities.some((quality) => quality.id === rules.defaultAmmoQuality)) problems.push(`the default ammunition quality \"${rules.defaultAmmoQuality}\" is not one of the qualities`)\n return problems\n}\n\n/** Every problem found in an arsenal, so a game sees them all at once instead of one per run. Empty when it is consistent. */\nexport const checkArsenal = ({ weapons, calibers, explosives, attachments, rules }: ArsenalParts): string[] => [\n ...[...weapons.values()].flatMap((def) => [...checkFirearm(def, calibers), ...checkTimings(def), ...checkExplosiveReference(def, explosives), ...checkFitted(def, attachments)]),\n ...[...(attachments?.values() ?? [])].flatMap((attachment) => checkAttachment(attachment, weapons)),\n ...[...explosives.values()].flatMap(checkExplosiveNumbers),\n ...checkRuleDefaults(rules),\n]\n","type PlainObject = Record<string, unknown>\n\n/** Keys that would reach the prototype of the result when a patch comes from parsed JSON. */\nconst UNSAFE_KEYS: ReadonlySet<string> = new Set(['__proto__', 'constructor', 'prototype'])\n\nconst isPlainObject = (value: unknown): value is PlainObject =>\n typeof value === 'object' && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype\n\n/** Merges `patch` over `base`: plain objects merge field by field, arrays, functions and primitives replace. `undefined` in the patch is ignored. */\nexport const deepMerge = <TBase extends object>(base: TBase, patch: object | undefined): TBase => {\n if (!patch) return base\n const result: PlainObject = { ...(base as PlainObject) }\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined || UNSAFE_KEYS.has(key)) continue\n const current = result[key]\n result[key] = isPlainObject(current) && isPlainObject(value) ? deepMerge(current, value) : value\n }\n return result as TBase\n}\n","import { deepMerge } from './merge'\nimport type { DeepPartial } from './types'\n\n/** Locales shipped with the package. Unknown locales fall back to `en`. */\nexport type WeaponsLocale = 'en' | 'pt-BR'\n\nexport interface WeaponsStrings {\n /** Display name of each weapon id. */\n weapons: Record<string, string>\n /** Display name of each fire mode. */\n modes: Record<string, string>\n /** Display name of each weapon category. */\n categories: Record<string, string>\n /** Display name of each explosive id. */\n explosives: Record<string, string>\n /** Display name of each weapon fault. */\n faults: Record<string, string>\n /** Display name of each weapon condition. */\n conditions: Record<string, string>\n}\n\nconst modesEn = { single: 'single action', semi: 'semi-automatic', burst: 'burst', auto: 'automatic', pump: 'pump action', bolt: 'bolt action', lever: 'lever action', break: 'break action', volley: 'volley' }\nconst categoriesEn = {\n pistol: 'pistol', revolver: 'revolver', smg: 'submachine gun', rifle: 'rifle', carbine: 'carbine', sniper: 'sniper rifle', shotgun: 'shotgun',\n bow: 'bow', crossbow: 'crossbow', melee_blunt: 'blunt melee', melee_blade: 'bladed melee', flame: 'flame', heat: 'heat', throwable: 'throwable',\n tool: 'tool', extinguisher: 'extinguisher', hand: 'hand', dmr: 'marksman rifle', hunting: 'hunting rifle', machine_gun: 'machine gun', launcher: 'launcher',\n}\nconst faultsEn = { misfire: 'misfire', stovepipe: 'stovepipe', double_feed: 'double feed', failure_to_extract: 'failure to extract' }\nconst conditionsEn = { new: 'new', used: 'used', worn: 'worn', rusty: 'rusty' }\n\nexport const locales: Record<WeaponsLocale, WeaponsStrings> = {\n en: {\n weapons: {\n hand: 'Hand', kick: 'Kick', shove: 'Shove', pistol_9mm: '9 mm service pistol', pistol_45: '.45 ACP pistol', pistol_22: '.22 LR pistol', revolver_357: '.357 Magnum revolver',\n revolver_38: '.38 Special revolver', smg_9mm: '9 mm submachine gun', carbine_22: '.22 LR carbine', rifle_5_56: '5.56 mm assault rifle',\n rifle_7_62x39: '7.62×39 mm assault rifle', rifle_bolt_308: '.308 bolt-action rifle', sniper_338: '.338 Lapua sniper rifle',\n anti_materiel_50: '.50 BMG anti-materiel rifle', shotgun_pump_12: '12 gauge pump-action shotgun', shotgun_double_12: '12 gauge double-barrel shotgun',\n shotgun_semi_12: '12 gauge semi-automatic shotgun', bow_compound: 'Compound bow', crossbow: 'Crossbow', hammer: 'Hammer', sledgehammer: 'Sledgehammer',\n baseball_bat: 'Baseball bat', crowbar: 'Crowbar', machete: 'Machete', axe: 'Axe', knife: 'Knife', fists: 'Fists', lighter: 'Lighter',\n flamethrower: 'Flamethrower', molotov: 'Molotov cocktail', cutting_torch: 'Oxy-fuel cutting torch', blowtorch: 'Blowtorch',\n frag_grenade: 'Fragmentation grenade', pipe_bomb: 'Pipe bomb', screwdriver: 'Screwdriver', wrench: 'Wrench', pry_bar: 'Pry bar', hacksaw: 'Hacksaw',\n utility_knife: 'Utility knife', claw_hammer: 'Claw hammer', extinguisher: 'Fire extinguisher',\n },\n modes: modesEn,\n categories: categoriesEn,\n explosives: {},\n faults: faultsEn,\n conditions: conditionsEn,\n },\n 'pt-BR': {\n weapons: {\n hand: 'mão', kick: 'chute', shove: 'empurrão', pistol_9mm: 'pistola 9 mm', pistol_45: 'pistola .45', pistol_22: 'pistola .22', revolver_357: 'revólver .357', revolver_38: 'revólver .38',\n smg_9mm: 'submetralhadora 9 mm', carbine_22: 'carabina .22', rifle_5_56: 'fuzil 5,56', rifle_7_62x39: 'fuzil 7,62×39', rifle_bolt_308: 'fuzil de ferrolho .308',\n sniper_338: 'fuzil de precisão .338', anti_materiel_50: 'fuzil antimaterial .50', shotgun_pump_12: 'espingarda de repetição calibre 12',\n shotgun_double_12: 'espingarda de dois canos calibre 12', shotgun_semi_12: 'espingarda semiautomática calibre 12', bow_compound: 'arco composto',\n crossbow: 'besta', hammer: 'martelo', sledgehammer: 'marreta', baseball_bat: 'taco de beisebol', crowbar: 'pé de cabra', machete: 'facão', axe: 'machado',\n knife: 'faca', fists: 'punhos', lighter: 'isqueiro', flamethrower: 'lança-chamas', molotov: 'coquetel molotov', cutting_torch: 'maçarico de corte',\n blowtorch: 'maçarico', frag_grenade: 'granada de fragmentação', pipe_bomb: 'bomba caseira', screwdriver: 'chave de fenda', wrench: 'chave inglesa',\n pry_bar: 'alavanca', hacksaw: 'serra de arco', utility_knife: 'estilete', claw_hammer: 'martelo de unha', extinguisher: 'extintor',\n boito_double_barrel: 'Boito (2 canos)', hunting_rifle_30_06: 'Rifle de caça .30-06', m2_flamethrower: 'Lança-chamas M2', improvised_flamethrower: 'Lança-chamas caseiro',\n m79: 'Lança-granadas M79',\n },\n modes: { single: 'tiro único', semi: 'semiautomático', burst: 'rajada', auto: 'automático', pump: 'repetição', bolt: 'ferrolho', lever: 'alavanca', break: 'basculante', volley: 'salva' },\n categories: {\n pistol: 'pistola', revolver: 'revólver', smg: 'submetralhadora', rifle: 'fuzil', carbine: 'carabina', sniper: 'fuzil de precisão', shotgun: 'espingarda',\n bow: 'arco', crossbow: 'besta', melee_blunt: 'corpo a corpo contundente', melee_blade: 'corpo a corpo cortante', flame: 'chama', heat: 'calor',\n throwable: 'arremessável', tool: 'ferramenta', extinguisher: 'extintor', hand: 'mão', dmr: 'fuzil de precisão semiautomático', hunting: 'arma de caça',\n machine_gun: 'metralhadora', launcher: 'lançador',\n },\n explosives: {\n m67: 'Granada M67', molotov: 'Coquetel molotov', pipe_bomb: 'Bomba caseira', propane_p13: 'Botijão de gás P13', dynamite: 'Dinamite', c4: 'C4 com detonador',\n claymore: 'Mina Claymore', flashbang: 'Granada de luz', m79_40mm: 'Granada de 40 mm', m72_66mm: 'Foguete HEAT de 66 mm', at4_84mm: 'Foguete HEAT de 84 mm',\n pg7v: 'Foguete PG-7V', carl_gustaf_84mm: 'Projétil de 84 mm (HE/HEAT)', fuel_barrel: 'Barril de combustível', car_fuel_tank: 'Tanque de combustível do carro',\n fuel_pump: 'Bomba de combustível', fuel_station_tank: 'Tanque do posto de gasolina',\n },\n faults: { misfire: 'nega', stovepipe: 'chaminé', double_feed: 'dupla alimentação', failure_to_extract: 'falha de extração' },\n conditions: { new: 'nova', used: 'usada', worn: 'gasta', rusty: 'enferrujada' },\n },\n}\n\nexport const resolveStrings = (locale: string | undefined, overrides?: DeepPartial<WeaponsStrings>): WeaponsStrings =>\n deepMerge(locales[(locale as WeaponsLocale) ?? 'en'] ?? locales.en, overrides)\n","import type { ExplosiveDef } from './explosive-types'\n\n/** The fuse of an explosive with no randomness: a fixed `fuse`, the burn of a safety fuse (length times rate), or the middle of `fuseRange`. */\nexport const nominalFuse = (explosive: ExplosiveDef, fuseLength?: number): number | undefined => {\n const length = fuseLength ?? explosive.fuseLength\n if (length !== undefined && explosive.burnRate !== undefined) return length * explosive.burnRate\n if (explosive.fuseRange) return (explosive.fuseRange[0] + explosive.fuseRange[1]) / 2\n return explosive.fuse\n}\n\n/**\n * The fuse of one throw. A safety fuse burns `fuseLength × burnRate` seconds, scattered by `burnTolerance` (a fraction, ±); `fuseRange` picks a time\n * between its two ends; a fixed `fuse` is returned as is. Draws from `random` only when the explosive is not fixed, so fixed ones leave the stream alone.\n */\nexport const sampleFuse = (explosive: ExplosiveDef, random: () => number, fuseLength?: number): number | undefined => {\n const length = fuseLength ?? explosive.fuseLength\n if (length !== undefined && explosive.burnRate !== undefined) {\n const tolerance = explosive.burnTolerance ?? 0\n return length * explosive.burnRate * (tolerance > 0 ? 1 + tolerance * (2 * random() - 1) : 1)\n }\n if (explosive.fuseRange) return explosive.fuseRange[0] + (explosive.fuseRange[1] - explosive.fuseRange[0]) * random()\n return explosive.fuse\n}\n","import { nominalFuse } from './fuse'\nimport { deepMerge } from './merge'\nimport type { DeepPartial, ExplosiveDef, WeaponDef } from './types'\n\ntype Entry = { readonly id: string }\n\n/** The shipped entries with the ones from `extra` added or, when the id exists, replaced. */\nexport const mergeById = <TEntry extends Entry>(shipped: readonly TEntry[], extra: readonly TEntry[] | undefined): Map<string, TEntry> => {\n const entries = new Map<string, TEntry>()\n for (const entry of [...shipped, ...(extra ?? [])]) entries.set(entry.id, entry)\n return entries\n}\n\n/** Applies `patch` by id; a patch for an id that does not exist is ignored. */\nexport const applyPatches = <TEntry extends Entry>(entries: Map<string, TEntry>, patches: Readonly<Record<string, DeepPartial<TEntry> | Partial<TEntry>>> | undefined): void => {\n for (const [id, patch] of Object.entries(patches ?? {})) {\n const entry = entries.get(id)\n if (entry) entries.set(id, deepMerge(entry, patch))\n }\n}\n\nexport const removeIds = (entries: Map<string, unknown>, ids: readonly string[] | undefined): void => {\n for (const id of ids ?? []) entries.delete(id)\n}\n\n/** A throwable that names an explosive takes its energy, noise, lethal radius, fuse (the nominal one, when it is sampled per throw) and fire from it, so changing the explosive changes the throwable. */\nexport const resolveThrowables = (weapons: Map<string, WeaponDef>, explosives: ReadonlyMap<string, ExplosiveDef>): void => {\n for (const [id, def] of weapons) {\n if (def.action.kind !== 'throwable' || def.action.explosive === undefined) continue\n const explosive = explosives.get(def.action.explosive)\n if (!explosive) continue\n const radius = explosive.lethalRadius > 0 ? explosive.lethalRadius : def.action.radius\n const fire = explosive.fire ? { ...explosive.fire } : def.action.fire\n weapons.set(id, { ...def, action: { ...def.action, energy: explosive.energy, noise: explosive.noise, radius, fuse: nominalFuse(explosive) ?? def.action.fuse, ...(fire ? { fire } : {}) } })\n }\n}\n","import type { FaultContext, WeaponRules } from './types'\n\nconst DEFAULT_HEAT: WeaponRules['heat'] = {\n cap: 140,\n displayMax: 120,\n decayBase: 1.6,\n decayPerPoint: 0.03,\n faultFrom: 60,\n faultSpan: 40,\n perShot: { shell: 6, big: 9, tiny: 1.2, pistol: 3, rifle: 4.5 },\n perRocket: 35,\n}\n\n/** Chance of a fault for one round: the wear of the weapon, scaled by its reliability and by how hot it is. */\nconst defaultFaultChance = (context: FaultContext): number => {\n const factor = context.def.action.kind === 'firearm' ? context.def.action.faultFactor ?? 1 : 1\n const overheat = 1 + Math.max(0, context.heat - DEFAULT_HEAT.faultFrom) / DEFAULT_HEAT.faultSpan\n return context.condition.faultChance * factor * overheat\n}\n\n/** The rules the kit ships with; a game overrides any of them through `ArsenalOptions.rules`. */\nexport const DEFAULT_RULES: WeaponRules = {\n faults: true,\n conditions: [\n { id: 'new', faultChance: 0.003 },\n { id: 'used', faultChance: 0.015 },\n { id: 'worn', faultChance: 0.05 },\n { id: 'rusty', faultChance: 0.12 },\n ],\n defaultCondition: 'new',\n ammoQualities: [\n { id: 'factory', faultChance: 0 },\n { id: 'reloaded', faultChance: 0.08 },\n ],\n defaultAmmoQuality: 'factory',\n faultChance: defaultFaultChance,\n heat: DEFAULT_HEAT,\n noiseBurst: { step: 0.05, window: 3, cap: 0.5 },\n // jogo.js (Jogo) explosionsUpdate 68300-68312: vy -= 9,8·dt; chão vy·-0,35 e vx,vz·0,6; parede v·-0,4\n explosives: { gravity: 9.8, groundRestitution: 0.35, groundFriction: 0.6, wallRestitution: 0.4, placeFuseFrom: 10, tripwire: { length: 10, angleDeg: 0, height: 0.15 } },\n // Arsenal §11: montar e desmontar exige chave de fenda ou bancada; 2/15/30 s e a troca do lança-granadas (0,8 s) são padrões aprovados pelo dono (2026-10-24)\n attachments: { fitSeconds: { field: 2, tool: 15, bench: 30 }, switchSeconds: 0.8, speedOfSound: 343 },\n // Arsenal §08: tempo de mira = 0,15 s + 0,05 s por kg. O quadril do Arsenal é ×6 (o ZombiAdA liga isso por configuração); o SDK é neutro (1)\n aim: { base: 0.15, perKg: 0.05, hipSpread: 1 },\n // Arsenal §08/§11: coronha retrátil saca mais rápido, mais recuo; os números são padrões aprovados pelo dono (2026-10-24)\n stock: {\n seconds: 0.6,\n collapsed: [\n { stat: 'draw', mul: 0.8 },\n { stat: 'aim', mul: 0.85 },\n { stat: 'recoilVertical', mul: 1.3 },\n { stat: 'spread', mul: 1.15 },\n ],\n },\n draw: 0.35,\n clear: 1.2,\n startSafe: false,\n}\n","import type { Vec3 } from './types'\n\nexport const subtract = (a: Vec3, b: Vec3): Vec3 => [a[0] - b[0], a[1] - b[1], a[2] - b[2]]\n\nexport const dot = (a: Vec3, b: Vec3): number => a[0] * b[0] + a[1] * b[1] + a[2] * b[2]\n\nexport const length = (v: Vec3): number => Math.hypot(v[0], v[1], v[2])\n\nexport const distance = (a: Vec3, b: Vec3): number => length(subtract(a, b))\n\n/** `v` rotated 180° about the origin: the direction pointing away. */\nexport const negate = (v: Vec3): Vec3 => [0 - v[0], 0 - v[1], 0 - v[2]]\n","import { normalize } from './rng'\nimport type { ExplosiveDef, ExplosiveId, ExplosiveTrigger, Use, Vec3, WeaponRules } from './types'\nimport { distance, dot, length } from './vec'\n\nconst EPS = 1e-9\n\n/** Everything a host needs to apply a blast: where, how big, in which direction, and what else it does. */\nexport interface Detonation {\n readonly explosive: ExplosiveId\n readonly cause: ExplosiveTrigger\n readonly point: Vec3\n /** The way a directional charge faces; for everything else the direction the body was moving (or facing when placed). */\n readonly direction: Vec3\n /** Seconds on the clock of the body. */\n readonly at: number\n readonly energy: number\n readonly lethalRadius: number\n readonly injuryRadius: number\n readonly noise: number\n readonly destructionLevel: ExplosiveDef['destructionLevel']\n readonly cone?: ExplosiveDef['cone']\n readonly stunSeconds?: number\n readonly fire?: ExplosiveDef['fire']\n}\n\nexport type ExplosiveEvent =\n | { type: 'armed'; at: number; distance: number }\n | { type: 'impact'; at: number; point: Vec3; armed: boolean }\n /** Hit something before it was armed: it does not explode. */\n | { type: 'dud'; at: number; point: Vec3 }\n | { type: 'detonate'; at: number; detonation: Detonation }\n\n/** The first surface the segment `from` to `to` crosses: where, its normal and whether it is ground (default: normal pointing up). */\nexport type SurfaceProbe = (from: Vec3, to: Vec3) => { point: Vec3; normal: Vec3; ground?: boolean } | null\n\nexport interface ExplosiveBodyInit {\n readonly explosive: ExplosiveDef\n readonly origin: Vec3\n /** Initial velocity in m/s; absent for something set down. */\n readonly velocity?: Vec3\n /** Facing of a placed charge (the cone of a mine). */\n readonly direction?: Vec3\n /** `timer`: explodes `fuse` seconds after it leaves the hand; `impact`: explodes on the first hit once armed; `wire`/`remote`: waits for `trigger()`. */\n readonly triggers: readonly ExplosiveTrigger[]\n readonly fuse?: number\n /** Metres to fly before an impact sets it off (rockets); 0 arms it at once. */\n readonly armDistance?: number\n readonly rules: WeaponRules['explosives']\n}\n\nconst bounce = (velocity: Vec3, normal: Vec3, ground: boolean, rules: WeaponRules['explosives']): Vec3 => {\n const along = dot(velocity, normal)\n if (along >= 0) return velocity\n const restitution = ground ? rules.groundRestitution : rules.wallRestitution\n const friction = ground ? rules.groundFriction : 1\n const normalPart: Vec3 = [normal[0] * along, normal[1] * along, normal[2] * along]\n return [\n (velocity[0] - normalPart[0]) * friction - normalPart[0] * restitution,\n (velocity[1] - normalPart[1]) * friction - normalPart[1] * restitution,\n (velocity[2] - normalPart[2]) * friction - normalPart[2] * restitution,\n ]\n}\n\n/**\n * One explosive in flight or set down. `step` flies it (gravity, bounces off what `probe` finds) and counts the fuse; `trigger` sets off what waits\n * for a wire, a remote detonator, a bullet, fire or a nearby blast. Same inputs, same events: there is no randomness.\n */\nexport class ExplosiveBody {\n position: Vec3\n velocity: Vec3\n readonly explosive: ExplosiveDef\n private readonly triggers: ReadonlySet<ExplosiveTrigger>\n private readonly armDistance: number\n private readonly rules: WeaponRules['explosives']\n private facing: Vec3\n private clock = 0\n private flown = 0\n private fuseLeft: number | undefined\n private isArmed: boolean\n private isDone = false\n private isDud = false\n\n constructor(init: ExplosiveBodyInit) {\n this.explosive = init.explosive\n this.position = [init.origin[0], init.origin[1], init.origin[2]]\n this.velocity = init.velocity ? [init.velocity[0], init.velocity[1], init.velocity[2]] : [0, 0, 0]\n this.facing = normalize(init.direction ?? (init.velocity ? init.velocity : [0, 0, -1]))\n this.triggers = new Set(init.triggers)\n this.armDistance = init.armDistance ?? 0\n this.isArmed = this.armDistance <= 0\n this.fuseLeft = this.triggers.has('timer') ? init.fuse : undefined\n this.rules = init.rules\n }\n\n get age(): number {\n return this.clock\n }\n /** Metres flown so far. */\n get travelled(): number {\n return this.flown\n }\n get armed(): boolean {\n return this.isArmed\n }\n /** Exploded or turned out a dud: nothing more happens. */\n get done(): boolean {\n return this.isDone\n }\n get dud(): boolean {\n return this.isDud\n }\n /** Seconds until the timer sets it off, or undefined without one. */\n get fuseRemaining(): number | undefined {\n return this.fuseLeft\n }\n\n step(dt: number, probe?: SurfaceProbe): ExplosiveEvent[] {\n const events: ExplosiveEvent[] = []\n if (this.isDone) return events\n const seconds = Math.max(0, dt)\n const slice = this.fuseLeft === undefined ? seconds : Math.min(seconds, this.fuseLeft)\n this.fly(slice, probe, events)\n if (this.isDone) return events\n if (this.fuseLeft !== undefined) {\n this.fuseLeft -= slice\n if (this.fuseLeft <= EPS) events.push(this.detonate('timer'))\n }\n return events\n }\n\n /** Sets it off from outside; undefined when this explosive does not answer to `cause` or is already done. */\n trigger(cause: ExplosiveTrigger): ExplosiveEvent | undefined {\n if (this.isDone || !this.triggers.has(cause)) return undefined\n if (cause === 'impact' && !this.isArmed) return undefined\n return this.detonate(cause)\n }\n\n private moves(): boolean {\n return length(this.velocity) > EPS\n }\n\n private fly(seconds: number, probe: SurfaceProbe | undefined, events: ExplosiveEvent[]): void {\n if (seconds <= 0 || !this.moves()) {\n this.clock += Math.max(0, seconds)\n return\n }\n this.velocity = [this.velocity[0], this.velocity[1] - this.rules.gravity * seconds, this.velocity[2]]\n const next: Vec3 = [this.position[0] + this.velocity[0] * seconds, this.position[1] + this.velocity[1] * seconds, this.position[2] + this.velocity[2] * seconds]\n const hit = probe?.(this.position, next) ?? null\n const target = hit ? hit.point : next\n const moved = distance(this.position, target)\n const planned = distance(this.position, next)\n this.flown += moved\n this.position = [target[0], target[1], target[2]]\n const hitAt = this.clock + (hit && planned > EPS ? seconds * Math.min(1, moved / planned) : seconds)\n this.clock += seconds\n if (length(this.velocity) > EPS) this.facing = normalize(this.velocity)\n this.checkArmed(events)\n if (hit) this.onImpact(hit, hitAt, events)\n }\n\n private checkArmed(events: ExplosiveEvent[]): void {\n if (this.isArmed || this.flown < this.armDistance) return\n this.isArmed = true\n events.push({ type: 'armed', at: this.clock, distance: this.flown })\n }\n\n private onImpact(hit: NonNullable<ReturnType<SurfaceProbe>>, at: number, events: ExplosiveEvent[]): void {\n events.push({ type: 'impact', at, point: hit.point, armed: this.isArmed })\n if (this.triggers.has('impact')) {\n if (this.isArmed) events.push(this.detonate('impact', at))\n else {\n this.isDone = true\n this.isDud = true\n events.push({ type: 'dud', at, point: hit.point })\n }\n return\n }\n this.velocity = bounce(this.velocity, hit.normal, hit.ground ?? hit.normal[1] > 0.7, this.rules)\n }\n\n private detonate(cause: ExplosiveTrigger, at = this.clock): ExplosiveEvent {\n this.isDone = true\n const def = this.explosive\n const detonation: Detonation = {\n explosive: def.id,\n cause,\n point: [this.position[0], this.position[1], this.position[2]],\n direction: this.facing,\n at,\n energy: def.energy,\n lethalRadius: def.lethalRadius,\n injuryRadius: def.injuryRadius,\n noise: def.noise,\n destructionLevel: def.destructionLevel,\n ...(def.cone ? { cone: def.cone } : {}),\n ...(def.stunSeconds !== undefined ? { stunSeconds: def.stunSeconds } : {}),\n ...(def.fire ? { fire: def.fire } : {}),\n }\n return { type: 'detonate', at, detonation }\n }\n}\n\n/** The body of the explosive a `throw` or `place` use carries; undefined for any other use or an unknown explosive id. */\nexport const createExplosiveBody = (use: Use, explosives: ReadonlyMap<ExplosiveId, ExplosiveDef>, rules: WeaponRules['explosives']): ExplosiveBody | undefined => {\n if (use.kind === 'throw' && use.explosive !== undefined) {\n const explosive = explosives.get(use.explosive)\n if (!explosive) return undefined\n return new ExplosiveBody({\n explosive,\n origin: use.origin,\n velocity: use.velocity,\n triggers: [use.trigger ?? (use.fuse > 0 ? 'timer' : 'impact')],\n fuse: use.fuse,\n ...(use.armDistance !== undefined ? { armDistance: use.armDistance } : {}),\n rules,\n })\n }\n if (use.kind !== 'place') return undefined\n const explosive = explosives.get(use.explosive)\n if (!explosive) return undefined\n return new ExplosiveBody({ explosive, origin: use.origin, direction: use.direction, triggers: use.triggers, ...(use.fuse !== undefined ? { fuse: use.fuse } : {}), rules })\n}\n","import type { ExplosiveDef, Use, Vec3, WeaponAction, WeaponRules } from './types'\nimport { negate } from './vec'\n\ntype LauncherAction = Extract<WeaponAction, { kind: 'launcher' }>\ntype ThrowableAction = Extract<WeaponAction, { kind: 'throwable' }>\n\n/** Fraction of the throw speed added upwards so a throw arcs. */\nconst THROW_LIFT = 0.15\n\nconst PLACED_TRIGGERS: ReadonlySet<string> = new Set(['wire', 'remote'])\n\nconst blastNumbers = (explosive: ExplosiveDef): Pick<Extract<Use, { kind: 'throw' }>, 'energy' | 'injuryRadius'> => ({\n energy: explosive.energy,\n injuryRadius: explosive.injuryRadius,\n})\n\n/** The rocket or grenade a launcher fires, plus the blast behind the tube when the launcher has one. */\nexport const launcherUses = (action: LauncherAction, explosive: ExplosiveDef | null, origin: Vec3, direction: Vec3): Use[] => {\n const velocity: Vec3 = [direction[0] * action.speed, direction[1] * action.speed, direction[2] * action.speed]\n const projectile: Use = {\n kind: 'throw',\n energy: explosive?.energy ?? 0,\n radius: explosive?.lethalRadius ?? 0,\n fuse: 0,\n velocity,\n origin,\n explosive: action.projectile,\n trigger: 'impact',\n armDistance: action.minArmDistance,\n ...(explosive ? { injuryRadius: explosive.injuryRadius } : {}),\n }\n if (action.backblast <= 0) return [projectile]\n return [projectile, { kind: 'backblast', radius: action.backblast, halfAngleDeg: action.backblastHalfAngleDeg ?? 180, origin, direction: negate(direction) }]\n}\n\nconst TIMER_TRIGGERS: ReadonlySet<string> = new Set(['timer', ...PLACED_TRIGGERS])\n\n/** Whether the explosive is set down instead of thrown: it waits for a trip wire or a detonator, or its fuse is so long that holding it makes no sense. */\nexport const isPlaced = (explosive: ExplosiveDef | null, fuse: number, rules: Pick<WeaponRules['explosives'], 'placeFuseFrom'>): boolean => {\n if (!explosive) return false\n if (explosive.triggers?.some((trigger) => PLACED_TRIGGERS.has(trigger))) return true\n return (explosive.triggers?.includes('timer') ?? false) && fuse >= rules.placeFuseFrom\n}\n\nexport type ThrowableUseParams = {\n readonly action: ThrowableAction\n readonly explosive: ExplosiveDef | null\n readonly origin: Vec3\n readonly direction: Vec3\n /** Seconds of fuse of this throw (sampled, or what is left after cooking). */\n readonly fuse: number\n /** Seconds the thrower held it after pulling the pin. */\n readonly cooked?: number\n /** Set off in the hand: no throw, the fuse is spent. */\n readonly inHand?: boolean\n readonly rules: Pick<WeaponRules['explosives'], 'placeFuseFrom' | 'tripwire'>\n}\n\nconst placedUse = ({ action, explosive, origin, direction, fuse, rules }: ThrowableUseParams & { explosive: ExplosiveDef }): Use => ({\n kind: 'place',\n explosive: explosive.id,\n triggers: (explosive.triggers ?? []).filter((trigger): trigger is 'timer' | 'wire' | 'remote' => TIMER_TRIGGERS.has(trigger)),\n energy: explosive.energy,\n radius: explosive.lethalRadius,\n injuryRadius: explosive.injuryRadius,\n ...(explosive.cone ? { cone: { halfAngleDeg: explosive.cone.halfAngleDeg, length: explosive.cone.length } } : {}),\n ...(explosive.triggers?.includes('wire') ? { tripwire: { ...rules.tripwire, ...explosive.tripwire } } : {}),\n ...(fuse > 0 && action.fuse > 0 ? { fuse } : {}),\n origin,\n direction,\n})\n\n/** One throw (or one charge set down) of a throwable: a fuse that counts from the throw, or an impact trigger when the fuse is 0. */\nexport const throwableUse = (params: ThrowableUseParams): Use => {\n const { action, explosive, origin, direction, fuse, cooked, inHand } = params\n if (explosive && isPlaced(explosive, fuse, params.rules)) return placedUse({ ...params, explosive })\n const velocity: Vec3 = inHand ? [0, 0, 0] : [direction[0] * action.throwSpeed, direction[1] * action.throwSpeed + action.throwSpeed * THROW_LIFT, direction[2] * action.throwSpeed]\n const use: Extract<Use, { kind: 'throw' }> = { kind: 'throw', energy: action.energy, radius: action.radius, fuse, velocity, origin }\n if (cooked !== undefined) use.cooked = cooked\n if (inHand) use.inHand = true\n if (action.fire) use.fire = { ...action.fire }\n if (!explosive) return use\n return {\n ...use,\n ...blastNumbers(explosive),\n radius: action.radius,\n explosive: explosive.id,\n trigger: fuse > 0 || inHand ? 'timer' : 'impact',\n armDistance: 0,\n ...(explosive.stunSeconds !== undefined ? { stunSeconds: explosive.stunSeconds } : {}),\n }\n}\n","import type { CaliberDef, WeaponAction, WeaponRules } from './types'\n\nconst SUBSTEP_SECONDS = 1 / 60\n\n/** Cools a barrel: each step loses `decayBase + heat × decayPerPoint` per second (explicit Euler, in steps of at most 1/60 s). */\nexport const decayHeat = (heat: number, seconds: number, rules: WeaponRules['heat']): number => {\n const steps = Math.max(1, Math.ceil(seconds / SUBSTEP_SECONDS - 1e-9))\n const step = seconds / steps\n let current = heat\n for (let i = 0; i < steps && current > 0; i++) current = Math.max(0, current - step * (rules.decayBase + current * rules.decayPerPoint))\n return current\n}\n\n/** Heat one round adds: by the cartridge case, or a fixed amount for a rocket. A bow has no cartridge and adds none. */\nexport const heatPerRound = (action: WeaponAction, caliber: CaliberDef | null, rules: WeaponRules['heat']): number => {\n if (action.kind === 'launcher') return rules.perRocket\n return caliber?.caseType ? rules.perShot[caliber.caseType] : 0\n}\n\n/** Each shot in the last few seconds makes the next one louder, up to a cap. */\nexport const burstNoise = (base: number, recentShots: number, rules: WeaponRules['noiseBurst']): number => base * (1 + Math.min(rules.cap, rules.step * recentShots))\n","import type { ReloadFamily, ReloadKind, ReloadStage } from './types'\n\ntype StageTable = Readonly<Record<ReloadKind, readonly ReloadStage[]>>\n\nconst magazineOut = { stage: 'magazine_out', at: 0 } as const\n// 0.45 s of the 0.82 s magazine swap in the gallery\nconst magazineIn = { stage: 'magazine_in', at: 0.549 } as const\n\nconst byMagazine = (chargeAt: number): StageTable => ({\n tactical: [magazineOut, magazineIn],\n empty: [magazineOut, magazineIn, { stage: 'charge', at: chargeAt }],\n one_by_one: [magazineOut, magazineIn],\n})\n\n// A reload that loads rounds one at a time: `round_in` opens the loading and the closing stage comes after the last round.\nconst byTube = (closing: ReloadStage | undefined): StageTable => ({\n tactical: [{ stage: 'round_in', at: 0 }],\n empty: closing ? [{ stage: 'round_in', at: 0 }, closing] : [{ stage: 'round_in', at: 0 }],\n one_by_one: [{ stage: 'round_in', at: 0 }],\n})\n\nconst revolverOpen = { stage: 'cylinder_open', at: 0 } as const\nconst revolverEject = { stage: 'cylinder_eject', at: 0.246 } as const\nconst revolverClose = { stage: 'cylinder_close', at: 0.808 } as const\nconst revolverJet: readonly ReloadStage[] = [revolverOpen, revolverEject, { stage: 'cylinder_load', at: 0.538 }, revolverClose]\nconst revolverRounds: readonly ReloadStage[] = [revolverOpen, revolverEject, revolverClose]\n\nconst breechSwing: readonly ReloadStage[] = [\n { stage: 'barrels_open', at: 0 },\n { stage: 'casings_eject', at: 0.208 },\n { stage: 'rounds_in', at: 0.542 },\n { stage: 'barrels_close', at: 0.833 },\n]\n\n// A grenade launcher under a barrel: the breech opens, the grenade goes in, the breech closes (the same stages for every kind of reload)\nconst breechLoad: readonly ReloadStage[] = [\n { stage: 'breech_open', at: 0 },\n { stage: 'round_in', at: 0.305 },\n { stage: 'breech_close', at: 0.724 },\n]\n\nconst beltSwap: readonly ReloadStage[] = [\n { stage: 'cover_open', at: 0 },\n { stage: 'belt_swap', at: 0.129 },\n { stage: 'cover_close', at: 0.581 },\n { stage: 'charge', at: 0.742 },\n]\n\n/** Where each step of a reload falls, as a fraction of its duration, from the key frames of the gallery animations. The runtime scales them to the duration of the weapon. */\nexport const RELOAD_STAGES: Readonly<Record<ReloadFamily, StageTable>> = {\n pistol: byMagazine(0.872),\n magazine: byMagazine(0.701),\n top_magazine: byMagazine(0.701),\n top_load_semi: byTube({ stage: 'charge', at: 0.893 }),\n tube_semi: byTube({ stage: 'charge', at: 0.88 }),\n pump: byTube({ stage: 'pump_cycle', at: 0.88 }),\n lever: byTube({ stage: 'lever_cycle', at: 0.873 }),\n bolt: {\n tactical: [{ stage: 'bolt_open', at: 0 }, { stage: 'round_in', at: 0.14 }, { stage: 'bolt_close', at: 0.86 }],\n empty: [{ stage: 'bolt_open', at: 0 }, { stage: 'round_in', at: 0.14 }, { stage: 'bolt_close', at: 0.86 }],\n one_by_one: [{ stage: 'bolt_open', at: 0 }, { stage: 'round_in', at: 0.14 }, { stage: 'bolt_close', at: 0.86 }],\n },\n bolt_magazine: {\n tactical: [magazineOut, magazineIn, { stage: 'bolt_open', at: 0.599 }, { stage: 'bolt_close', at: 0.89 }],\n empty: [magazineOut, magazineIn, { stage: 'bolt_open', at: 0.599 }, { stage: 'bolt_close', at: 0.89 }],\n one_by_one: [magazineOut, magazineIn],\n },\n belt: { tactical: beltSwap, empty: beltSwap, one_by_one: beltSwap },\n revolver: { tactical: revolverJet, empty: revolverJet, one_by_one: revolverRounds },\n break: { tactical: breechSwing, empty: breechSwing, one_by_one: breechSwing },\n // tactical: reusable launcher takes a rocket; empty: disposable tube is dropped and a new one seated; one_by_one: breech-loaded grenade\n rocket: {\n tactical: [{ stage: 'rocket_seat', at: 0 }],\n empty: [{ stage: 'tube_drop', at: 0 }, { stage: 'tube_seat', at: 0.522 }],\n one_by_one: [\n { stage: 'breech_open', at: 0 },\n { stage: 'round_in', at: 0.305 },\n { stage: 'breech_close', at: 0.724 },\n ],\n },\n underbarrel: { tactical: breechLoad, empty: breechLoad, one_by_one: breechLoad },\n flame: {\n tactical: [{ stage: 'tank_swap', at: 0 }],\n empty: [{ stage: 'tank_swap', at: 0 }],\n one_by_one: [{ stage: 'tank_swap', at: 0 }],\n },\n}\n","import { RELOAD_STAGES } from './reload-stages'\nimport type { ReloadKind, ReloadRequest, ReloadStageId, WeaponAction } from './types'\n\nexport type ReloadableAction = Extract<WeaponAction, { kind: 'firearm' | 'launcher' }>\n\nexport interface ReloadPlan {\n readonly kind: ReloadKind\n /** Seconds per round when the weapon loads one at a time, null when the whole magazine goes in at once. */\n readonly step: number | null\n /** Seconds until the first round (or the whole magazine) is in. */\n readonly first: number\n /** Seconds of the whole reload; the stages are placed along it. */\n readonly total: number\n}\n\nexport const isReloadable = (action: WeaponAction): action is ReloadableAction => action.kind === 'firearm' || action.kind === 'launcher'\n\nconst baseSeconds = (action: ReloadableAction): number => action.timings?.reload ?? action.reload\n\nconst secondsPerRound = (action: ReloadableAction): number | undefined => {\n if (action.kind !== 'firearm') return undefined\n return action.timings?.perRound ?? (action.perRound ? baseSeconds(action) : undefined)\n}\n\nconst pickKind = (action: ReloadableAction, ammo: number, oneAtATime: boolean, request: ReloadRequest): ReloadKind => {\n if (action.kind === 'launcher') return action.disposable ? 'empty' : 'tactical'\n if (request === 'one_by_one' && oneAtATime) return 'one_by_one'\n if (request === 'full') return ammo === 0 ? 'empty' : 'tactical'\n if (oneAtATime && (action.family === 'revolver' || ammo > 0)) return 'one_by_one'\n return ammo === 0 ? 'empty' : 'tactical'\n}\n\n/** How a reload goes: tactical (a magazine swap), empty (with the action to work after) or one by one; `full` loads a revolver all at once with a speed loader. */\nexport const planReload = (action: ReloadableAction, ammo: number, capacity: number, reserve: number, request: ReloadRequest): ReloadPlan => {\n const perRound = secondsPerRound(action)\n const oneAtATime = perRound !== undefined && request !== 'full'\n const kind = pickKind(action, ammo, oneAtATime, request)\n if (kind === 'one_by_one' && perRound !== undefined) {\n const rounds = Math.max(1, Math.min(capacity - ammo, reserve))\n return { kind, step: perRound, first: perRound, total: rounds * perRound }\n }\n const seconds = kind === 'empty' ? action.timings?.reloadEmpty ?? baseSeconds(action) : baseSeconds(action)\n return { kind, step: null, first: seconds, total: seconds }\n}\n\n/** The steps of a reload with the time they happen, scaled to the duration of this weapon's reload. */\nexport const reloadStages = (action: ReloadableAction, plan: ReloadPlan, startAt: number): { stage: ReloadStageId; at: number }[] => {\n if (!action.family) return []\n return RELOAD_STAGES[action.family][plan.kind].map((entry) => ({ stage: entry.stage, at: startAt + entry.at * plan.total }))\n}\n","import type { AmmoQualityDef, CaliberDef, ConditionDef, FaultId, ReloadFamily, WeaponDef, WeaponRules } from './types'\n\nconst MISFIRE_ONLY: ReadonlySet<ReloadFamily | undefined> = new Set(['revolver', 'break'])\nconst MANUAL: ReadonlySet<ReloadFamily | undefined> = new Set(['pump', 'bolt', 'bolt_magazine', 'lever'])\nconst MISFIRE_SHARE = 0.35\nconst STOVEPIPE_UPTO = 0.8\n\nexport interface FaultRoll {\n readonly def: WeaponDef\n readonly caliber: CaliberDef | null\n readonly condition: ConditionDef\n readonly ammoQuality: AmmoQualityDef\n readonly heat: number\n readonly rules: WeaponRules\n readonly random: () => number\n}\n\n/** Whether the round about to fire jams, and how. Only a weapon that fires cartridges can. */\nexport const rollFault = (roll: FaultRoll): FaultId | null => {\n const action = roll.def.action\n if (!roll.rules.faults || action.kind !== 'firearm' || !roll.caliber?.caseType) return null\n if (roll.random() < roll.rules.faultChance({ def: roll.def, condition: roll.condition, heat: roll.heat })) {\n const kind = roll.random()\n if (MISFIRE_ONLY.has(action.family) || kind < MISFIRE_SHARE) return 'misfire'\n if (MANUAL.has(action.family)) return 'failure_to_extract'\n return kind < STOVEPIPE_UPTO ? 'stovepipe' : 'double_feed'\n }\n return roll.ammoQuality.faultChance > 0 && roll.random() < roll.ammoQuality.faultChance ? 'misfire' : null\n}\n\n/** A dud in a revolver or a break-action just spends the round; anywhere else the round stays in the chamber and the weapon jams. */\nexport const isDudWithoutJam = (action: WeaponDef['action'], fault: FaultId): boolean => fault === 'misfire' && action.kind === 'firearm' && MISFIRE_ONLY.has(action.family)\n","import type { CaliberDef, FireMode, FirearmAction, WeaponAction, WeaponRules, WeaponTimings } from './types'\n\nconst EPS = 1e-9\nconst MANUAL_MODES: ReadonlySet<FireMode> = new Set(['pump', 'bolt', 'lever'])\n\nexport const weaponSpeed = (action: FirearmAction, caliber: CaliberDef): number => action.muzzleSpeed ?? caliber.muzzleSpeed * (action.barrel ?? 1)\n\nexport const weaponNoise = (action: FirearmAction, caliber: CaliberDef): number => action.noise ?? caliber.noise ?? 0\n\nexport const timingsOf = (action: WeaponAction): WeaponTimings | undefined => ('timings' in action ? action.timings : undefined)\n\nexport const drawSeconds = (action: WeaponAction, rules: WeaponRules): number => timingsOf(action)?.draw ?? rules.draw\n\nexport const clearSeconds = (action: WeaponAction, rules: WeaponRules): number => timingsOf(action)?.clear ?? rules.clear\n\n/** Seconds a manual action (pump, bolt, lever) needs to cycle after a shot; 0 for every other mode. */\nexport const manualCycleSeconds = (action: FirearmAction, mode: FireMode): number => (MANUAL_MODES.has(mode) ? action.timings?.cycle ?? 0 : 0)\n\n/** When each round of one pull leaves the barrel: a held auto trigger fires through the frame, a burst at the cyclic rate, a volley all at once. */\nexport const planRounds = (action: FirearmAction, mode: FireMode, ammo: number, firstAt: number, frameEnd: number): number[] => {\n const interval = 60 / action.rpm\n const times: number[] = []\n if (mode === 'auto') {\n for (let t = firstAt; times.length < ammo && (times.length === 0 ? t <= frameEnd + EPS : t < frameEnd - EPS); t += interval) times.push(t)\n return times\n }\n if (mode === 'burst') {\n const count = Math.min(action.burst ?? 3, ammo)\n for (let k = 0; k < count; k++) times.push(firstAt + k * interval)\n return times\n }\n if (mode === 'volley') return Array.from({ length: Math.min(action.magazine, ammo) }, () => firstAt)\n return [firstAt]\n}\n","import type { AttachmentDef, AttachmentId, FittedAttachment, StatModifier, WeaponStat } from './attachment-types'\nimport type { CaliberDef, FirearmAction, WeaponAction, WeaponDef, WeaponRules } from './types'\n\n/** How the weapon is held and what it is in: what the conditional effects (`aiming`, `hip`, `supported`, `subsonic`, `collapsed`) ask. */\nexport interface LoadoutContext {\n readonly aiming: boolean\n readonly supported: boolean\n readonly stock: 'collapsed' | 'extended'\n readonly caliber: CaliberDef | null\n readonly rules: Pick<WeaponRules, 'attachments' | 'aim' | 'stock'>\n}\n\nexport interface Loadout {\n /** The action with every effect applied; the very object of the def when nothing differs from the weapon as it ships. */\n readonly action: WeaponAction\n /** Kg: the weapon with what is on it. */\n readonly mass: number\n /** Seconds to raise the weapon to the sights. */\n readonly aimSeconds: number\n /** Times the spread when not aiming. */\n readonly hipFactor: number\n readonly suppressed: boolean\n readonly drawFactor: number\n readonly heatFactor: number\n readonly faultFactor: number\n /** What a dual coupler does to the reload of every second magazine change (1: nothing). */\n readonly secondReloadFactor: number\n readonly optic: AttachmentDef['optic'] | undefined\n readonly light: (NonNullable<AttachmentDef['light']> & { readonly id: AttachmentId }) | undefined\n readonly laser: (NonNullable<AttachmentDef['laser']> & { readonly id: AttachmentId }) | undefined\n}\n\ntype Catalogue = ReadonlyMap<AttachmentId, AttachmentDef>\ntype Condition = NonNullable<StatModifier['when']>\ntype Effects = readonly (readonly StatModifier[])[]\n\n/** The accessories that count: a light or a laser only while it is on. */\nconst activeParts = (fitted: readonly FittedAttachment[], catalogue: Catalogue): AttachmentDef[] =>\n fitted.flatMap((part) => {\n const def = catalogue.get(part.id)\n const isOn = def?.kind !== 'light' && def?.kind !== 'laser' ? true : part.on === true\n return def && isOn ? [def] : []\n })\n\nconst holds = (when: Condition | undefined, active: ReadonlySet<Condition>): boolean => when === undefined || when === 'always' || active.has(when)\n\nconst modifiersOf = (name: WeaponStat, sources: Effects, active: ReadonlySet<Condition>): StatModifier[] =>\n sources.flatMap((effects) => effects.filter((effect) => effect.stat === name && holds(effect.when, active)))\n\nconst sum = (modifiers: readonly StatModifier[]): number => modifiers.reduce((total, modifier) => total + (modifier.add ?? 0), 0)\nconst product = (modifiers: readonly StatModifier[]): number => modifiers.reduce((total, modifier) => total * (modifier.mul ?? 1), 1)\n\ninterface StatSources {\n readonly now: Effects\n /** The effects of what the weapon ships with: they are in the base numbers already. */\n readonly shipped: Effects\n /** What already held when the base numbers were made: only `subsonic`, for a weapon that is subsonic with its factory parts on (the MP5SD). */\n readonly shippedActive?: ReadonlySet<Condition>\n}\n\n/** Takes out of both lists the very same modifier objects (one for one), so a factory part that is still on cancels exactly whatever order the parts are in. */\nconst cancelShipped = (current: readonly StatModifier[], shipped: readonly StatModifier[]): [StatModifier[], StatModifier[]] => {\n const added = [...current]\n const taken: StatModifier[] = []\n for (const modifier of shipped) {\n const index = added.indexOf(modifier)\n if (index === -1) taken.push(modifier)\n else added.splice(index, 1)\n }\n return [added, taken]\n}\n\n/**\n * One number of the weapon with everything on it: every `set` first (the last wins), then the sum of the `add`s, then the product of the `mul`s.\n * The factory parts' effects that always count are in `base` already, so they are taken back out: with the same parts on, the result is `base`\n * itself, and without one of them it is what the weapon would be without it.\n */\nconst stat = (name: WeaponStat, base: number, sources: StatSources, active: ReadonlySet<Condition>): number => {\n const current = modifiersOf(name, sources.now, active)\n const lastSet = [...current].reverse().find((modifier) => modifier.set !== undefined)?.set\n if (lastSet !== undefined) return (lastSet + sum(current)) * product(current)\n const [added, taken] = cancelShipped(current, modifiersOf(name, sources.shipped, sources.shippedActive ?? new Set<Condition>()))\n return (base + (sum(added) - sum(taken))) * (product(added) / product(taken))\n}\n\nconst baseSpeedOf = (action: FirearmAction, caliber: CaliberDef | null): number => action.muzzleSpeed ?? (caliber?.muzzleSpeed ?? 0) * (action.barrel ?? 1)\n\nconst scaleTimings = (timings: NonNullable<FirearmAction['timings']>, reload: number, empty: number): NonNullable<FirearmAction['timings']> => ({\n ...timings,\n reload: timings.reload * reload,\n ...(timings.reloadEmpty === undefined ? {} : { reloadEmpty: timings.reloadEmpty * reload * empty }),\n ...(timings.perRound === undefined ? {} : { perRound: timings.perRound * reload }),\n})\n\ninterface ActionEffects {\n readonly spread: number\n readonly recoil: [number, number]\n readonly range: number\n readonly noise: number | undefined\n readonly speed: number\n readonly magazine: number\n readonly reload: number\n readonly empty: number\n}\n\nconst isUnchanged = (action: FirearmAction, effects: ActionEffects, context: LoadoutContext): boolean =>\n effects.spread === action.spreadDeg &&\n effects.recoil[0] === action.recoil[0] &&\n effects.recoil[1] === action.recoil[1] &&\n effects.range === action.range &&\n effects.noise === (action.noise ?? context.caliber?.noise) &&\n effects.speed === baseSpeedOf(action, context.caliber) &&\n effects.magazine === action.magazine &&\n effects.reload === 1 &&\n effects.empty === 1\n\nconst applyEffects = (action: FirearmAction, effects: ActionEffects): FirearmAction => ({\n ...action,\n spreadDeg: effects.spread,\n recoil: effects.recoil,\n range: effects.range,\n ...(effects.noise === undefined ? {} : { noise: effects.noise }),\n muzzleSpeed: effects.speed,\n magazine: effects.magazine,\n reload: action.reload * effects.reload,\n ...(action.timings ? { timings: scaleTimings(action.timings, effects.reload, effects.empty) } : {}),\n})\n\n/** The weapon with what is on it: the numbers of the action, the mass, the time to aim, and the lights, laser and optic that are on. */\nexport const resolveLoadout = (def: WeaponDef, fitted: readonly FittedAttachment[], catalogue: Catalogue, context: LoadoutContext): Loadout => {\n const parts = activeParts(fitted, catalogue)\n const factory = activeParts(def.fitted ?? [], catalogue)\n const isRegular = (part: AttachmentDef): boolean => part.secondReload !== true\n const collapsedStock = context.stock === 'collapsed' ? [context.rules.stock.collapsed] : []\n const shipsSubsonic = def.action.kind === 'firearm' && baseSpeedOf(def.action, context.caliber) < context.rules.attachments.speedOfSound\n const sources: StatSources = {\n now: [...parts.filter(isRegular).map((part) => part.effects), ...collapsedStock],\n shipped: factory.filter(isRegular).map((part) => part.effects),\n ...(shipsSubsonic ? { shippedActive: new Set<Condition>(['subsonic']) } : {}),\n }\n const baseActive = new Set<Condition>([context.aiming ? 'aiming' : 'hip'])\n if (context.supported || parts.some((part) => part.kind === 'mount')) baseActive.add('supported')\n if (context.stock === 'collapsed') baseActive.add('collapsed')\n\n const firearm = def.action.kind === 'firearm' ? def.action : undefined\n const speed = firearm ? stat('muzzleSpeed', baseSpeedOf(firearm, context.caliber), sources, baseActive) : 0\n const active = new Set(baseActive)\n if (firearm && speed < context.rules.attachments.speedOfSound) active.add('subsonic')\n const read = (name: WeaponStat, base: number): number => stat(name, base, sources, active)\n\n const mass = read('mass', def.mass + parts.reduce((total, part) => total + part.mass, 0) - factory.reduce((total, part) => total + part.mass, 0))\n const hipFactor = context.aiming ? 1 : 1 + (context.rules.aim.hipSpread - 1) * read('hipSpreadExcess', 1)\n let action: WeaponAction = def.action\n if (firearm) {\n const baseNoise = firearm.noise ?? context.caliber?.noise\n const effects: ActionEffects = {\n spread: read('spread', firearm.spreadDeg) * hipFactor,\n recoil: [read('recoilVertical', firearm.recoil[0]), read('recoilHorizontal', firearm.recoil[1])],\n range: read('range', firearm.range),\n noise: baseNoise === undefined ? undefined : read('noise', baseNoise),\n speed,\n magazine: Math.max(1, Math.round(read('capacity', firearm.magazine))),\n reload: read('reload', 1),\n empty: read('reloadEmpty', 1),\n }\n if (!isUnchanged(firearm, effects, context)) action = applyEffects(firearm, effects)\n }\n const lit = parts.find((part) => part.light)\n const beam = parts.find((part) => part.laser)\n return {\n action,\n mass,\n aimSeconds: read('aim', context.rules.aim.base + context.rules.aim.perKg * mass),\n hipFactor,\n suppressed: parts.some((part) => part.kind === 'suppressor'),\n drawFactor: read('draw', 1),\n heatFactor: read('heatPerShot', 1),\n faultFactor: read('faultChance', 1),\n secondReloadFactor: stat('reload', 1, { now: parts.filter((part) => !isRegular(part)).map((part) => part.effects), shipped: [] }, active),\n optic: parts.find((part) => part.optic)?.optic,\n light: lit?.light ? { ...lit.light, id: lit.id } : undefined,\n laser: beam?.laser ? { ...beam.laser, id: beam.id } : undefined,\n }\n}\n","import type { AttachmentDef, AttachmentId, WeaponSnapshot } from './attachment-types'\nimport type { IsCompatible } from './attachments'\nimport type {\n CaliberDef,\n ExplosiveDef,\n TriggerResult,\n WeaponDef,\n WeaponId,\n WeaponState,\n WeaponEvent,\n WeaponRules,\n} from './types'\n\nexport const EPS = 1e-9\n/** Total spread (base + bloom) never exceeds this many times the base spread. */\nexport const BLOOM_CAP = 4\n\n/** Muzzle energy in joules of ONE projectile (a bullet, or one pellet): 0.5 × mass × speed², speed scaled by the barrel factor. */\nexport const muzzleEnergy = (caliber: CaliberDef, barrel = 1): number => {\n const v = caliber.muzzleSpeed * barrel\n return 0.5 * (caliber.bulletGrams / 1000) * v * v\n}\n\nexport interface WeaponStateInit {\n def: WeaponDef\n caliber: CaliberDef | null\n seed: number\n reserve?: number\n rules: WeaponRules\n /** What a launcher shoots, or the explosive a throwable carries. */\n explosive?: ExplosiveDef | null\n condition?: string\n ammoQuality?: string\n /** The accessories of the arsenal, by id (without them the weapon carries only its own numbers). */\n attachments?: ReadonlyMap<AttachmentId, AttachmentDef>\n isCompatible?: IsCompatible\n /** Makes the state of the launcher under the barrel (`attachment.launcher`), from the seed given and, when restoring, its own snapshot. */\n makeUnderbarrel?: (id: WeaponId, seed: number, snapshot?: WeaponSnapshot) => WeaponState\n /** Weapon, with its parts and ammunition, to start from instead of a fresh one. */\n snapshot?: WeaponSnapshot\n}\n\n/** Something that happens at a later time of the weapon clock. */\nexport interface Scheduled {\n readonly at: number\n readonly tag?: 'reload'\n readonly event?: WeaponEvent\n readonly apply?: () => void\n}\n\nexport const FAULT_RNG_SALT = 0x6a09e667\n/** Stream of the fuse sampling: separate from the spread and the faults, so a sampled fuse never shifts a shot. */\nexport const FUSE_RNG_SALT = 0xbb67ae85\n/** Stream that draws the shot a home-made suppressor breaks on: separate, so a break never moves a spread or a fault. */\nexport const BREAK_RNG_SALT = 0x3c6ef372\n/** Seed of the launcher under the barrel: its own streams, so the rifle's spread does not move. */\nexport const UNDERBARREL_SEED_SALT = 0xa54ff53a\n\nexport const findById = <TEntry extends { readonly id: string }>(entries: readonly TEntry[], id: string, label: string): TEntry => {\n const found = entries.find((entry) => entry.id === id)\n if (!found) throw new Error(`game-weapons: unknown ${label} \"${id}\"`)\n return found\n}\n\nexport const result = (status: TriggerResult['status'], extra: Partial<TriggerResult> = {}): TriggerResult => ({\n shots: [],\n uses: [],\n status,\n recoil: [0, 0],\n noise: 0,\n rounds: 0,\n roundTimes: [],\n ...extra,\n})\n\n/** Runtime of one weapon. See `WeaponState` for the contract. */\n","import { decayHeat } from './heat'\nimport { isReloadable } from './reload'\nimport { createRng } from './rng'\nimport type { AmmoQualityDef, CaliberDef, ConditionDef, ExplosiveDef, FaultId, FireMode, ReloadKind, Vec3, WeaponAction, WeaponDef, WeaponEvent, WeaponPhase, WeaponRules } from './types'\nimport { EPS, FAULT_RNG_SALT, FUSE_RNG_SALT, findById } from './weapon-shared'\nimport type { Scheduled, WeaponStateInit } from './weapon-shared'\n\nconst DEFAULT_THROWABLES = 3\n\n/** State and clock of one weapon: ammunition, phases, scheduled events and reload settling. Commands and firing are layered on top. */\nexport abstract class WeaponCore {\n readonly def: WeaponDef\n readonly caliber: CaliberDef | null\n reserve: number\n mode: FireMode\n protected _ammo: number\n protected _capacity: number\n /** What the weapon does now: the numbers of the def with the effects of the accessories on it (the def's own action when there are none). */\n protected action: WeaponAction\n protected readonly rng: () => number\n protected readonly initialReserve: number\n protected readonly rules: WeaponRules\n protected readonly faultRng: () => number\n protected readonly fuseRng: () => number\n /** Metres of safety fuse set by the host; replaces the `fuseLength` of the explosive. */\n protected fuseLengthOverride: number | undefined\n protected readonly explosive: ExplosiveDef | null\n\n protected clock = 0\n /** Time already advanced by the other of update / trigger in the same frame (so calling both does not count `dt` twice). */\n protected pend: { src: 'update' | 'trigger'; amt: number } | null = null\n protected readyAt = 0\n protected latched = false\n /** A throwable whose pin is pulled: the clock it started at, its whole fuse and the aim of the last frame it was held. */\n protected cook: { readonly start: number; readonly fuse: number; origin: Vec3; direction: Vec3 } | null = null\n\n protected _reloading = false\n protected reloadEnd = 0\n /** Seconds per round while a one-by-one reload runs; null when the magazine goes in at once. */\n protected loadStep: number | null = null\n protected _locked = false\n protected reloadKind: ReloadKind = 'tactical'\n protected drawEnd = 0\n protected _phase: WeaponPhase | null = null\n protected _fault: FaultId | null = null\n protected _clearing = false\n protected _safety: boolean\n protected _heat = 0\n protected _condition: ConditionDef\n protected _ammoQuality: AmmoQualityDef\n /** Times of the shots that still count for the noise of a burst. */\n protected recentShots: number[] = []\n protected events: WeaponEvent[] = []\n protected scheduled: Scheduled[] = []\n\n /** Bloom degrees at `extraClock`. */\n protected extra = 0\n protected extraClock = 0\n\n constructor(init: WeaponStateInit) {\n this.def = init.def\n this.caliber = init.caliber\n this.action = init.def.action\n this.rules = init.rules\n this.rng = createRng(init.seed)\n this.faultRng = createRng((init.seed ^ FAULT_RNG_SALT) >>> 0)\n this.fuseRng = createRng((init.seed ^ FUSE_RNG_SALT) >>> 0)\n this.explosive = init.explosive ?? null\n this._safety = init.rules.startSafe\n this._condition = findById(init.rules.conditions, init.condition ?? init.rules.defaultCondition, 'condition')\n this._ammoQuality = findById(init.rules.ammoQualities, init.ammoQuality ?? init.rules.defaultAmmoQuality, 'ammo quality')\n const a = this.action\n this.mode = a.kind === 'firearm' ? a.modes[0] ?? 'single' : 'single'\n switch (a.kind) {\n case 'firearm':\n case 'launcher':\n this._capacity = a.magazine\n break\n case 'flame':\n case 'heat':\n this._capacity = a.fuel\n break\n case 'extinguisher':\n this._capacity = a.charge\n break\n case 'throwable':\n this._capacity = a.count ?? DEFAULT_THROWABLES\n break\n default:\n this._capacity = 0\n }\n this._ammo = this._capacity\n this.initialReserve = init.reserve ?? (isReloadable(a) ? a.magazine * 3 : 0)\n this.reserve = this.initialReserve\n }\n\n get ammo(): number {\n return this._ammo\n }\n get capacity(): number {\n return this._capacity\n }\n /** True while a throwable's pin is pulled and the trigger is held. */\n get cooking(): boolean {\n return this.cook !== null\n }\n get reloading(): boolean {\n return this._reloading\n }\n get locked(): boolean {\n return this._locked\n }\n get phase(): WeaponPhase | null {\n const phase = this._phase\n return phase && this.clock < phase.end - EPS ? phase : null\n }\n get fault(): FaultId | null {\n return this._fault\n }\n get clearing(): boolean {\n return this._clearing\n }\n get safety(): boolean {\n return this._safety\n }\n get heat(): number {\n return this._heat\n }\n get heatLevel(): number {\n return Math.min(1, this._heat / this.rules.heat.displayMax)\n }\n get condition(): string {\n return this._condition.id\n }\n get ammoQuality(): string {\n return this._ammoQuality.id\n }\n get spread(): number {\n if (this.action.kind !== 'firearm') return 0\n return this.action.spreadDeg + this.extraAt(this.clock)\n }\n\n protected extraAt(t: number): number {\n if (this.action.kind !== 'firearm') return 0\n const rec = this.action.recoveryDegPerS ?? 4\n return Math.max(0, this.extra - rec * Math.max(0, t - this.extraClock))\n }\n\n // --- time -----------------------------------------------------------------------------------------------------------------------\n\n update(dt: number): void {\n const d = Math.max(0, dt)\n let eff = d\n if (this.pend && this.pend.src === 'trigger') {\n eff = Math.max(0, d - this.pend.amt)\n this.pend = null\n } else {\n this.pend = { src: 'update', amt: d }\n }\n this.advance(eff)\n this.settle(this.clock)\n }\n\n protected emit(event: WeaponEvent): void {\n this.events.push(event)\n }\n\n protected schedule(item: Scheduled): void {\n const index = this.scheduled.findIndex((other) => other.at > item.at)\n if (index < 0) this.scheduled.push(item)\n else this.scheduled.splice(index, 0, item)\n }\n\n drain(): WeaponEvent[] {\n const drained = this.events.sort((a, b) => a.at - b.at)\n this.events = []\n return drained\n }\n\n protected advance(seconds: number): void {\n if (seconds <= 0) return\n this._heat = decayHeat(this._heat, seconds, this.rules.heat)\n this.clock += seconds\n }\n\n /** Complete what falls at or before `t`: scheduled events and the reload steps. */\n protected settle(t: number): void {\n while (this.scheduled[0] && this.scheduled[0].at <= t + EPS) {\n const item = this.scheduled.shift() as Scheduled\n item.apply?.()\n if (item.event) this.emit(item.event)\n }\n const a = this.action\n if (!isReloadable(a)) return\n while (this._reloading && this.reloadEnd <= t + EPS) {\n const doneAt = this.reloadEnd\n if (this.loadStep !== null) {\n if (this.reserve > 0 && this._ammo < this._capacity) {\n this._ammo += 1\n this.reserve -= 1\n this.emit({ type: 'feed', at: doneAt })\n }\n if (this._ammo >= this._capacity || this.reserve <= 0) this.finishReload(doneAt)\n else this.reloadEnd += this.loadStep\n } else {\n const take = Math.min(this._capacity - this._ammo, this.reserve)\n this._ammo += take\n this.reserve -= take\n this.finishReload(doneAt)\n }\n }\n }\n\n protected finishReload(at: number): void {\n this._reloading = false\n this._locked = false\n this.emit({ type: 'reload', phase: 'end', kind: this.reloadKind, at })\n }\n\n protected stopReload(at: number): void {\n this._reloading = false\n this._phase = null\n this.scheduled = this.scheduled.filter((item) => item.tag !== 'reload')\n this.emit({ type: 'reload', phase: 'end', kind: this.reloadKind, at })\n }\n\n release(): void {\n this.latched = false\n }\n}\n","import { clearSeconds, drawSeconds } from './fire'\nimport { isReloadable, planReload, reloadStages } from './reload'\nimport type { FireMode, ReloadRequest } from './types'\nimport { WeaponCore } from './weapon-core'\nimport { EPS, findById } from './weapon-shared'\n\n/** Commands that change the state of a weapon: safety, fault clearing, condition, draw, reload, fire mode and refill. */\nexport abstract class WeaponCommands extends WeaponCore {\n setSafety(on: boolean): boolean {\n if (!isReloadable(this.action) || on === this._safety) return this._safety\n this._safety = on\n this.emit({ type: 'safety', on, at: this.clock })\n return on\n }\n\n clearFault(): boolean {\n const fault = this._fault\n if (!fault || this._clearing) return false\n const endAt = this.clock + clearSeconds(this.action, this.rules)\n this._clearing = true\n this._phase = { id: 'clear', start: this.clock, end: endAt }\n this.emit({ type: 'clear', fault, phase: 'start', at: this.clock })\n const finish = (): void => {\n this._fault = null\n this._clearing = false\n if (fault === 'misfire') this._ammo = Math.max(0, this._ammo - 1) // the dud is ejected\n }\n this.schedule({ at: endAt, event: { type: 'clear', fault, phase: 'end', at: endAt }, apply: finish })\n return true\n }\n\n setCondition(id: string): void {\n this._condition = findById(this.rules.conditions, id, 'condition')\n }\n\n setAmmoQuality(id: string): void {\n this._ammoQuality = findById(this.rules.ammoQualities, id, 'ammo quality')\n }\n\n setFuseLength(metres: number | undefined): void {\n this.fuseLengthOverride = metres\n }\n\n /** Seconds to put the weapon in hand. */\n protected drawDuration(): number {\n return drawSeconds(this.action, this.rules)\n }\n\n draw(): void {\n const seconds = this.drawDuration()\n this.drawEnd = this.clock + seconds\n this._phase = { id: 'draw', start: this.clock, end: this.drawEnd }\n this.emit({ type: 'draw', phase: 'start', at: this.clock })\n this.schedule({ at: this.drawEnd, event: { type: 'draw', phase: 'end', at: this.drawEnd } })\n }\n\n reload(request: ReloadRequest = 'auto'): boolean {\n const a = this.action\n if (a.kind === 'throwable') {\n if (this._ammo >= this._capacity || this.reserve <= 0) return false\n this._ammo += 1\n this.reserve -= 1\n return true\n }\n if (!isReloadable(a) || this._reloading || this._fault || this._clearing || this.clock < this.drawEnd - EPS) return false\n if ((this._ammo >= this._capacity && !this._locked) || this.reserve <= 0) return false\n const plan = planReload(a, this._ammo, this._capacity, this.reserve, request)\n this._reloading = true\n this.loadStep = plan.step\n this.reloadKind = plan.kind\n this.reloadEnd = this.clock + plan.first\n this._phase = { id: 'reload', start: this.clock, end: this.clock + plan.total }\n this.emit({ type: 'reload', phase: 'start', kind: plan.kind, at: this.clock })\n for (const { stage, at } of reloadStages(a, plan, this.clock)) this.schedule({ at, tag: 'reload', event: { type: 'reload_stage', stage, at } })\n return true\n }\n\n cycleMode(): FireMode {\n if (this.action.kind !== 'firearm') return this.mode\n const modes = this.action.modes\n const i = modes.indexOf(this.mode)\n this.mode = modes[(i + 1) % modes.length] ?? this.mode\n this.emit({ type: 'mode', mode: this.mode, at: this.clock })\n return this.mode\n }\n\n refill(): void {\n this._ammo = this._capacity\n this.reserve = this.initialReserve\n this._reloading = false\n this._locked = false\n this._fault = null\n this._clearing = false\n this._phase = null\n this.scheduled = []\n this.readyAt = this.clock\n this.latched = false\n this.cook = null\n this.extra = 0\n }\n}\n","import type { AttachmentDef, AttachmentId, FittedAttachment, MountKind, StockState, WeaponSnapshot } from './attachment-types'\nimport { resolveLoadout } from './attachment-effects'\nimport type { Loadout } from './attachment-effects'\nimport { canFit, canInstallWith } from './attachments'\nimport type { CanFit } from './attachments'\nimport { createRng } from './rng'\nimport type { FitOptions, FitResult, ReloadRequest, WeaponEvent, WeaponState, WeaponStance } from './types'\nimport { WeaponCommands } from './weapon-commands'\nimport { BREAK_RNG_SALT, EPS, UNDERBARREL_SEED_SALT } from './weapon-shared'\nimport type { WeaponStateInit } from './weapon-shared'\n\nconst NO_ATTACHMENTS: ReadonlyMap<AttachmentId, AttachmentDef> = new Map()\n\nconst copyOf = (part: FittedAttachment): FittedAttachment => ({ ...part })\n\n/** What is on the weapon: fitting and removing accessories, the stock, how it is held, and the numbers all of that changes. */\nexport abstract class WeaponAttachments extends WeaponCommands {\n protected fitted: FittedAttachment[]\n protected load: Loadout\n protected stockState: StockState = 'extended'\n protected aiming = false\n protected supportedStance = false\n /** Magazine changes so far: a dual coupler makes every second one fast. */\n protected reloadCount = 0\n protected readonly catalogue: ReadonlyMap<AttachmentId, AttachmentDef>\n protected readonly isCompatible: WeaponStateInit['isCompatible']\n protected readonly breakRng: () => number\n protected under: WeaponState | null = null\n /** The accessory the launcher state belongs to. */\n private underOwner: AttachmentId | null = null\n /** Launchers whose accessory is off the weapon, by accessory id, with the clock they were put away at: the same accessory brings its own rounds back (grenades are conserved). */\n private readonly shelvedLaunchers = new Map<AttachmentId, { readonly state: WeaponState; readonly at: number }>()\n protected underActive = false\n /** Seconds the weapon has run since the launcher under the barrel was last brought up to its clock (it idles while the rifle is in use). */\n protected underBehind = 0\n private readonly makeUnderbarrel: WeaponStateInit['makeUnderbarrel']\n private readonly seed: number\n\n constructor(init: WeaponStateInit) {\n super(init)\n this.catalogue = init.attachments ?? NO_ATTACHMENTS\n this.isCompatible = init.isCompatible\n this.makeUnderbarrel = init.makeUnderbarrel\n this.seed = init.seed\n this.breakRng = createRng((init.seed ^ BREAK_RNG_SALT) >>> 0)\n this.fitted = (init.snapshot?.attachments ?? init.def.fitted ?? []).map(copyOf)\n if (init.snapshot) this.stockState = init.snapshot.stock\n this.fitted = this.fitted.map((part) => (part.shotsLeft === undefined ? this.withDurability(part) : part))\n this.load = this.resolve()\n this.applyLoad()\n this.syncUnderbarrel(init.snapshot?.underbarrel)\n if (init.snapshot) this.applySnapshot(init.snapshot)\n }\n\n get underbarrel(): WeaponState | null {\n return this.under\n }\n get underbarrelActive(): boolean {\n return this.underActive\n }\n\n get attachments(): readonly FittedAttachment[] {\n return this.fitted.map(copyOf)\n }\n get mass(): number {\n return this.load.mass\n }\n get aimSeconds(): number {\n return this.load.aimSeconds\n }\n get suppressed(): boolean {\n return this.load.suppressed\n }\n get stock(): StockState {\n return this.stockState\n }\n\n private resolve(): Loadout {\n const supported = this.supportedStance\n return resolveLoadout(this.def, this.fitted, this.catalogue, { aiming: this.aiming, supported, stock: this.stockState, caliber: this.caliber, rules: this.rules })\n }\n\n /** Takes the numbers of the accessories on the weapon: the action, the capacity (what no longer fits goes back to the reserve) and the draw time. */\n protected applyLoad(): void {\n this.load = this.resolve()\n this.action = this.load.action\n const capacity = this.action.kind === 'firearm' ? this.action.magazine : this._capacity\n if (capacity === this._capacity) return\n this._capacity = capacity\n if (this._ammo <= capacity) return\n this.reserve += this._ammo - capacity\n this._ammo = capacity\n }\n\n /** Makes the launcher state when a fitted accessory is one; when it comes off the state is kept for that accessory, and a re-fit gets it back as it was. */\n private syncUnderbarrel(snapshot?: WeaponSnapshot): void {\n const owner = this.fitted.find((part) => this.catalogue.get(part.id)?.launcher !== undefined)\n const launcher = owner ? this.catalogue.get(owner.id)?.launcher : undefined\n if (!owner || launcher === undefined || !this.makeUnderbarrel) {\n this.shelveUnderbarrel()\n this.underActive = false\n return\n }\n if (this.underOwner === owner.id) return\n this.shelveUnderbarrel()\n const kept = this.shelvedLaunchers.get(owner.id)\n this.shelvedLaunchers.delete(owner.id)\n this.under = kept?.state ?? this.makeUnderbarrel(launcher, (this.seed ^ UNDERBARREL_SEED_SALT) >>> 0, snapshot)\n this.underOwner = owner.id\n this.underBehind = this.clock - (kept?.at ?? 0)\n this.flushUnderbarrel()\n }\n\n private shelveUnderbarrel(): void {\n if (this.under && this.underOwner !== null) this.shelvedLaunchers.set(this.underOwner, { state: this.under, at: this.clock })\n this.under = null\n this.underOwner = null\n }\n\n /** Brings the idle launcher up to the clock of the weapon (its phases and events keep the same time). */\n private flushUnderbarrel(): void {\n if (!this.under) return\n if (this.underBehind > 0) {\n this.under.update(this.underBehind)\n this.under.update(0)\n }\n this.underBehind = 0\n }\n\n protected advance(seconds: number): void {\n super.advance(seconds)\n if (!this.underActive) this.underBehind += Math.max(0, seconds)\n }\n\n update(dt: number): void {\n super.update(dt)\n if (this.underActive) this.under?.update(dt)\n }\n\n drain(): WeaponEvent[] {\n const own = super.drain()\n const launcher = this.under?.drain() ?? []\n return launcher.length === 0 ? own : [...own, ...launcher].sort((a, b) => a.at - b.at)\n }\n\n refill(): void {\n super.refill()\n this.under?.refill()\n }\n\n useUnderbarrel(on: boolean): boolean {\n if (!this.under || on === this.underActive || this.isWorking() || this._reloading || this.under.reloading) return false\n const seconds = this.rules.attachments.switchSeconds\n this.emit({ type: 'underbarrel', on, at: this.clock })\n const apply = (): void => {\n if (on) this.flushUnderbarrel()\n this.underActive = on\n }\n if (seconds <= EPS) {\n apply()\n return true\n }\n this._phase = { id: 'switch', start: this.clock, end: this.clock + seconds }\n this.schedule({ at: this.clock + seconds, apply })\n return true\n }\n\n /** The weapon is busy fitting, folding or switching: nothing else answers. */\n protected workGate(): boolean {\n return this.isWorking()\n }\n\n private applySnapshot(snapshot: WeaponSnapshot): void {\n this._ammo = Math.min(snapshot.ammo, this._capacity)\n this.reserve = snapshot.reserve\n this.mode = snapshot.mode\n }\n\n private withDurability(part: FittedAttachment): FittedAttachment {\n const shots = this.catalogue.get(part.id)?.durability?.shots\n if (!shots) return part\n return { ...part, shotsLeft: shots[0] + Math.floor(this.breakRng() * (shots[1] - shots[0] + 1)) }\n }\n\n protected isWorking(): boolean {\n const phase = this.phase\n return phase !== null && (phase.id === 'fit' || phase.id === 'stock' || phase.id === 'switch')\n }\n\n protected drawDuration(): number {\n return super.drawDuration() * this.load.drawFactor\n }\n\n canFit(id: AttachmentId, mount?: MountKind): CanFit {\n const attachment = this.catalogue.get(id)\n if (!attachment) return { ok: false, reason: 'no_mount' }\n return canFit(this.def, attachment, this.fitted, { caliber: this.caliber, catalogue: this.catalogue, isCompatible: this.isCompatible }, mount)\n }\n\n /** Starts the work: the phase and the event now, the change when the phase ends. */\n private startWork(action: 'fit' | 'remove', attachment: AttachmentDef, mount: MountKind, apply: () => void): FitResult {\n const seconds = this.rules.attachments.fitSeconds[attachment.install]\n this.emit({ type: 'attachment', action, id: attachment.id, mount, at: this.clock })\n if (seconds <= EPS) {\n apply()\n return { ok: true, seconds: 0 }\n }\n this._phase = { id: 'fit', start: this.clock, end: this.clock + seconds }\n this.schedule({ at: this.clock + seconds, apply })\n return { ok: true, seconds }\n }\n\n fit(id: AttachmentId, options: FitOptions = {}): FitResult {\n const attachment = this.catalogue.get(id)\n if (!attachment) return { ok: false, reason: 'unknown' }\n if (this.isWorking() || this._reloading) return { ok: false, reason: 'busy' }\n if (!canInstallWith(options.install ?? 'field', attachment.install)) return { ok: false, reason: 'install' }\n const check = canFit(this.def, attachment, this.fitted, { caliber: this.caliber, catalogue: this.catalogue, isCompatible: this.isCompatible }, options.mount)\n if (!check.ok) return check\n return this.startWork('fit', attachment, check.mount, () => {\n this.fitted.push(this.withDurability({ id, mount: check.mount }))\n this.applyLoad()\n this.syncUnderbarrel()\n })\n }\n\n remove(id: AttachmentId, options: FitOptions = {}): FitResult {\n const part = this.fitted.find((candidate) => candidate.id === id)\n const attachment = this.catalogue.get(id)\n if (!part || !attachment) return { ok: false, reason: 'not_fitted' }\n if (part.integral === true || attachment.removable === false) return { ok: false, reason: 'fixed' }\n if (this.isWorking() || this._reloading) return { ok: false, reason: 'busy' }\n if (!canInstallWith(options.install ?? 'field', attachment.install)) return { ok: false, reason: 'install' }\n return this.startWork('remove', attachment, part.mount, () => {\n this.fitted = this.fitted.filter((candidate) => candidate !== part)\n this.applyLoad()\n this.syncUnderbarrel()\n })\n }\n\n toggle(id: AttachmentId): boolean | null {\n const index = this.fitted.findIndex((part) => part.id === id)\n const kind = this.catalogue.get(id)?.kind\n const part = this.fitted[index]\n if (!part || (kind !== 'light' && kind !== 'laser')) return null\n const on = part.on !== true\n this.fitted[index] = { ...part, on }\n this.emit({ type: 'toggle', id, on, at: this.clock })\n this.applyLoad()\n return on\n }\n\n setStock(state: StockState): boolean {\n const kind = this.def.stock?.kind\n if (kind === undefined || kind === 'fixed' || kind === 'none' || state === this.stockState || this.isWorking() || this._reloading) return false\n const seconds = this.rules.stock.seconds\n this.emit({ type: 'stock', state, kind, at: this.clock })\n const apply = (): void => {\n this.stockState = state\n this.applyLoad()\n }\n if (seconds <= EPS) {\n apply()\n return true\n }\n this._phase = { id: 'stock', start: this.clock, end: this.clock + seconds }\n this.schedule({ at: this.clock + seconds, apply })\n return true\n }\n\n setStance(stance: WeaponStance): void {\n const aiming = stance.aiming ?? this.aiming\n const supported = stance.supported ?? this.supportedStance\n if (aiming === this.aiming && supported === this.supportedStance) return\n this.aiming = aiming\n this.supportedStance = supported\n this.applyLoad()\n }\n\n snapshot(): WeaponSnapshot {\n const launcher = this.under?.snapshot()\n return {\n id: this.def.id,\n attachments: this.fitted.map(copyOf),\n stock: this.stockState,\n ammo: this._ammo,\n reserve: this.reserve,\n mode: this.mode,\n condition: this._condition.id,\n ammoQuality: this._ammoQuality.id,\n ...(launcher ? { underbarrel: launcher } : {}),\n }\n }\n\n /** A home-made accessory wears out with the shots: when the drawn number is spent it breaks and comes off. */\n protected wearAttachments(at: number): void {\n if (!this.fitted.some((part) => part.shotsLeft !== undefined)) return\n let broke = false\n this.fitted = this.fitted.flatMap((part) => {\n if (part.shotsLeft === undefined) return [part]\n if (part.shotsLeft > 1) return [{ ...part, shotsLeft: part.shotsLeft - 1 }]\n this.emit({ type: 'attachment', action: 'break', id: part.id, mount: part.mount, at })\n broke = true\n return []\n })\n if (broke) this.applyLoad()\n }\n\n reload(request: ReloadRequest = 'auto'): boolean {\n if (this.isWorking()) return false\n if (this.underActive && this.under) return this.under.reload(request)\n const base = this.action\n const factor = this.load.secondReloadFactor\n const isFast = factor !== 1 && this.reloadCount % 2 === 1 && base.kind === 'firearm'\n if (isFast && base.kind === 'firearm') this.action = { ...base, reload: base.reload * factor, ...(base.timings ? { timings: { ...base.timings, reload: base.timings.reload * factor, ...(base.timings.reloadEmpty === undefined ? {} : { reloadEmpty: base.timings.reloadEmpty * factor }) } } : {}) }\n const started = super.reload(request)\n this.action = base\n if (started) this.reloadCount += 1\n return started\n }\n}\n\n","import { isDudWithoutJam, rollFault } from './faults'\nimport { manualCycleSeconds, planRounds, weaponNoise, weaponSpeed } from './fire'\nimport { burstNoise, heatPerRound } from './heat'\nimport { sampleCone } from './rng'\nimport type { CaliberDef, FaultId, FirearmAction, Shot, TriggerResult, Vec3, WeaponRules } from './types'\nimport { WeaponAttachments } from './weapon-attachments'\nimport { BLOOM_CAP, EPS, result } from './weapon-shared'\n\n// frames of one pull follow each other closely; a longer gap means the trigger was let go and the barrels start from rest again\nconst SPIN_PULL_GAP = 0.1\n\n/** Pulling the trigger of a firearm: rounds, faults, heat, bloom and noise. */\nexport abstract class WeaponFirearm extends WeaponAttachments {\n /** Semi-style gating: a held trigger that already fired does nothing until `release()` or a new pull (`held` false). */\n private spinSince: number | undefined\n private spinFrameEnd = Number.NEGATIVE_INFINITY\n private lastRoundAt = Number.NEGATIVE_INFINITY\n\n /** When the barrels of a rotary gun are at speed: `upSeconds` after the pull began, and at once while they still spin from the last round. */\n private spunUpAt(spin: FirearmAction['spin'], start: number, end: number): number {\n if (!spin || start - this.lastRoundAt <= spin.holdSeconds + EPS) return 0\n if (this.spinSince === undefined || start - this.spinFrameEnd > SPIN_PULL_GAP) this.spinSince = start\n this.spinFrameEnd = end\n return this.spinSince + spin.upSeconds\n }\n\n protected oncePerPull(held: boolean): boolean {\n if (!held) this.latched = false\n if (this.latched) return false\n this.latched = true\n return true\n }\n\n protected fireFirearm(a: FirearmAction, origin: Vec3, dir: Vec3, start: number, end: number, held: boolean, source?: string): TriggerResult {\n if (this._reloading) {\n if (this.loadStep !== null && this._ammo > 0) this.stopReload(start) // a tube reload is interrupted by the trigger\n else return result('reloading')\n }\n if (this.mode !== 'auto' && !this.oncePerPull(held)) return result('cooldown')\n if (this._ammo <= 0) {\n this.emit({ type: 'empty', at: start })\n return result('empty')\n }\n\n const t0 = Math.max(start, this.readyAt, this.spunUpAt(a.spin, start, end))\n if (t0 > end + EPS) return result('cooldown')\n\n const res = result('ok')\n const times = planRounds(a, this.mode, this._ammo, t0, end)\n let lastAt = t0\n for (const t of times) {\n const fault = rollFault({ def: this.def, caliber: this.caliber, condition: this._condition, ammoQuality: this._ammoQuality, heat: this._heat, rules: this.faultRules(), random: this.faultRng })\n if (fault === 'misfire') {\n this.misfire(a, t, start, res)\n lastAt = t\n break\n }\n this.fireOne(this.action.kind === 'firearm' ? this.action : a, origin, dir, t, res, source)\n res.roundTimes.push(t - start)\n res.rounds += 1\n lastAt = t\n if (fault) {\n this.jam(fault, t, res)\n break\n }\n }\n if (res.shots.length === 0) res.status = res.fault ? 'fault' : 'misfire'\n else this.emit({ type: 'shot', shots: res.shots.length, rounds: res.rounds, mode: this.mode, at: t0, ...(res.suppressed ? { suppressed: true } : {}) })\n if (res.rounds > 0) {\n this.lastRoundAt = lastAt\n this.spinSince = undefined\n this.afterRounds(a, lastAt)\n }\n return res\n }\n\n /** The rules with the chance of a fault scaled by the accessories (a drum magazine jams more); the very rules when nothing scales it. */\n private faultRules(): WeaponRules {\n const factor = this.load.faultFactor\n if (factor === 1) return this.rules\n return { ...this.rules, faultChance: (context) => this.rules.faultChance(context) * factor }\n }\n\n protected jam(fault: FaultId, at: number, res: TriggerResult): void {\n this._fault = fault\n res.fault = fault\n this.emit({ type: 'fault', fault, at })\n }\n\n protected misfire(a: FirearmAction, at: number, start: number, res: TriggerResult): void {\n if (!isDudWithoutJam(a, 'misfire')) {\n this.jam('misfire', at, res)\n return\n }\n this._ammo -= 1\n res.rounds += 1\n res.roundTimes.push(at - start)\n this.emit({ type: 'misfire', at })\n }\n\n /** Cooldown, the cycle of a manual action and the pistol slide that stays back on the last round. */\n protected afterRounds(a: FirearmAction, lastAt: number): void {\n const cycle = manualCycleSeconds(a, this.mode)\n if (cycle > 0) {\n this.readyAt = Math.max(this.readyAt, lastAt + cycle)\n this._phase = { id: 'cycle', start: lastAt, end: lastAt + cycle }\n this.emit({ type: 'cycle', phase: 'start', at: lastAt })\n this.schedule({ at: lastAt + cycle, event: { type: 'cycle', phase: 'end', at: lastAt + cycle } })\n }\n if (this._ammo === 0 && a.family === 'pistol') this._locked = true\n }\n\n protected fireOne(a: FirearmAction, origin: Vec3, dir: Vec3, t: number, res: TriggerResult, source?: string): void {\n const cal = this.caliber as CaliberDef\n const isFirstRound = res.shots.length === 0\n const speed = weaponSpeed(a, cal)\n const energy = 0.5 * (cal.bulletGrams / 1000) * speed * speed\n const drag = cal.dragPer100m ?? 0.1\n const energyAt = (distance: number): number => {\n const f = Math.pow(1 - drag, Math.max(0, distance) / 100)\n return energy * f * f\n }\n const bloomNow = this.extraAt(t)\n const spread = a.spreadDeg + bloomNow\n const aim = sampleCone(dir, spread, this.rng)\n const pellets = cal.pellets ?? 1\n const pelletSpread = pellets > 1 ? a.pelletSpreadDeg ?? 3 : 0\n for (let p = 0; p < pellets; p++) {\n const shot: Shot = {\n origin: [origin[0], origin[1], origin[2]],\n direction: sampleCone(aim, pelletSpread, this.rng),\n energy,\n caliber: cal.diameter,\n caliberId: cal.id,\n speed,\n energyAt,\n pellet: p,\n weapon: this.def.id,\n }\n if (source !== undefined) shot.source = source\n res.shots.push(shot)\n }\n this._ammo -= 1\n this._heat = Math.min(this.rules.heat.cap, this._heat + heatPerRound(a, cal, this.rules.heat) * this.load.heatFactor)\n this.readyAt = t + 60 / a.rpm\n this.extra = Math.min(bloomNow + (a.bloomDeg ?? 0), a.spreadDeg * (BLOOM_CAP - 1))\n this.extraClock = t\n res.recoil = [res.recoil[0] + a.recoil[0], res.recoil[1] + (this.rng() * 2 - 1) * a.recoil[1]]\n const { window } = this.rules.noiseBurst\n this.recentShots = this.recentShots.filter((shotAt) => shotAt > t - window)\n res.noise = burstNoise(weaponNoise(a, cal), this.recentShots.length, this.rules.noiseBurst)\n this.recentShots.push(t)\n if (!this.load.suppressed) delete res.suppressed\n else if (isFirstRound) res.suppressed = true\n this.wearAttachments(t)\n }\n\n}\n","import { isPlaced, launcherUses, throwableUse } from './explosive-use'\nimport { sampleFuse } from './fuse'\nimport { heatPerRound } from './heat'\nimport { isReloadable } from './reload'\nimport { normalize } from './rng'\nimport type { TriggerResult, Use, Vec3, WeaponAction, WeaponState } from './types'\nimport { WeaponFirearm } from './weapon-firearm'\nimport type { WeaponCore } from './weapon-core'\nimport { EPS, result } from './weapon-shared'\n\nexport { BLOOM_CAP, muzzleEnergy } from './weapon-shared'\nexport type { WeaponStateInit } from './weapon-shared'\n\n/** Runtime of one weapon. See `WeaponState` for the contract. */\nexport class WeaponRuntime extends WeaponFirearm implements WeaponState {\n trigger(origin: Vec3, direction: Vec3, dt: number, held = false, source?: string): TriggerResult {\n const d = Math.max(0, dt)\n let overlap = 0\n if (this.pend && this.pend.src === 'update') {\n overlap = Math.min(this.pend.amt, d)\n this.pend = null\n } else {\n this.pend = { src: 'trigger', amt: d }\n }\n const start = this.clock - overlap\n const end = start + d\n this.settle(start)\n const dir = normalize(direction)\n let res: TriggerResult\n const a = this.action\n const launcher = this.underActive ? this.under : null\n const gate = launcher ? this.launcherGate(start) : this.gateStatus(start)\n if (gate) res = gate\n else if (launcher) res = launcher.trigger(origin, dir, d, held, source)\n else switch (a.kind) {\n case 'firearm':\n res = this.fireFirearm(a, origin, dir, start, end, held, source)\n break\n case 'melee':\n res = this.fireMelee(a, origin, dir, start, end)\n break\n case 'flame':\n case 'heat':\n res = this.fireFuel(a, origin, dir, d)\n break\n case 'extinguisher':\n res = this.fireExtinguisher(a, origin, dir, d)\n break\n case 'throwable':\n res = this.fireThrowable(a, origin, dir, held, start, end)\n break\n case 'launcher':\n res = this.fireLauncher(a, origin, dir, start, held)\n break\n case 'tool':\n res = d > 0 ? result('ok', { uses: [{ kind: 'tool', tool: a.tool, reach: a.reach, duration: d, origin, direction: dir }], noise: a.noise }) : result('ok')\n break\n case 'hand':\n res = this.oncePerPull(held)\n ? result('ok', { uses: [{ kind: 'hand', reach: a.reach, origin, direction: dir }] })\n : result('cooldown')\n break\n }\n this.advance(Math.max(0, end - this.clock))\n this.settle(this.clock)\n return res\n }\n\n /** The launcher under the barrel answers for itself; the weapon only says when it is busy putting it in hand. */\n protected launcherGate(start: number): TriggerResult | null {\n if (start < this.drawEnd - EPS) return result('drawing')\n return this.workGate() ? result('busy') : null\n }\n\n /** Why the trigger does nothing before the action even looks at it. */\n protected gateStatus(start: number): TriggerResult | null {\n if (start < this.drawEnd - EPS) return result('drawing')\n if (this.isWorking()) return result('busy')\n if (!isReloadable(this.action)) return null\n if (this._safety) return result('safe')\n if (this._clearing) return result('clearing')\n if (this._fault) return result('fault', { fault: this._fault })\n return null\n }\n\n protected fireLauncher(a: Extract<WeaponAction, { kind: 'launcher' }>, origin: Vec3, dir: Vec3, start: number, held: boolean): TriggerResult {\n if (this._reloading) return result('reloading')\n if (!this.oncePerPull(held)) return result('cooldown')\n if (this._ammo <= 0) {\n this.emit({ type: 'empty', at: start })\n return result('empty')\n }\n const t = Math.max(start, this.readyAt)\n this._ammo -= 1\n this._heat = Math.min(this.rules.heat.cap, this._heat + heatPerRound(a, null, this.rules.heat))\n this.emit({ type: 'shot', shots: 0, rounds: 1, mode: this.mode, at: t })\n return result('ok', { uses: launcherUses(a, this.explosive, origin, dir), recoil: [a.recoil[0], a.recoil[1]], noise: a.noise ?? 0, rounds: 1, roundTimes: [t - start] })\n }\n\n protected fireMelee(a: Extract<WeaponAction, { kind: 'melee' }>, origin: Vec3, dir: Vec3, start: number, end: number): TriggerResult {\n const t0 = Math.max(start, this.readyAt)\n if (t0 > end + EPS) return result('cooldown')\n this.readyAt = t0 + 60 / a.rpm\n const use: Use = { kind: 'melee', damage: a.damage, energy: a.energy, radius: a.radius, reach: a.reach, origin, direction: dir }\n return result('ok', { uses: [use], noise: a.noise })\n }\n\n protected fireFuel(a: Extract<WeaponAction, { kind: 'flame' | 'heat' }>, origin: Vec3, dir: Vec3, dt: number): TriggerResult {\n if (this._ammo <= EPS) return result('no_fuel')\n if (dt <= 0) return result('ok')\n const need = a.fuelPerSecond * dt\n let duration = dt\n if (need > this._ammo) {\n duration = dt * (this._ammo / need)\n this._ammo = 0\n } else {\n this._ammo -= need\n }\n const use: Use =\n a.kind === 'flame'\n ? { kind: 'flame', temperature: a.temperature, radius: a.radius, range: a.range, cone: a.cone ?? false, duration, origin, direction: dir }\n : { kind: 'heat', temperature: a.temperature, radius: a.radius, range: a.range, duration, origin, direction: dir }\n return result('ok', { uses: [use], noise: a.noise })\n }\n\n protected fireExtinguisher(a: Extract<WeaponAction, { kind: 'extinguisher' }>, origin: Vec3, dir: Vec3, dt: number): TriggerResult {\n if (this._ammo <= EPS) return result('no_fuel')\n if (dt <= 0) return result('ok')\n const duration = Math.min(dt, this._ammo)\n this._ammo -= duration\n return result('ok', { uses: [{ kind: 'extinguish', range: a.range, coolC: a.coolC, duration, origin, direction: dir }], noise: a.noise })\n }\n\n /** The fuse of this throw: sampled from the explosive when it has a range or a burn, else the fixed one of the action. */\n protected sampleThrowFuse(a: Extract<WeaponAction, { kind: 'throwable' }>): number {\n return (this.explosive ? sampleFuse(this.explosive, this.fuseRng, this.fuseLengthOverride) : undefined) ?? a.fuse\n }\n\n protected throwUse(a: Extract<WeaponAction, { kind: 'throwable' }>, origin: Vec3, dir: Vec3, fuse: number, extra: { cooked?: number; inHand?: boolean } = {}): TriggerResult {\n return result('ok', { uses: [throwableUse({ action: a, explosive: this.explosive, origin, direction: dir, fuse, rules: this.rules.explosives, ...extra })], noise: a.noise })\n }\n\n /** A timer throwable is cooked from the pull; impact, remote and wire ones (and a long fuse that sets down) act at once. */\n protected fireThrowable(a: Extract<WeaponAction, { kind: 'throwable' }>, origin: Vec3, dir: Vec3, held: boolean, start: number, end: number): TriggerResult {\n if (this.cook) return this.cookStep(a, origin, dir, end)\n if (!this.oncePerPull(held)) return result('cooldown')\n if (this._ammo <= 0) return result('empty')\n const fuse = this.sampleThrowFuse(a)\n if (fuse <= 0 || isPlaced(this.explosive, fuse, this.rules.explosives)) {\n this._ammo -= 1\n return this.throwUse(a, origin, dir, fuse)\n }\n this.cook = { start, fuse, origin, direction: dir }\n this.emit({ type: 'cook', phase: 'start', fuse, at: start })\n return this.cookStep(a, origin, dir, end)\n }\n\n /** The trigger stays down on a cooked throwable: nothing happens until the fuse runs out in the hand. */\n protected cookStep(a: Extract<WeaponAction, { kind: 'throwable' }>, origin: Vec3, dir: Vec3, now: number): TriggerResult {\n const cook = this.cook as NonNullable<WeaponCore['cook']>\n cook.origin = origin\n cook.direction = dir\n if (now - cook.start < cook.fuse - EPS) return result('ok')\n return this.burstInHand(a, cook, origin, dir)\n }\n\n protected burstInHand(a: Extract<WeaponAction, { kind: 'throwable' }>, cook: NonNullable<WeaponCore['cook']>, origin: Vec3, dir: Vec3): TriggerResult {\n this.cook = null\n this._ammo -= 1\n this.emit({ type: 'cook', phase: 'burst', fuse: 0, at: cook.start + cook.fuse })\n return this.throwUse(a, origin, dir, 0, { cooked: cook.fuse, inHand: true })\n }\n\n release(origin?: Vec3, direction?: Vec3): TriggerResult | null {\n super.release()\n const cook = this.cook\n const a = this.action\n if (!cook || a.kind !== 'throwable') return null\n const from = origin ?? cook.origin\n const dir = direction ? normalize(direction) : cook.direction\n const held = this.clock - cook.start\n if (held >= cook.fuse - EPS) return this.burstInHand(a, cook, from, dir)\n this.cook = null\n this._ammo -= 1\n const remaining = cook.fuse - held\n this.emit({ type: 'cook', phase: 'throw', fuse: remaining, at: this.clock })\n return this.throwUse(a, from, dir, remaining, { cooked: held })\n }\n}\n","import attachmentsJson from './data/attachments.json'\nimport archetypesJson from './data/archetypes.json'\nimport calibersJson from './data/calibers.json'\nimport explosivesJson from './data/explosives.json'\nimport explosiveWeaponsJson from './data/explosive-weapons.json'\nimport firearmsJson from './data/firearms.json'\nimport launchersJson from './data/launchers.json'\nimport { canFit as canFitAttachment } from './attachments'\nimport { checkArsenal, findDuplicateIds } from './check-arsenal'\nimport { resolveStrings } from './locale'\nimport { deepMerge } from './merge'\nimport { applyPatches, mergeById, removeIds, resolveThrowables } from './registry'\nimport { DEFAULT_RULES } from './rules'\nimport type { AttachmentDef, FittedAttachment, MountKind, WeaponSnapshot } from './attachment-types'\nimport type { Arsenal, ArsenalOptions, CaliberDef, CaliberId, ExplosiveDef, WeaponCategory, WeaponDef, WeaponId, WeaponState } from './types'\nimport { createExplosiveBody } from './explosive-body'\nimport { muzzleEnergy, WeaponRuntime } from './weapon'\n\nexport const CALIBERS = calibersJson as unknown as CaliberDef[]\nexport const ATTACHMENTS = attachmentsJson as unknown as AttachmentDef[]\nexport const EXPLOSIVES = explosivesJson as unknown as ExplosiveDef[]\n/** The generic weapons: handling numbers (spread, bloom, range, recoil) by type, which the real models point to through `archetype`. */\nconst ARCHETYPES = archetypesJson as unknown as WeaponDef[]\nexport const ARCHETYPE_IDS: readonly WeaponId[] = ARCHETYPES.map((def) => def.id)\nexport const WEAPONS: WeaponDef[] = [...ARCHETYPES, ...(firearmsJson as unknown as WeaponDef[]), ...(launchersJson as unknown as WeaponDef[]), ...(explosiveWeaponsJson as unknown as WeaponDef[])]\n\n/** A reasonable starting kit for a test room or a sandbox. */\nexport const DEFAULT_LOADOUT: WeaponId[] = [\n 'hand', 'kick', 'shove', 'pistol_9mm', 'revolver_357', 'shotgun_pump_12', 'rifle_5_56', 'rifle_bolt_308', 'hammer', 'axe', 'machete', 'utility_knife', 'crowbar', 'lighter', 'flamethrower',\n 'cutting_torch', 'molotov', 'frag_grenade', 'screwdriver', 'wrench', 'pry_bar', 'hacksaw', 'extinguisher',\n]\n\nexport { muzzleEnergy, checkArsenal }\n\nconst explosiveOf = (def: WeaponDef, explosives: ReadonlyMap<string, ExplosiveDef>): ExplosiveDef | null => {\n const id = def.action.kind === 'launcher' ? def.action.projectile : def.action.kind === 'throwable' ? def.action.explosive : undefined\n return id === undefined ? null : explosives.get(id) ?? null\n}\n\nconst energyOf = (def: WeaponDef, calibers: ReadonlyMap<CaliberId, CaliberDef>, explosives: ReadonlyMap<string, ExplosiveDef>): number => {\n const action = def.action\n if (action.kind === 'firearm') {\n const caliber = calibers.get(action.caliber)\n const speed = action.muzzleSpeed ?? (caliber?.muzzleSpeed ?? 0) * (action.barrel ?? 1)\n return 0.5 * ((caliber?.bulletGrams ?? 0) / 1000) * speed * speed\n }\n if (action.kind === 'launcher') return explosives.get(action.projectile)?.energy ?? 0\n return action.kind === 'throwable' || action.kind === 'melee' ? action.energy : 0\n}\n\n/** A shipped grenade launcher accessory goes when its launcher was removed or filtered out (one the game added itself is left for `checkArsenal` to report). */\nconst dropOrphanLaunchers = (attachments: Map<string, AttachmentDef>, weapons: ReadonlyMap<WeaponId, WeaponDef>, added: readonly AttachmentDef[] | undefined): void => {\n const addedIds = new Set((added ?? []).map((attachment) => attachment.id))\n for (const [id, attachment] of attachments) if (attachment.launcher !== undefined && !addedIds.has(id) && !weapons.has(attachment.launcher)) attachments.delete(id)\n}\n\n/**\n * Create an arsenal. Order: the shipped entries, then `calibers`/`weapons`/`explosives` (added or replaced by id), then `patch`, then `remove`, then `include`;\n * a throwable that names an explosive follows that explosive. Every inconsistency found is reported in one error.\n */\nexport const createArsenal = (options: ArsenalOptions = {}): Arsenal => {\n const calibers = mergeById(CALIBERS, options.calibers)\n const explosives = mergeById(EXPLOSIVES, options.explosives)\n const weapons = mergeById(WEAPONS, options.weapons)\n const attachments = mergeById(ATTACHMENTS, options.attachments)\n applyPatches(calibers, options.patch?.calibers)\n applyPatches(explosives, options.patch?.explosives)\n applyPatches(attachments, options.patch?.attachments)\n resolveThrowables(weapons, explosives)\n applyPatches(weapons, options.patch?.weapons)\n removeIds(calibers, options.remove?.calibers)\n removeIds(explosives, options.remove?.explosives)\n removeIds(attachments, options.remove?.attachments)\n removeIds(weapons, options.remove?.weapons)\n if (options.include) for (const [id, def] of weapons) if (!options.include(def)) weapons.delete(id)\n dropOrphanLaunchers(attachments, weapons, options.attachments)\n\n const rules = deepMerge(DEFAULT_RULES, options.rules)\n const problems = [\n ...findDuplicateIds('calibre', options.calibers),\n ...findDuplicateIds('weapon', options.weapons),\n ...findDuplicateIds('explosive', options.explosives),\n ...findDuplicateIds('attachment', options.attachments),\n ...checkArsenal({ weapons, calibers, explosives, attachments, rules }),\n ]\n if (problems.length > 0) throw new Error(`game-weapons: the arsenal is not consistent:\\n${problems.map((problem) => ` - ${problem}`).join('\\n')}`)\n\n const strings = resolveStrings(options.locale, options.strings)\n const baseSeed = options.seed ?? 1\n let counter = 0\n\n const create = (id: WeaponId, opts: { seed?: number; reserve?: number; condition?: string; ammoQuality?: string; snapshot?: WeaponSnapshot } = {}): WeaponState => {\n const def = weapons.get(id)\n if (!def) throw new Error(`game-weapons: unknown weapon \"${id}\"`)\n const caliber = def.action.kind === 'firearm' ? calibers.get(def.action.caliber) ?? null : null\n counter += 1\n const seed = opts.seed ?? (baseSeed + Math.imul(counter, 0x9e3779b1)) >>> 0\n const explosive = explosiveOf(def, explosives)\n return new WeaponRuntime({ def, caliber, seed, reserve: opts.reserve, rules, explosive, condition: opts.condition, ammoQuality: opts.ammoQuality, attachments, isCompatible: options.isCompatible, snapshot: opts.snapshot, makeUnderbarrel: (launcherId, launcherSeed, launcherSnapshot) => create(launcherId, { seed: launcherSeed, snapshot: launcherSnapshot }) })\n }\n\n return {\n calibers,\n weapons,\n explosives,\n attachments,\n rules,\n create,\n canFit(weapon, attachment, opts = {}) {\n const def = weapons.get(weapon)\n if (!def) throw new Error(`game-weapons: unknown weapon \"${weapon}\"`)\n const part = attachments.get(attachment)\n if (!part) throw new Error(`game-weapons: unknown attachment \"${attachment}\"`)\n const caliber = def.action.kind === 'firearm' ? calibers.get(def.action.caliber) ?? null : null\n const fitted: readonly FittedAttachment[] = opts.fitted ?? def.fitted ?? []\n return canFitAttachment(def, part, fitted, { caliber, catalogue: attachments, isCompatible: options.isCompatible }, opts.mount as MountKind | undefined)\n },\n restore(snapshot, opts = {}) {\n return create(snapshot.id, { seed: opts.seed, reserve: snapshot.reserve, condition: snapshot.condition, ammoQuality: snapshot.ammoQuality, snapshot })\n },\n muzzleEnergy(caliber, barrel = 1) {\n const c = calibers.get(caliber)\n if (!c) throw new Error(`game-weapons: unknown calibre \"${caliber}\"`)\n return muzzleEnergy(c, barrel)\n },\n explosiveBody(use) {\n return createExplosiveBody(use, explosives, rules.explosives)\n },\n energy(id) {\n const def = weapons.get(id)\n if (!def) throw new Error(`game-weapons: unknown weapon \"${id}\"`)\n return energyOf(def, calibers, explosives)\n },\n name(id) {\n const weapon = weapons.get(id)\n if (weapon) return strings.weapons[id] ?? weapon.name ?? id\n return strings.explosives[id] ?? explosives.get(id)?.name ?? strings.modes[id] ?? strings.categories[id] ?? strings.faults[id] ?? strings.conditions[id] ?? calibers.get(id)?.label ?? attachments.get(id)?.name ?? id\n },\n list(category?: WeaponCategory) {\n const all = [...weapons.values()]\n return category ? all.filter((w) => w.category === category) : all\n },\n }\n}\n","import type { Detonation } from './explosive-body'\nimport { normalize } from './rng'\nimport type { Use, Vec3 } from './types'\nimport { dot, length, subtract } from './vec'\n\nexport interface BlastEffect {\n /** `lethal` kills and dismembers, `injury` wounds, `none` is out of reach (or behind a directional charge). */\n readonly zone: 'lethal' | 'injury' | 'none'\n readonly distance: number\n /** 1 in the lethal zone, falling linearly to 0 at the edge of the injury zone. */\n readonly falloff: number\n /** Seconds of stun for whoever is in reach (flashbang). */\n readonly stunSeconds: number\n}\n\nconst OUT_OF_REACH: BlastEffect = { zone: 'none', distance: Infinity, falloff: 0, stunSeconds: 0 }\n\nconst insideCone = (offset: Vec3, facing: Vec3, halfAngleDeg: number): boolean => {\n const distance = length(offset)\n if (distance <= 1e-9) return true\n return dot(offset, normalize(facing)) / distance >= Math.cos((halfAngleDeg * Math.PI) / 180)\n}\n\n/** What a detonation does to something at `target`: the zone, how hard, and the stun. A directional charge only reaches inside its cone. */\nexport const blastEffect = (detonation: Detonation, target: Vec3): BlastEffect => {\n const offset = subtract(target, detonation.point)\n const distance = length(offset)\n const { lethalRadius, injuryRadius, cone } = detonation\n const reach = cone ? Math.min(injuryRadius, cone.length) : injuryRadius\n if (distance > reach) return OUT_OF_REACH\n if (cone && !insideCone(offset, detonation.direction, cone.halfAngleDeg)) return OUT_OF_REACH\n const stunSeconds = detonation.stunSeconds ?? 0\n if (distance <= lethalRadius) return { zone: 'lethal', distance, falloff: 1, stunSeconds }\n const span = reach - lethalRadius\n return { zone: 'injury', distance, falloff: span > 0 ? 1 - (distance - lethalRadius) / span : 1, stunSeconds }\n}\n\n/** How much of the blast behind a launcher reaches `target`: 0 outside the cone or the radius, falling linearly from 1 at the tube. */\nexport const backblastEffect = (use: Extract<Use, { kind: 'backblast' }>, target: Vec3): number => {\n const offset = subtract(target, use.origin)\n const distance = length(offset)\n if (distance > use.radius || !insideCone(offset, use.direction, use.halfAngleDeg)) return 0\n return 1 - distance / use.radius\n}\n\nexport interface TripwireSegment {\n readonly from: Vec3\n readonly to: Vec3\n}\n\n/**\n * Where the wire of a charge set down with `use` runs: from the charge, `length` metres along the horizontal facing turned by `angleDeg`\n * (counter-clockwise seen from above), `height` metres above it. Null for a charge with no wire.\n */\nexport const tripwireSegment = (use: Extract<Use, { kind: 'place' }>): TripwireSegment | null => {\n const wire = use.tripwire\n if (!wire) return null\n const facing = normalize([use.direction[0], 0, use.direction[2]])\n const angle = (wire.angleDeg * Math.PI) / 180\n const dx = facing[0] * Math.cos(angle) + facing[2] * Math.sin(angle)\n const dz = -facing[0] * Math.sin(angle) + facing[2] * Math.cos(angle)\n const from: Vec3 = [use.origin[0], use.origin[1] + wire.height, use.origin[2]]\n return { from, to: [from[0] + dx * wire.length, from[1], from[2] + dz * wire.length] }\n}\n","import type { HostToolAttachment } from '@adatechnology/game-contracts'\n\n/** A cheap identity of what is on the weapon (count, ids, mounts and which are on), compared every frame in place of serializing the whole list. */\nexport const attachmentsKey = (parts: readonly HostToolAttachment[] | undefined): string => {\n if (!parts) return ''\n let key = String(parts.length)\n for (const part of parts) key += `|${part.id}@${part.mount}${part.on ? '+' : ''}`\n return key\n}\n","import type * as THREE_NS from 'three'\nimport type { BenchChange, ChoiceOption, HostTool, HostToolAttachment, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, ToolCommand } from '@adatechnology/game-contracts'\nimport type { Arsenal, FittedAttachment, MountKind } from '@adatechnology/game-weapons'\nimport { attachmentsKey } from './attachments-key'\nimport type { AccessoryText } from './accessory-text'\n\n/** The places of a weapon the bench offers accessories for, in the order the panel lists them. */\nexport const ACCESSORY_MOUNTS: readonly MountKind[] = ['muzzle', 'rail_top', 'rail_left', 'rail_right', 'rail_bottom', 'underbarrel', 'magazine', 'feed', 'sling', 'barrel']\n/** Keys of the accessories. V (the stock) is the room's kick when the weapon has no stock that moves; the others are free in the room. */\nexport const ACCESSORY_KEYS = { light: 'KeyL', laser: 'KeyK', stock: 'KeyV', underbarrel: 'KeyU' } as const\nconst FIT_PREFIX = 'fit_'\nconst NONE = 'none'\nexport const SUPPORTED_CONTROL_ID = 'supported_stance'\nconst ACTION_IDS = { light: 'toggle_light', laser: 'toggle_laser', stock: 'toggle_stock', underbarrel: 'switch_underbarrel' } as const\nconst SECONDARY_BUTTON = 2\nconst TEXT_FIELDS = new Set(['INPUT', 'TEXTAREA', 'SELECT'])\n\nexport const accessoryControls = (text: AccessoryText): ModuleControl[] => [\n ...ACCESSORY_MOUNTS.map((mount): ModuleControl => ({ kind: 'choice', id: `${FIT_PREFIX}${mount}`, name: text.mounts[mount] ?? mount, options: [{ id: NONE, name: text.none }], default: NONE })),\n { kind: 'boolean', id: SUPPORTED_CONTROL_ID, name: text.supported.name, hint: text.supported.hint, default: false },\n ...(Object.keys(ACTION_IDS) as Array<keyof typeof ACTION_IDS>).map((key): ModuleControl => ({ kind: 'action', id: ACTION_IDS[key], name: text.actions[key].name, hint: text.actions[key].hint })),\n]\n\nexport const accessoryLayers = (text: AccessoryText): ModuleLayer[] => [\n { id: 'attachments', name: text.layers.attachments },\n { id: 'beams', name: text.layers.beams },\n]\n\nexport const accessoryMetrics = (text: AccessoryText, tool: () => HostTool): ModuleMetric[] => [\n { id: 'weapon_mass', name: text.metrics.mass, unit: 'kg', digits: 2, read: () => tool().mass ?? 0 },\n { id: 'aim_time', name: text.metrics.aim, unit: 's', digits: 2, read: () => tool().aimSeconds ?? 0 },\n { id: 'accessories_fitted', name: text.metrics.fitted, digits: 0, read: () => (tool().attachments ?? []).length },\n { id: 'suppressed', name: text.metrics.suppressed, read: () => (tool().suppressed ? text.yes : text.no) },\n]\n\nexport interface AccessoryBenchOptions {\n readonly arsenal: Arsenal\n readonly host: ModuleHost\n readonly text: AccessoryText\n}\n\nexport interface AccessoryBench {\n /** Gives it a change of the bench (a choice of accessory for a mount, a button); false when the change is not one of its own. */\n handleChange(change: BenchChange): boolean\n dispose(): void\n}\n\nconst fittedOf = (parts: readonly HostToolAttachment[] | undefined): FittedAttachment[] =>\n (parts ?? []).map((part) => ({ id: part.id, mount: part.mount as MountKind, ...(part.integral ? { integral: true } : {}), ...(part.on === undefined ? {} : { on: part.on }) }))\n\nconst fillText = (template: string, vars: Record<string, string>): string => template.replace(/\\{(\\w+)\\}/g, (_, key: string) => vars[key] ?? '')\n\n/**\n * The accessory bench of the weapons area: a choice per mount that fits and removes what is compatible with the weapon in hand (and only that), the keys of the light (L), the laser (K),\n * the stock (V) and the launcher under the barrel (U), and the right mouse button, which aims: the camera zooms by the optic that is fitted, over the seconds the weapon takes to the sights.\n */\nexport function createAccessoryBench(options: AccessoryBenchOptions): AccessoryBench {\n const { arsenal, host, text } = options\n const camera = host.camera as THREE_NS.PerspectiveCamera\n const bench = host.bench\n const pending = new Map<MountKind, string>()\n let signature = ''\n let aiming = false\n let aimProgress = 0\n let baseFov = camera.fov\n let appliedZoom = 1\n\n const nameOf = (id: string): string => text.attachments[id] ?? arsenal.attachments.get(id)?.name ?? id\n\n const offers = (tool: HostTool, mount: MountKind): ChoiceOption[] => {\n const fitted = fittedOf(tool.attachments)\n const here = fitted.find((part) => part.mount === mount)\n const choices: ChoiceOption[] = [{ id: NONE, name: text.none }]\n if (here) choices.push({ id: here.id, name: nameOf(here.id) })\n for (const def of arsenal.attachments.values()) {\n if (def.id === here?.id || !arsenal.canFit(tool.weapon, def.id, { fitted, mount }).ok) continue\n choices.push({ id: def.id, name: nameOf(def.id) })\n }\n return choices\n }\n\n const refresh = (): void => {\n const tool = host.tool()\n const next = `${tool.weapon}|${attachmentsKey(tool.attachments)}`\n if (next === signature) return\n signature = next\n const def = arsenal.weapons.get(tool.weapon)\n for (const mount of ACCESSORY_MOUNTS) {\n const has = (def?.mounts ?? []).some((place) => place.kind === mount)\n const here = (tool.attachments ?? []).find((part) => part.mount === mount)\n const choices = offers(tool, mount)\n const isFixed = here?.integral === true\n bench?.patch(`${FIT_PREFIX}${mount}`, { hidden: !has, disabled: isFixed, options: choices, ...(pending.has(mount) ? {} : { value: here?.id ?? NONE }) })\n }\n }\n\n const refuse = (mount: MountKind, reason: string | undefined): void => {\n host.log(fillText(text.fitRefused, { mount: text.mounts[mount] ?? mount, weapon: arsenal.name(host.tool().weapon), reason: reason ?? '' }), { mount, reason })\n pending.delete(mount)\n signature = ''\n }\n\n const settle = (): void => {\n for (const [mount, wanted] of pending) {\n const here = (host.tool().attachments ?? []).find((part) => part.mount === mount && !part.integral)\n if (here?.id === wanted || (!here && wanted === NONE)) {\n pending.delete(mount)\n continue\n }\n const request: ToolCommand = here ? { type: 'remove', attachment: here.id } : { type: 'fit', attachment: wanted, mount }\n const result = host.command?.(request)\n if (!result || (!result.ok && result.reason !== 'busy')) refuse(mount, result?.reason)\n if (result?.reason === 'busy') return\n }\n }\n\n const toggleKind = (kind: 'light' | 'laser'): void => {\n const part = (host.tool().attachments ?? []).find((candidate) => arsenal.attachments.get(candidate.id)?.kind === kind)\n if (!part) host.log(kind === 'light' ? text.noLight : text.noLaser)\n else host.command?.({ type: 'toggle', attachment: part.id })\n }\n\n const toggleStock = (): boolean => {\n const tool = host.tool()\n const kind = arsenal.weapons.get(tool.weapon)?.stock?.kind\n if (kind === undefined || kind === 'fixed' || kind === 'none') return false\n host.command?.({ type: 'stock', state: tool.stock === 'collapsed' ? 'extended' : 'collapsed' })\n return true\n }\n\n const switchUnderbarrel = (): void => {\n const tool = host.tool()\n const hasLauncher = (tool.attachments ?? []).some((part) => arsenal.attachments.get(part.id)?.launcher !== undefined)\n if (!hasLauncher) host.log(text.noLauncher)\n else host.command?.({ type: 'underbarrel', on: tool.underbarrelActive !== true })\n }\n\n const act = (id: string): boolean => {\n if (id === ACTION_IDS.light) toggleKind('light')\n else if (id === ACTION_IDS.laser) toggleKind('laser')\n else if (id === ACTION_IDS.stock) {\n if (!toggleStock()) host.log(text.noStock)\n } else if (id === ACTION_IDS.underbarrel) switchUnderbarrel()\n else return false\n return true\n }\n\n const zoomOf = (tool: HostTool): number => {\n const optic = (tool.attachments ?? []).map((part) => arsenal.attachments.get(part.id)?.optic).find((entry) => entry !== undefined)\n return optic?.zoom[0] ?? 1\n }\n\n const isFirearm = (tool: HostTool): boolean => arsenal.weapons.get(tool.weapon)?.action.kind === 'firearm'\n\n const setAim = (on: boolean): void => {\n if (on === aiming) return\n aiming = on\n host.command?.({ type: 'stance', aiming: on })\n }\n\n const follow = (dt: number): void => {\n const tool = host.tool()\n const seconds = Math.max(0.05, tool.aimSeconds ?? 0.2)\n aimProgress = Math.max(0, Math.min(1, aimProgress + (aiming ? dt : -dt) / seconds))\n const zoom = 1 + (zoomOf(tool) - 1) * aimProgress\n if (Math.abs(zoom - appliedZoom) < 1e-4) return\n if (appliedZoom === 1) baseFov = camera.fov\n appliedZoom = zoom\n camera.fov = zoom === 1 ? baseFov : (2 * Math.atan(Math.tan((baseFov * Math.PI) / 360) / zoom) * 180) / Math.PI\n camera.updateProjectionMatrix()\n }\n\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.repeat || event.ctrlKey || event.metaKey || event.altKey || TEXT_FIELDS.has((event.target as HTMLElement | null)?.tagName ?? '')) return\n const handled = event.code === ACCESSORY_KEYS.light ? act(ACTION_IDS.light) : event.code === ACCESSORY_KEYS.laser ? act(ACTION_IDS.laser) : event.code === ACCESSORY_KEYS.underbarrel ? act(ACTION_IDS.underbarrel) : event.code === ACCESSORY_KEYS.stock && toggleStock()\n if (!handled) return\n event.preventDefault()\n event.stopImmediatePropagation()\n }\n // only the room's own surface aims: a click on a panel, an input or an overlay is left alone\n const isOnRoom = (event: MouseEvent): boolean => Boolean(document.pointerLockElement) || event.target instanceof HTMLCanvasElement\n const onMouseDown = (event: MouseEvent): void => {\n if (event.button !== SECONDARY_BUTTON || !isOnRoom(event) || !isFirearm(host.tool())) return\n event.preventDefault()\n event.stopImmediatePropagation()\n setAim(true)\n }\n const onMouseUp = (event: MouseEvent): void => {\n if (event.button === SECONDARY_BUTTON) setAim(false)\n }\n const onBlur = (): void => setAim(false)\n\n // capture phase: the room grabs on the right button and kicks on V, and these win only where the weapon in hand has something to do with them\n window.addEventListener('keydown', onKeyDown, true)\n window.addEventListener('mousedown', onMouseDown, true)\n window.addEventListener('mouseup', onMouseUp)\n window.addEventListener('blur', onBlur)\n const offFrame = host.onFrame((dt) => {\n refresh()\n settle()\n follow(dt)\n })\n const offEvents = host.on((event) => {\n if (event.type === 'attachment') {\n const template = event.action === 'fit' ? text.fitting : event.action === 'remove' ? text.removing : text.broke\n host.log(fillText(template, { attachment: nameOf(event.attachment), weapon: arsenal.name(event.weapon), seconds: String(event.duration ?? 0) }), { attachment: event.attachment, action: event.action })\n }\n if (event.type !== 'tool') return\n pending.clear()\n setAim(false)\n bench?.patch(SUPPORTED_CONTROL_ID, { value: false })\n signature = ''\n })\n\n return {\n handleChange(change) {\n if (change.kind === 'action') return act(change.id)\n if (change.kind === 'control' && change.id === SUPPORTED_CONTROL_ID && typeof change.value === 'boolean') {\n host.command?.({ type: 'stance', supported: change.value })\n return true\n }\n if (change.kind !== 'control' || !change.id.startsWith(FIT_PREFIX) || typeof change.value !== 'string') return false\n const mount = change.id.slice(FIT_PREFIX.length) as MountKind\n pending.set(mount, change.value)\n settle()\n return true\n },\n dispose() {\n offFrame()\n offEvents()\n window.removeEventListener('keydown', onKeyDown, true)\n window.removeEventListener('mousedown', onMouseDown, true)\n window.removeEventListener('mouseup', onMouseUp)\n window.removeEventListener('blur', onBlur)\n if (appliedZoom !== 1) {\n camera.fov = baseFov\n camera.updateProjectionMatrix()\n }\n },\n }\n}\n","/** The words of the accessory bench, by locale (`en` and `pt-BR`). */\nexport interface AccessoryText {\n none: string\n mounts: Record<string, string>\n actions: Record<'light' | 'laser' | 'stock' | 'underbarrel', { name: string; hint: string }>\n layers: Record<'attachments' | 'beams', string>\n supported: { name: string; hint: string }\n metrics: Record<'mass' | 'aim' | 'fitted' | 'suppressed', string>\n yes: string\n no: string\n attachments: Record<string, string>\n fitRefused: string\n fitting: string\n removing: string\n broke: string\n noLight: string\n noLaser: string\n noStock: string\n noLauncher: string\n}\n\nexport const ACCESSORY_TEXT: Record<string, AccessoryText> = {\n en: {\n none: 'None',\n mounts: { muzzle: 'Muzzle', rail_top: 'Top rail', rail_left: 'Left rail', rail_right: 'Right rail', rail_bottom: 'Bottom rail', underbarrel: 'Under the barrel', magazine: 'Magazine', feed: 'Feed (backpack)', sling: 'Sling', barrel: 'Barrel' },\n actions: {\n light: { name: 'Light on/off (L)', hint: 'Turns the weapon light on or off' },\n laser: { name: 'Laser on/off (K)', hint: 'Turns the laser sight on or off' },\n stock: { name: 'Fold or open the stock (V)', hint: 'Folds or slides the stock in, or opens it' },\n underbarrel: { name: 'Launcher under the barrel (U)', hint: 'Switches the trigger and the reload between the weapon and the launcher under its barrel' },\n },\n layers: { attachments: 'Accessory models', beams: 'Light cone and laser beam' },\n supported: { name: 'Supported (deployed / prone)', hint: 'The weapon rests on something: a bipod then takes its recoil and spread effect' },\n metrics: { mass: 'Weapon mass', aim: 'Time to the sights', fitted: 'Accessories on the weapon', suppressed: 'Suppressed' },\n yes: 'yes',\n no: 'no',\n attachments: {},\n fitRefused: 'Could not change {mount} of {weapon}: {reason}',\n fitting: 'Fitting {attachment} on {weapon} ({seconds} s)',\n removing: 'Taking {attachment} off {weapon} ({seconds} s)',\n broke: '{attachment} broke on {weapon}',\n noLight: 'No light on this weapon',\n noLaser: 'No laser on this weapon',\n noStock: 'This weapon has no stock that folds or slides',\n noLauncher: 'No launcher under the barrel of this weapon',\n },\n 'pt-BR': {\n none: 'Nenhum',\n mounts: { muzzle: 'Boca do cano', rail_top: 'Trilho superior', rail_left: 'Trilho esquerdo', rail_right: 'Trilho direito', rail_bottom: 'Trilho inferior', underbarrel: 'Sob o cano', magazine: 'Carregador', feed: 'Alimentação (mochila)', sling: 'Bandoleira', barrel: 'Cano' },\n actions: {\n light: { name: 'Ligar/desligar a lanterna (L)', hint: 'Liga ou desliga a lanterna da arma' },\n laser: { name: 'Ligar/desligar o laser (K)', hint: 'Liga ou desliga o laser da arma' },\n stock: { name: 'Dobrar ou abrir a coronha (V)', hint: 'Dobra ou recolhe a coronha, ou a abre' },\n underbarrel: { name: 'Lança-granada sob o cano (U)', hint: 'Passa o gatilho e a recarga entre a arma e o lança-granada sob o cano' },\n },\n layers: { attachments: 'Modelos dos acessórios', beams: 'Cone da lanterna e feixe do laser' },\n supported: { name: 'Apoiado (bipé aberto / deitado)', hint: 'A arma está apoiada: o bipé passa a valer no recuo e na dispersão' },\n metrics: { mass: 'Massa da arma', aim: 'Tempo até a mira', fitted: 'Acessórios na arma', suppressed: 'Silenciada' },\n yes: 'sim',\n no: 'não',\n attachments: {\n suppressor: 'Supressor',\n oil_filter_suppressor: 'Supressor de filtro de óleo',\n integral_suppressor: 'Supressor integrado',\n muzzle_brake: 'Freio de boca',\n muzzle_brake_heavy: 'Freio de boca pesado',\n compensator: 'Compensador',\n red_dot: 'Mira red dot',\n holographic_sight: 'Mira holográfica',\n acog_4x: 'ACOG 4×',\n scope_3_9x: 'Luneta 3–9×',\n scope_6_24x: 'Luneta 6–24×',\n night_vision_scope: 'Mira noturna',\n thermal_scope: 'Mira térmica',\n integral_optic_1_5x: 'Mira integrada 1,5×',\n integral_optic_3x: 'Mira integrada 3×',\n pso_1: 'Mira PSO-1',\n fixed_scope_10x: 'Luneta fixa 10×',\n vertical_grip: 'Empunhadura vertical',\n bipod: 'Bipé',\n m203: 'Lança-granada M203',\n gp_25: 'Lança-granada GP-25',\n ag36: 'Lança-granada AG36',\n weapon_light: 'Lanterna',\n laser_sight: 'Laser',\n extended_magazine: 'Carregador estendido',\n drum_magazine: 'Carregador tambor',\n dual_coupler: 'Acoplador de carregadores',\n sawn_off_barrel: 'Cano serrado',\n long_barrel: 'Cano longo',\n sling: 'Bandoleira',\n ammo_backpack: 'Mochila de munição',\n tripod: 'Tripé',\n },\n fitRefused: 'Não deu para mudar {mount} de {weapon}: {reason}',\n fitting: 'Encaixando {attachment} em {weapon} ({seconds} s)',\n removing: 'Tirando {attachment} de {weapon} ({seconds} s)',\n broke: '{attachment} quebrou em {weapon}',\n noLight: 'Esta arma não tem lanterna',\n noLaser: 'Esta arma não tem laser',\n noStock: 'Esta arma não tem coronha que dobre ou recolha',\n noLauncher: 'Esta arma não tem lança-granada sob o cano',\n },\n}\n\nexport const accessoryTextOf = (locale: string): AccessoryText => ACCESSORY_TEXT[locale] ?? (ACCESSORY_TEXT.en as AccessoryText)\n","import type { ReloadStageId, WeaponEvent } from '@adatechnology/game-weapons'\n\nimport type { GAME_SOUND_CLASSES } from './shot-sound'\n\n/** One layer of a mechanical sound; `at` is seconds after the start. */\nexport type SoundStep =\n /** Metal click: a short high noise plus a square tone at 0.6 × the frequency (the SDK synth, as before). */\n | { readonly layer: 'metal'; readonly at: number; readonly frequency: number; readonly gain: number }\n /** A sound class of the game (`recarga`, `vazio`...) played at a volume. */\n | { readonly layer: 'class'; readonly at: number; readonly soundClass: keyof typeof GAME_SOUND_CLASSES; readonly volume: number }\n /** Dull landing: lowpass noise. */\n | { readonly layer: 'thud'; readonly at: number; readonly gain: number; readonly frequency: number }\n\nexport type MechanicalSoundId =\n | ReloadStageId\n | 'dry_fire'\n | 'misfire'\n | 'feed'\n | 'cycle'\n | 'mode'\n | 'safety_on'\n | 'safety_off'\n | 'jam'\n | 'clear_start'\n | 'clear_end'\n | 'stock_fold'\n | 'light_click'\n | 'attach'\n\nconst metal = (at: number, frequency: number, gain: number): SoundStep => ({ layer: 'metal', at, frequency, gain })\nconst sound = (at: number, soundClass: keyof typeof GAME_SOUND_CLASSES, volume: number): SoundStep => ({ layer: 'class', at, soundClass, volume })\nconst thud = (at: number, gain: number, frequency: number): SoundStep => ({ layer: 'thud', at, gain, frequency })\n\nconst slide = [metal(0, 900, 0.35), metal(0.14, 1300, 0.35)]\nconst seat = [metal(0, 1100, 0.45), sound(0, 'reload', 0.8)]\n\n/**\n * Sounds keyed by the rule: the `reload_stage` ids of `RELOAD_STAGES`, plus the other weapon events. The click of an empty weapon and the generic\n * reload tick are the game's `vazio` and `recarga` classes (jogo.js L62101-L62104; played at L68644-L68662); the gallery (sources/armas-itens__galeria-3d-arsenal.js)\n * has no sound, so the metal layers are the SDK synth (the same `metal` used since the first version).\n */\nexport const MECHANICAL_SOUNDS: Readonly<Record<MechanicalSoundId, readonly SoundStep[]>> = {\n dry_fire: [sound(0, 'empty', 1), metal(0, 2600, 0.25)],\n misfire: [sound(0, 'empty', 0.8), metal(0, 2200, 0.2)],\n feed: [metal(0, 1900, 0.2)],\n cycle: [metal(0.22, 900, 0.35), metal(0.36, 1300, 0.35)],\n mode: [metal(0, 2000, 0.15)],\n safety_on: [metal(0, 2200, 0.22)],\n safety_off: [metal(0, 1800, 0.22)],\n jam: [metal(0, 700, 0.4), metal(0.08, 500, 0.35)],\n clear_start: [metal(0, 1000, 0.3)],\n clear_end: [metal(0, 1300, 0.35)],\n stock_fold: [metal(0, 800, 0.3), metal(0.18, 1200, 0.3), thud(0.3, 0.2, 600)],\n light_click: [metal(0, 2400, 0.2), metal(0.03, 1800, 0.12)],\n attach: [metal(0, 1400, 0.35), thud(0.04, 0.2, 700), metal(0.12, 1900, 0.25)],\n magazine_out: [metal(0, 1500, 0.35), sound(0, 'reload', 0.6)],\n magazine_in: seat,\n charge: slide,\n bolt_open: [metal(0, 900, 0.35)],\n round_in: [metal(0, 2000, 0.2), sound(0, 'reload', 0.6)],\n bolt_close: [metal(0, 1300, 0.35)],\n pump_cycle: slide,\n lever_cycle: [metal(0, 1000, 0.35), metal(0.12, 1500, 0.35)],\n cylinder_open: [metal(0, 1500, 0.3)],\n cylinder_eject: [metal(0, 2400, 0.25), metal(0.05, 2800, 0.2)],\n cylinder_load: [metal(0, 2000, 0.2)],\n cylinder_close: seat,\n barrels_open: [metal(0, 1000, 0.4)],\n casings_eject: [metal(0, 2600, 0.25)],\n rounds_in: [metal(0, 2000, 0.25), sound(0, 'reload', 0.6)],\n barrels_close: seat,\n cover_open: [metal(0, 800, 0.4)],\n belt_swap: [metal(0, 1400, 0.3), metal(0.08, 1800, 0.25)],\n cover_close: [metal(0, 1000, 0.45)],\n tank_swap: [thud(0, 0.4, 500), metal(0.05, 600, 0.3)],\n tube_drop: [thud(0, 0.35, 380)],\n tube_seat: seat,\n rocket_seat: [metal(0, 900, 0.45), sound(0, 'reload', 0.8)],\n breech_open: [metal(0, 1000, 0.35)],\n breech_close: seat,\n}\n\n/** Which mechanical sound a weapon event asks for, if any (`shot`, `draw` and `reload` start/end have their own handling). */\nexport const mechanicalSoundOf = (event: WeaponEvent): MechanicalSoundId | undefined => {\n switch (event.type) {\n case 'reload_stage':\n return event.stage\n case 'empty':\n return 'dry_fire'\n case 'misfire':\n return 'misfire'\n case 'feed':\n return 'feed'\n case 'cycle':\n return event.phase === 'start' ? 'cycle' : undefined\n case 'mode':\n return 'mode'\n case 'safety':\n return event.on ? 'safety_on' : 'safety_off'\n case 'fault':\n return 'jam'\n case 'clear':\n return event.phase === 'start' ? 'clear_start' : 'clear_end'\n case 'attachment':\n return event.action === 'break' ? 'jam' : 'attach'\n case 'toggle':\n return 'light_click'\n case 'stock':\n return 'stock_fold'\n case 'underbarrel':\n return 'mode'\n default:\n return undefined\n }\n}\n","import { muzzleEnergy } from '@adatechnology/game-weapons'\nimport type { CaliberDef } from '@adatechnology/game-weapons'\n\n/** One sound of the game: [lowpass cutoff Hz, gain, seconds]. Literal from the `P` table of `sfx` in the game (jogo.js L62101-L62104). */\nexport type SoundClassDef = readonly [cutoff: number, gain: number, seconds: number]\n\n/** The game names are pistola, escopeta, fuzil, rifle, impacto, carne, passo, vidro, madeira, recarga, vazio and explosao. */\nexport const GAME_SOUND_CLASSES = {\n pistol: [1800, 0.9, 0.18],\n shotgun: [900, 1.2, 0.35],\n rifle: [1400, 1.1, 0.28],\n long_rifle: [1100, 1.3, 0.45],\n impact: [2500, 0.25, 0.05],\n flesh: [600, 0.35, 0.08],\n step: [400, 0.08, 0.05],\n glass: [5000, 0.5, 0.3],\n wood: [700, 0.5, 0.2],\n reload: [3000, 0.15, 0.06],\n empty: [4000, 0.12, 0.03],\n explosion: [200, 1.6, 1.4],\n} as const satisfies Record<string, SoundClassDef>\n\n/** `|| [1000, 0.5, 0.1]` of the game (jogo.js L62104), for a class name that is not in the table. */\nexport const FALLBACK_SOUND_CLASS: SoundClassDef = [1000, 0.5, 0.1]\n\n/** The four classes a shot can have: the game picks one by calibre (jogo.js L68697). */\nexport type ShotSoundClass = 'pistol' | 'shotgun' | 'rifle' | 'long_rifle'\n\n/** Distance muffling of the game (jogo.js L62092, L62105): `gain / (1 + d² × gainFalloff)`, `cutoff / (1 + d × cutoffFalloff)`, silent under `minGain`. */\nexport type DistanceCurve = { readonly gainFalloff: number; readonly cutoffFalloff: number; readonly minGain: number }\nexport const GAME_DISTANCE_CURVE: DistanceCurve = { gainFalloff: 0.004, cutoffFalloff: 0.01, minGain: 0.01 }\n\n/**\n * The calibre energy (joules) scales loudness, length and brightness around the class: each factor is `base + span × k`, where k goes from 0 (50 J)\n * to 1 (50 J × 10^spanDecades) on a log scale, divided by the same factor at the class reference energy. So the game calibres sound exactly as in\n * the game, and a lighter or heavier calibre of the same class is quieter and brighter, or louder and duller.\n */\nexport type EnergyCurve = {\n readonly floorJ: number\n readonly spanDecades: number\n readonly gain: readonly [base: number, span: number]\n readonly duration: readonly [base: number, span: number]\n readonly cutoff: readonly [base: number, span: number]\n /** The muzzle crack (high noise) and the body (low thump) follow the energy alone. */\n readonly crackGain: readonly [base: number, span: number]\n readonly bodyGain: readonly [base: number, span: number]\n readonly bodyDuration: readonly [base: number, span: number]\n readonly bodyFrequency: readonly [base: number, span: number]\n}\n\nexport const DEFAULT_ENERGY_CURVE: EnergyCurve = {\n floorJ: 50,\n spanDecades: 2.5,\n gain: [0.7, 0.6],\n duration: [0.75, 0.5],\n cutoff: [1.15, -0.3],\n crackGain: [0.3, 0.4],\n bodyGain: [0.35, 0.4],\n bodyDuration: [0.14, 0.2],\n bodyFrequency: [140, -70],\n}\n\n/** Muzzle energy of the game calibres in the SDK (9x19, 12ga_00buck × pellets, 7_62x39, 7_62x51): where a class sounds exactly as in the game. */\nexport const CLASS_REFERENCE_ENERGY: Readonly<Record<ShotSoundClass, number>> = { pistol: 500, shotgun: 2700, rifle: 2100, long_rifle: 3500 }\n\nexport type ShotSoundOptions = {\n /** Replaces or adds sound classes (the game table is the default). */\n readonly classes?: Readonly<Record<string, SoundClassDef>>\n readonly distance?: Partial<DistanceCurve>\n readonly energy?: Partial<EnergyCurve>\n readonly referenceEnergy?: Partial<Record<ShotSoundClass, number>>\n /** Picks the class of a shot; the default follows the game (shotgun by shell, handguns by category, then by energy). */\n readonly classOf?: (input: ShotSoundInput, energyJ: number) => ShotSoundClass\n /** Class bands by energy (J): below `handgunBelowJ` a pistol, below `rifleBelowJ` a rifle, above that a long rifle. */\n readonly bands?: { readonly handgunBelowJ: number; readonly rifleBelowJ: number }\n readonly suppressor?: { readonly gain: number; readonly cutoff: number; readonly crack: number; readonly body: number }\n readonly indoors?: { readonly duration: number; readonly cutoff: number }\n}\n\nexport type ShotSoundInput = {\n /** The calibre; its energy (× pellets) is used unless `energyJ` is given. */\n readonly caliber?: CaliberDef\n readonly energyJ?: number\n readonly category?: string\n /** Metres from the listener, default 0. */\n readonly distance?: number\n /** Master gain of the game `sfx` (its `vol`), default 1. */\n readonly volume?: number\n readonly suppressed?: boolean\n readonly indoors?: boolean\n}\n\nexport type ShotSound = {\n readonly soundClass: ShotSoundClass\n readonly energyJ: number\n /** False when the shot is under the game's `minGain` at this distance: nothing is played. */\n readonly audible: boolean\n /** The main noise burst: lowpass cutoff Hz, starting gain and the seconds of the exponential tail (to 0.001). */\n readonly cutoff: number\n readonly gain: number\n readonly duration: number\n /** High noise burst of the muzzle. */\n readonly crack: { readonly gain: number; readonly cutoff: number; readonly duration: number }\n /** Low thump that sweeps from `frequency` to `to`. */\n readonly body: { readonly gain: number; readonly frequency: number; readonly to: number; readonly duration: number }\n}\n\nconst HANDGUN_CATEGORIES: ReadonlySet<string> = new Set(['pistol', 'revolver', 'smg'])\nconst SHELL_KINDS: ReadonlySet<string> = new Set(['buck', 'slug', 'birdshot'])\nconst DEFAULT_BANDS = { handgunBelowJ: 1000, rifleBelowJ: 3000 }\nconst DEFAULT_SUPPRESSOR = { gain: 0.3, cutoff: 0.6, crack: 0, body: 0.5 }\nconst DEFAULT_INDOORS = { duration: 1.5, cutoff: 0.85 }\nconst CRACK_CUTOFF = 3000\nconst CRACK_SECONDS = 0.03\nconst BODY_TO_FREQUENCY = 40\n\nconst linear = ([base, span]: readonly [number, number], k: number): number => base + span * k\n\nconst energyPosition = (energyJ: number, curve: EnergyCurve): number =>\n Math.min(1, Math.max(0, Math.log10(Math.max(energyJ, curve.floorJ) / curve.floorJ) / curve.spanDecades))\n\nexport const energyOfShot = (input: ShotSoundInput): number => {\n if (input.energyJ !== undefined) return input.energyJ\n if (!input.caliber) return 0\n return muzzleEnergy(input.caliber) * (input.caliber.pellets ?? 1)\n}\n\nconst defaultClassOf = (input: ShotSoundInput, energyJ: number, bands: { handgunBelowJ: number; rifleBelowJ: number }): ShotSoundClass => {\n if (input.category === 'shotgun' || (input.caliber?.pellets ?? 1) > 1 || SHELL_KINDS.has(input.caliber?.kind ?? '')) return 'shotgun'\n if (input.category && HANDGUN_CATEGORIES.has(input.category)) return 'pistol'\n if (energyJ < bands.handgunBelowJ) return 'pistol'\n return energyJ < bands.rifleBelowJ ? 'rifle' : 'long_rifle'\n}\n\n/**\n * The parameters of a gunshot, without WebAudio: the sound class and the distance muffling of the game (S2) with the calibre energy of the SDK.\n * Pure and deterministic; the playback layer only turns it into nodes.\n */\nexport const computeShotSound = (input: ShotSoundInput, options: ShotSoundOptions = {}): ShotSound => {\n const curve: EnergyCurve = { ...DEFAULT_ENERGY_CURVE, ...options.energy }\n const distanceCurve: DistanceCurve = { ...GAME_DISTANCE_CURVE, ...options.distance }\n const energyJ = energyOfShot(input)\n const soundClass = options.classOf ? options.classOf(input, energyJ) : defaultClassOf(input, energyJ, options.bands ?? DEFAULT_BANDS)\n const table: Readonly<Record<string, SoundClassDef>> = { ...GAME_SOUND_CLASSES, ...options.classes }\n const [classCutoff, classGain, classSeconds] = table[soundClass] ?? FALLBACK_SOUND_CLASS\n const referenceEnergy = options.referenceEnergy?.[soundClass] ?? CLASS_REFERENCE_ENERGY[soundClass] ?? energyJ\n\n const k = energyPosition(energyJ, curve)\n const referenceK = energyPosition(referenceEnergy, curve)\n const distance = Math.max(0, input.distance ?? 0)\n const attenuation = (input.volume ?? 1) / (1 + distance * distance * distanceCurve.gainFalloff)\n const muffling = 1 / (1 + distance * distanceCurve.cutoffFalloff)\n\n const suppressor = input.suppressed ? { ...DEFAULT_SUPPRESSOR, ...options.suppressor } : { gain: 1, cutoff: 1, crack: 1, body: 1 }\n const indoors = input.indoors ? { ...DEFAULT_INDOORS, ...options.indoors } : { duration: 1, cutoff: 1 }\n\n const gain = classGain * attenuation * (linear(curve.gain, k) / linear(curve.gain, referenceK)) * suppressor.gain\n const duration = classSeconds * (linear(curve.duration, k) / linear(curve.duration, referenceK)) * indoors.duration\n const cutoff = classCutoff * muffling * (linear(curve.cutoff, k) / linear(curve.cutoff, referenceK)) * suppressor.cutoff * indoors.cutoff\n\n return {\n soundClass,\n energyJ,\n audible: attenuation >= distanceCurve.minGain,\n cutoff,\n gain,\n duration,\n crack: { gain: linear(curve.crackGain, k) * attenuation * suppressor.crack, cutoff: CRACK_CUTOFF, duration: CRACK_SECONDS },\n body: {\n gain: linear(curve.bodyGain, k) * attenuation * suppressor.body,\n frequency: linear(curve.bodyFrequency, k),\n to: BODY_TO_FREQUENCY,\n duration: linear(curve.bodyDuration, k) * indoors.duration,\n },\n }\n}\n","// Weapon sounds synthesized with WebAudio: no sound files, so the kit stays offline and small. Every call is a no-op where there is no\n// AudioContext (tests, workers), and the context is only created on the first sound, which comes from a click or a key (browsers allow it).\n// The numbers live in ./audio/*: `computeShotSound` is pure and this file only turns its result into nodes.\nimport { createRng } from '@adatechnology/game-weapons'\nimport type { WeaponEvent } from '@adatechnology/game-weapons'\n\nimport { MECHANICAL_SOUNDS, mechanicalSoundOf } from './audio/mechanical-sounds'\nimport type { MechanicalSoundId, SoundStep } from './audio/mechanical-sounds'\nimport { computeShotSound, FALLBACK_SOUND_CLASS, GAME_DISTANCE_CURVE, GAME_SOUND_CLASSES } from './audio/shot-sound'\nimport type { ShotSound, ShotSoundInput, ShotSoundOptions, SoundClassDef } from './audio/shot-sound'\n\nexport { computeShotSound, GAME_SOUND_CLASSES, GAME_DISTANCE_CURVE, DEFAULT_ENERGY_CURVE, CLASS_REFERENCE_ENERGY } from './audio/shot-sound'\nexport type { ShotSound, ShotSoundInput, ShotSoundOptions, ShotSoundClass, SoundClassDef, DistanceCurve, EnergyCurve } from './audio/shot-sound'\nexport { MECHANICAL_SOUNDS, mechanicalSoundOf } from './audio/mechanical-sounds'\nexport type { MechanicalSoundId, SoundStep } from './audio/mechanical-sounds'\n\n/** What a shot adds to the energy and the category: where the listener is and how the weapon is set. */\nexport type ShotExtras = Pick<ShotSoundInput, 'caliber' | 'distance' | 'volume' | 'suppressed' | 'indoors'>\n\nexport interface WeaponAudioOptions extends ShotSoundOptions {\n /** Seed of the noise buffer, of the start point in it and of the casing pitch: same seed, same sound. Default 1. */\n readonly seed?: number\n /** Replaces or adds mechanical sounds by id. */\n readonly mechanical?: Readonly<Partial<Record<MechanicalSoundId, readonly SoundStep[]>>>\n /** Where the AudioContext comes from (default: the global one); lets a host or a test lend its own. */\n readonly createContext?: () => AudioContext\n}\n\n/** Sounds the weapon presentation plays. */\nexport interface WeaponAudio {\n /** A shot: class and distance muffling of the game, loudness and body from the muzzle energy (joules). */\n shot(energyJ: number, category: string, extras?: ShotExtras): void\n /** The parameters `shot` would play (pure). */\n shotSound(input: ShotSoundInput): ShotSound\n /** Dry click of an empty weapon. */\n click(): void\n /** A mechanical sound by id: a reload stage, `dry_fire`, `jam`, `safety_on`... */\n mechanical(id: MechanicalSoundId): void\n /** The mechanical sound of a weapon event, if it has one (reload stages, empty, misfire, fault, clear, safety, mode, feed). */\n event(event: WeaponEvent): void\n /** A sound class of the game by name (`impact`, `flesh`, `glass`...), with the game's distance muffling. */\n play(soundClass: string, volume?: number, distance?: number): void\n /** Magazine out, or the first shell in. */\n reloadStart(category: string): void\n /** Magazine seated and the action racked. */\n reloadEnd(category: string): void\n /** The pump or lever cycling after a shot. */\n cycle(): void\n /** A casing bouncing on the floor. */\n clink(): void\n /** A magazine landing on the floor. */\n thud(): void\n /** Master volume, 0 to 1. */\n setVolume(volume: number): void\n dispose(): void\n}\n\ntype AudioContextCtor = new () => AudioContext\n\nconst NOISE_SECONDS = 1.5\n\nconst globalContext = (): AudioContext | null => {\n const scope = globalThis as { AudioContext?: AudioContextCtor; webkitAudioContext?: AudioContextCtor }\n const Ctor = scope.AudioContext ?? scope.webkitAudioContext\n return Ctor ? new Ctor() : null\n}\n\nexport function createWeaponAudio(volume = 0.6, options: WeaponAudioOptions = {}): WeaponAudio {\n const makeContext = options.createContext ?? globalContext\n const rng = createRng(options.seed ?? 1)\n const classes: Readonly<Record<string, SoundClassDef>> = { ...GAME_SOUND_CLASSES, ...options.classes }\n const distanceCurve = { ...GAME_DISTANCE_CURVE, ...options.distance }\n const mechanicalTable = { ...MECHANICAL_SOUNDS, ...options.mechanical }\n let ctx: AudioContext | null = null\n let master: GainNode | null = null\n let noise: AudioBuffer | null = null\n let level = volume\n\n const ready = (): AudioContext | null => {\n if (!ctx) {\n const created = makeContext()\n if (!created) return null\n ctx = created\n master = ctx.createGain()\n master.gain.value = level\n master.connect(ctx.destination)\n noise = ctx.createBuffer(1, Math.floor(ctx.sampleRate * NOISE_SECONDS), ctx.sampleRate)\n const data = noise.getChannelData(0)\n for (let i = 0; i < data.length; i++) data[i] = rng() * 2 - 1\n }\n if (ctx.state === 'suspended') void ctx.resume()\n return ctx\n }\n\n // a filtered noise burst with a fast attack and an exponential tail\n const burst = (config: { at?: number; seconds: number; gain: number; filter: BiquadFilterType; frequency: number; q?: number }): void => {\n const audio = ready()\n if (!audio || !noise || !master) return\n const start = audio.currentTime + (config.at ?? 0)\n const source = audio.createBufferSource()\n source.buffer = noise\n const filter = audio.createBiquadFilter()\n filter.type = config.filter\n filter.frequency.value = config.frequency\n filter.Q.value = config.q ?? 0.8\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(Math.max(config.gain, 0.0002), start + 0.004)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + config.seconds)\n source.connect(filter).connect(gain).connect(master)\n source.start(start, rng() * Math.max(0, NOISE_SECONDS - config.seconds))\n source.stop(start + config.seconds + 0.05)\n }\n\n // the game `sfx`: lowpass noise, gain set at once and an exponential fall to 0.001 (jogo.js L62097-L62110)\n const classBurst = (at: number, cutoff: number, gain: number, seconds: number): void => {\n const audio = ready()\n if (!audio || !noise || !master) return\n const start = audio.currentTime + at\n const source = audio.createBufferSource()\n source.buffer = noise\n const filter = audio.createBiquadFilter()\n filter.type = 'lowpass'\n filter.frequency.value = cutoff\n const envelope = audio.createGain()\n envelope.gain.setValueAtTime(gain, start)\n envelope.gain.exponentialRampToValueAtTime(0.001, start + seconds)\n source.connect(filter).connect(envelope).connect(master)\n source.start(start, rng() * Math.max(0, NOISE_SECONDS - seconds))\n source.stop(start + seconds + 0.05)\n }\n\n const tone = (config: { at?: number; seconds: number; gain: number; frequency: number; to?: number; type?: OscillatorType }): void => {\n const audio = ready()\n if (!audio || !master) return\n const start = audio.currentTime + (config.at ?? 0)\n const osc = audio.createOscillator()\n osc.type = config.type ?? 'sine'\n osc.frequency.setValueAtTime(config.frequency, start)\n if (config.to) osc.frequency.exponentialRampToValueAtTime(config.to, start + config.seconds)\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(Math.max(config.gain, 0.0002), start + 0.003)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + config.seconds)\n osc.connect(gain).connect(master)\n osc.start(start)\n osc.stop(start + config.seconds + 0.05)\n }\n\n const metal = (at: number, frequency: number, gain: number): void => {\n burst({ at, seconds: 0.05, gain, filter: 'highpass', frequency, q: 2 })\n tone({ at, seconds: 0.04, gain: gain * 0.6, frequency: frequency * 0.6, type: 'square' })\n }\n\n const play = (soundClass: string, classVolume = 1, distance = 0, at = 0): void => {\n const attenuation = classVolume / (1 + distance * distance * distanceCurve.gainFalloff)\n if (attenuation < distanceCurve.minGain) return\n const [cutoff, gain, seconds] = classes[soundClass] ?? FALLBACK_SOUND_CLASS\n classBurst(at, cutoff / (1 + distance * distanceCurve.cutoffFalloff), gain * attenuation, seconds)\n }\n\n const step = (entry: SoundStep): void => {\n if (entry.layer === 'metal') metal(entry.at, entry.frequency, entry.gain)\n else if (entry.layer === 'class') play(entry.soundClass, entry.volume, 0, entry.at)\n else burst({ at: entry.at, seconds: 0.09, gain: entry.gain, filter: 'lowpass', frequency: entry.frequency })\n }\n\n const mechanical = (id: MechanicalSoundId): void => {\n for (const entry of mechanicalTable[id] ?? []) step(entry)\n }\n\n const shotSound = (input: ShotSoundInput): ShotSound => computeShotSound(input, options)\n\n return {\n shot(energyJ, category, extras = {}) {\n const sound = shotSound({ ...extras, energyJ, category })\n if (!sound.audible) return\n classBurst(0, sound.cutoff, sound.gain, sound.duration)\n if (sound.crack.gain > 0) burst({ seconds: sound.crack.duration, gain: sound.crack.gain, filter: 'highpass', frequency: sound.crack.cutoff })\n tone({ seconds: sound.body.duration, gain: sound.body.gain, frequency: sound.body.frequency, to: sound.body.to })\n },\n shotSound,\n click() {\n mechanical('dry_fire')\n },\n mechanical,\n event(event) {\n const id = mechanicalSoundOf(event)\n if (id) mechanical(id)\n },\n play(soundClass, classVolume, distance) {\n play(soundClass, classVolume, distance)\n },\n reloadStart(category) {\n metal(0, 1500, 0.35)\n if (category !== 'shotgun' && category !== 'revolver') metal(0.12, 900, 0.2)\n },\n reloadEnd(category) {\n metal(0, 1100, 0.45)\n if (category !== 'revolver') metal(0.18, 1900, 0.4)\n },\n cycle() {\n mechanical('cycle')\n },\n clink() {\n const f = 3200 + rng() * 2000\n tone({ seconds: 0.09, gain: 0.12, frequency: f })\n tone({ seconds: 0.06, gain: 0.06, frequency: f * 2.7 })\n },\n thud() {\n burst({ seconds: 0.09, gain: 0.35, filter: 'lowpass', frequency: 380 })\n },\n setVolume(next) {\n level = Math.max(0, Math.min(1, next))\n if (master) master.gain.value = level\n },\n dispose() {\n void ctx?.close()\n ctx = null\n master = null\n noise = null\n },\n }\n}\n","/** What the bench turns on or off in the presentation of the weapon: the ejected casings, the dropped magazines, the muzzle flash, the accessory models and the light and laser beams. */\nexport interface FxLayers {\n casings: boolean\n magazines: boolean\n muzzleFlash: boolean\n attachments: boolean\n beams: boolean\n}\n\nexport const createLayers = (): FxLayers => ({ casings: true, magazines: true, muzzleFlash: true, attachments: true, beams: true })\n","import type * as THREE_NS from 'three'\nimport type { LaserRaycast } from './models/attachments/types'\n\n/** Names of the groups that hold the weapon in the hands: the beam of a laser never lands on its own weapon. */\nexport const VIEWMODEL_NODE_NAME = 'weapon-viewmodel'\nexport const IN_HAND_NODE_NAME = 'weapon-in-hand'\n\n/** The laser is measured this many times per second at most; between the casts the last distance holds. */\nexport const LASER_RAYCAST_HZ = 30\n\nconst isHeld = (object: THREE_NS.Object3D): boolean => {\n for (let node: THREE_NS.Object3D | null = object; node; node = node.parent) if (node.name === VIEWMODEL_NODE_NAME || node.name === IN_HAND_NODE_NAME) return true\n return false\n}\n\n/** A node counts only when it and every ancestor are visible: `Object3D.visible` of a parent hides the children but the raycaster does not look at it. */\nexport const isVisibleInScene = (object: THREE_NS.Object3D): boolean => {\n for (let node: THREE_NS.Object3D | null = object; node; node = node.parent) if (!node.visible) return false\n return true\n}\n\nexport interface LaserRaycastOptions {\n /** Milliseconds clock (default `performance.now`). */\n readonly now?: () => number\n}\n\n/** The ray of a laser sight against what is in the scene, ignoring the weapon in the hands, what is hidden (itself or by an ancestor), what is see-through and what is not a surface (particles, sprites). */\nexport const createLaserRaycast = (THREE: typeof THREE_NS, scene: THREE_NS.Scene, camera: THREE_NS.Camera, options: LaserRaycastOptions = {}): LaserRaycast => {\n const now = options.now ?? ((): number => performance.now())\n const interval = 1000 / LASER_RAYCAST_HZ\n const raycaster = new THREE.Raycaster()\n // the smoke is made of sprites, which need the camera to be tested at all\n raycaster.camera = camera\n let lastAt = -Infinity\n let lastReach: number | null = null\n return (origin, direction, maxDistance) => {\n const at = now()\n if (at - lastAt < interval) return lastReach\n lastAt = at\n raycaster.set(origin, direction)\n raycaster.far = maxDistance\n const hit = raycaster.intersectObjects(scene.children, true).find((entry) => {\n const mesh = entry.object as THREE_NS.Mesh\n const material = mesh.material as THREE_NS.Material | undefined\n return mesh.isMesh && isVisibleInScene(mesh) && material?.transparent !== true && !isHeld(mesh)\n })\n lastReach = hit ? hit.distance : null\n return lastReach\n }\n}\n","import type * as THREE_NS from 'three'\n\nconst ATTRIBUTES = ['position', 'normal', 'uv'] as const\n\nconst isVisible = (object: THREE_NS.Object3D): boolean => {\n for (let node: THREE_NS.Object3D | null = object; node; node = node.parent) if (!node.visible) return false\n return true\n}\n\n/** A copy of the geometry with the matrix baked in, not indexed, keeping only what every model has (position, normal, uv), so that any two of them can be joined. */\nconst bake = (THREE: typeof THREE_NS, mesh: THREE_NS.Mesh, matrix: THREE_NS.Matrix4): THREE_NS.BufferGeometry => {\n const source = mesh.geometry.index ? mesh.geometry.toNonIndexed() : mesh.geometry.clone()\n const baked = new THREE.BufferGeometry()\n const count = source.getAttribute('position').count\n for (const name of ATTRIBUTES) {\n const attribute = source.getAttribute(name)\n baked.setAttribute(name, attribute ?? new THREE.BufferAttribute(new Float32Array(count * (name === 'uv' ? 2 : 3)), name === 'uv' ? 2 : 3))\n }\n source.dispose()\n return baked.applyMatrix4(matrix)\n}\n\n/** One non-indexed geometry out of several, in order (the port of `mergeGeometries` of three/addons for the three attributes above). */\nconst join = (THREE: typeof THREE_NS, geometries: readonly THREE_NS.BufferGeometry[]): THREE_NS.BufferGeometry => {\n const merged = new THREE.BufferGeometry()\n for (const name of ATTRIBUTES) {\n const size = (geometries[0]?.getAttribute(name) as THREE_NS.BufferAttribute).itemSize\n const total = geometries.reduce((sum, geometry) => sum + geometry.getAttribute(name).count, 0)\n const array = new Float32Array(total * size)\n let offset = 0\n for (const geometry of geometries) {\n array.set(geometry.getAttribute(name).array, offset)\n offset += geometry.getAttribute(name).count * size\n }\n merged.setAttribute(name, new THREE.BufferAttribute(array, size))\n }\n return merged\n}\n\n/**\n * Every visible mesh under `root` (whose world matrix must be up to date), baked into the space of `space` and joined by material: one mesh per material, no shadow cast.\n * Weapons lying on a counter are never animated, so the hundreds of meshes of a model cost one draw call per material instead.\n */\nexport function mergeByMaterial(THREE: typeof THREE_NS, root: THREE_NS.Object3D, space: THREE_NS.Object3D): THREE_NS.Mesh[] {\n const toSpace = space.matrixWorld.clone().invert()\n const byMaterial = new Map<THREE_NS.Material, THREE_NS.BufferGeometry[]>()\n root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh || Array.isArray(mesh.material) || !isVisible(mesh)) return\n const list = byMaterial.get(mesh.material) ?? []\n list.push(bake(THREE, mesh, new THREE.Matrix4().multiplyMatrices(toSpace, mesh.matrixWorld)))\n byMaterial.set(mesh.material, list)\n })\n return [...byMaterial].map(([material, geometries]) => {\n const merged = new THREE.Mesh(join(THREE, geometries), material)\n for (const geometry of geometries) geometry.dispose()\n merged.castShadow = false\n merged.receiveShadow = true\n return merged\n })\n}\n","{\n \"glock_17\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 202,\n \"barrel\": 114,\n \"options\": {\n \"st\": \"glock\",\n \"rel\": 0.7\n }\n },\n \"glock_18\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 202,\n \"barrel\": 114,\n \"options\": {\n \"st\": \"glock\",\n \"sel\": 1,\n \"rpm\": 1200,\n \"rel\": 0.9\n }\n },\n \"glock_19\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 185,\n \"barrel\": 102,\n \"options\": {\n \"st\": \"glock\",\n \"gl\": 0.095,\n \"rel\": 0.7\n }\n },\n \"taurus_g2c\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 159,\n \"barrel\": 81,\n \"options\": {\n \"st\": \"g2c\",\n \"gl\": 0.085,\n \"rel\": 1.5\n }\n },\n \"taurus_ts9\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 194,\n \"barrel\": 104,\n \"options\": {\n \"st\": \"taurus\",\n \"rel\": 1.2\n }\n },\n \"beretta_92fs\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 217,\n \"barrel\": 125,\n \"options\": {\n \"st\": \"beretta\",\n \"h\": 0.032,\n \"rel\": 0.9\n }\n },\n \"sig_sauer_p226\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 196,\n \"barrel\": 112,\n \"options\": {\n \"st\": \"sig\",\n \"h\": 0.034,\n \"rel\": 0.8\n }\n },\n \"cz_75\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 206,\n \"barrel\": 120,\n \"options\": {\n \"st\": \"cz\",\n \"h\": 0.03,\n \"rel\": 0.9\n }\n },\n \"taurus_pt100\": {\n \"builder\": \"pistol\",\n \"caliber\": \".40 S&W\",\n \"length\": 216,\n \"barrel\": 127,\n \"options\": {\n \"st\": \"pt100\",\n \"stain\": 1,\n \"rel\": 1.2\n }\n },\n \"colt_m1911\": {\n \"builder\": \"pistol\",\n \"caliber\": \".45 ACP\",\n \"length\": 216,\n \"barrel\": 127,\n \"options\": {\n \"st\": \"m1911\",\n \"h\": 0.029,\n \"gl\": 0.1,\n \"rel\": 1.1\n }\n },\n \"makarov_pm\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×18\",\n \"length\": 161,\n \"barrel\": 94,\n \"options\": {\n \"st\": \"makarov\",\n \"h\": 0.028,\n \"gl\": 0.088,\n \"rel\": 0.8\n }\n },\n \"fn_five_seven\": {\n \"builder\": \"pistol\",\n \"caliber\": \"5,7×28\",\n \"length\": 208,\n \"barrel\": 122,\n \"options\": {\n \"st\": \"fiveseven\",\n \"gl\": 0.12,\n \"rel\": 0.9\n }\n },\n \"desert_eagle_mark_xix\": {\n \"builder\": \"pistol\",\n \"caliber\": \".50 AE\",\n \"length\": 270,\n \"barrel\": 152,\n \"options\": {\n \"st\": \"deagle\",\n \"h\": 0.04,\n \"gl\": 0.125,\n \"deagle\": 1,\n \"steel\": 1,\n \"rel\": 1.8\n }\n },\n \"taurus_82\": {\n \"builder\": \"revolver\",\n \"caliber\": \".38 SPL\",\n \"length\": 240,\n \"barrel\": 102,\n \"options\": {\n \"wood\": 1\n }\n },\n \"sw_686\": {\n \"builder\": \"revolver\",\n \"caliber\": \".357 Magnum\",\n \"length\": 244,\n \"barrel\": 102,\n \"options\": {\n \"steel\": 1,\n \"chambers\": 7\n }\n },\n \"sw_model_29\": {\n \"builder\": \"revolver\",\n \"caliber\": \".44 Magnum\",\n \"length\": 302,\n \"barrel\": 165,\n \"options\": {\n \"wood\": 1\n }\n },\n \"hk_mp5a3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 700,\n \"barrel\": 225,\n \"options\": {\n \"mag\": \"curved\",\n \"magLen\": 0.72,\n \"stock\": \"retract\",\n \"stockLen\": 0.22,\n \"hR\": 0.055,\n \"hg\": \"poly\",\n \"hgFrac\": 0.85,\n \"g3\": 1,\n \"rpm\": 800,\n \"sel\": 1\n }\n },\n \"taurus_smt9\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 660,\n \"barrel\": 200,\n \"options\": {\n \"mag\": \"box\",\n \"stock\": \"retract\",\n \"stockLen\": 0.2,\n \"hg\": \"rail\",\n \"hgFrac\": 0.8,\n \"rail\": 1,\n \"rpm\": 750,\n \"sel\": 1\n }\n },\n \"hk_ump_45\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 690,\n \"barrel\": 200,\n \"options\": {\n \"mag\": \"box\",\n \"magLen\": 1.1,\n \"stock\": \"skeleton\",\n \"stockLen\": 0.22,\n \"hR\": 0.07,\n \"hg\": \"poly\",\n \"hgFrac\": 0.85,\n \"rpm\": 600,\n \"sel\": 1,\n \"rail\": 1\n }\n },\n \"uzi\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 650,\n \"barrel\": 260,\n \"options\": {\n \"mag\": \"box\",\n \"magAt\": 0.06,\n \"magLen\": 1.3,\n \"stock\": \"fold\",\n \"stockLen\": 0.2,\n \"hR\": 0.065,\n \"hg\": \"poly\",\n \"hgFrac\": 0.4,\n \"grip\": \"none\",\n \"rpm\": 600\n }\n },\n \"fn_p90\": {\n \"builder\": \"p90\",\n \"caliber\": \"5,7×28\",\n \"length\": 500,\n \"barrel\": 264,\n \"options\": {\n \"rpm\": 900\n }\n },\n \"kriss_vector\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 622,\n \"barrel\": 140,\n \"options\": {\n \"mag\": \"box\",\n \"magLen\": 1.1,\n \"stock\": \"retract\",\n \"stockLen\": 0.2,\n \"hR\": 0.085,\n \"hg\": \"rail\",\n \"hgFrac\": 0.9,\n \"rail\": 1,\n \"scope\": 1,\n \"rpm\": 1100\n }\n },\n \"thompson_m1a1\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 813,\n \"barrel\": 267,\n \"options\": {\n \"wood\": 1,\n \"mag\": \"box\",\n \"magLen\": 1.2,\n \"stock\": \"fixed\",\n \"stockLen\": 0.3,\n \"hg\": \"none\",\n \"hR\": 0.055,\n \"jacket\": 1,\n \"rpm\": 700,\n \"charge\": 1\n }\n },\n \"cz_scorpion_evo_3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 670,\n \"barrel\": 196,\n \"options\": {\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1.2,\n \"stock\": \"fold\",\n \"stockLen\": 0.22,\n \"hg\": \"rail\",\n \"hgFrac\": 0.85,\n \"rail\": 1,\n \"scope\": 1,\n \"rpm\": 1150\n }\n },\n \"mac_10\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 548,\n \"barrel\": 146,\n \"options\": {\n \"mag\": \"box\",\n \"magAt\": 0.04,\n \"magLen\": 1.2,\n \"stock\": \"fold\",\n \"stockLen\": 0.22,\n \"hR\": 0.075,\n \"hg\": \"none\",\n \"grip\": \"none\",\n \"brake\": 2,\n \"rpm\": 1090,\n \"rel\": 1.4\n }\n },\n \"remington_870\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 990,\n \"barrel\": 470,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"wood\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.055,\n \"noFH\": 1\n }\n },\n \"mossberg_500\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 990,\n \"barrel\": 470,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.055,\n \"noFH\": 1\n }\n },\n \"cbc_pump_military_3_0\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1000,\n \"barrel\": 480,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"tubeLen\": 0.95,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.055,\n \"rail\": 1,\n \"noFH\": 1\n }\n },\n \"benelli_m4\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1010,\n \"barrel\": 470,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"br\": 0.0105,\n \"hR\": 0.06,\n \"rail\": 1,\n \"scope\": 1,\n \"noFH\": 1,\n \"charge\": 1\n }\n },\n \"franchi_spas_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1041,\n \"barrel\": 546,\n \"options\": {\n \"stock\": \"fold\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.06,\n \"heat\": 1,\n \"noFH\": 1\n }\n },\n \"kel_tec_ksg\": {\n \"builder\": \"bullpup\",\n \"caliber\": \"12 ga\",\n \"length\": 660,\n \"barrel\": 470,\n \"options\": {\n \"shot\": 1\n }\n },\n \"saiga_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1000,\n \"barrel\": 430,\n \"options\": {\n \"mag\": \"box\",\n \"magLen\": 1.15,\n \"stock\": \"fixed\",\n \"hg\": \"poly\",\n \"br\": 0.0105,\n \"hR\": 0.07,\n \"gas\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rel\": 1.3\n }\n },\n \"aa_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 966,\n \"barrel\": 457,\n \"options\": {\n \"mag\": \"drum\",\n \"stock\": \"fixed\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.6,\n \"br\": 0.0105,\n \"hR\": 0.085,\n \"carry\": 1,\n \"rpm\": 300\n }\n },\n \"boito_double_barrel\": {\n \"builder\": \"break\",\n \"caliber\": \"12 ga\",\n \"length\": 1130,\n \"barrel\": 710,\n \"options\": {}\n },\n \"ak_47\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×39\",\n \"length\": 880,\n \"barrel\": 415,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"wood\",\n \"mag\": \"curved\",\n \"hg\": \"wood\",\n \"hgFrac\": 0.42,\n \"gas\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rod\": 1,\n \"bayo\": 1,\n \"rpm\": 600,\n \"rel\": 0.4\n }\n },\n \"akm\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×39\",\n \"length\": 880,\n \"barrel\": 415,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"wood\",\n \"mag\": \"curved\",\n \"hg\": \"wood\",\n \"hgFrac\": 0.42,\n \"gas\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rod\": 1,\n \"rpm\": 600,\n \"magMat\": \"bakelite\",\n \"rel\": 0.45\n }\n },\n \"ak_74\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,45×39\",\n \"length\": 943,\n \"barrel\": 415,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"curved\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.42,\n \"gas\": 1,\n \"charge\": 1,\n \"brake\": 1,\n \"ak\": 1,\n \"rod\": 1,\n \"rpm\": 650,\n \"magMat\": \"bakelite\"\n }\n },\n \"ak_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,45×39\",\n \"length\": 945,\n \"barrel\": 415,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"curved\",\n \"hg\": \"rail\",\n \"hgFrac\": 0.5,\n \"rail\": 1,\n \"brake\": 1,\n \"scope\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rpm\": 700,\n \"magMat\": \"poly\"\n }\n },\n \"imbel_ia2\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 850,\n \"barrel\": 330,\n \"options\": {\n \"stock\": \"fold\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.25,\n \"hg\": \"poly\",\n \"hgFrac\": 0.6,\n \"rail\": 1,\n \"charge\": 1,\n \"rpm\": 700\n }\n },\n \"taurus_t4\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 840,\n \"barrel\": 368,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"rail\": 1,\n \"scope\": 1,\n \"ar\": 1,\n \"rpm\": 750\n }\n },\n \"colt_m4a1\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 840,\n \"barrel\": 368,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"rail\",\n \"hgFrac\": 0.6,\n \"rail\": 1,\n \"scope\": 2,\n \"ar\": 1,\n \"rpm\": 800\n }\n },\n \"colt_m16a2\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 1000,\n \"barrel\": 508,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"carry\": 1,\n \"ar\": 1,\n \"rpm\": 800,\n \"burst\": 3\n }\n },\n \"hk416\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 900,\n \"barrel\": 368,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"rail\",\n \"hgFrac\": 0.75,\n \"rail\": 1,\n \"scope\": 1,\n \"ar\": 1,\n \"rpm\": 850\n }\n },\n \"steyr_aug_a1\": {\n \"builder\": \"bullpup\",\n \"caliber\": \"5,56×45\",\n \"length\": 790,\n \"barrel\": 508,\n \"options\": {\n \"rpm\": 680\n }\n },\n \"fn_fal\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1090,\n \"barrel\": 533,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1.05,\n \"hg\": \"poly\",\n \"hgFrac\": 0.45,\n \"carry\": 1,\n \"brake\": 1,\n \"charge\": 1,\n \"rpm\": 650\n }\n },\n \"hk_g3a3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1025,\n \"barrel\": 450,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.05,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.058,\n \"g3\": 1,\n \"rpm\": 550\n }\n },\n \"sks\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×39\",\n \"length\": 1020,\n \"barrel\": 520,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"fore\": 0.55,\n \"gas\": 1,\n \"charge\": 1,\n \"bayo\": 1\n }\n },\n \"m14_ebr\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1000,\n \"barrel\": 457,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.035,\n \"magLen\": 1.05,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"rail\": 1,\n \"scope\": 3,\n \"olive\": 1,\n \"charge\": 1\n }\n },\n \"svd_dragunov\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×54R\",\n \"length\": 1225,\n \"barrel\": 620,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"skeleton\",\n \"stockLen\": 0.32,\n \"mag\": \"box\",\n \"curve\": 0.09,\n \"magLen\": 0.9,\n \"hg\": \"wood\",\n \"hgFrac\": 0.4,\n \"scope\": 4,\n \"brake\": 1,\n \"ak\": 1,\n \"charge\": 1\n }\n },\n \"fn_scar_h\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 965,\n \"barrel\": 400,\n \"options\": {\n \"tan\": 1,\n \"stock\": \"fold\",\n \"mag\": \"box\",\n \"magLen\": 1.05,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"hR\": 0.07,\n \"rail\": 1,\n \"scope\": 2,\n \"charge\": 1,\n \"rpm\": 600\n }\n },\n \"knights_sr_25_mk11\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1156,\n \"barrel\": 508,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"magLen\": 1,\n \"hg\": \"rail\",\n \"hgFrac\": 0.75,\n \"rail\": 1,\n \"scope\": 3,\n \"bipod\": 1,\n \"ar\": 1\n }\n },\n \"hk_psg_1\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1208,\n \"barrel\": 650,\n \"options\": {\n \"stock\": \"fixed\",\n \"stockLen\": 0.3,\n \"mag\": \"box\",\n \"curve\": 0.06,\n \"magLen\": 0.75,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.058,\n \"g3\": 1,\n \"scope\": 3,\n \"rel\": 0.7\n }\n },\n \"steyr_ssg_69\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1140,\n \"barrel\": 650,\n \"options\": {\n \"olive\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1,\n \"rel\": 0.6\n }\n },\n \"barrett_mrad\": {\n \"builder\": \"rifle\",\n \"caliber\": \".338 Lapua\",\n \"length\": 1260,\n \"barrel\": 686,\n \"options\": {\n \"tan\": 1,\n \"stock\": \"fold\",\n \"stockLen\": 0.33,\n \"mag\": \"box\",\n \"magLen\": 0.75,\n \"hg\": \"rail\",\n \"hgFrac\": 0.55,\n \"rail\": 1,\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"cheytac_m200\": {\n \"builder\": \"rifle\",\n \"caliber\": \".408 CheyTac\",\n \"length\": 1397,\n \"barrel\": 737,\n \"options\": {\n \"stock\": \"retract\",\n \"stockLen\": 0.3,\n \"mag\": \"box\",\n \"magLen\": 0.85,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.07,\n \"scope\": 4,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"remington_700\": {\n \"builder\": \"rifle\",\n \"caliber\": \".308\",\n \"length\": 1100,\n \"barrel\": 610,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1\n }\n },\n \"m24_sws\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1092,\n \"barrel\": 610,\n \"options\": {\n \"olive\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"round\": 1\n }\n },\n \"mosin_nagant_91_30\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×54R\",\n \"length\": 1232,\n \"barrel\": 730,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"fore\": 0.85,\n \"bolt\": 1,\n \"round\": 1,\n \"bands\": 1\n }\n },\n \"accuracy_awm\": {\n \"builder\": \"rifle\",\n \"caliber\": \".338 Lapua\",\n \"length\": 1230,\n \"barrel\": 686,\n \"options\": {\n \"olive\": 1,\n \"stock\": \"skeleton\",\n \"stockLen\": 0.34,\n \"mag\": \"box\",\n \"magLen\": 0.6,\n \"hg\": \"poly\",\n \"hgFrac\": 0.3,\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"sako_trg_42\": {\n \"builder\": \"rifle\",\n \"caliber\": \".338 Lapua\",\n \"length\": 1200,\n \"barrel\": 690,\n \"options\": {\n \"stock\": \"fixed\",\n \"stockLen\": 0.33,\n \"mag\": \"box\",\n \"magLen\": 0.6,\n \"hg\": \"poly\",\n \"hgFrac\": 0.3,\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"barrett_m82a1\": {\n \"builder\": \"rifle\",\n \"caliber\": \".50 BMG\",\n \"length\": 1448,\n \"barrel\": 737,\n \"options\": {\n \"stock\": \"fixed\",\n \"stockLen\": 0.3,\n \"mag\": \"box\",\n \"magLen\": 0.8,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.1,\n \"wR\": 0.05,\n \"br\": 0.014,\n \"scope\": 3,\n \"bipod\": 1,\n \"brake\": 2,\n \"carry\": 1,\n \"charge\": 1\n }\n },\n \"ruger_10_22\": {\n \"builder\": \"rifle\",\n \"caliber\": \".22 LR\",\n \"length\": 940,\n \"barrel\": 470,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"hR\": 0.05,\n \"br\": 0.007,\n \"charge\": 1\n }\n },\n \"cbc_7022\": {\n \"builder\": \"rifle\",\n \"caliber\": \".22 LR\",\n \"length\": 1000,\n \"barrel\": 530,\n \"options\": {\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"hR\": 0.05,\n \"br\": 0.007,\n \"charge\": 1\n }\n },\n \"cbc_122\": {\n \"builder\": \"rifle\",\n \"caliber\": \".22 LR\",\n \"length\": 1030,\n \"barrel\": 590,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"hR\": 0.045,\n \"br\": 0.007,\n \"bolt\": 1,\n \"round\": 1\n }\n },\n \"winchester_1894\": {\n \"builder\": \"rifle\",\n \"caliber\": \".30-30\",\n \"length\": 965,\n \"barrel\": 508,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"straight\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"lever\": 1,\n \"hR\": 0.05,\n \"fore\": 0,\n \"bands\": 1\n }\n },\n \"rossi_puma\": {\n \"builder\": \"rifle\",\n \"caliber\": \".38 SPL / .357\",\n \"length\": 950,\n \"barrel\": 508,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"straight\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"lever\": 1,\n \"hR\": 0.048,\n \"fore\": 0\n }\n },\n \"hunting_rifle_30_06\": {\n \"builder\": \"rifle\",\n \"caliber\": \".30-06\",\n \"length\": 1100,\n \"barrel\": 560,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1\n }\n },\n \"fn_minimi\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 1040,\n \"barrel\": 465,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.35,\n \"bipod\": 1,\n \"hR\": 0.08,\n \"carry\": 1,\n \"charge\": 1,\n \"rpm\": 850\n }\n },\n \"pkm\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×54R\",\n \"length\": 1173,\n \"barrel\": 658,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"skeleton\",\n \"mag\": \"belt\",\n \"hg\": \"none\",\n \"bipod\": 1,\n \"hR\": 0.08,\n \"br\": 0.01,\n \"charge\": 1,\n \"rpm\": 650\n }\n },\n \"m60\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1105,\n \"barrel\": 560,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.3,\n \"bipod\": 1,\n \"hR\": 0.085,\n \"br\": 0.011,\n \"charge\": 1,\n \"rpm\": 550,\n \"rel\": 1.3\n }\n },\n \"rpg_7\": {\n \"builder\": \"launcher\",\n \"caliber\": \"PG-7V 40/85 mm\",\n \"length\": 950,\n \"barrel\": 950,\n \"options\": {\n \"lt\": \"rpg\"\n }\n },\n \"m72_law\": {\n \"builder\": \"launcher\",\n \"caliber\": \"66 mm HEAT\",\n \"length\": 881,\n \"barrel\": 881,\n \"options\": {\n \"lt\": \"m72\"\n }\n },\n \"at4\": {\n \"builder\": \"launcher\",\n \"caliber\": \"84 mm HEAT\",\n \"length\": 1020,\n \"barrel\": 1020,\n \"options\": {\n \"lt\": \"at4\"\n }\n },\n \"carl_gustaf_m4\": {\n \"builder\": \"launcher\",\n \"caliber\": \"84 mm (HE / HEAT)\",\n \"length\": 950,\n \"barrel\": 950,\n \"options\": {\n \"lt\": \"carl\"\n }\n },\n \"m2_flamethrower\": {\n \"builder\": \"launcher\",\n \"caliber\": \"Napalm / gasolina gel\",\n \"length\": 1000,\n \"barrel\": 620,\n \"options\": {\n \"lt\": \"flame\"\n }\n },\n \"improvised_flamethrower\": {\n \"builder\": \"launcher\",\n \"caliber\": \"Gasolina + extintor pressurizado\",\n \"length\": 800,\n \"barrel\": 660,\n \"options\": {\n \"lt\": \"flameDIY\"\n }\n },\n \"browning_m2\": {\n \"builder\": \"m2\",\n \"caliber\": \".50 BMG\",\n \"length\": 1650,\n \"barrel\": 1140,\n \"options\": {\n \"rpm\": 550\n }\n },\n \"remington_700_300wm\": {\n \"builder\": \"rifle\",\n \"caliber\": \".308\",\n \"length\": 1100,\n \"barrel\": 610,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1\n },\n \"variantOf\": \"remington_700\"\n },\n \"hk_mp5sd3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 805,\n \"barrel\": 146,\n \"options\": {\n \"mag\": \"curved\",\n \"magLen\": 0.72,\n \"stock\": \"retract\",\n \"stockLen\": 0.22,\n \"hR\": 0.055,\n \"hg\": \"poly\",\n \"hgFrac\": 0.85,\n \"g3\": 1,\n \"rpm\": 700,\n \"sel\": 1,\n \"jacket\": 1,\n \"noFH\": 1,\n \"br\": 0.0115\n },\n \"variantOf\": \"hk_mp5a3\"\n },\n \"fn_parafal\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1020,\n \"barrel\": 440,\n \"options\": {\n \"stock\": \"fold\",\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1.05,\n \"hg\": \"poly\",\n \"hgFrac\": 0.45,\n \"carry\": 1,\n \"brake\": 1,\n \"charge\": 1,\n \"rpm\": 650,\n \"stockLen\": 0.25\n },\n \"variantOf\": \"fn_fal\"\n },\n \"taurus_t4_civil\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 878,\n \"barrel\": 406,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"rail\": 1,\n \"scope\": 1,\n \"ar\": 1,\n \"rpm\": 120\n },\n \"variantOf\": \"taurus_t4\"\n },\n \"taurus_th380\": {\n \"builder\": \"pistol\",\n \"caliber\": \".380 ACP\",\n \"length\": 165,\n \"barrel\": 90,\n \"options\": {\n \"st\": \"g2c\",\n \"gl\": 0.085,\n \"rel\": 1.5\n },\n \"variantOf\": \"taurus_g2c\"\n },\n \"mossberg_500_cruiser\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 720,\n \"barrel\": 470,\n \"options\": {\n \"stock\": \"none\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.055,\n \"noFH\": 1\n },\n \"variantOf\": \"mossberg_500\"\n },\n \"hk_mp5k\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 325,\n \"barrel\": 115,\n \"options\": {\n \"mag\": \"curved\",\n \"magLen\": 0.72,\n \"stock\": \"none\",\n \"stockLen\": 0.22,\n \"hR\": 0.055,\n \"hg\": \"poly\",\n \"hgFrac\": 0.5,\n \"g3\": 1,\n \"rpm\": 900,\n \"sel\": 1\n },\n \"variantOf\": \"hk_mp5a3\"\n },\n \"hk_ump9\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 690,\n \"barrel\": 200,\n \"options\": {\n \"mag\": \"curved\",\n \"magLen\": 1,\n \"stock\": \"skeleton\",\n \"stockLen\": 0.22,\n \"hR\": 0.07,\n \"hg\": \"poly\",\n \"hgFrac\": 0.85,\n \"rpm\": 700,\n \"sel\": 1,\n \"rail\": 1\n },\n \"variantOf\": \"hk_ump_45\"\n },\n \"mini_uzi\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 600,\n \"barrel\": 197,\n \"options\": {\n \"mag\": \"box\",\n \"magAt\": 0.06,\n \"magLen\": 0.9,\n \"stock\": \"fold\",\n \"stockLen\": 0.2,\n \"hR\": 0.065,\n \"hg\": \"poly\",\n \"hgFrac\": 0.4,\n \"grip\": \"none\",\n \"rpm\": 950\n },\n \"variantOf\": \"uzi\"\n },\n \"hk_mp7a1\": {\n \"builder\": \"rifle\",\n \"caliber\": \"4,6×30\",\n \"length\": 638,\n \"barrel\": 180,\n \"options\": {\n \"mag\": \"box\",\n \"magAt\": 0.1,\n \"magLen\": 0.8,\n \"stock\": \"retract\",\n \"stockLen\": 0.2,\n \"hR\": 0.07,\n \"hg\": \"rail\",\n \"hgFrac\": 0.45,\n \"grip\": \"none\",\n \"rail\": 1,\n \"rpm\": 950,\n \"sel\": 1\n }\n },\n \"hk_g36\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 999,\n \"barrel\": 480,\n \"options\": {\n \"stock\": \"fold\",\n \"stockLen\": 0.24,\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1,\n \"hg\": \"poly\",\n \"hgFrac\": 0.5,\n \"hR\": 0.065,\n \"charge\": 1,\n \"sel\": 1,\n \"rpm\": 750,\n \"carry\": 1,\n \"scope\": 2\n }\n },\n \"hk_g36k\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 860,\n \"barrel\": 318,\n \"options\": {\n \"stock\": \"fold\",\n \"stockLen\": 0.24,\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1,\n \"hg\": \"poly\",\n \"hgFrac\": 0.5,\n \"hR\": 0.065,\n \"charge\": 1,\n \"sel\": 1,\n \"rpm\": 750,\n \"carry\": 1,\n \"scope\": 2\n }\n },\n \"hk_g36c\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 720,\n \"barrel\": 228,\n \"options\": {\n \"stock\": \"fold\",\n \"stockLen\": 0.24,\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1,\n \"hg\": \"poly\",\n \"hgFrac\": 0.5,\n \"hR\": 0.065,\n \"charge\": 1,\n \"sel\": 1,\n \"rpm\": 750,\n \"rail\": 1\n }\n },\n \"fn_m249\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 1040,\n \"barrel\": 465,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.35,\n \"bipod\": 1,\n \"hR\": 0.08,\n \"carry\": 1,\n \"charge\": 1,\n \"rpm\": 850\n },\n \"variantOf\": \"fn_minimi\"\n },\n \"fn_minimi_para\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 893,\n \"barrel\": 349,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.35,\n \"bipod\": 1,\n \"hR\": 0.08,\n \"carry\": 1,\n \"charge\": 1,\n \"rpm\": 850,\n \"stockLen\": 0.22\n },\n \"variantOf\": \"fn_minimi\"\n },\n \"fn_mag\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1263,\n \"barrel\": 630,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.35,\n \"bipod\": 1,\n \"carry\": 1,\n \"hR\": 0.085,\n \"br\": 0.011,\n \"charge\": 1,\n \"rpm\": 750\n }\n },\n \"rpk\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×39\",\n \"length\": 1040,\n \"barrel\": 590,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"wood\",\n \"mag\": \"curved\",\n \"hg\": \"wood\",\n \"hgFrac\": 0.42,\n \"gas\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rod\": 1,\n \"bayo\": 0,\n \"rpm\": 600,\n \"rel\": 0.4,\n \"bipod\": 1,\n \"magLen\": 1.4\n },\n \"variantOf\": \"ak_47\"\n },\n \"sig_mpx\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 610,\n \"barrel\": 203,\n \"options\": {\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1,\n \"stock\": \"retract\",\n \"stockLen\": 0.2,\n \"hR\": 0.06,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"rail\": 1,\n \"charge\": 1,\n \"sel\": 1,\n \"rpm\": 850\n }\n },\n \"mg3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1225,\n \"barrel\": 565,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.3,\n \"bipod\": 1,\n \"carry\": 1,\n \"hR\": 0.085,\n \"br\": 0.011,\n \"charge\": 1,\n \"rpm\": 1100\n }\n },\n \"pp19_bizon\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×18\",\n \"length\": 660,\n \"barrel\": 195,\n \"options\": {\n \"mag\": \"helical\",\n \"magLen\": 1,\n \"stock\": \"fold\",\n \"stockLen\": 0.2,\n \"hR\": 0.06,\n \"hg\": \"poly\",\n \"hgFrac\": 0.5,\n \"ak\": 1,\n \"charge\": 1,\n \"rpm\": 680\n }\n },\n \"vz61\": {\n \"builder\": \"rifle\",\n \"caliber\": \".32 ACP\",\n \"length\": 517,\n \"barrel\": 115,\n \"options\": {\n \"mag\": \"curved\",\n \"magLen\": 0.6,\n \"stock\": \"fold\",\n \"stockLen\": 0.2,\n \"hR\": 0.05,\n \"hg\": \"none\",\n \"rpm\": 850,\n \"sel\": 1\n }\n },\n \"m134\": {\n \"builder\": \"m134\",\n \"caliber\": \"7,62×51\",\n \"length\": 801,\n \"barrel\": 559,\n \"options\": {\n \"rpm\": 3000\n }\n }\n}\n","import type * as THREE_NS from 'three'\n\ntype Three = typeof THREE_NS\ntype Axis = 'x' | 'y' | 'z'\n\n// Port of three/examples/jsm/geometries/RoundedBoxGeometry (MIT, three.js authors) onto the host's THREE: the host lends its namespace, not the addon.\nconst uvAlong = (THREE: Three, faceDirection: THREE_NS.Vector3, normal: THREE_NS.Vector3, uvAxis: Axis, projectionAxis: Axis, radius: number, sideLength: number): number => {\n const arcLength = (2 * Math.PI * radius) / 4\n const centerLength = Math.max(sideLength - 2 * radius, 0)\n const halfArc = Math.PI / 4\n const projected = new THREE.Vector3().copy(normal)\n projected[projectionAxis] = 0\n projected.normalize()\n const arcUvRatio = (0.5 * arcLength) / (arcLength + centerLength)\n const arcAngleRatio = 1.0 - projected.angleTo(faceDirection) / halfArc\n if (Math.sign(projected[uvAxis]) === 1) return arcAngleRatio * arcUvRatio\n const centerUv = centerLength / (arcLength + centerLength)\n return centerUv + arcUvRatio + arcUvRatio * (1.0 - arcAngleRatio)\n}\n\ntype Face = { direction: [number, number, number]; u: [Axis, Axis, boolean]; v: [Axis, Axis, boolean] }\n\n// right, left, top, bottom, front, back: the axes each face reads its u and v from, and whether the value is mirrored\nconst FACES: readonly Face[] = [\n { direction: [1, 0, 0], u: ['z', 'y', false], v: ['y', 'z', true] },\n { direction: [-1, 0, 0], u: ['z', 'y', true], v: ['y', 'z', true] },\n { direction: [0, 1, 0], u: ['x', 'z', true], v: ['z', 'x', false] },\n { direction: [0, -1, 0], u: ['x', 'z', true], v: ['z', 'x', true] },\n { direction: [0, 0, 1], u: ['x', 'y', true], v: ['y', 'x', true] },\n { direction: [0, 0, -1], u: ['x', 'y', false], v: ['y', 'x', true] },\n]\n\n/** A box with rounded edges (`segments` per corner) made from the host's BoxGeometry, vertex for vertex like the three.js addon the gallery used. */\nexport function createRoundedBoxGeometry(THREE: Three, width: number, height: number, depth: number, segments: number, radius: number): THREE_NS.BufferGeometry {\n const count = segments * 2 + 1\n const rounding = Math.min(width / 2, height / 2, depth / 2, radius)\n const geometry = new THREE.BoxGeometry(1, 1, 1, count, count, count)\n const flat = geometry.toNonIndexed()\n geometry.setIndex(null)\n geometry.setAttribute('position', flat.attributes.position as THREE_NS.BufferAttribute)\n geometry.setAttribute('normal', flat.attributes.normal as THREE_NS.BufferAttribute)\n geometry.setAttribute('uv', flat.attributes.uv as THREE_NS.BufferAttribute)\n const position = new THREE.Vector3()\n const normal = new THREE.Vector3()\n const box = new THREE.Vector3(width, height, depth).divideScalar(2).subScalar(rounding)\n const positions = geometry.attributes.position.array as Float32Array\n const normals = geometry.attributes.normal.array as Float32Array\n const uvs = geometry.attributes.uv.array as Float32Array\n const faceTriangles = positions.length / 6\n const halfSegment = 0.5 / count\n const sides: Record<Axis, number> = { x: width, y: height, z: depth }\n for (let i = 0, j = 0; i < positions.length; i += 3, j += 2) {\n position.fromArray(positions, i)\n normal.copy(position)\n normal.x -= Math.sign(normal.x) * halfSegment\n normal.y -= Math.sign(normal.y) * halfSegment\n normal.z -= Math.sign(normal.z) * halfSegment\n normal.normalize()\n positions[i] = box.x * Math.sign(position.x) + normal.x * rounding\n positions[i + 1] = box.y * Math.sign(position.y) + normal.y * rounding\n positions[i + 2] = box.z * Math.sign(position.z) + normal.z * rounding\n normals[i] = normal.x\n normals[i + 1] = normal.y\n normals[i + 2] = normal.z\n const face = FACES[Math.floor(i / faceTriangles)]\n if (!face) continue\n const direction = new THREE.Vector3(...face.direction)\n for (const [offset, [uvAxis, projectionAxis, mirrored]] of [[0, face.u], [1, face.v]] as const) {\n const value = uvAlong(THREE, direction, normal, uvAxis, projectionAxis, rounding, sides[uvAxis])\n uvs[j + offset] = mirrored ? 1 - value : value\n }\n }\n return geometry\n}\n","import type * as THREE_NS from 'three'\nimport { createRoundedBoxGeometry } from './rounded-box'\n\ntype Three = typeof THREE_NS\ntype Material = THREE_NS.Material\nexport type Parent = THREE_NS.Object3D\n\nconst PI = Math.PI\n\nconst createMaterials = (THREE: Three) => {\n const standard = (color: number, roughness = 0.7, metalness = 0.2, extra: THREE_NS.MeshStandardMaterialParameters = {}): THREE_NS.MeshStandardMaterial =>\n new THREE.MeshStandardMaterial({ color, roughness, metalness, ...extra })\n const basic = (color: number, extra: THREE_NS.MeshBasicMaterialParameters = {}): THREE_NS.MeshBasicMaterial => new THREE.MeshBasicMaterial({ color, ...extra })\n const additive = { transparent: true, opacity: 0.95, blending: THREE.AdditiveBlending, depthWrite: false }\n return {\n metal: standard(0x34373a, 0.42, 0.75),\n steel: standard(0x6c6f72, 0.32, 0.85),\n steelL: standard(0x8a8d90, 0.28, 0.9),\n dark: standard(0x1a1c1d, 0.55, 0.5),\n poly: standard(0x242622, 0.8, 0.05),\n olive: standard(0x4b5231, 0.8, 0.05),\n tan: standard(0x9c8a63, 0.8, 0.05),\n wood: standard(0x4a2c17, 0.55, 0),\n woodL: standard(0x5e3a1f, 0.55, 0),\n brass: standard(0xc39a45, 0.28, 0.9),\n copper: standard(0xb06a3b, 0.3, 0.85),\n lead: standard(0x6d6f73, 0.5, 0.5),\n shell: standard(0xa3271c, 0.5, 0.05),\n glass: standard(0x7fa3a8, 0.05, 0.1, { transparent: true, opacity: 0.42 }),\n lens: standard(0x23465a, 0.05, 0.3, { transparent: true, opacity: 0.9, emissive: 0x061820 }),\n rubber: standard(0x151515, 0.85, 0),\n white: standard(0xcfc8b4, 0.8, 0),\n hole: standard(0x080807, 1, 0),\n bake: standard(0x5a3220, 0.55, 0),\n rust: standard(0x6b3a1e, 0.95, 0.3),\n rustD: standard(0x4a2a18, 0.95, 0.25),\n worn: standard(0x55585a, 0.6, 0.6),\n fire: basic(0xff7a22),\n fire2: basic(0xffcf5a),\n flashA: basic(0xffb347, additive),\n flashB: basic(0xfff1c0, additive),\n smokeP: standard(0x8a8a86, 1, 0, { transparent: true, opacity: 0.35, depthWrite: false }),\n /** Launcher paints. */\n yellow: standard(0xb08f22, 0.6, 0),\n red: standard(0x8e1c14, 0.45, 0.1),\n redPaint: standard(0xa3231a, 0.35, 0.2),\n tape: standard(0x8a8c88, 0.9, 0),\n pipe: standard(0x9a5a32, 0.35, 0.8),\n green: standard(0x3a4428, 0.75, 0.05),\n /** Magazine finishes named by the options. */\n bakelite: standard(0x6a2e1c, 0.6, 0),\n polyMag: standard(0x2a2a26, 0.85, 0),\n }\n}\nexport type ModelMaterials = ReturnType<typeof createMaterials>\n\n/**\n * The gallery's primitives on the host's three.js. Each takes the parent first and the position last as the page does (`box(parent, w, h, d, material, x, y, z, rz, ry, rx)`),\n * so that the builders read like the originals. `roundness` is the page's `RF`: how round the next boxes are, `null` for the default.\n */\nexport interface ModelKit {\n readonly THREE: Three\n readonly M: ModelMaterials\n roundness: number | null\n group(): THREE_NS.Group\n box(parent: Parent, w: number, h: number, d: number, material: Material, x: number, y: number, z: number, rz?: number, ry?: number, rx?: number): THREE_NS.Mesh\n /** Cylinders along x, y and z. `radiusEnd` makes a cone. */\n cylinderX(parent: Parent, radius: number, length: number, material: Material, x: number, y: number, z: number, segments?: number, radiusEnd?: number): THREE_NS.Mesh\n cylinderY(parent: Parent, radius: number, height: number, material: Material, x: number, y: number, z: number, segments?: number, radiusEnd?: number): THREE_NS.Mesh\n cylinderZ(parent: Parent, radius: number, length: number, material: Material, x: number, y: number, z: number, segments?: number): THREE_NS.Mesh\n sphere(parent: Parent, radius: number, material: Material, x: number, y: number, z: number, detail?: number): THREE_NS.Mesh\n torus(parent: Parent, geometry: THREE_NS.TorusGeometry, material: Material, x: number, y: number, z: number): THREE_NS.Mesh\n mark(parent: Parent, x: number, y: number, z: number): THREE_NS.Object3D\n pivot(parent: Parent, x?: number, y?: number, z?: number): THREE_NS.Group\n}\n\nconst kits = new WeakMap<Three, ModelKit>()\n\n/** One kit per three.js namespace: the materials and the geometry cache are shared by every model built with it. */\nexport function modelKit(THREE: Three): ModelKit {\n const cached = kits.get(THREE)\n if (cached) return cached\n const geometries = new Map<string, THREE_NS.BufferGeometry>()\n const shadowed = <TObject extends THREE_NS.Mesh>(mesh: TObject): TObject => {\n mesh.castShadow = true\n mesh.receiveShadow = true\n return mesh\n }\n const place = (parent: Parent, mesh: THREE_NS.Mesh, x: number, y: number, z: number): THREE_NS.Mesh => {\n mesh.position.set(x, y, z)\n parent.add(mesh)\n return mesh\n }\n const kit: ModelKit = {\n THREE,\n M: createMaterials(THREE),\n roundness: null,\n group: () => new THREE.Group(),\n box(parent, w, h, d, material, x, y, z, rz = 0, ry = 0, rx = 0) {\n const radius = Math.min(w, h, d) * (kit.roundness ?? 0.2)\n const key = `${w.toFixed(4)},${h.toFixed(4)},${d.toFixed(4)},${radius.toFixed(5)}`\n let geometry = geometries.get(key)\n if (!geometry) {\n geometry = radius > 0.00025 ? createRoundedBoxGeometry(THREE, w, h, d, 2, radius) : new THREE.BoxGeometry(w, h, d)\n geometries.set(key, geometry)\n }\n const mesh = place(parent, shadowed(new THREE.Mesh(geometry, material)), x, y, z)\n mesh.rotation.set(rx, ry, rz)\n return mesh\n },\n cylinderX(parent, radius, length, material, x, y, z, segments = 16, radiusEnd) {\n const mesh = shadowed(new THREE.Mesh(new THREE.CylinderGeometry(radiusEnd ?? radius, radius, length, segments), material))\n mesh.rotation.z = -PI / 2\n return place(parent, mesh, x, y, z)\n },\n cylinderY(parent, radius, height, material, x, y, z, segments = 16, radiusEnd) {\n return place(parent, shadowed(new THREE.Mesh(new THREE.CylinderGeometry(radiusEnd ?? radius, radius, height, segments), material)), x, y, z)\n },\n cylinderZ(parent, radius, length, material, x, y, z, segments = 16) {\n const mesh = shadowed(new THREE.Mesh(new THREE.CylinderGeometry(radius, radius, length, segments), material))\n mesh.rotation.x = PI / 2\n return place(parent, mesh, x, y, z)\n },\n sphere(parent, radius, material, x, y, z, detail = 1) {\n return place(parent, shadowed(new THREE.Mesh(new THREE.IcosahedronGeometry(radius, detail), material)), x, y, z)\n },\n torus: (parent, geometry, material, x, y, z) => place(parent, shadowed(new THREE.Mesh(geometry, material)), x, y, z),\n mark(parent, x, y, z) {\n const object = new THREE.Object3D()\n object.position.set(x, y, z)\n parent.add(object)\n return object\n },\n pivot(parent, x = 0, y = 0, z = 0) {\n const group = new THREE.Group()\n group.position.set(x, y, z)\n parent.add(group)\n return group\n },\n }\n kits.set(THREE, kit)\n return kit\n}\n\n/** Gives the mesh its own copy of the material, and lists it among the parts that glow with heat. */\nexport function heatify<TMesh extends THREE_NS.Mesh>(glow: THREE_NS.Mesh[], mesh: TMesh): TMesh {\n mesh.material = (mesh.material as Material).clone()\n glow.push(mesh)\n return mesh\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\n/** Port of the gallery's `shotgunBreak`: the double barrel, hinged at the action so that it opens to reload. */\nexport function buildBreakAction(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box, cylinderX, sphere } = kit\n const group = kit.group()\n const L = (options.L ?? 0) / 1000\n const barrel = (options.B ?? 0) / 1000\n const parts: ModelParts = { family: 'break', kick: 1.6, glow: [] }\n box(group, 0.09, 0.05, 0.042, M.steel, L - barrel - 0.04, -0.005, 0)\n for (let i = 0; i < 4; i++) box(group, 0.05, 0.002, 0.043, M.dark, L - barrel - 0.04, 0.01 - i * 0.008, 0)\n const barrels = kit.pivot(group, L - barrel, -0.01, 0)\n parts.barrels = barrels\n heatify(parts.glow, cylinderX(barrels, 0.0105, barrel, M.steel, barrel / 2, 0.01, 0.011, 18))\n heatify(parts.glow, cylinderX(barrels, 0.0105, barrel, M.steel, barrel / 2, 0.01, -0.011, 18))\n box(barrels, barrel, 0.004, 0.008, M.metal, barrel / 2, 0.022, 0)\n sphere(barrels, 0.002, M.white, barrel - 0.01, 0.026, 0, 1)\n cylinderX(barrels, 0.0075, 0.004, M.hole, barrel + 0.001, 0.01, 0.011, 12)\n cylinderX(barrels, 0.0075, 0.004, M.hole, barrel + 0.001, 0.01, -0.011, 12)\n box(barrels, 0.22, 0.03, 0.038, M.wood, 0.12, -0.01, 0)\n parts.breech = [kit.mark(barrels, 0.004, 0.01, 0.011), kit.mark(barrels, 0.004, 0.01, -0.011)]\n box(group, 0.12, 0.042, 0.032, M.wood, L - barrel - 0.14, -0.022, 0, 0.14)\n box(group, 0.28, 0.07, 0.036, M.wood, 0.15, -0.05, 0, 0.08)\n box(group, 0.012, 0.13, 0.04, M.rubber, 0.006, -0.06, 0)\n box(group, 0.004, 0.014, 0.004, M.dark, L - barrel - 0.05, -0.04, 0)\n parts.trigger = box(group, 0.004, 0.014, 0.004, M.dark, L - barrel - 0.035, -0.04, 0)\n box(group, 0.04, 0.004, 0.01, M.steel, L - barrel - 0.045, -0.05, 0)\n box(group, 0.012, 0.016, 0.006, M.dark, L - barrel - 0.08, 0.022, 0.012, 0.5)\n box(group, 0.012, 0.016, 0.006, M.dark, L - barrel - 0.08, 0.022, -0.012, 0.5)\n parts.safety = box(group, 0.02, 0.006, 0.008, M.steel, L - barrel - 0.07, 0.025, 0)\n parts.muzzle = kit.mark(barrels, barrel + 0.01, 0.01, 0)\n parts.eject = parts.breech[0]\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport type { MountKind } from '@adatechnology/game-weapons'\nimport type { ModelFrames, ModelParts } from '../types'\n\ntype Vec3 = [number, number, number]\nconst DEFAULT_BARREL_RADIUS = 0.0085\nconst DEFAULT_RECEIVER_WIDTH = 0.034\nconst RECEIVER_START_FRACTION = 0.25\nconst RECEIVER_END_FRACTION = 0.55\nconst RECEIVER_HEIGHT_FRACTION = 0.4\nconst DEFAULT_GRIP_OFFSET = 0.07\n// how far the handguard reaches past the receiver, as a fraction of what is left of the barrel, for a model that does not say\nconst HANDGUARD_FRACTION = 0.5\n\n/** The shape of a model that carries its `inner` and `root` as `buildWeaponModelById` makes them. */\nexport interface FramedModel {\n readonly root: THREE_NS.Group\n readonly inner: THREE_NS.Group\n readonly parts: ModelParts\n}\n\n/** Where an accessory of one kind of mount goes, in the space of the wrapper (`root`): the origin of its own frame and the sizes it needs from the weapon. */\nexport interface MountFrame {\n readonly mount: MountKind\n readonly position: Vec3\n /** The other end, for what stretches between two points (a sling between its swivels). */\n readonly secondary?: Vec3\n readonly barrelRadius: number\n readonly receiverWidth: number\n readonly receiverHeight: number\n /** The top rail is drawn: an optic needs no adapter. */\n readonly hasRail: boolean\n /** The sign of z for a side rail: left is negative, right is positive (z is to the right of the weapon). */\n readonly side: -1 | 0 | 1\n}\n\n/**\n * Frames for a model whose builder wrote none (pistols, revolvers, bullpups, launchers...): measured from the model as it is built, with `root` still at the origin.\n * The numbers are in the space of `inner`, like the ones the rifle builder writes.\n */\nexport function deriveFrames(THREE: typeof THREE_NS, model: FramedModel): ModelFrames {\n const { root, inner, parts } = model\n root.updateMatrixWorld(true)\n const box = new THREE.Box3().setFromObject(root)\n const span = box.max.x - box.min.x\n const toInnerX = (x: number): number => (x - inner.position.x) / inner.scale.x\n const muzzle = parts.muzzle?.position\n const length = muzzle ? muzzle.x - 0.01 : toInnerX(box.max.x)\n const receiverStart = toInnerX(box.min.x + span * RECEIVER_START_FRACTION)\n const receiverEnd = toInnerX(box.min.x + span * RECEIVER_END_FRACTION)\n return {\n length,\n barrelY: muzzle?.y ?? (box.max.y + box.min.y) / 2,\n barrelRadius: DEFAULT_BARREL_RADIUS,\n receiverStart,\n receiverEnd,\n receiverHeight: (box.max.y - box.min.y) * RECEIVER_HEIGHT_FRACTION,\n receiverWidth: Math.min(DEFAULT_RECEIVER_WIDTH, box.max.z - box.min.z),\n handguardEnd: receiverEnd + (length - receiverEnd) * HANDGUARD_FRACTION,\n magazineX: parts.mag ? parts.mag.position.x : (receiverStart + receiverEnd) / 2,\n gripX: receiverStart + DEFAULT_GRIP_OFFSET,\n hasRail: false,\n }\n}\n\n/** The frame of a mount of the model, or undefined for the mounts nothing is drawn on (`stock`, `barrel`). */\nexport function mountFrame(model: FramedModel, mount: MountKind): MountFrame | undefined {\n const frames = model.parts.frames\n if (!frames) return undefined\n const { inner } = model\n const toRoot = (x: number, y: number, z: number): Vec3 => [inner.position.x + x * inner.scale.x, y, z]\n const handguardHeight = frames.receiverHeight * 0.8\n const railTopY = frames.receiverHeight / 2 + (frames.hasRail ? 0.006 : 0)\n const forendMiddle = (frames.receiverEnd + frames.handguardEnd) / 2\n const base = { mount, barrelRadius: frames.barrelRadius, receiverWidth: frames.receiverWidth, receiverHeight: frames.receiverHeight, hasRail: frames.hasRail }\n switch (mount) {\n case 'muzzle':\n return { ...base, position: toRoot(frames.length, frames.barrelY, 0), side: 0 }\n case 'rail_top':\n return { ...base, position: toRoot((frames.receiverStart + frames.receiverEnd) / 2 + 0.03, railTopY, 0), side: 0 }\n case 'rail_bottom':\n return { ...base, position: toRoot(forendMiddle, frames.barrelY - handguardHeight / 2, 0), side: 0 }\n case 'rail_left':\n return { ...base, position: toRoot(forendMiddle, frames.barrelY, -(frames.receiverWidth * 0.54 + 0.004)), side: -1 }\n case 'rail_right':\n return { ...base, position: toRoot(forendMiddle, frames.barrelY, frames.receiverWidth * 0.54 + 0.004), side: 1 }\n case 'underbarrel': {\n const [x, y] = frames.underbarrel ?? [frames.receiverEnd + (frames.handguardEnd - frames.receiverEnd) * 0.25, frames.barrelY - handguardHeight / 2 - 0.02]\n return { ...base, position: toRoot(x, y, 0), side: 0 }\n }\n case 'magazine':\n return { ...base, position: toRoot(frames.magazineX, -frames.receiverHeight / 2, 0), side: 0 }\n case 'feed': {\n const belt = model.parts.belt?.position\n return { ...base, position: belt ? toRoot(belt.x, belt.y, belt.z) : toRoot(frames.magazineX + 0.02, -frames.receiverHeight / 2 - 0.05, -0.045), side: -1 }\n }\n case 'sling':\n return {\n ...base,\n position: toRoot(frames.receiverEnd + (frames.length - frames.receiverEnd) * 0.45, -frames.receiverHeight / 2 - 0.03, 0),\n secondary: toRoot(0.08, -0.09, 0),\n side: 0,\n }\n default:\n return undefined\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit, Parent } from './kit'\n\nconst PI = Math.PI\n\n/** A picatinny rail: a dark base and the cross slots, on a pivot so that it can lie on any side of the handguard. */\nexport function rail(kit: ModelKit, parent: Parent, x: number, length: number, y: number, z: number, width: number, rotationX = 0): THREE_NS.Group {\n const { M, box } = kit\n const pivot = kit.pivot(parent, 0, y, z)\n pivot.rotation.x = rotationX\n box(pivot, length, 0.005, width, M.dark, x + length / 2, 0, 0)\n const slots = Math.floor(length / 0.0095)\n for (let i = 0; i < slots; i++) box(pivot, 0.0052, 0.0035, width * 1.12, M.metal, x + 0.006 + i * 0.0095, 0.0035, 0)\n return pivot\n}\n\n/** Cooling slots along a handguard. */\nexport function vents(kit: ModelKit, parent: Parent, x: number, length: number, y: number, z: number, count: number, height: number): void {\n for (let i = 0; i < count; i++) kit.box(parent, (length / count) * 0.45, height, 0.003, kit.M.hole, x + ((i + 0.5) * length) / count, y, z)\n}\n\n/** An optic: 1 red dot, 2 short scope, 3 and 4 long scopes with their rings. */\nexport function scope(kit: ModelKit, parent: Parent, kind: number, cx: number, cy: number, cz = 0): void {\n const { M, box, cylinderX, cylinderY, cylinderZ, THREE } = kit\n if (kind === 1) {\n box(parent, 0.044, 0.01, 0.028, M.dark, cx, cy + 0.005, cz)\n cylinderX(parent, 0.0155, 0.034, M.dark, cx + 0.004, cy + 0.026, cz, 18)\n cylinderX(parent, 0.0125, 0.002, M.lens, cx + 0.022, cy + 0.026, cz, 18)\n cylinderY(parent, 0.004, 0.006, M.dark, cx + 0.004, cy + 0.044, cz, 10)\n return\n }\n if (kind === 2) {\n box(parent, 0.07, 0.012, 0.026, M.dark, cx, cy + 0.006, cz)\n cylinderX(parent, 0.016, 0.1, M.dark, cx - 0.01, cy + 0.032, cz, 18)\n cylinderX(parent, 0.016, 0.035, M.dark, cx + 0.055, cy + 0.032, cz, 18, 0.02)\n cylinderX(parent, 0.017, 0.002, M.lens, cx + 0.073, cy + 0.032, cz, 18)\n cylinderY(parent, 0.007, 0.012, M.dark, cx, cy + 0.052, cz, 12)\n box(parent, 0.03, 0.01, 0.012, M.dark, cx - 0.01, cy + 0.054, cz)\n return\n }\n const sleeve = kind === 4 ? 0.2 : 0.32\n cylinderX(parent, 0.0135, sleeve * 0.55, M.dark, cx, cy + 0.045, cz, 18)\n cylinderX(parent, 0.0135, sleeve * 0.25, M.dark, cx + sleeve * 0.36, cy + 0.045, cz, 18, 0.026)\n cylinderX(parent, 0.026, 0.05, M.dark, cx + sleeve * 0.5, cy + 0.045, cz, 18)\n cylinderX(parent, 0.024, 0.002, M.lens, cx + sleeve * 0.5 + 0.026, cy + 0.045, cz, 18)\n cylinderX(parent, 0.019, 0.06, M.dark, cx - sleeve * 0.38, cy + 0.045, cz, 18, 0.0135)\n cylinderX(parent, 0.019, 0.035, M.rubber, cx - sleeve * 0.38 - 0.045, cy + 0.045, cz, 18)\n cylinderX(parent, 0.017, 0.002, M.lens, cx - sleeve * 0.38 - 0.063, cy + 0.045, cz, 18)\n cylinderY(parent, 0.01, 0.022, M.dark, cx, cy + 0.066, cz, 14)\n cylinderY(parent, 0.011, 0.004, M.metal, cx, cy + 0.078, cz, 14)\n cylinderZ(parent, 0.01, 0.022, M.dark, cx, cy + 0.045, cz + 0.022, 14)\n for (const offset of [-0.07, 0.07]) {\n const ring = kit.torus(parent, new THREE.TorusGeometry(0.0155, 0.003, 8, 20), M.dark, cx + offset, cy + 0.045, cz)\n ring.rotation.y = PI / 2\n box(parent, 0.016, 0.03, 0.022, M.dark, cx + offset, cy + 0.018, cz)\n }\n}\n\nexport const buttpad = (kit: ModelKit, parent: Parent, x: number, y: number, height: number, width: number): void => void kit.box(parent, 0.012, height, width, kit.M.rubber, x, y, 0)\n\nexport const swivel = (kit: ModelKit, parent: Parent, x: number, y: number): void => void kit.torus(parent, new kit.THREE.TorusGeometry(0.006, 0.0015, 6, 12), kit.M.metal, x, y, 0)\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport { rail, scope } from './details'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\n/** Port of the gallery's `bullpup`: the rifle (AUG) or, with `shot`, the twin-tube pump shotgun (KSG). */\nexport function buildBullpup(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box, cylinderX } = kit\n const group = kit.group()\n const L = (options.L ?? 0) / 1000\n const barrel = (options.B ?? 0) / 1000\n const bodyLength = Math.max(0.32, L - barrel * 0.72)\n const body = options.shot ? M.poly : M.olive\n const parts: ModelParts = { family: options.shot ? 'pump' : 'rifle', stroke: 0.06, glow: [] }\n box(group, bodyLength, 0.075, 0.042, body, bodyLength / 2, 0, 0)\n box(group, bodyLength * 0.9, 0.02, 0.044, M.dark, bodyLength * 0.5, -0.02, 0)\n box(group, 0.032, 0.13, 0.044, M.rubber, 0.016, -0.025, 0)\n const gx = bodyLength * 0.8\n const grip = kit.pivot(group, gx, -0.085, 0)\n grip.rotation.z = -0.25\n box(grip, 0.03, 0.1, 0.03, M.poly, 0, 0, 0)\n box(group, 0.1, 0.006, 0.03, body, gx + 0.01, -0.06, 0)\n parts.trigger = box(group, 0.004, 0.016, 0.004, M.dark, gx + 0.02, -0.05, 0, 0.15)\n heatify(parts.glow, cylinderX(group, options.shot ? 0.0105 : 0.0085, barrel, M.metal, L - barrel / 2, 0.012, 0, 16))\n cylinderX(group, 0.006, 0.004, M.hole, L + 0.001, 0.012, 0, 12)\n box(group, 0.05, 0.024, 0.004, M.hole, bodyLength * 0.25, 0.005, 0.0212)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n box(bolt, 0.044, 0.02, 0.006, M.steelL, bodyLength * 0.25, 0.005, 0.02)\n if (options.shot) {\n cylinderX(group, 0.012, bodyLength * 0.75, M.metal, bodyLength * 0.55, -0.025, 0.014, 14)\n cylinderX(group, 0.012, bodyLength * 0.75, M.metal, bodyLength * 0.55, -0.025, -0.014, 14)\n const pump = kit.pivot(group)\n parts.pump = pump\n box(pump, 0.15, 0.045, 0.052, M.poly, bodyLength + 0.06, -0.015, 0)\n for (let i = 0; i < 6; i++) box(pump, 0.006, 0.047, 0.054, M.dark, bodyLength + 0.005 + i * 0.022, -0.015, 0)\n rail(kit, group, bodyLength * 0.15, bodyLength * 0.8, 0.04, 0, 0.02)\n parts.loadPort = kit.mark(group, bodyLength * 0.2, -0.04, 0)\n } else {\n const magazine = kit.pivot(group, gx - 0.11, -0.03, 0)\n magazine.rotation.z = 0.14\n parts.mag = magazine\n box(magazine, 0.05, 0.14, 0.026, M.glass, 0, -0.07, 0)\n for (let i = 0; i < 6; i++) cylinderX(magazine, 0.003, 0.04, M.brass, 0, -0.01 - i * 0.02, 0, 6)\n parts.magDrop = 0.18\n scope(kit, group, 2, bodyLength * 0.5, 0.04, 0)\n box(group, 0.2, 0.03, 0.02, body, bodyLength * 0.62, 0.048, 0)\n box(group, 0.026, 0.075, 0.026, body, bodyLength + 0.05, -0.05, 0, 0.1)\n }\n parts.muzzle = kit.mark(group, L + 0.01, 0.012, 0)\n parts.eject = kit.mark(group, bodyLength * 0.25, 0.005, 0.03)\n return { group, parts }\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { ModelParts } from './types'\n\ntype Point = [number, number, number]\n\nconst hose = (kit: ModelKit, group: THREE.Group, points: Point[], radius: number, material: THREE.Material): void => {\n const { THREE } = kit\n const curve = new THREE.CatmullRomCurve3(points.map((point) => new THREE.Vector3(...point)))\n const tube = new THREE.Mesh(new THREE.TubeGeometry(curve, 40, radius, 8, false), material)\n tube.castShadow = tube.receiveShadow = true\n group.add(tube)\n}\n\n/** The pilot light at the nozzle; its two flames carry `userData.flame` for the effect that flickers them. */\nconst pilot = (kit: ModelKit, group: THREE.Group, x: number, y: number): void => {\n const { M, cylinderX } = kit\n cylinderX(group, 0.006, 0.03, M.fire2, x + 0.015, y, 0, 6, 0).userData.flame = 1\n cylinderX(group, 0.004, 0.022, M.fire, x + 0.012, y, 0, 6, 0).userData.flame = 1\n}\n\n/** The M2 flamethrower: nozzle gun, hose and the two fuel tanks with the pressure bottle and its gauge. */\nexport function buildFlamethrower(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX, cylinderY, sphere } = kit\n parts.kick = 0.15\n heatify(parts.glow, cylinderX(group, 0.016, 0.62, M.steel, 0.42, 0, 0, 14))\n cylinderX(group, 0.022, 0.1, M.dark, 0.78, 0, 0, 14)\n heatify(parts.glow, cylinderX(group, 0.013, 0.1, M.steel, 0.88, 0, 0, 12, 0.009))\n cylinderX(group, 0.018, 0.02, M.metal, 0.73, 0, 0, 14)\n cylinderX(group, 0.012, 0.06, M.metal, 0.84, -0.025, 0, 10)\n pilot(kit, group, 0.92, -0.012)\n const foreGrip = kit.pivot(group, 0.6, -0.02, 0)\n foreGrip.rotation.z = -0.1\n box(foreGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n const lever = kit.pivot(group, 0.62, -0.02, 0)\n parts.trigger = box(lever, 0.008, 0.05, 0.006, M.metal, 0.02, -0.03, 0, 0.3)\n const rearGrip = kit.pivot(group, 0.17, -0.02, 0)\n rearGrip.rotation.z = -0.28\n box(rearGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n box(group, 0.05, 0.004, 0.012, M.metal, 0.2, -0.035, 0)\n cylinderX(group, 0.02, 0.04, M.metal, 0.1, 0, 0, 12)\n hose(kit, group, [[0.08, 0, 0], [0, -0.04, 0], [-0.08, -0.2, 0.05], [-0.18, -0.32, 0.08], [-0.25, -0.33, 0.08]], 0.011, M.rubber)\n for (const z of [-0.1, 0.1]) {\n cylinderY(group, 0.085, 0.5, M.olive, -0.3, -0.05, z, 20)\n sphere(group, 0.085, M.olive, -0.3, 0.2, z, 2).scale.y = 0.45\n sphere(group, 0.085, M.olive, -0.3, -0.3, z, 2).scale.y = 0.45\n cylinderY(group, 0.03, 0.03, M.metal, -0.3, 0.24, z, 12)\n }\n sphere(group, 0.075, M.olive, -0.3, 0.1, 0, 2).position.x = -0.39\n box(group, 0.03, 0.6, 0.24, M.dark, -0.4, -0.05, 0)\n cylinderY(group, 0.03, 0.012, M.metal, -0.39, 0.18, 0, 14)\n const gauge = kit.pivot(group, -0.39, 0.18, 0.003)\n parts.gauge = gauge\n box(gauge, 0.002, 0.022, 0.002, M.red, 0, 0.008, 0.012)\n parts.muzzle = kit.pivot(group, 0.94, 0, 0)\n parts.rear = kit.pivot(group, 0.1, 0, 0)\n}\n\n/** The improvised flamethrower: a copper pipe, a fire extinguisher as the tank and a rubber hose. */\nexport function buildImprovisedFlamethrower(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX, cylinderY, sphere } = kit\n parts.kick = 0.12\n heatify(parts.glow, cylinderX(group, 0.011, 0.66, M.pipe, 0.38, 0, 0, 12))\n heatify(parts.glow, cylinderX(group, 0.015, 0.06, M.steel, 0.74, 0, 0, 12, 0.01))\n cylinderX(group, 0.006, 0.05, M.metal, 0.735, -0.02, 0, 8)\n pilot(kit, group, 0.77, -0.02)\n cylinderY(group, 0.012, 0.04, M.redPaint, 0.72, -0.055, 0, 10)\n box(group, 0.02, 0.03, 0.012, M.dark, 0.72, -0.085, 0)\n cylinderX(group, 0.06, 0.42, M.redPaint, 0.3, -0.09, 0, 22)\n sphere(group, 0.06, M.redPaint, 0.51, -0.09, 0, 2).scale.x = 0.5\n sphere(group, 0.06, M.redPaint, 0.09, -0.09, 0, 2).scale.x = 0.5\n cylinderX(group, 0.02, 0.04, M.dark, 0.04, -0.09, 0, 12)\n box(group, 0.02, 0.06, 0.005, M.white, 0.3, -0.09, 0.06)\n for (const x of [0.15, 0.3, 0.45]) cylinderX(group, 0.063, 0.03, M.tape, x, -0.09, 0, 22)\n cylinderX(group, 0.016, 0.03, M.tape, 0.3, 0, 0, 12)\n hose(kit, group, [[0.04, -0.09, 0], [-0.02, -0.06, 0.02], [0, 0, 0.02], [0.05, 0, 0]], 0.007, M.rubber)\n const rearGrip = kit.pivot(group, 0.12, -0.01, 0)\n rearGrip.rotation.z = -0.3\n box(rearGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n const lever = kit.pivot(group, 0.17, -0.02, 0)\n parts.trigger = box(lever, 0.008, 0.04, 0.006, M.metal, 0, -0.02, 0, 0.2)\n parts.muzzle = kit.pivot(group, 0.78, 0, 0)\n parts.rear = kit.pivot(group, 0.05, 0, 0)\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\n\nconst PI = Math.PI\n\n/** The PG-7V grenade of the RPG-7: warhead, body and the booster. */\nexport function buildRocketGrenade(kit: ModelKit): THREE.Group {\n const { M, cylinderX } = kit\n const round = kit.group()\n cylinderX(round, 0.018, 0.15, M.olive, -0.05, 0, 0, 14)\n cylinderX(round, 0.02, 0.07, M.olive, 0.035, 0, 0, 18, 0.0425)\n cylinderX(round, 0.0425, 0.12, M.olive, 0.13, 0, 0, 20)\n cylinderX(round, 0.0428, 0.012, M.dark, 0.09, 0, 0, 20)\n cylinderX(round, 0.0425, 0.13, M.olive, 0.255, 0, 0, 20, 0.011)\n cylinderX(round, 0.011, 0.03, M.metal, 0.335, 0, 0, 10, 0.004)\n return round\n}\n\n/** The 84 mm round of the Carl Gustaf. */\nexport function buildRecoillessRound(kit: ModelKit): THREE.Group {\n const { M, cylinderX } = kit\n const round = kit.group()\n cylinderX(round, 0.041, 0.32, M.green, -0.16, 0, 0, 20)\n cylinderX(round, 0.0415, 0.02, M.yellow, -0.05, 0, 0, 20)\n cylinderX(round, 0.041, 0.12, M.green, 0.06, 0, 0, 20, 0.012)\n cylinderX(round, 0.043, 0.03, M.brass, -0.33, 0, 0, 20)\n return round\n}\n\n/** The rocket that flies off a disposable tube or a rocket launcher without a model of its own round. */\nexport function buildFlyingRocket(kit: ModelKit, launcherType: string | undefined): THREE.Group {\n const { M, box, cylinderX } = kit\n const rocket = kit.group()\n const diameter = launcherType === 'at4' || launcherType === 'carl' ? 0.041 : 0.032\n cylinderX(rocket, diameter * 0.5, 0.2, M.dark, -0.1, 0, 0, 10)\n cylinderX(rocket, diameter, 0.3, M.olive, 0.15, 0, 0, 18)\n cylinderX(rocket, diameter, 0.12, M.olive, 0.36, 0, 0, 18, diameter * 0.25)\n for (let i = 0; i < 4; i++) {\n const fin = box(rocket, 0.06, 0.002, diameter * 1.4, M.metal, -0.17, 0, 0)\n fin.rotation.x = (i * PI) / 4\n }\n return rocket\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport { buildRecoillessRound, buildRocketGrenade } from './launcher-rounds'\nimport type { ModelParts } from './types'\n\n/** The RPG-7: tube, wooden heat shield, two grips, optic and the grenade in the muzzle. */\nfunction buildRpg(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX } = kit\n parts.kick = 1.6\n cylinderX(group, 0.036, 0.13, M.dark, 0.065, 0, 0, 20, 0.021)\n cylinderX(group, 0.038, 0.012, M.metal, 0, 0, 0, 20)\n heatify(parts.glow, cylinderX(group, 0.021, 0.83, M.steel, 0.545, 0, 0, 18))\n cylinderX(group, 0.03, 0.3, M.wood, 0.47, 0, 0, 16)\n cylinderX(group, 0.031, 0.012, M.metal, 0.32, 0, 0, 16)\n cylinderX(group, 0.031, 0.012, M.metal, 0.62, 0, 0, 16)\n cylinderX(group, 0.024, 0.02, M.metal, 0.94, 0, 0, 16)\n box(group, 0.09, 0.03, 0.032, M.metal, 0.46, -0.028, 0)\n const frontGrip = kit.pivot(group, 0.4, -0.04, 0)\n frontGrip.rotation.z = -0.22\n box(frontGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n const rearGrip = kit.pivot(group, 0.5, -0.04, 0)\n rearGrip.rotation.z = -0.18\n box(rearGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n box(group, 0.06, 0.004, 0.012, M.metal, 0.53, -0.05, 0)\n box(group, 0.004, 0.025, 0.012, M.metal, 0.56, -0.04, 0)\n parts.trigger = box(group, 0.004, 0.018, 0.004, M.dark, 0.535, -0.045, 0, 0.15)\n const hammer = kit.pivot(group, 0.44, -0.012, 0)\n parts.hammer = hammer\n box(hammer, 0.012, 0.02, 0.01, M.dark, 0, 0, 0)\n box(group, 0.006, 0.03, 0.006, M.dark, 0.78, 0.032, 0)\n box(group, 0.02, 0.022, 0.014, M.dark, 0.46, 0.032, 0)\n box(group, 0.12, 0.042, 0.032, M.dark, 0.5, 0.04, -0.04)\n cylinderX(group, 0.013, 0.05, M.rubber, 0.42, 0.048, -0.04, 14)\n cylinderX(group, 0.016, 0.004, M.lens, 0.565, 0.048, -0.04, 14)\n box(group, 0.04, 0.012, 0.012, M.metal, 0.5, 0.016, -0.03)\n const round = buildRocketGrenade(kit)\n round.position.x = 0.95\n group.add(round)\n parts.round = round\n parts.roundRest = 0.95\n parts.makeRound = () => buildRocketGrenade(kit)\n parts.muzzle = kit.pivot(group, 0.95, 0, 0)\n parts.rear = kit.pivot(group, 0, 0, 0)\n}\n\n/** The M72 LAW: a disposable tube with its sight flaps and the firing pin. */\nfunction buildM72(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX, cylinderY } = kit\n parts.kick = 1.1\n parts.disposable = true\n heatify(parts.glow, cylinderX(group, 0.0365, 0.6, M.olive, 0.58, 0, 0, 20))\n cylinderX(group, 0.032, 0.32, M.olive, 0.16, 0, 0, 20)\n cylinderX(group, 0.039, 0.03, M.rubber, 0.866, 0, 0, 20)\n cylinderX(group, 0.035, 0.025, M.rubber, 0.012, 0, 0, 20)\n cylinderX(group, 0.037, 0.015, M.yellow, 0.8, 0, 0, 20)\n cylinderX(group, 0.037, 0.012, M.dark, 0.3, 0, 0, 20)\n box(group, 0.004, 0.05, 0.05, M.dark, 0.79, 0.055, 0)\n box(group, 0.004, 0.006, 0.04, M.dark, 0.79, 0.078, 0)\n box(group, 0.004, 0.035, 0.024, M.dark, 0.38, 0.05, 0)\n cylinderY(group, 0.004, 0.006, M.lens, 0.38, 0.064, 0, 8)\n parts.trigger = box(group, 0.05, 0.016, 0.024, M.rubber, 0.5, 0.042, 0)\n box(group, 0.1, 0.01, 0.03, M.dark, 0.47, 0.036, 0)\n box(group, 0.02, 0.03, 0.01, M.dark, 0.66, -0.035, 0.03)\n box(group, 0.008, 0.03, 0.008, M.metal, 0.25, -0.04, 0.03)\n parts.muzzle = kit.pivot(group, 0.881, 0, 0)\n parts.rear = kit.pivot(group, 0, 0, 0)\n}\n\n/** The AT4: a heavier disposable tube with the fire-control box and the front grip. */\nfunction buildAt4(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX } = kit\n parts.kick = 1.3\n parts.disposable = true\n heatify(parts.glow, cylinderX(group, 0.05, 0.86, M.olive, 0.51, 0, 0, 24))\n cylinderX(group, 0.056, 0.08, M.dark, 0.98, 0, 0, 24)\n cylinderX(group, 0.058, 0.07, M.dark, 0.04, 0, 0, 24, 0.05)\n cylinderX(group, 0.051, 0.015, M.yellow, 0.86, 0, 0, 24)\n box(group, 0.16, 0.026, 0.05, M.dark, 0.42, 0.058, 0)\n box(group, 0.03, 0.012, 0.016, M.red, 0.47, 0.075, 0)\n parts.trigger = box(group, 0.022, 0.012, 0.018, M.rubber, 0.5, 0.074, 0)\n box(group, 0.012, 0.07, 0.02, M.dark, 0.35, 0.09, -0.035)\n box(group, 0.012, 0.05, 0.02, M.dark, 0.71, 0.08, -0.035)\n const grip = kit.pivot(group, 0.68, -0.05, 0)\n grip.rotation.z = -0.15\n box(grip, 0.035, 0.11, 0.032, M.dark, 0, -0.05, 0)\n box(group, 0.14, 0.035, 0.06, M.rubber, 0.32, -0.06, 0)\n box(group, 0.3, 0.012, 0.055, M.dark, 0.5, -0.05, 0)\n parts.muzzle = kit.pivot(group, 1.02, 0, 0)\n parts.rear = kit.pivot(group, 0, 0, 0)\n}\n\n/** The Carl Gustaf M4: a reusable recoilless rifle with a hinged breech that takes a round from behind. */\nfunction buildCarlGustaf(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX } = kit\n parts.kick = 1.4\n heatify(parts.glow, cylinderX(group, 0.045, 0.72, M.dark, 0.59, 0, 0, 24))\n cylinderX(group, 0.05, 0.04, M.rubber, 0.93, 0, 0, 24)\n const breech = kit.pivot(group, 0.21, 0, 0.05)\n parts.breech = [breech]\n cylinderX(breech, 0.06, 0.16, M.dark, -0.1, 0, -0.05, 24, 0.046)\n cylinderX(breech, 0.062, 0.015, M.metal, -0.18, 0, -0.05, 24)\n box(group, 0.025, 0.03, 0.02, M.metal, 0.22, 0, 0.052)\n const foreGrip = kit.pivot(group, 0.62, -0.05, 0)\n foreGrip.rotation.z = -0.2\n box(foreGrip, 0.035, 0.11, 0.034, M.dark, 0, -0.05, 0)\n parts.trigger = box(group, 0.004, 0.018, 0.004, M.dark, 0.66, -0.06, 0, 0.15)\n box(group, 0.06, 0.004, 0.012, M.metal, 0.66, -0.07, 0)\n const rearGrip = kit.pivot(group, 0.4, -0.05, 0)\n rearGrip.rotation.z = -0.25\n box(rearGrip, 0.035, 0.1, 0.034, M.dark, 0, -0.05, 0)\n box(group, 0.13, 0.04, 0.07, M.rubber, 0.28, -0.065, 0)\n box(group, 0.16, 0.05, 0.045, M.dark, 0.56, 0.07, -0.035)\n cylinderX(group, 0.016, 0.05, M.rubber, 0.46, 0.075, -0.035, 14)\n cylinderX(group, 0.02, 0.004, M.lens, 0.645, 0.075, -0.035, 14)\n box(group, 0.06, 0.02, 0.02, M.metal, 0.56, 0.04, -0.03)\n box(group, 0.22, 0.01, 0.02, M.dark, 0.6, 0.06, 0.03)\n box(group, 0.01, 0.03, 0.02, M.dark, 0.5, 0.05, 0.03)\n box(group, 0.01, 0.03, 0.02, M.dark, 0.7, 0.05, 0.03)\n parts.makeRound = () => buildRecoillessRound(kit)\n parts.muzzle = kit.pivot(group, 0.95, 0, 0)\n parts.rear = kit.pivot(group, 0.05, 0, 0)\n}\n\nexport const ROCKET_BUILDERS: Record<string, (kit: ModelKit, group: THREE.Group, parts: ModelParts) => void> = {\n rpg: buildRpg,\n m72: buildM72,\n at4: buildAt4,\n carl: buildCarlGustaf,\n}\n","import type { ModelKit } from './kit'\nimport { buildFlamethrower, buildImprovisedFlamethrower } from './launcher-flame'\nimport { ROCKET_BUILDERS } from './launcher-rocket'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\n/** Port of the gallery's `launcher`: the four rocket launchers and the two flamethrowers, picked by `lt`. */\nexport function buildLauncher(kit: ModelKit, options: ModelOptions): BuiltModel {\n const group = kit.group()\n const type = options.lt ?? ''\n const isFlame = type === 'flame' || type === 'flameDIY'\n const parts: ModelParts = { family: isFlame ? 'flame' : 'rocket', launcherType: type, glow: [] }\n if (type === 'flame') buildFlamethrower(kit, group, parts)\n else if (type === 'flameDIY') buildImprovisedFlamethrower(kit, group, parts)\n else ROCKET_BUILDERS[type]?.(kit, group, parts)\n parts.eject = parts.muzzle\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { BuiltModel, ModelParts } from './types'\n\nconst PI = Math.PI\nconst BARRELS = 6\n// the barrels sit on a circle around the rotor axis\nconst CLUSTER_RADIUS = 0.03\nconst BARREL_RADIUS = 0.0078\nconst BARREL_END = 0.8\n\n/** The six barrels and their clamps in one pivot on the rotor axis: the viewmodel turns `parts.barrels` while the gun fires. */\nfunction buildBarrelCluster(kit: ModelKit, parts: ModelParts, group: BuiltModel['group']): void {\n const { M, cylinderX } = kit\n const barrels = kit.pivot(group, 0, 0, 0)\n parts.barrels = barrels\n const length = BARREL_END - 0.3\n let heated: THREE_NS.Material | undefined\n for (let i = 0; i < BARRELS; i++) {\n const angle = (i * 2 * PI) / BARRELS\n const y = Math.cos(angle) * CLUSTER_RADIUS\n const z = Math.sin(angle) * CLUSTER_RADIUS\n const barrel = cylinderX(barrels, BARREL_RADIUS, length, M.metal, 0.3 + length / 2, y, z, 14)\n // the six barrels heat together: one material of their own, shared\n if (heated) barrel.material = heated\n else heated = heatify(parts.glow, barrel).material as THREE_NS.Material\n cylinderX(barrels, BARREL_RADIUS * 0.55, 0.004, M.hole, BARREL_END + 0.0005, y, z, 10)\n }\n cylinderX(barrels, 0.012, length, M.steel, 0.3 + length / 2, 0, 0, 12)\n for (const x of [0.42, 0.58, 0.74]) cylinderX(barrels, CLUSTER_RADIUS + BARREL_RADIUS * 1.6, 0.014, M.steel, x, 0, 0, 24)\n cylinderX(barrels, CLUSTER_RADIUS + BARREL_RADIUS * 1.8, 0.03, M.dark, BARREL_END - 0.015, 0, 0, 24)\n}\n\n/** Housing with the motor, the rotor housing and the two spade grips with the trigger switch of the hand-held gun. */\nfunction buildHousing(kit: ModelKit, parts: ModelParts, group: BuiltModel['group']): void {\n const { M, box, cylinderX, cylinderZ } = kit\n box(group, 0.3, 0.14, 0.15, M.metal, 0.18, 0, 0)\n cylinderX(group, 0.052, 0.12, M.dark, 0.06, 0, 0, 20)\n cylinderX(group, 0.062, 0.2, M.dark, 0.38, 0, 0, 22)\n for (let i = 0; i < 4; i++) cylinderX(group, 0.064, 0.008, M.steel, 0.3 + i * 0.05, 0, 0, 22)\n box(group, 0.04, 0.05, 0.2, M.dark, 0.1, 0.095, 0)\n box(group, 0.2, 0.012, 0.045, M.dark, 0.22, 0.158, 0)\n box(group, 0.012, 0.05, 0.045, M.dark, 0.13, 0.13, 0)\n box(group, 0.012, 0.05, 0.045, M.dark, 0.31, 0.13, 0)\n for (const side of [-1, 1]) {\n box(group, 0.03, 0.03, 0.1, M.poly, 0.06, -0.01, side * 0.14)\n cylinderZ(group, 0.016, 0.07, M.poly, 0.06, -0.01, side * 0.2, 14)\n }\n parts.trigger = box(group, 0.012, 0.02, 0.016, M.dark, 0.1, 0.085, 0.14, 0.3)\n parts.safety = box(group, 0.014, 0.006, 0.01, M.dark, 0.2, 0.073, -0.076, 0.4)\n}\n\n/** The belt box on the left, the feed chute that carries the belt to the rotor, the cover over it and the charging piece. */\nfunction buildFeed(kit: ModelKit, parts: ModelParts, group: BuiltModel['group']): void {\n const { M, box, cylinderX } = kit\n const belt = kit.pivot(group, 0.2, -0.13, -0.16)\n parts.belt = belt\n box(belt, 0.16, 0.12, 0.1, M.olive, 0, 0, 0)\n box(belt, 0.162, 0.012, 0.102, M.dark, 0, 0.056, 0)\n for (let i = 0; i < 8; i++) cylinderX(belt, 0.0046, 0.04, M.brass, -0.07 + i * 0.02, 0.075, 0.04, 10)\n box(group, 0.1, 0.03, 0.1, M.metal, 0.22, -0.06, -0.1, 0, 0, 0.5)\n const cover = kit.pivot(group, 0.1, 0.075, 0)\n parts.cover = cover\n box(cover, 0.24, 0.012, 0.15, M.metal, 0.12, 0.006, 0)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n parts.stroke = 0.03\n box(bolt, 0.03, 0.012, 0.012, M.steelL, 0.28, 0.02, 0.078)\n}\n\n/** The M134 Minigun: a rotary machine gun of six barrels, electric driven, belt fed. A creation of the kit (the team pages have none): there is no page golden, the model has its own. */\nexport function buildM134(kit: ModelKit): BuiltModel {\n const group = kit.group()\n const parts: ModelParts = { family: 'belt', kick: 0.9, glow: [] }\n buildHousing(kit, parts, group)\n buildBarrelCluster(kit, parts, group)\n buildFeed(kit, parts, group)\n parts.frames = {\n length: BARREL_END,\n barrelY: 0,\n barrelRadius: BARREL_RADIUS,\n receiverStart: 0.06,\n receiverEnd: 0.48,\n receiverHeight: 0.14,\n receiverWidth: 0.15,\n handguardEnd: 0.6,\n magazineX: 0.2,\n gripX: 0.06,\n hasRail: false,\n // the tripod head, where the gun balances (the tripod of the counters joins here too)\n underbarrel: [0.4, -0.1],\n }\n parts.muzzle = kit.mark(group, BARREL_END + 0.01, 0, 0)\n parts.eject = kit.mark(group, 0.3, -0.07, 0.08)\n return { group, parts }\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { BuiltModel, ModelParts } from './types'\n\n/** Port of the gallery's `m2`: the Browning .50 on its tripod, with the cover, the belt box and the bolt. */\nexport function buildM2(kit: ModelKit): BuiltModel {\n const { M, box, cylinderX, cylinderZ } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'belt', kick: 2.2, stroke: 0.08, glow: [] }\n box(group, 0.52, 0.13, 0.12, M.metal, 0.36, 0, 0)\n for (let i = 0; i < 5; i++) cylinderZ(group, 0.006, 0.124, M.dark, 0.15 + i * 0.1, -0.03, 0, 10)\n heatify(parts.glow, cylinderX(group, 0.016, 1.14, M.metal, 1.14, 0.01, 0, 16))\n cylinderX(group, 0.034, 0.24, M.dark, 0.74, 0.01, 0, 16)\n for (let i = 0; i < 6; i++) cylinderX(group, 0.036, 0.012, M.metal, 0.66 + i * 0.035, 0.01, 0, 16)\n cylinderX(group, 0.022, 0.05, M.dark, 1.69, 0.01, 0, 16)\n box(group, 0.04, 0.09, 0.03, M.wood, 0.05, -0.02, 0.05)\n box(group, 0.04, 0.09, 0.03, M.wood, 0.05, -0.02, -0.05)\n box(group, 0.06, 0.02, 0.12, M.metal, 0.09, -0.02, 0)\n const belt = kit.pivot(group, 0.38, -0.05, -0.12)\n parts.belt = belt\n box(belt, 0.16, 0.12, 0.09, M.olive, 0, 0, 0)\n for (let i = 0; i < 8; i++) cylinderX(belt, 0.006, 0.05, M.brass, -0.08 + i * 0.02, 0.08, 0.04, 8)\n const cover = kit.pivot(group, 0.12, 0.065, 0)\n parts.cover = cover\n box(cover, 0.4, 0.012, 0.12, M.metal, 0.2, 0.006, 0)\n box(group, 0.04, 0.05, 0.04, M.dark, 0.66, 0.1, 0)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n box(bolt, 0.03, 0.03, 0.02, M.metal, 0.5, 0, 0.07)\n const tripod = kit.group()\n tripod.position.set(0.42, -0.1, 0)\n group.add(tripod)\n box(tripod, 0.03, 0.06, 0.03, M.metal, 0, 0, 0)\n box(tripod, 0.012, 0.62, 0.012, M.metal, -0.2, -0.25, 0, 0.75)\n box(tripod, 0.012, 0.62, 0.012, M.metal, 0.22, -0.25, 0.16, -0.75, 0, 0.3)\n box(tripod, 0.012, 0.62, 0.012, M.metal, 0.22, -0.25, -0.16, -0.75, 0, -0.3)\n parts.muzzle = kit.mark(group, 1.72, 0.01, 0)\n parts.eject = kit.mark(group, 0.3, -0.07, 0)\n return { group, parts }\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport { scope } from './details'\nimport type { BuiltModel, ModelParts } from './types'\n\n/** Port of the gallery's `p90`: the bullpup with the horizontal magazine on top. */\nexport function buildP90(kit: ModelKit): BuiltModel {\n const { M, box, cylinderX } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'p90', stroke: 0.04, kick: 0.6, glow: [] }\n box(group, 0.4, 0.07, 0.055, M.poly, 0.2, 0, 0)\n box(group, 0.12, 0.075, 0.05, M.poly, 0.2, -0.07, 0)\n box(group, 0.08, 0.04, 0.03, M.hole, 0.21, -0.06, 0)\n box(group, 0.06, 0.13, 0.056, M.poly, 0.03, -0.03, 0)\n box(group, 0.05, 0.03, 0.056, M.poly, 0.33, -0.04, 0)\n heatify(parts.glow, cylinderX(group, 0.008, 0.09, M.metal, 0.43, 0, 0, 16))\n const magazine = kit.pivot(group, 0.22, 0.047, 0)\n parts.mag = magazine\n parts.magDir = 1\n parts.magDrop = 0.08\n box(magazine, 0.3, 0.022, 0.05, M.glass, 0, 0, 0)\n for (let i = 0; i < 12; i++) cylinderX(magazine, 0.0028, 0.02, M.brass, -0.12 + i * 0.022, 0, 0, 6)\n scope(kit, group, 1, 0.24, 0.06, 0)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n box(bolt, 0.02, 0.012, 0.012, M.dark, 0.3, 0.02, 0.03)\n parts.trigger = box(group, 0.004, 0.016, 0.004, M.dark, 0.24, -0.045, 0)\n parts.muzzle = kit.mark(group, 0.48, 0, 0)\n parts.eject = kit.mark(group, 0.2, -0.07, 0)\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelParts } from './types'\n\nconst SINGLE_PARTS = ['slide', 'bolt', 'boltHandle', 'mag', 'trigger', 'hammer', 'lever', 'pump', 'belt', 'cover', 'crane', 'cylinder', 'barrels', 'safety', 'muzzle', 'eject', 'loadPort', 'topLoad', 'rear', 'round', 'gauge', 'stock', 'ugl'] as const\n\n/** The parts of a model by the id the clips use: `slide`, `mag`, `trigger`..., `breech_0`, `chamber_3`. */\nexport function partRegistry(parts: ModelParts): Map<string, THREE_NS.Object3D> {\n const registry = new Map<string, THREE_NS.Object3D>()\n for (const key of SINGLE_PARTS) {\n const part = parts[key]\n if (part) registry.set(key, part)\n }\n parts.breech?.forEach((part, index) => registry.set(`breech_${index}`, part))\n parts.chambers?.forEach((part, index) => registry.set(`chamber_${index}`, part))\n return registry\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { Material, PistolSize, PistolStyle } from './pistol-style'\nimport type { ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\n\n/** The slide: its body by style, serrations, ejection port, barrel tip, sights and the small controls that ride on it. */\nexport function buildSlide(kit: ModelKit, slide: THREE.Group, parts: ModelParts, options: ModelOptions, style: PistolStyle, size: PistolSize, metal: Material): void {\n const { M, box, cylinderX } = kit\n const { length: L, width: w } = size\n const slideHeight = style.inset ? size.height * 0.92 : size.height\n const slideWidth = style.inset ? w * 0.86 : w\n kit.roundness = style.rf\n if (style.tri) box(slide, L * 0.42, slideHeight, slideWidth, metal, L * 0.21, 0, 0)\n else if (style.open) {\n box(slide, L * 0.45, slideHeight, slideWidth, metal, L * 0.225, 0, 0)\n box(slide, L * 0.55, slideHeight * 0.62, slideWidth, metal, L * 0.72, -slideHeight * 0.19, 0)\n } else box(slide, L, slideHeight, slideWidth, metal, L / 2, 0, 0)\n if (style.slope) box(slide, L * 0.25, slideHeight * 0.5, slideWidth * 0.98, metal, L * 0.86, slideHeight * 0.35, 0, -0.22)\n kit.roundness = null\n for (let i = 0; i < (style.flush ? 9 : 7); i++) box(slide, 0.0022, slideHeight * 0.72, slideWidth + 0.0014, M.dark, 0.007 + i * 0.0052, -0.002, 0, 0)\n if (style.frontSer) for (let i = 0; i < 5; i++) box(slide, 0.0022, slideHeight * 0.6, slideWidth + 0.0014, M.dark, L * 0.76 + i * 0.0052, -0.003, 0)\n if (style.port) {\n box(slide, L * style.port, 0.004, slideWidth * 0.55, M.hole, L * 0.6, slideHeight / 2 - 0.001, slideWidth * 0.12)\n box(slide, L * style.port * 0.85, 0.003, slideWidth * 0.4, M.steelL, L * 0.6, slideHeight / 2 - 0.0004, slideWidth * 0.1)\n box(slide, 0.012, 0.004, 0.002, M.dark, L * 0.55, slideHeight * 0.15, slideWidth / 2 + 0.0008)\n }\n if (style.open) {\n heatify(parts.glow, cylinderX(slide, 0.0062, L * 0.56, M.steelL, L * 0.7, slideHeight * 0.12, 0, 18))\n box(slide, 0.03, 0.004, slideWidth * 0.6, M.hole, L * 0.48, slideHeight / 2 - 0.001, 0)\n }\n if (style.tri) {\n const tube = new kit.THREE.Mesh(new kit.THREE.CylinderGeometry(0.016, 0.016, L * 0.6, 3), metal)\n tube.castShadow = tube.receiveShadow = true\n tube.rotation.set(0, 0, -PI / 2)\n tube.rotateY(PI / 6)\n tube.position.set(L * 0.7, slideHeight * 0.08, 0)\n slide.add(tube)\n heatify(parts.glow, tube)\n box(slide, L * 0.6, 0.006, 0.012, metal, L * 0.7, slideHeight * 0.38, 0)\n for (let i = 0; i < 6; i++) box(slide, 0.008, 0.003, 0.013, M.hole, L * 0.45 + i * 0.04, slideHeight * 0.41, 0)\n }\n if (style.bushing) {\n heatify(parts.glow, cylinderX(slide, 0.0078, 0.006, M.steelL, L + 0.002, 0.001, 0, 18))\n cylinderX(slide, 0.0045, 0.004, M.steel, L + 0.002, -0.012, 0, 12)\n }\n const muzzleY = style.tri ? slideHeight * 0.08 : 0.002\n heatify(parts.glow, cylinderX(slide, style.tri ? 0.0072 : 0.0062, 0.004, M.dark, L + 0.0015, muzzleY, 0, 18))\n cylinderX(slide, 0.0034, 0.005, M.hole, L + 0.0025, muzzleY, 0, 12)\n const top = slideHeight / 2\n if (style.sight === 'u' || style.sight === '3dot') {\n box(slide, 0.004, 0.007, 0.004, M.dark, L - 0.008, top + 0.0035, 0)\n box(slide, 0.0022, 0.0022, 0.0046, M.white, L - 0.008, top + 0.0058, 0)\n box(slide, 0.008, 0.007, 0.016, M.dark, 0.009, top + 0.0035, 0)\n if (style.sight === 'u') box(slide, 0.004, 0.002, 0.0122, M.white, 0.009, top + 0.006, 0)\n else box(slide, 0.0022, 0.0022, 0.0166, M.white, 0.009, top + 0.0058, 0)\n } else {\n box(slide, 0.006, 0.004, 0.003, M.dark, L - 0.006, top + 0.002, 0)\n box(slide, 0.006, 0.004, 0.012, M.dark, 0.008, top + 0.002, 0)\n }\n if (style.decock === 'slide') {\n box(slide, 0.012, 0.008, 0.004, M.dark, 0.02, slideHeight * 0.15, slideWidth / 2 + 0.002, 0.3)\n box(slide, 0.012, 0.008, 0.004, M.dark, 0.02, slideHeight * 0.15, -slideWidth / 2 - 0.002, 0.3)\n }\n if (style.safety === 'slide') parts.safety = box(slide, 0.012, 0.008, 0.004, M.dark, 0.018, slideHeight * 0.1, -slideWidth / 2 - 0.002, 0.2)\n if (options.sel) {\n const selector = box(slide, 0.01, 0.008, 0.003, M.dark, 0.014, -slideHeight * 0.2, slideWidth / 2 + 0.0014)\n parts.safety ??= selector\n }\n}\n\n","import type * as THREE from 'three'\n\nexport interface PistolStyle {\n rf: number\n ga: number\n grip: 'finger' | 'panel' | 'wood' | 'rubber' | 'star' | 'chunky'\n guard: 'square' | 'round' | 'hook'\n rail?: number\n sight: 'u' | '3dot' | 'small'\n port: number\n slideM?: string\n frame: 'poly' | 'metal'\n frontSer?: number\n safety?: 'thumb' | 'slide'\n hammer?: 'spur' | 'ring' | 'big'\n open?: number\n decock?: 'slide' | 'frame'\n tall?: number\n inset?: number\n bushing?: number\n beaver?: number\n slideStop?: number\n flush?: number\n lanyard?: number\n slope?: number\n tri?: number\n}\n\nexport const STYLES: Record<string, PistolStyle> = {\n glock: { rf: 0.07, ga: -0.36, grip: 'finger', guard: 'square', rail: 1, sight: 'u', port: 0.2, slideM: 'metal', frame: 'poly' },\n taurus: { rf: 0.16, ga: -0.3, grip: 'panel', guard: 'square', rail: 1, sight: '3dot', port: 0.18, frontSer: 1, frame: 'poly' },\n g2c: { rf: 0.2, ga: -0.3, grip: 'panel', guard: 'round', rail: 0, sight: '3dot', port: 0.17, frame: 'poly', safety: 'thumb' },\n beretta: { rf: 0.28, ga: -0.27, grip: 'wood', guard: 'round', hammer: 'spur', sight: '3dot', open: 1, decock: 'slide', port: 0, frame: 'metal' },\n pt100: { rf: 0.25, ga: -0.27, grip: 'rubber', guard: 'round', hammer: 'spur', sight: '3dot', port: 0.17, decock: 'frame', frame: 'metal' },\n sig: { rf: 0.14, ga: -0.3, grip: 'rubber', guard: 'hook', hammer: 'spur', sight: '3dot', port: 0.19, decock: 'frame', rail: 1, tall: 1.12, frame: 'metal' },\n cz: { rf: 0.32, ga: -0.3, grip: 'rubber', guard: 'round', hammer: 'spur', sight: '3dot', port: 0.15, inset: 1, safety: 'thumb', frame: 'metal' },\n m1911: { rf: 0.24, ga: -0.2, grip: 'wood', guard: 'round', hammer: 'ring', sight: 'small', port: 0.12, bushing: 1, beaver: 1, safety: 'thumb', slideStop: 1, frame: 'metal' },\n makarov: { rf: 0.48, ga: -0.24, grip: 'star', guard: 'round', hammer: 'ring', sight: 'small', port: 0.14, flush: 1, safety: 'slide', lanyard: 1, frame: 'metal' },\n fiveseven: { rf: 0.2, ga: -0.4, grip: 'chunky', guard: 'square', rail: 1, sight: '3dot', port: 0.18, slope: 1, frame: 'poly' },\n deagle: { rf: 0.08, ga: -0.28, grip: 'rubber', guard: 'round', hammer: 'big', sight: 'small', port: 0.16, tri: 1, safety: 'slide', frame: 'metal' },\n}\n\nexport type Material = THREE.Material\n\nexport interface PistolSize {\n length: number\n height: number\n width: number\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { buildSlide } from './pistol-slide'\nimport type { Material, PistolSize, PistolStyle } from './pistol-style'\nimport { STYLES } from './pistol-style'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\n\n/** Frame, grip and magazine below the slide. Returns the grip x and the trigger guard line the guard is drawn from. */\nfunction buildFrame(kit: ModelKit, group: THREE.Group, parts: ModelParts, options: ModelOptions, style: PistolStyle, size: PistolSize, materials: { frame: Material; grip: Material }): { gx: number; ty: number } {\n const { M, box, cylinderZ, sphere } = kit\n const { length: L, height: h, width: w } = size\n const fm = materials.frame\n if (style.inset) {\n box(group, L * 0.9, h * 0.35, w * 0.12, fm, L * 0.47, -h * 0.32, w * 0.47)\n box(group, L * 0.9, h * 0.35, w * 0.12, fm, L * 0.47, -h * 0.32, -w * 0.47)\n }\n const frameLength = style.tri ? L * 0.66 : L * 0.8\n kit.roundness = style.rf\n box(group, frameLength, 0.016, w * 0.92, fm, frameLength / 2 + L * 0.06, -h / 2 - 0.008, 0)\n kit.roundness = null\n if (style.rail) for (let i = 0; i < (style.slope ? 5 : 3); i++) box(group, 0.004, 0.003, w * 0.96, M.dark, L * 0.62 + i * 0.009, -h / 2 - 0.017, 0)\n const isGlock = options.st === 'glock' || !options.st\n if (isGlock) {\n box(group, 0.008, 0.004, 0.003, M.dark, L * 0.5, -h / 2 - 0.003, -w / 2 - 0.0012)\n box(group, 0.008, 0.004, 0.003, M.dark, L * 0.5, -h / 2 - 0.003, w / 2 + 0.0012)\n }\n if (style.slideStop) {\n box(group, 0.03, 0.006, 0.003, M.dark, L * 0.42, -h / 2 - 0.002, -w / 2 - 0.0014)\n sphere(group, 0.0028, M.dark, L * 0.55, -h / 2 - 0.003, w / 2 + 0.001, 1)\n } else box(group, 0.012, 0.004, 0.003, M.dark, L * 0.45, -h / 2 - 0.003, -w / 2 - 0.0012)\n if (style.decock === 'frame') box(group, 0.01, 0.012, 0.003, M.dark, L * 0.38, -h / 2 - 0.012, -w / 2 - 0.0014, 0.6)\n if (style.safety === 'thumb') parts.safety = box(group, 0.014, 0.006, 0.004, M.dark, 0.02, -h / 2 - 0.002, -w / 2 - 0.0016)\n const gripLength = options.gl ?? 0.105\n const gx = 0.034 + (L - 0.2) * 0.15\n const gy = -h / 2 - gripLength / 2 + 0.006\n const grip = kit.pivot(group, gx, gy, 0)\n grip.rotation.z = style.ga\n const gripWidth = style.grip === 'chunky' ? w * 1.18 : w * 1.06\n const gripDepth = style.grip === 'chunky' ? 0.036 : 0.032\n kit.roundness = 0.3\n if (style.grip === 'wood' || style.grip === 'star') {\n box(grip, gripDepth * 0.86, gripLength, w * 0.9, fm, 0, 0, 0)\n box(grip, gripDepth * 0.8, gripLength * 0.86, 0.004, materials.grip, 0.001, -0.002, w * 0.47)\n box(grip, gripDepth * 0.8, gripLength * 0.86, 0.004, materials.grip, 0.001, -0.002, -w * 0.47)\n if (style.grip === 'wood') {\n for (let i = 0; i < 6; i++) for (let j = 0; j < 2; j++) box(grip, 0.003, 0.003, 0.0012, M.woodL, -0.006 + j * 0.012, -gripLength * 0.3 + i * 0.012, w * 0.495, 0, 0, 0)\n cylinderZ(grip, 0.0035, 0.0015, M.brass, 0, gripLength * 0.25, w * 0.5, 10)\n cylinderZ(grip, 0.0035, 0.0015, M.brass, 0, -gripLength * 0.3, w * 0.5, 10)\n } else cylinderZ(grip, 0.008, 0.0015, M.dark, 0, gripLength * 0.1, w * 0.5, 5)\n } else box(grip, gripDepth, gripLength, gripWidth, materials.grip, 0, 0, 0)\n kit.roundness = null\n if (style.grip === 'finger') {\n for (let i = 0; i < 3; i++) box(grip, 0.006, 0.012, gripWidth * 0.98, materials.grip, gripDepth / 2 + 0.002, gripLength * 0.18 - i * 0.022, 0)\n for (let i = 0; i < 5; i++) for (let j = 0; j < 3; j++) box(grip, 0.003, 0.003, 0.0012, M.dark, -0.008 + j * 0.008, -gripLength * 0.25 + i * 0.012, gripWidth / 2 + 0.0004)\n }\n if (style.grip === 'panel' || style.grip === 'rubber' || style.grip === 'chunky') for (let i = 0; i < 6; i++) box(grip, gripDepth * 0.75, 0.0025, gripWidth + 0.001, M.dark, 0.002, -gripLength / 2 + 0.018 + i * 0.013, 0)\n if (style.grip === 'chunky') box(grip, 0.008, gripLength * 0.8, gripWidth * 0.9, materials.grip, gripDepth / 2 + 0.002, -0.004, 0)\n if (style.beaver) {\n box(group, 0.026, 0.008, w * 0.9, fm, -0.004, -h / 2 - 0.004, 0, 0.25)\n box(grip, 0.006, gripLength * 0.55, w * 0.9, fm, -gripDepth * 0.5 - 0.002, gripLength * 0.18, 0)\n } else box(group, 0.02, 0.009, w * 0.9, fm, 0.004, -h / 2 - 0.006, 0)\n if (style.lanyard) {\n const ring = kit.torus(grip, new kit.THREE.TorusGeometry(0.005, 0.0013, 6, 12), M.dark, -0.012, -gripLength / 2 + 0.004, 0)\n ring.position.set(-0.012, -gripLength / 2 + 0.004, 0)\n }\n const magazine = kit.pivot(grip)\n parts.mag = magazine\n parts.magDrop = gripLength * 1.15\n box(magazine, 0.022, gripLength * 0.94, w * 0.72, M.dark, 0.003, -0.004, 0)\n if (style.grip === 'chunky') box(magazine, 0.04, 0.01, gripWidth * 1.02, M.poly, 0.003, -gripLength / 2 - 0.004, 0)\n else if (style.flush || style.grip === 'wood') box(magazine, 0.028, 0.004, w * 0.9, M.steel, 0.003, -gripLength / 2 - 0.001, 0)\n else box(magazine, 0.031, 0.006, gripWidth * 1.02, M.dark, 0.003, -gripLength / 2 - 0.002, 0)\n return { gx, ty: -h / 2 }\n}\n\n/** Port of the gallery's `pistol` (Galeria 3D do Arsenal): slide, frame, grip, magazine, trigger and hammer, in the order the page adds them. */\nexport function buildPistol(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box } = kit\n const style = { ...STYLES[options.st ?? 'glock'] } as PistolStyle\n const group = kit.group()\n const parts: ModelParts = { family: 'pistol', kick: options.deagle ? 1.8 : 0.6, glow: [] }\n const size: PistolSize = { length: ((options.L ?? 0) / 1000) * 0.97, height: (options.h ?? 0.031) * (style.tall ?? 1), width: options.deagle ? 0.032 : style.flush ? 0.024 : 0.025 }\n const { length: L, height: h, width: w } = size\n const slideMetal = options.steel ? M.steel : options.stain ? M.steelL : M.metal\n const frameMetal = style.frame === 'poly' ? M.poly : slideMetal\n const gripMaterial = style.grip === 'wood' ? M.wood : style.grip === 'star' ? M.bake : style.grip === 'rubber' ? M.rubber : M.poly\n const slide = kit.pivot(group)\n parts.slide = slide\n parts.stroke = L * 0.15\n buildSlide(kit, slide, parts, options, style, size, slideMetal)\n const { gx, ty } = buildFrame(kit, group, parts, options, style, size, { frame: frameMetal, grip: gripMaterial })\n if (style.guard === 'square') {\n box(group, 0.046, 0.004, 0.009, frameMetal, gx + 0.05, ty - 0.034, 0)\n box(group, 0.004, 0.03, 0.009, frameMetal, gx + 0.074, ty - 0.02, 0)\n box(group, 0.006, 0.004, 0.009, frameMetal, gx + 0.075, ty - 0.034, 0)\n } else if (style.guard === 'hook') {\n box(group, 0.046, 0.004, 0.009, frameMetal, gx + 0.05, ty - 0.034, 0)\n box(group, 0.004, 0.03, 0.009, frameMetal, gx + 0.073, ty - 0.02, 0, 0.2)\n box(group, 0.008, 0.006, 0.009, frameMetal, gx + 0.074, ty - 0.037, 0, 0.4)\n } else {\n const guard = kit.torus(group, new kit.THREE.TorusGeometry(0.019, 0.0022, 6, 16, PI), frameMetal, gx + 0.05, ty - 0.014, 0)\n guard.rotation.z = PI\n guard.scale.set(1.2, 1, 1)\n }\n const isGlock = options.st === 'glock' || !options.st\n parts.trigger = box(group, 0.004, 0.014, 0.004, isGlock ? M.dark : M.steel, gx + 0.042, ty - 0.022, 0, 0.2)\n if (isGlock) box(parts.trigger, 0.0015, 0.008, 0.0045, M.metal, 0, -0.001, 0)\n if (style.hammer) {\n const hammer = kit.pivot(group, 0.003, h / 2 - 0.008, 0)\n parts.hammer = hammer\n if (style.hammer === 'ring') {\n box(hammer, 0.006, 0.012, 0.006, M.dark, -0.002, 0.004, 0, 0.3)\n kit.torus(hammer, new kit.THREE.TorusGeometry(0.0045, 0.0016, 6, 12), M.dark, -0.004, 0.012, 0)\n } else if (style.hammer === 'big') box(hammer, 0.014, 0.02, 0.009, M.dark, -0.004, 0.007, 0, 0.35)\n else {\n box(hammer, 0.008, 0.016, 0.007, M.dark, -0.002, 0.006, 0, 0.3)\n box(hammer, 0.008, 0.004, 0.008, M.dark, -0.006, 0.013, 0, 0.3)\n }\n }\n parts.muzzle = kit.mark(group, L + 0.006, style.tri ? h * 0.08 : 0.002, 0)\n parts.eject = kit.mark(group, L * 0.6, h / 2, w * 0.25)\n return { group, parts }\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\nconst DEFAULT_CHAMBERS = 6\n\n/** Port of the gallery's `revolver`: frame, swing-out crane with the cylinder (six chambers, or as many as the weapon holds), barrel, hammer, grip and trigger. */\nexport function buildRevolver(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box, cylinderX } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'revolver', kick: options.cal === '.44 Magnum' ? 1.5 : 0.9, glow: [] }\n const barrel = (options.B ?? 0) / 1000\n const chambers = options.chambers ?? DEFAULT_CHAMBERS\n const metal = options.steel ? M.steel : M.metal\n box(group, 0.08, 0.044, 0.024, metal, 0.07, 0, 0)\n box(group, 0.036, 0.012, 0.022, metal, 0.096, 0.022, 0)\n box(group, 0.024, 0.012, 0.004, M.dark, 0.055, 0.006, -0.013)\n const crane = kit.pivot(group, 0.077, -0.024, 0)\n parts.crane = crane\n const cylinder = kit.pivot(crane, 0, 0.022, 0)\n parts.cylinder = cylinder\n cylinderX(cylinder, 0.0215, 0.042, metal, 0, 0, 0, 24)\n for (let i = 0; i < chambers; i++) {\n const angle = (i * 2 * PI) / chambers\n box(cylinder, 0.026, 0.005, 0.005, M.dark, 0, Math.cos(angle) * 0.0205, Math.sin(angle) * 0.0205, 0, 0, angle)\n }\n parts.chambers = []\n for (let i = 0; i < chambers; i++) {\n const angle = (i * 2 * PI) / chambers + PI / chambers\n parts.chambers.push(kit.mark(cylinder, -0.022, Math.cos(angle) * 0.013, Math.sin(angle) * 0.013))\n cylinderX(cylinder, 0.0046, 0.002, M.brass, -0.0215, Math.cos(angle) * 0.013, Math.sin(angle) * 0.013, 12)\n }\n heatify(parts.glow, cylinderX(group, 0.0088, barrel, metal, 0.112 + barrel / 2, 0.009, 0, 18))\n box(group, barrel * 0.92, 0.015, 0.013, metal, 0.112 + barrel * 0.46, -0.005, 0)\n cylinderX(group, 0.004, 0.005, M.hole, 0.112 + barrel + 0.0015, 0.009, 0, 12)\n box(group, 0.012, 0.009, 0.004, M.dark, 0.112 + barrel - 0.008, 0.021, 0, -0.3)\n box(group, 0.012, 0.006, 0.012, M.dark, 0.105, 0.031, 0)\n const hammer = kit.pivot(group, 0.036, 0.018, 0)\n box(hammer, 0.01, 0.02, 0.008, M.dark, -0.004, 0.008, 0, 0.45)\n parts.hammer = hammer\n const grip = kit.pivot(group, 0.024, -0.062, 0)\n grip.rotation.z = -0.38\n box(grip, 0.034, 0.1, 0.031, options.wood ? M.wood : M.rubber, 0, 0, 0)\n if (!options.wood) for (let i = 0; i < 4; i++) box(grip, 0.006, 0.07, 0.033, M.dark, -0.012 + i * 0.008, 0, 0)\n box(group, 0.038, 0.004, 0.008, metal, 0.062, -0.036, 0)\n box(group, 0.004, 0.022, 0.008, metal, 0.08, -0.026, 0, 0.2)\n parts.trigger = box(group, 0.004, 0.015, 0.004, M.dark, 0.06, -0.027, 0, 0.2)\n parts.muzzle = kit.mark(group, 0.112 + barrel + 0.006, 0.009, 0)\n parts.eject = kit.mark(group, 0.077, 0, 0)\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport type { Parent, ModelKit } from '../kit'\n\n/** The muzzle brake of the gallery's rifles (`brake` 1 the plain one, 2 the heavy one with eight sides), its end flush with the muzzle at `x`. `heat` receives the body so a builder can make it glow. */\nexport function buildBrake(kit: ModelKit, parent: Parent, kind: 1 | 2, x: number, y: number, barrelRadius: number, heat: (body: THREE_NS.Mesh) => void = () => undefined): void {\n const { M, box, cylinderX } = kit\n const scale = kind === 2 ? 3.2 : 2.0\n const length = kind === 2 ? 0.12 : 0.06\n heat(cylinderX(parent, barrelRadius * scale, length, M.dark, x - length / 2, y, 0, kind === 2 ? 8 : 16))\n for (let i = 0; i < 3; i++) box(parent, length * 0.16, barrelRadius * scale * 1.3, barrelRadius * scale * 2.2, M.hole, x - length * 0.25 - i * length * 0.25, y, 0)\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelParts } from './types'\n\n/** Runs `draw` and returns what it added to `parent` (the meshes of one part), so that the part can be hidden later; the scene is exactly what `draw` made. */\nexport function captured(parent: THREE_NS.Object3D, draw: () => void): THREE_NS.Object3D[] {\n const before = parent.children.length\n draw()\n return parent.children.slice(before)\n}\n\n/** Draws a part that ships on the weapon and records its meshes under the id of the accessory it stands for. */\nexport function recordFitting(parts: ModelParts, id: string, parent: THREE_NS.Object3D, draw: () => void): void {\n parts.fittings = { ...parts.fittings, [id]: captured(parent, draw) }\n}\n","import type { AttachmentModelBuilder } from './types'\nimport type { Parent, ModelKit } from '../kit'\n\n/** The bipod of the gallery's rifles: the hinge block and the two splayed legs with rubber feet, hinged at (`x`, `y`) of `parent`. */\nexport function buildBipod(kit: ModelKit, parent: Parent, x: number, y: number): void {\n const { M, box, cylinderX } = kit\n cylinderX(parent, 0.008, 0.02, M.dark, x, y, 0, 12)\n for (const side of [-1, 1]) {\n const leg = kit.pivot(parent, x, y, side * 0.012)\n leg.rotation.set(side * 0.15, 0, -0.35)\n box(leg, 0.006, 0.2, 0.006, M.dark, 0, -0.1, 0)\n box(leg, 0.01, 0.006, 0.01, M.rubber, 0, -0.2, 0)\n }\n}\n\nexport const buildBipodModel: AttachmentModelBuilder = ({ kit }) => {\n const group = kit.group()\n buildBipod(kit, group, 0, 0)\n return group\n}\n","import { buildBipod } from './attachments/bipod'\nimport { recordFitting } from './capture'\nimport { scope } from './details'\nimport type { RifleContext } from './rifle-context'\n\n/** The accessory each `scope` option of the page stands for. */\nconst SCOPE_IDS: Readonly<Record<number, string>> = { 1: 'red_dot', 2: 'acog_4x', 3: 'scope_3_9x', 4: 'scope_6_24x' }\n\n/** What is bolted on after the stock: optic, carry handle, bipod, bolt handle, lever, magazine tube, pump, heat shield, bayonet lug and cleaning rod. */\nexport function buildFittings(context: RifleContext, gripX: number): void {\n const { kit, group, parts, options: o, furniture: furn, length: L, receiverStart: x0, receiverEnd: x1, receiverHeight: hR, receiverWidth: wR, barrelRadius: r, barrelY: by } = context\n const { M, box, cylinderX, cylinderZ, sphere } = kit\n const middle = (x0 + x1) / 2\n if (o.scope) recordFitting(parts, SCOPE_IDS[o.scope] ?? 'scope', group, () => scope(kit, group, o.scope as number, middle + 0.03, hR / 2 + (o.rail ? 0.006 : 0), o.scope === 4 ? -0.02 : 0))\n if (o.carry) {\n box(group, 0.15, 0.026, 0.014, M.metal, middle, hR / 2 + 0.03, 0)\n box(group, 0.012, 0.03, 0.014, M.metal, middle + 0.07, hR / 2 + 0.014, 0)\n box(group, 0.012, 0.03, 0.014, M.metal, middle - 0.07, hR / 2 + 0.014, 0)\n }\n if (o.bipod) recordFitting(parts, 'bipod', group, () => buildBipod(kit, group, x1 + (L - x1) * 0.45 + 0.04, by - 0.012))\n if (o.bolt) {\n const handle = kit.pivot(group, x1 - 0.045, by, 0)\n parts.boltHandle = handle\n parts.boltHandleRest = handle.position.x\n cylinderZ(handle, 0.0042, 0.05, M.steelL, 0, 0, wR / 2 + 0.022, 12)\n sphere(handle, 0.0095, M.dark, 0, -0.004, wR / 2 + 0.048, 1)\n cylinderX(group, hR * 0.3, 0.03, M.steel, x0 + 0.005, by, 0, 16)\n }\n if (o.lever) {\n const lever = kit.pivot(group, gripX - 0.02, -hR / 2 - 0.01, 0)\n parts.lever = lever\n box(lever, 0.11, 0.006, 0.012, M.metal, 0.055, -0.052, 0)\n box(lever, 0.006, 0.05, 0.012, M.metal, 0.003, -0.028, 0)\n box(lever, 0.006, 0.05, 0.012, M.metal, 0.108, -0.028, 0)\n box(lever, 0.04, 0.006, 0.012, M.metal, 0.08, -0.002, 0)\n box(group, 0.03, 0.012, 0.003, M.dark, x1 - 0.04, by, wR / 2 + 0.001)\n }\n if (o.tube) {\n const tubeLength = (L - x1) * (o.tubeLen || 0.8)\n cylinderX(group, 0.0105, tubeLength, M.metal, x1 + tubeLength / 2, by - 0.023, 0, 16)\n cylinderX(group, 0.0125, 0.02, M.dark, x1 + tubeLength + 0.006, by - 0.023, 0, 16)\n }\n if (o.pump) {\n const pump = kit.pivot(group)\n parts.pump = pump\n box(pump, 0.17, 0.042, 0.046, furn, x1 + 0.14, by - 0.022, 0)\n for (let i = 0; i < 8; i++) box(pump, 0.006, 0.044, 0.048, M.dark, x1 + 0.07 + i * 0.02, by - 0.022, 0)\n }\n if (o.heat) {\n cylinderX(group, r * 1.75, (L - x1) * 0.7, M.dark, x1 + (L - x1) * 0.4, by, 0, 12)\n for (let i = 0; i < 10; i++) box(group, 0.008, r * 1.5, 0.004, M.hole, x1 + (L - x1) * (0.1 + i * 0.06), by + r * 0.8, r * 1.5)\n }\n if (o.bayo) box(group, 0.025, 0.008, 0.01, M.metal, L - 0.07, by - 0.016, 0)\n if (o.rod) cylinderX(group, 0.003, (L - x1) * 0.85, M.steel, x1 + (L - x1) * 0.45, by - 0.014, 0, 8)\n}\n","import { rail, vents } from './details'\nimport type { RifleContext } from './rifle-context'\n\nconst PI = Math.PI\n\n/** Handguard by kind and the front sight, which the page draws unless a long scope replaces it. */\nexport function buildForend(context: RifleContext): void {\n const { kit, group, options: o, furniture: furn, length: L, receiverEnd: x1, receiverHeight: hR, receiverWidth: wR, barrelRadius: r, barrelY: by } = context\n const { M, box } = kit\n const hasLongScope = (o.scope ?? 0) >= 3\n if (!context.isTraditional && o.hg !== 'none') {\n const handguardLength = (L - x1) * (o.hgFrac || 0.5)\n const hx = x1 + handguardLength / 2\n const hh = hR * 0.8\n if (o.hg === 'rail') {\n box(group, handguardLength, hh, wR * 1.04, M.dark, hx, by - 0.002, 0)\n rail(kit, group, x1, handguardLength, by + hh / 2, 0, wR * 0.66)\n rail(kit, group, x1 + 0.01, handguardLength - 0.02, by - 0.002, wR * 0.54, wR * 0.4, PI / 2)\n rail(kit, group, x1 + 0.01, handguardLength - 0.02, by - 0.002, -wR * 0.54, wR * 0.4, -PI / 2)\n rail(kit, group, x1 + 0.01, handguardLength - 0.02, by - hh / 2, 0, wR * 0.6, PI)\n } else {\n const material = o.hg === 'wood' ? M.wood : furn\n if (o.ak) {\n box(group, handguardLength, hh * 0.55, wR * 1.08, material, hx, by - hh * 0.22, 0)\n box(group, handguardLength * 0.75, hh * 0.35, wR * 0.7, material, hx - handguardLength * 0.1, by + r * 2.2, 0)\n } else {\n box(group, handguardLength, hh, wR * 1.08, material, hx, by - 0.002, 0)\n vents(kit, group, x1 + 0.01, handguardLength - 0.02, by + hh * 0.15, wR * 0.54 + 0.001, Math.round(handguardLength / 0.025), hh * 0.3)\n vents(kit, group, x1 + 0.01, handguardLength - 0.02, by + hh * 0.15, -wR * 0.54 - 0.001, Math.round(handguardLength / 0.025), hh * 0.3)\n }\n }\n if (!hasLongScope && !o.rail && o.ak) {\n box(group, 0.03, 0.016, wR * 0.6, M.metal, x1 + 0.02, by + r * 2.5 + 0.01, 0)\n box(group, 0.012, 0.004, wR * 0.5, M.dark, x1 + 0.03, by + r * 2.5 + 0.019, 0)\n }\n }\n if (hasLongScope) return\n const sightX = L - (o.ak ? 0.06 : 0.08)\n if (o.ak) {\n box(group, 0.022, 0.022, wR * 0.6, M.metal, sightX, by + 0.008, 0)\n box(group, 0.006, 0.024, 0.004, M.metal, sightX, by + 0.026, 0.008)\n box(group, 0.006, 0.024, 0.004, M.metal, sightX, by + 0.026, -0.008)\n box(group, 0.003, 0.016, 0.003, M.dark, sightX, by + 0.022, 0)\n } else if (!o.rail || o.carry) {\n box(group, 0.018, 0.014, wR * 0.55, M.dark, sightX, by + 0.008, 0)\n box(group, 0.012, 0.034, 0.008, M.dark, sightX, by + 0.03, 0, -0.25)\n } else box(group, 0.012, 0.024, 0.012, M.dark, sightX - 0.04, by + hR * 0.4 + 0.012, 0)\n}\n","import type { Parent, ModelKit } from '../kit'\n\n/** The belt box of the gallery's belt-fed rifles: the olive box with its lid and the loose cartridges of the belt on top. Drawn in the frame of the belt pivot. */\nexport function buildBeltBox(kit: ModelKit, belt: Parent): void {\n const { M, box, cylinderX } = kit\n box(belt, 0.11, 0.1, 0.08, M.olive, 0, 0, 0)\n box(belt, 0.112, 0.012, 0.082, M.dark, 0, 0.046, 0)\n for (let i = 0; i < 7; i++) {\n cylinderX(belt, 0.0042, 0.034, M.brass, -0.04 + i * 0.012, 0.07, 0.035, 10)\n box(belt, 0.006, 0.006, 0.012, M.metal, -0.04 + i * 0.012, 0.066, 0.035)\n }\n}\n","import type { Parent, ModelKit } from '../kit'\n\n/** The drum magazine of the gallery (`mag: 'drum'`): the drum with its core, and the neck that goes into the well. Drawn in the frame of the magazine pivot. */\nexport function buildDrum(kit: ModelKit, magazine: Parent): void {\n const { M, box, cylinderZ } = kit\n cylinderZ(magazine, 0.075, 0.07, M.dark, 0.02, -0.085, 0, 22)\n cylinderZ(magazine, 0.05, 0.074, M.metal, 0.02, -0.085, 0, 18)\n box(magazine, 0.05, 0.04, 0.03, M.dark, 0, -0.02, 0)\n}\n","import type { RifleContext } from './rifle-context'\n\nconst PI = Math.PI\nconst LENGTH = 0.26\nconst RADIUS = 0.026\nconst TURNS = 11\n\n/** The helical magazine of the PP-19 Bizon: a drum along the barrel, under it, with the ridge of the helix drawn as slanted bands. Returns the x of its middle. */\nexport function buildHelicalMagazine(context: RifleContext): number {\n const { kit, group, parts, receiverEnd, barrelY, barrelRadius } = context\n const { M, cylinderX, box } = kit\n const x = receiverEnd + LENGTH / 2 + 0.02\n const y = barrelY - barrelRadius - RADIUS - 0.012\n const magazine = kit.pivot(group, x, y, 0)\n parts.mag = magazine\n cylinderX(magazine, RADIUS, LENGTH, M.dark, 0, 0, 0, 20)\n cylinderX(magazine, RADIUS * 1.06, 0.01, M.metal, -LENGTH / 2, 0, 0, 20)\n cylinderX(magazine, RADIUS * 1.06, 0.01, M.metal, LENGTH / 2, 0, 0, 20)\n for (let i = 0; i < TURNS; i++) box(magazine, 0.012, RADIUS * 2.15, 0.014, M.metal, -LENGTH / 2 + ((i + 0.5) * LENGTH) / TURNS, 0, 0, 0, 0, (i * PI) / 4)\n box(magazine, 0.05, 0.03, 0.03, M.dark, -LENGTH / 2 - 0.02, RADIUS * 0.4, 0)\n parts.magDrop = 0.16\n return x\n}\n","import type * as THREE from 'three'\nimport { buildBeltBox } from './attachments/belt-box'\nimport { buildDrum } from './attachments/drum'\nimport { buildHelicalMagazine } from './helical-magazine'\nimport type { RifleContext } from './rifle-context'\n\n/** Grip, trigger group and selector. Returns the x of the grip, which the magazine and the lever hang from. */\nexport function buildGrip(context: RifleContext): number {\n const { kit, group, parts, options: o, furniture: furn, receiverStart: x0, receiverHeight: hR, receiverWidth: wR } = context\n const { M, box } = kit\n const gx = x0 + (o.gripAt || 0.07)\n if (!context.isTraditional && o.grip !== 'none') {\n const grip = kit.pivot(group, gx - 0.012, -hR / 2 - 0.046, 0)\n grip.rotation.z = -0.3\n box(grip, 0.032, 0.105, 0.028, furn, 0, 0, 0)\n for (let i = 0; i < 3; i++) box(grip, 0.006, 0.012, 0.026, furn, 0.017, 0.022 - i * 0.02, 0)\n box(grip, 0.034, 0.008, 0.03, furn, 0, -0.052, 0)\n }\n box(group, 0.06, 0.004, 0.01, M.metal, gx + 0.03, -hR / 2 - 0.024, 0)\n box(group, 0.004, 0.022, 0.01, M.metal, gx + 0.06, -hR / 2 - 0.013, 0)\n parts.trigger = box(group, 0.004, 0.016, 0.004, M.dark, gx + 0.024, -hR / 2 - 0.012, 0, 0.15)\n if (o.sel) parts.safety = box(group, 0.016, 0.005, 0.003, M.dark, gx + 0.005, -hR * 0.15, -wR / 2 - 0.002, 0.4)\n return gx\n}\n\n/** The magazine of the kind the options name (curved, box, drum, internal, belt), and the cover and belt box of a belt-fed gun. Returns the x of the well. */\nexport function buildMagazine(context: RifleContext, gx: number): number {\n const { kit, group, parts, options: o, receiverStart: x0, receiverHeight: hR, receiverWidth: wR, receiverLength: RL } = context\n const { M, box } = kit\n if (o.mag === 'helical') return buildHelicalMagazine(context)\n const mx = o.magAt != null ? x0 + o.magAt : gx + 0.075\n const scale = o.magLen || 1\n const magazine = kit.pivot(group, mx, -hR / 2, 0)\n parts.mag = magazine\n const finish: THREE.Material | undefined = o.magMat === 'bakelite' ? M.bakelite : o.magMat === 'poly' ? M.polyMag : undefined\n if (o.mag === 'curved') {\n let px = 0\n let py = 0\n const material = finish ?? M.metal\n for (const angle of [0.06, 0.22, 0.38]) {\n const length = 0.07 * scale\n const cx = px + (Math.sin(angle) * length) / 2\n const cy = py - (Math.cos(angle) * length) / 2\n box(magazine, 0.052, length + 0.004, 0.024, material, cx, cy, 0, angle)\n box(magazine, 0.04, length * 0.8, 0.026, M.dark, cx, cy, 0, angle)\n px += Math.sin(angle) * length\n py -= Math.cos(angle) * length\n }\n box(magazine, 0.058, 0.008, 0.028, material, px, py, 0, 0.38)\n parts.magDrop = 0.07 * scale * 3 + 0.04\n } else if (o.mag === 'box') {\n const length = 0.13 * scale\n const curve = o.curve || 0\n const segment = length / 3\n const material = finish ?? M.dark\n let px = 0\n let py = 0\n let angle = 0.08\n for (let i = 0; i < 3; i++) {\n angle = 0.08 + curve * i\n const cx = px + (Math.sin(angle) * segment) / 2\n const cy = py - (Math.cos(angle) * segment) / 2\n box(magazine, 0.05, segment + 0.004, 0.024, material, cx, cy, 0, angle)\n box(magazine, 0.04, 0.003, 0.026, M.metal, cx, cy, 0, angle)\n px += Math.sin(angle) * segment\n py -= Math.cos(angle) * segment\n }\n box(magazine, 0.056, 0.007, 0.028, material, px, py - 0.002, 0, angle)\n parts.magDrop = length + 0.03\n } else if (o.mag === 'drum') {\n buildDrum(kit, magazine)\n parts.magDrop = 0.2\n } else if (o.mag === 'internal') {\n box(group, 0.08, 0.025, 0.03, context.isTraditional ? context.furniture : M.metal, mx, -hR / 2 - 0.012, 0)\n parts.mag = null\n } else parts.mag = null\n if (o.mag === 'belt') {\n const belt = kit.pivot(group, mx + 0.02, -hR / 2 - 0.05, -0.045)\n parts.belt = belt\n buildBeltBox(kit, belt)\n const cover = kit.pivot(group, x0 + 0.01, hR / 2, 0)\n parts.cover = cover\n box(cover, RL - 0.03, 0.014, wR * 1.05, M.metal, (RL - 0.03) / 2, 0.007, 0)\n box(cover, 0.02, 0.012, wR * 0.6, M.dark, RL - 0.04, 0.016, 0)\n }\n return mx\n}\n","import { buttpad, swivel } from './details'\nimport type { RifleContext } from './rifle-context'\n\n/** The stock by kind, in the order the page draws them. `magazineX` places the magazine well plate of the one-piece stock. */\nexport function buildStock(context: RifleContext, magazineX: number): void {\n const { kit, group, options: o, furniture: furn, length: L, stockLength: S, receiverStart: x0, receiverEnd: x1, receiverHeight: hR } = context\n const { M, box, cylinderX } = kit\n if (context.isTraditional) {\n buttpad(kit, group, 0.006, -0.04, 0.13, 0.038)\n box(group, 0.03, 0.13, 0.038, furn, 0.024, -0.04, 0)\n box(group, S, 0.055, 0.034, furn, S / 2, -0.012, 0, 0.06)\n box(group, 0.09, 0.05, 0.032, furn, x0 - 0.02, -0.035, 0, 0.25)\n const forendLength = x1 - x0 + (L - x1) * (o.fore ?? 0.62)\n if (forendLength > 0) box(group, forendLength, 0.045, 0.04, furn, x0 + forendLength / 2, -hR / 2 + 0.004, 0)\n if (o.stock === 'straight') box(group, 0.15, 0.04, 0.035, furn, x1 + 0.08, -hR / 2, 0)\n box(group, 0.04, 0.004, 0.03, M.metal, magazineX, -hR / 2 - 0.022, 0)\n swivel(kit, group, 0.2, -0.08)\n swivel(kit, group, x1 + (L - x1) * 0.45, -hR / 2 - 0.03)\n if (o.bands) for (const fraction of [0.35, 0.75]) cylinderX(group, 0.024, 0.008, M.metal, x1 + (L - x1) * fraction * (o.fore || 0.62), -0.004, 0, 16)\n } else if (o.stock === 'fixed' || o.stock === 'wood') {\n box(group, S, 0.05, 0.03, furn, S / 2, -0.008, 0, 0.05)\n box(group, 0.03, 0.13, 0.036, furn, 0.022, -0.035, 0)\n buttpad(kit, group, 0.004, -0.035, 0.13, 0.036)\n if (o.stock === 'wood') box(group, S * 0.6, 0.03, 0.028, furn, S * 0.55, -0.045, 0, 0.2)\n swivel(kit, group, 0.08, -0.09)\n } else if (o.stock === 'skeleton') {\n box(group, S, 0.014, 0.026, furn, S / 2, 0.012, 0, 0.03)\n box(group, S, 0.014, 0.026, furn, S / 2, -0.05, 0, -0.08)\n box(group, 0.03, 0.12, 0.034, furn, 0.02, -0.025, 0)\n buttpad(kit, group, 0.004, -0.025, 0.12, 0.034)\n } else if (o.stock === 'retract') {\n cylinderX(group, 0.013, S, M.metal, S / 2, 0, 0, 16)\n for (let i = 0; i < 5; i++) box(group, 0.003, 0.003, 0.008, M.dark, S * 0.2 + i * 0.015, -0.013, 0)\n box(group, 0.034, 0.11, 0.036, furn, 0.02, -0.025, 0)\n box(group, S * 0.55, 0.032, 0.03, furn, S * 0.35, 0, 0)\n buttpad(kit, group, 0.003, -0.025, 0.11, 0.036)\n } else if (o.stock === 'fold') {\n box(group, S, 0.006, 0.006, M.metal, S / 2, 0.01, 0.012)\n box(group, S, 0.006, 0.006, M.metal, S / 2, -0.04, 0.012, -0.12)\n box(group, 0.012, 0.1, 0.03, M.metal, 0.006, -0.02, 0.012)\n }\n}\n","import { heatify } from './kit'\nimport type { ModelKit } from './kit'\nimport { buildBrake } from './attachments/muzzle-brake'\nimport { captured, recordFitting } from './capture'\nimport { rail } from './details'\nimport { buildFittings } from './rifle-fittings'\nimport { buildForend } from './rifle-forend'\nimport { buildGrip, buildMagazine } from './rifle-controls'\nimport { buildStock } from './rifle-stock'\nimport type { RifleContext } from './rifle-context'\nimport type { BuiltModel, ModelFamily, ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\n\n/** Receiver by kind (round, AR, plain), the AK and G3 extras, the ejection port, the bolt and its charging handle. */\nfunction buildReceiver(context: RifleContext): void {\n const { kit, group, parts, options: o, length: L, receiverStart: x0, receiverEnd: x1, receiverHeight: hR, receiverWidth: wR, receiverLength: RL, barrelY: by } = context\n const { M, box, cylinderX, cylinderY, cylinderZ, sphere } = kit\n const receiverMaterial = o.tan ? M.tan : M.metal\n const middle = (x0 + x1) / 2\n if (o.round) {\n cylinderX(group, hR * 0.36, RL, M.steel, middle, by, 0, 20)\n cylinderX(group, hR * 0.32, 0.05, M.steel, x0 - 0.01, by, 0, 18)\n } else if (o.ar) {\n box(group, RL, hR * 0.5, wR, receiverMaterial, middle, hR * 0.25, 0)\n box(group, RL * 0.92, hR * 0.52, wR * 0.96, receiverMaterial, middle - RL * 0.02, -hR * 0.24, 0)\n box(group, 0.05, 0.03, wR * 1.15, receiverMaterial, x0 + RL * 0.62, -hR * 0.5 - 0.01, 0)\n cylinderZ(group, 0.006, 0.012, M.metal, x1 - 0.03, hR * 0.28, wR / 2 + 0.006, 12)\n box(group, 0.012, 0.01, 0.012, M.metal, x1 - 0.05, hR * 0.12, wR / 2 + 0.006)\n box(group, 0.03, 0.008, 0.012, M.dark, x0 + 0.02, hR / 2 + 0.004, 0)\n box(group, 0.012, 0.006, 0.004, M.dark, x0 + RL * 0.55, -hR * 0.15, -wR / 2 - 0.002)\n } else box(group, RL, hR, wR, receiverMaterial, middle, 0, 0)\n if (o.ak) {\n box(group, RL * 0.86, hR * 0.28, wR * 0.95, M.metal, middle - 0.008, hR / 2 + 0.004, 0)\n for (let i = 0; i < 3; i++) box(group, 0.004, hR * 0.3, wR * 0.97, M.dark, x0 + RL * 0.25 + i * 0.02, hR / 2 + 0.004, 0)\n box(group, RL * 0.5, 0.012, 0.003, M.metal, x0 + RL * 0.55, -hR * 0.02, wR / 2 + 0.0015, -0.05)\n box(group, 0.012, 0.014, 0.003, M.dark, x0 + RL * 0.32, -hR * 0.05, wR / 2 + 0.002)\n }\n if (o.g3) {\n cylinderX(group, 0.009, (L - x1) * 0.6, M.metal, x1 + (L - x1) * 0.28, hR * 0.48, 0, 14)\n box(group, 0.012, 0.024, 0.008, M.dark, x1 + (L - x1) * 0.5, hR * 0.48, -0.012)\n cylinderY(group, 0.012, 0.016, M.dark, x0 + 0.03, hR / 2 + 0.008, 0, 12)\n }\n const ejectX = x1 - (o.ejectBack || 0.07)\n const ejectY = o.ar ? hR * 0.2 : by\n box(group, 0.05, hR * 0.36, 0.004, M.hole, ejectX, ejectY, wR / 2 - 0.0004)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n parts.stroke = Math.min(0.1, RL * 0.32)\n box(bolt, 0.044, hR * 0.26, 0.006, M.steelL, ejectX, ejectY, wR / 2 - 0.0012)\n if (o.charge) {\n box(bolt, 0.012, 0.01, 0.03, M.metal, ejectX + 0.04, ejectY + 0.004, wR / 2 + 0.012)\n sphere(bolt, 0.0065, M.metal, ejectX + 0.04, ejectY + 0.004, wR / 2 + 0.028, 1)\n }\n if (o.ar) box(group, 0.012, 0.016, 0.006, receiverMaterial, ejectX - 0.03, ejectY + 0.004, wR / 2 + 0.004)\n if (o.rail) rail(kit, group, x0 - 0.005, RL + 0.07, hR / 2 + (o.ar ? 0 : 0.003), 0, wR * 0.68)\n}\n\n/** Barrel with its jacket, gas tube and muzzle device. */\nfunction buildBarrel(context: RifleContext): void {\n const { kit, group, parts, options: o, length: L, barrelLength: Bl, receiverEnd: x1, barrelRadius: r, barrelY: by } = context\n const { M, box, cylinderX } = kit\n heatify(parts.glow, cylinderX(group, r, Bl, M.metal, L - Bl / 2, by, 0, 16))\n if (o.jacket) {\n cylinderX(group, r * 2, (L - x1) * 0.6, M.dark, x1 + (L - x1) * 0.3, by, 0, 16)\n for (let i = 0; i < 6; i++) cylinderX(group, r * 2.15, 0.004, M.metal, x1 + (L - x1) * (0.05 + i * 0.09), by, 0, 16)\n }\n if (o.gas) cylinderX(group, r * 0.75, (L - x1) * 0.55, M.metal, x1 + (L - x1) * 0.3, by + r * 2.2, 0, 14)\n if (o.brake) {\n const kind = o.brake === 2 ? 2 : 1\n recordFitting(parts, kind === 2 ? 'muzzle_brake_heavy' : 'muzzle_brake', group, () => buildBrake(kit, group, kind, L, by, r, (body) => void heatify(parts.glow, body)))\n } else if (!o.noFH) {\n recordFitting(parts, 'muzzle_default', group, () => {\n heatify(parts.glow, cylinderX(group, r * 1.45, 0.042, M.dark, L - 0.021, by, 0, 16))\n for (let i = 0; i < 4; i++) {\n const angle = (i * PI) / 2 + PI / 4\n box(group, 0.026, 0.0025, 0.004, M.hole, L - 0.02, by + Math.cos(angle) * r * 1.42, Math.sin(angle) * r * 1.42, 0, 0, angle)\n }\n })\n }\n cylinderX(group, r * 0.55, 0.004, M.hole, L + 0.0005, by, 0, 12)\n}\n\nconst familyOf = (o: ModelOptions): ModelFamily => {\n if (o.mag === 'belt') return 'belt'\n if (o.pump) return 'pump'\n if (o.lever) return 'lever'\n if (o.tube) return 'semi12'\n if (o.bolt) return o.mag === 'box' ? 'boltmag' : 'bolt'\n return o.mag === 'internal' ? 'semiint' : 'rifle'\n}\n\n/** Port of the gallery's `rifle`, the builder of 51 of the weapons: receiver, barrel, forend, grip, magazine, stock and what is fitted on them. */\nexport function buildRifle(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'rifle', glow: [] }\n const length = (options.L ?? 0) / 1000\n const barrelLength = (options.B ?? 0) / 1000\n const isTraditional = options.stock === 'trad' || options.stock === 'straight'\n const stockLength = options.stock === 'none' ? 0 : options.stockLen || Math.min(0.36, Math.max(0.2, 0.3 * length))\n const receiverStart = stockLength\n const receiverEnd = Math.max(receiverStart + 0.12, length - barrelLength * 0.92)\n const receiverHeight = options.hR || 0.06\n const context: RifleContext = {\n kit,\n group,\n parts,\n options,\n furniture: options.wood ? M.wood : options.olive ? M.olive : options.tan ? M.tan : M.poly,\n isTraditional,\n length,\n barrelLength,\n stockLength,\n receiverStart,\n receiverEnd,\n receiverHeight,\n receiverWidth: options.wR || 0.034,\n barrelRadius: options.br || 0.0085,\n barrelY: receiverHeight * 0.15,\n receiverLength: receiverEnd - receiverStart,\n }\n buildReceiver(context)\n buildBarrel(context)\n buildForend(context)\n const gripX = buildGrip(context)\n const magazineX = buildMagazine(context, gripX)\n parts.stockMeshes = context.isTraditional ? [] : captured(group, () => buildStock(context, magazineX))\n if (context.isTraditional) buildStock(context, magazineX)\n buildFittings(context, gripX)\n const hasHandguard = !context.isTraditional && options.hg !== 'none'\n parts.frames = {\n length,\n barrelY: context.barrelY,\n barrelRadius: context.barrelRadius,\n receiverStart,\n receiverEnd,\n receiverHeight,\n receiverWidth: context.receiverWidth,\n handguardEnd: receiverEnd + (length - receiverEnd) * (hasHandguard ? options.hgFrac || 0.5 : 0.4),\n magazineX,\n gripX,\n hasRail: Boolean(options.rail),\n }\n const { barrelY: by, receiverWidth: wR } = context\n const ejectX = receiverEnd - (options.ejectBack || 0.07)\n const ejectY = options.ar ? receiverHeight * 0.2 : by\n parts.muzzle = kit.mark(group, length + 0.01, by, 0)\n parts.eject = kit.mark(group, ejectX, ejectY, wR / 2 + 0.006)\n parts.loadPort = kit.mark(group, receiverEnd - 0.05, -receiverHeight / 2 - 0.004, 0)\n parts.topLoad = kit.mark(group, ejectX, receiverHeight / 2 + 0.004, 0)\n parts.family = familyOf(options)\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport { WEAPONS } from '@adatechnology/game-weapons'\nimport data from '../data/models.json'\nimport { buildBreakAction } from './break-action'\nimport { deriveFrames } from './attachments/mount-frames'\nimport { buildBullpup } from './bullpup'\nimport { modelKit } from './kit'\nimport type { ModelKit } from './kit'\nimport { buildLauncher } from './launcher'\nimport { buildM134 } from './m134'\nimport { buildM2 } from './m2'\nimport { buildP90 } from './p90'\nimport { partRegistry } from './part-registry'\nimport { buildPistol } from './pistol'\nimport { buildRevolver } from './revolver'\nimport { buildRifle } from './rifle'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\nexport type { ModelFamily, ModelOptions, ModelParts } from './types'\n\n/** One weapon of the gallery as `data/models.json` keeps it: the builder, the measures in mm and the builder's options. */\nexport interface ModelEntry {\n readonly builder: 'pistol' | 'revolver' | 'rifle' | 'bullpup' | 'p90' | 'break' | 'm2' | 'm134' | 'launcher'\n readonly caliber: string\n readonly length: number\n readonly barrel: number\n readonly options: ModelOptions\n readonly variantOf?: string\n}\n\nexport const MODEL_ENTRIES: Readonly<Record<string, ModelEntry>> = data as Record<string, ModelEntry>\n\n/**\n * The model each generic archetype wears: the one of the first brand weapon (lowest id) that points to it with `archetype` and fires the same way (a rocket launcher that points to\n * `shotgun_pump_12` does not lend its tube to the shotgun). An archetype nothing points to, the melee weapons and the bow keep their simple prop.\n */\nexport const ARCHETYPE_MODELS: Readonly<Record<string, string>> = (() => {\n const actionOf = new Map(WEAPONS.map((def) => [def.id, def.action.kind]))\n const chosen: Record<string, string> = {}\n for (const def of [...WEAPONS].sort((a, b) => (a.id < b.id ? -1 : 1))) {\n const { archetype } = def\n if (!archetype || !(def.id in MODEL_ENTRIES) || archetype in MODEL_ENTRIES || archetype in chosen) continue\n if (actionOf.get(archetype) === def.action.kind) chosen[archetype] = def.id\n }\n return chosen\n})()\n\n/** A weapon model: `root` (the page's `wr`) holds `inner` (what the builder made, fitted to the real length); `parts` are pivots and marks inside `inner`. */\nexport interface WeaponModel {\n readonly id: string\n readonly root: THREE_NS.Group\n readonly inner: THREE_NS.Group\n readonly parts: ModelParts\n}\n\nconst BUILDERS: Record<ModelEntry['builder'], (kit: ModelKit, options: ModelOptions) => BuiltModel> = {\n pistol: buildPistol,\n revolver: buildRevolver,\n rifle: buildRifle,\n bullpup: buildBullpup,\n p90: (kit) => buildP90(kit),\n break: buildBreakAction,\n m2: (kit) => buildM2(kit),\n m134: (kit) => buildM134(kit),\n launcher: buildLauncher,\n}\n\nconst nameParts = (parts: ModelParts): void => {\n for (const [name, part] of partRegistry(parts)) part.name = name\n}\n\n/** Stretches the model along x to the real length of the weapon (the page's `fitLength`) and puts its rear at the origin. */\nconst fitLength = (kit: ModelKit, inner: THREE_NS.Group, lengthMetres: number): THREE_NS.Group => {\n const box = new kit.THREE.Box3().setFromObject(inner)\n const factor = lengthMetres / (box.max.x - box.min.x)\n inner.scale.x = factor\n inner.position.x = -box.min.x * factor\n const root = kit.group()\n root.add(inner)\n return root\n}\n\nexport const hasWeaponModel = (id: string): boolean => id in MODEL_ENTRIES || id in ARCHETYPE_MODELS\n\n/** The gallery model of a weapon (or of the brand weapon an archetype wears, see `ARCHETYPE_MODELS`), long axis along +x, rear at the origin; undefined for melee, throwables and what nothing drew. */\nexport function buildWeaponModelById(THREE: typeof THREE_NS, id: string): WeaponModel | undefined {\n const entry = MODEL_ENTRIES[ARCHETYPE_MODELS[id] ?? id]\n if (!entry) return undefined\n const kit = modelKit(THREE)\n const options: ModelOptions = { L: entry.length, B: entry.barrel, cal: entry.caliber, ...entry.options }\n if (id in ARCHETYPE_MODELS) delete options.chambers // a generic weapon holds the default six, not the brand's capacity\n const built = BUILDERS[entry.builder](kit, options)\n nameParts(built.parts)\n let root: THREE_NS.Group\n if (entry.builder === 'launcher') {\n root = kit.group()\n root.add(built.group)\n built.group.position.x = -new THREE.Box3().setFromObject(built.group).min.x\n } else root = fitLength(kit, built.group, entry.length / 1000)\n root.name = id\n const model: WeaponModel = { id, root, inner: built.group, parts: built.parts }\n if (!built.parts.frames) built.parts.frames = deriveFrames(THREE, model)\n return model\n}\n","import type { ModelKit, Parent } from '../kit'\nimport type { AttachmentModelBuilder } from './types'\n\n// how far the three legs reach and how thick they are\nconst LEG = { length: 0.62, width: 0.012 }\n\n/** The tripod of three steel legs under the gun, the head at the origin of `parent`: the creation the counters' mounted M134 and the `tripod` accessory both draw. */\nexport function buildTripodLegs(kit: ModelKit, parent: Parent): void {\n const { length, width } = LEG\n kit.box(parent, 0.03, 0.06, 0.03, kit.M.metal, 0, 0, 0)\n kit.box(parent, width, length, width, kit.M.metal, -0.2, -0.25, 0, 0.75)\n kit.box(parent, width, length, width, kit.M.metal, 0.22, -0.25, 0.16, -0.75, 0, 0.3)\n kit.box(parent, width, length, width, kit.M.metal, 0.22, -0.25, -0.16, -0.75, 0, -0.3)\n}\n\nexport const buildTripod: AttachmentModelBuilder = ({ kit }) => {\n const group = kit.group()\n buildTripodLegs(kit, group)\n return group\n}\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, JointSpec, PartSpec, Vec3 } from '@adatechnology/game-contracts'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\nimport { mergeByMaterial } from './merge-by-material'\nimport { buildWeaponModelById } from './models'\nimport { buildTripodLegs } from './models/attachments/tripod'\nimport { modelKit } from './models/kit'\n\n/** A low-poly prop: its destruction spec (box parts only) and one colour per part. */\nexport interface WeaponProp {\n spec: DestructibleSpec\n colors: Record<string, number>\n}\n\ntype Extra = Partial<Omit<PartSpec, 'id' | 'material' | 'shape' | 'position'>>\nconst box = (id: string, material: string, size: Vec3, position: Vec3, extra: Extra = {}): PartSpec => ({ id, material, shape: { kind: 'box', size }, position, ...extra })\nconst joint = (a: string, b: string, kind: JointSpec['kind']): JointSpec => ({ a, b, kind })\n\n// A grip and a body lying flat end to end, long axis along +x, the muzzle or head at +x. One thickness for both parts so the prop lies flat,\n// and the parts touch without overlapping: overlapping parts are pushed apart by the physics and the prop slides away.\nconst handled = (name: string, handle: [string, Vec3], head: [string, Vec3]): WeaponProp => {\n const [handleMaterial, rawHandle] = handle\n const [headMaterial, rawHead] = head\n const thickness = Math.max(rawHandle[1], rawHead[1])\n const handleSize: Vec3 = [rawHandle[0], thickness, rawHandle[2]]\n const headSize: Vec3 = [rawHead[0], thickness, rawHead[2]]\n const shift = (handleSize[0] - headSize[0]) / 2\n return {\n spec: {\n name,\n parts: [box('handle', handleMaterial, handleSize, [-handleSize[0] / 2 + shift, thickness / 2, 0]), box('head', headMaterial, headSize, [headSize[0] / 2 + shift, thickness / 2, 0])],\n joints: [joint('handle', 'head', 'screw')],\n tags: ['weapon'],\n },\n colors: { handle: handleMaterial === 'steel' ? 0x3a3d42 : handleMaterial === 'plastic' ? 0x2b2d30 : 0x7a5530, head: headMaterial === 'steel' ? 0x8f969e : headMaterial === 'copper' ? 0xb87333 : 0x6b4a2a },\n }\n}\nconst solid = (name: string, material: string, size: Vec3, color: number): WeaponProp => ({\n spec: { name, parts: [box('body', material, size, [0, size[1] / 2, 0])], joints: [], tags: ['weapon'] },\n colors: { body: color },\n})\n\nconst SHAPES: Record<string, (name: string, id: string) => WeaponProp> = {\n pistol: (n) => handled(n, ['plastic', [0.06, 0.03, 0.11]], ['steel', [0.2, 0.03, 0.04]]),\n revolver: (n) => handled(n, ['wood_soft', [0.06, 0.035, 0.11]], ['steel', [0.24, 0.04, 0.05]]),\n smg: (n) => handled(n, ['plastic', [0.2, 0.05, 0.14]], ['steel', [0.45, 0.05, 0.06]]),\n carbine: (n) => handled(n, ['wood_soft', [0.35, 0.05, 0.12]], ['steel', [0.6, 0.04, 0.05]]),\n rifle: (n) => handled(n, ['wood_soft', [0.35, 0.06, 0.13]], ['steel', [0.75, 0.05, 0.07]]),\n sniper: (n) => handled(n, ['plastic', [0.4, 0.06, 0.14]], ['steel', [0.95, 0.06, 0.08]]),\n shotgun: (n) => handled(n, ['wood_soft', [0.38, 0.06, 0.13]], ['steel', [0.7, 0.05, 0.06]]),\n bow: (n) => solid(n, 'wood_soft', [0.95, 0.03, 0.22], 0x5a3d22),\n crossbow: (n) => handled(n, ['wood_soft', [0.6, 0.06, 0.08]], ['steel', [0.12, 0.04, 0.26]]),\n melee_blunt: (n, id) =>\n id === 'baseball_bat'\n ? solid(n, 'wood_soft', [0.84, 0.06, 0.06], 0xb08550)\n : handled(n, ['wood_soft', [id === 'sledgehammer' ? 0.8 : 0.32, 0.03, 0.03]], ['steel', id === 'sledgehammer' ? [0.08, 0.08, 0.2] : [0.06, 0.04, 0.12]]),\n melee_blade: (n, id) => handled(n, ['wood_soft', [0.13, 0.03, 0.03]], ['steel', id === 'axe' ? [0.5, 0.03, 0.16] : id === 'knife' ? [0.16, 0.01, 0.03] : [0.45, 0.01, 0.05]]),\n tool: (n) => handled(n, ['plastic', [0.12, 0.025, 0.03]], ['steel', [0.16, 0.02, 0.03]]),\n flame: (n, id) => (id === 'flamethrower' ? handled(n, ['steel', [0.3, 0.14, 0.14]], ['steel', [0.6, 0.05, 0.05]]) : solid(n, 'plastic', [0.08, 0.02, 0.04], 0xd9482b)),\n heat: (n) => handled(n, ['steel', [0.2, 0.08, 0.08]], ['copper', [0.25, 0.03, 0.03]]),\n throwable: (n, id) => (id === 'molotov' ? solid(n, 'glass', [0.25, 0.07, 0.07], 0x7fd6b0) : solid(n, 'steel', [id === 'pipe_bomb' ? 0.25 : 0.1, 0.06, 0.06], 0x4c5a3a)),\n extinguisher: (n) => solid(n, 'steel', [0.5, 0.15, 0.15], 0xc0392b),\n}\n\n/** Body actions of the arsenal: nothing to hold or lay on a counter. */\nexport const BODY_ACTIONS: ReadonlySet<string> = new Set(['hand', 'kick', 'shove', 'fists'])\n\n// Real weights from the arsenal data: solid steel boxes would weigh several times more, go past a carry limit and stop being props.\nconst withMass = (prop: WeaponProp, kg: number): WeaponProp => {\n const volumes = prop.spec.parts.map((part) => (part.shape.kind === 'box' ? part.shape.size[0] * part.shape.size[1] * part.shape.size[2] : 0))\n const total = volumes.reduce((sum, volume) => sum + volume, 0) || 1\n return { ...prop, spec: { ...prop.spec, parts: prop.spec.parts.map((part, index) => ({ ...part, mass: (kg * volumes[index]) / total })) } }\n}\n\n/** The prop of a weapon: low-poly parts by category, the real mass of the weapon spread over them. */\nexport function weaponProp(def: Pick<WeaponDef, 'id' | 'category' | 'mass'>, name = def.id): WeaponProp {\n const shape = SHAPES[def.category] ?? SHAPES.tool\n return withMass(shape(name, def.id), def.mass)\n}\n\n/** One mesh per box part, named after the part (what destruction renderers bind to), in a group with its origin on the floor. */\nexport function buildProp(THREE: typeof THREE_NS, prop: WeaponProp): THREE_NS.Group {\n const group = new THREE.Group()\n group.name = prop.spec.name ?? 'weapon'\n for (const part of prop.spec.parts) {\n if (part.shape.kind !== 'box') continue\n const [w, h, d] = part.shape.size\n const material = new THREE.MeshStandardMaterial({ color: prop.colors[part.id] ?? 0x777777, roughness: 0.6, metalness: part.material === 'steel' ? 0.6 : 0.05 })\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), material)\n mesh.name = part.id\n mesh.position.set(part.position[0], part.position[1], part.position[2])\n mesh.castShadow = true\n mesh.receiveShadow = true\n group.add(mesh)\n }\n return group\n}\n\n/** The model of a weapon for the hands or a shelf: the same prop the counters show. */\nexport function buildWeaponModel(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id' | 'category' | 'mass'>): THREE_NS.Group {\n return buildProp(THREE, weaponProp(def))\n}\n\nconst MODEL_BODY = 'body'\n\n/**\n * The prop of a weapon the gallery drew, for a counter or the floor: its model lying on the side, centred on the footprint with its underside on the floor, joined into one mesh per\n * material (the hands keep the model with its pivots, `buildWeaponModelById`), every mesh naming the one rigid part (`body`) that moves it. The size of that part is left in\n * `userData.footprint` for `modeledPropSpec`.\n */\nexport function buildModeledProp(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id'>, name: string, decorate?: (root: THREE_NS.Object3D) => void): THREE_NS.Group | undefined {\n const model = buildWeaponModelById(THREE, def.id)\n if (!model) return undefined\n decorate?.(model.root)\n const group = new THREE.Group()\n group.name = name\n const box = new THREE.Box3().setFromObject(model.root)\n const center = box.getCenter(new THREE.Vector3())\n model.root.position.set(-center.x, -box.min.y, -center.z)\n group.add(model.root)\n group.updateMatrixWorld(true)\n for (const mesh of mergeByMaterial(THREE, model.root, group)) {\n mesh.userData.destructionPart = MODEL_BODY\n group.add(mesh)\n }\n group.remove(model.root)\n const size = box.getSize(new THREE.Vector3())\n group.userData.footprint = [size.x, size.y, size.z]\n return group\n}\n\n// where the tripod joins the gun (along it, under it)\nconst TRIPOD_HEAD = { x: 0.4, y: -0.1 }\n\n/** A modeled weapon on a tripod of three steel legs under its middle (the same legs the `tripod` accessory draws in the hands). */\nexport function buildTripodMountedProp(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id'>, name: string): THREE_NS.Group | undefined {\n return buildModeledProp(THREE, def, name, (root) => {\n const kit = modelKit(THREE)\n buildTripodLegs(kit, kit.pivot(root, TRIPOD_HEAD.x, TRIPOD_HEAD.y, 0))\n })\n}\n\n/** The destruction spec of a modeled prop: one steel box of its measures, with the real mass of the weapon. */\nexport function modeledPropSpec(root: unknown, def: Pick<WeaponDef, 'mass'>, name: string): DestructibleSpec {\n const footprint = ((root as THREE_NS.Object3D).userData.footprint ?? [0.3, 0.1, 0.1]) as Vec3\n const size: Vec3 = [Math.max(0.02, footprint[0]), Math.max(0.02, footprint[1]), Math.max(0.02, footprint[2])]\n return { name, parts: [{ id: MODEL_BODY, material: 'steel', shape: { kind: 'box', size }, position: [0, size[1] / 2, 0], mass: def.mass }], joints: [], tags: ['weapon'] }\n}\n","import type * as THREE_NS from 'three'\nimport type { HostEvent, HostTool } from '@adatechnology/game-contracts'\nimport { createRng, muzzleEnergy } from '@adatechnology/game-weapons'\nimport type { Arsenal, WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponAudio } from './audio'\nimport { createLayers } from './fx/layers'\nimport type { FxLayers } from './fx/layers'\nimport type { AttachmentModelRegistry, LaserRaycast } from './models/attachments/types'\nimport { IN_HAND_NODE_NAME } from './laser-raycast'\nimport { BODY_ACTIONS, buildWeaponModel } from './props'\n\nexport interface WeaponFxOptions {\n THREE: typeof THREE_NS\n scene: THREE_NS.Scene\n camera: THREE_NS.Camera\n arsenal: Arsenal\n /** Height things rest on at (x, z): casings and magazines land there. */\n groundAt: (x: number, z: number) => number\n /** Sounds (`createWeaponAudio`); null or absent: silent. */\n audio?: WeaponAudio | null\n /** Seed of the scatter of the effects of the gallery models. */\n seed?: number\n /** The tool as it is now (barrel heat, fuel burning). */\n tool?: () => HostTool\n /** Wear of the weapon: `new`, `used`, `worn` or `rusty`. */\n condition?: string\n /** What is drawn: read at the moment of each event, so the bench can change it live. */\n layers?: FxLayers\n /** Metres between the shooter and the listener, for the distance muffling of the shot sound (default 0). */\n soundDistance?: () => number\n /** Builders of accessory models that replace or add to the ones the kit ships (by the `model` of the accessory). */\n attachmentModels?: AttachmentModelRegistry\n /** How far a laser beam goes from a point along a direction (metres), or null when it hits nothing: the dot lands where it ends. */\n raycast?: LaserRaycast\n}\n\n/** The weapon in the hands, its fire and reload motion, ejected casings and dropped magazines, and their sounds. */\nexport interface BoxFx {\n /** Feed every tool event of the host, with the tool as it is after the event. */\n handle(event: HostEvent, tool: HostTool): void\n update(dt: number): void\n /** Takes the weapon out of the hands. */\n unequip(): void\n /** Weapon shown in the hands, or null. */\n readonly inHand: string | null\n /** Casings and magazines currently on the floor or in the air. */\n readonly casings: number\n readonly magazines: number\n dispose(): void\n}\n\n/** Weapons that throw the spent case out on every shot. Revolvers keep them in the cylinder; break-actions open on reload. */\nconst EJECTS_ON_SHOT = new Set(['pistol', 'smg', 'carbine', 'rifle', 'sniper', 'shotgun'])\n/** Weapons whose reload drops a magazine. */\nconst DROPS_MAGAZINE = new Set(['pistol', 'smg', 'carbine', 'rifle', 'sniper'])\n/** Manual actions that cycle (pump, bolt) after each shot: the sound of the cycle. */\nconst CYCLES = new Set(['shotgun_pump_12', 'rifle_bolt_308'])\n// a bow, a crossbow or a tool has no calibre: about a small handgun round\nconst FALLBACK_ENERGY = 300\nconst MAX_CASINGS = 120\nconst MAX_MAGAZINES = 12\nconst LIFETIME_S = 25\nconst HAND_OFFSET: [number, number, number] = [0.2, -0.2, -0.42]\nconst GRAVITY = 9.81\n\ninterface Body {\n mesh: THREE_NS.Mesh\n velocity: THREE_NS.Vector3\n spin: THREE_NS.Vector3\n radius: number\n age: number\n resting: boolean\n bounces: number\n kind: 'casing' | 'magazine'\n}\n\n/** The presentation of a weapon the gallery did not draw (the generic archetypes): a low-poly prop in the hands, a dip on reload and a casing per shot. */\nexport function createBoxFx(options: WeaponFxOptions): BoxFx {\n const { THREE, scene, camera, arsenal, groundAt } = options\n const audio = options.audio ?? null\n const random = createRng(options.seed ?? 1)\n const layers = options.layers ?? createLayers()\n const bodies: Body[] = []\n const brass = new THREE.MeshStandardMaterial({ color: 0xc9a24a, metalness: 0.8, roughness: 0.35 })\n const shell = new THREE.MeshStandardMaterial({ color: 0xa8322b, roughness: 0.6 })\n const steel = new THREE.MeshStandardMaterial({ color: 0x2f3237, metalness: 0.5, roughness: 0.5 })\n const hand = new THREE.Group()\n hand.name = IN_HAND_NODE_NAME\n scene.add(hand)\n let model: THREE_NS.Object3D | null = null\n let inHand: string | null = null\n let def: WeaponDef | null = null\n let kick = 0\n let dip = 0\n let reloading = false\n const v = new THREE.Vector3()\n const q = new THREE.Quaternion()\n const pointForward = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2)\n\n const equip = (weapon: string): void => {\n if (model) hand.remove(model)\n model = null\n inHand = null\n def = arsenal.weapons.get(weapon) ?? null\n if (!def || BODY_ACTIONS.has(def.id)) return\n model = buildWeaponModel(THREE, def)\n const length = new THREE.Box3().setFromObject(model).getSize(v).x\n // long guns are drawn smaller so they do not fill the view\n model.scale.setScalar(length > 0.8 ? 0.55 : length > 0.4 ? 0.75 : 1)\n model.quaternion.copy(pointForward)\n hand.add(model)\n inHand = def.id\n }\n\n // a point on the gun in camera space, turned into the world\n const handPoint = (x: number, y: number, z: number, out: THREE_NS.Vector3): THREE_NS.Vector3 =>\n out.set(HAND_OFFSET[0] + x, HAND_OFFSET[1] + y, HAND_OFFSET[2] + z).applyQuaternion(camera.quaternion).add(camera.position)\n\n const throwBody = (kind: Body['kind'], mesh: THREE_NS.Mesh, from: THREE_NS.Vector3, velocity: THREE_NS.Vector3, radius: number): void => {\n if (!(kind === 'casing' ? layers.casings : layers.magazines)) {\n mesh.geometry.dispose()\n return\n }\n const limit = kind === 'casing' ? MAX_CASINGS : MAX_MAGAZINES\n const same = bodies.filter((b) => b.kind === kind)\n if (same.length >= limit) removeBody(same[0])\n mesh.position.copy(from)\n mesh.castShadow = true\n scene.add(mesh)\n bodies.push({ mesh, velocity, spin: new THREE.Vector3(random() * 20 - 10, random() * 30 - 15, random() * 20 - 10), radius, age: 0, resting: false, bounces: 0, kind })\n }\n\n const ejectCasing = (caliberMm: number, isShell: boolean, downward: boolean): void => {\n const radius = isShell ? 0.0105 : Math.max(0.003, (caliberMm / 1000) * 0.6)\n const length = isShell ? 0.068 : Math.min(0.07, Math.max(0.015, (caliberMm / 1000) * 2.6))\n const mesh = new THREE.Mesh(new THREE.CylinderGeometry(radius, radius, length, 8), isShell ? shell : brass)\n mesh.name = 'casing'\n const from = handPoint(0.03, 0.03, 0.05, new THREE.Vector3())\n const right = new THREE.Vector3(1, 0, 0).applyQuaternion(camera.quaternion)\n const up = new THREE.Vector3(0, 1, 0)\n const velocity = downward\n ? up.clone().multiplyScalar(-0.5).addScaledVector(right, (random() - 0.5) * 0.4)\n : right.multiplyScalar(1.6 + random() * 0.8).addScaledVector(up, 1.4 + random() * 0.8)\n throwBody('casing', mesh, from, velocity, radius)\n }\n\n const dropMagazine = (category: string): void => {\n const long = category === 'rifle' || category === 'sniper' || category === 'carbine'\n const size: [number, number, number] = long ? [0.03, 0.17, 0.07] : [0.025, 0.11, 0.035]\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(...size), steel)\n mesh.name = 'magazine'\n const from = handPoint(0, -0.06, 0, new THREE.Vector3())\n throwBody('magazine', mesh, from, new THREE.Vector3(0, -0.4, 0), size[1] / 2)\n audio?.reloadStart(category)\n }\n\n const caliberOf = (weapon: WeaponDef): number => {\n if (weapon.action.kind !== 'firearm') return 9\n return arsenal.calibers.get(weapon.action.caliber)?.diameter ?? 9\n }\n\n function removeBody(body: Body): void {\n body.mesh.removeFromParent()\n body.mesh.geometry.dispose()\n bodies.splice(bodies.indexOf(body), 1)\n }\n\n const onShot = (weapon: WeaponDef): void => {\n kick = 1\n const caliber = weapon.action.kind === 'firearm' ? arsenal.calibers.get(weapon.action.caliber) : undefined\n const energy = caliber ? muzzleEnergy(caliber) * (caliber.pellets ?? 1) : FALLBACK_ENERGY\n audio?.shot(energy, weapon.category, { ...(caliber ? { caliber } : {}), distance: options.soundDistance?.() ?? 0 })\n if (CYCLES.has(weapon.id)) audio?.cycle()\n if (EJECTS_ON_SHOT.has(weapon.category) && weapon.id !== 'shotgun_double_12') ejectCasing(caliberOf(weapon), weapon.category === 'shotgun', false)\n }\n\n const onReloadStart = (weapon: WeaponDef, tool: HostTool): void => {\n if (DROPS_MAGAZINE.has(weapon.category)) dropMagazine(weapon.category)\n else audio?.reloadStart(weapon.category)\n // revolvers and break-action shotguns dump their spent cases when opened\n if (weapon.category === 'revolver' || weapon.id === 'shotgun_double_12') {\n const spent = Math.max(1, tool.capacity - tool.ammo)\n for (let i = 0; i < spent; i++) ejectCasing(caliberOf(weapon), weapon.category === 'shotgun', true)\n }\n }\n\n const stepBody = (body: Body, dt: number): void => {\n body.age += dt\n if (body.resting) return\n body.velocity.y -= GRAVITY * dt\n body.mesh.position.addScaledVector(body.velocity, dt)\n body.mesh.rotation.x += body.spin.x * dt\n body.mesh.rotation.y += body.spin.y * dt\n body.mesh.rotation.z += body.spin.z * dt\n const floor = groundAt(body.mesh.position.x, body.mesh.position.z) + body.radius\n if (body.mesh.position.y > floor) return\n body.mesh.position.y = floor\n if (Math.abs(body.velocity.y) > 0.7 && body.bounces < 4) {\n body.bounces++\n body.velocity.y = -body.velocity.y * 0.35\n body.velocity.x *= 0.55\n body.velocity.z *= 0.55\n body.spin.multiplyScalar(0.5)\n if (body.kind === 'casing') audio?.clink()\n else audio?.thud()\n return\n }\n if (body.kind === 'magazine' && body.bounces === 0) audio?.thud()\n body.resting = true\n body.mesh.rotation.x = Math.PI / 2\n body.mesh.rotation.z = 0\n }\n\n return {\n unequip() {\n if (model) hand.remove(model)\n model = null\n inHand = null\n },\n handle(event, tool) {\n if (event.type === 'explosion') return\n const weapon = arsenal.weapons.get(event.weapon)\n if (event.type === 'tool') equip(event.weapon)\n if (!weapon) return\n if (event.type === 'shot') onShot(weapon)\n else if (event.type === 'empty') audio?.click()\n else if (event.type === 'reload' && event.phase === 'start') onReloadStart(weapon, tool)\n else if (event.type === 'reload' && event.phase === 'end') audio?.reloadEnd(weapon.category)\n reloading = tool.reloading\n },\n update(dt) {\n kick *= Math.exp(-dt * 14)\n dip += ((reloading ? 1 : 0) - dip) * Math.min(1, dt * 8)\n if (inHand) {\n handPoint(0, -0.12 * dip, 0.05 * kick, hand.position)\n q.setFromEuler(new THREE.Euler(0.14 * kick - 0.25 * dip, 0, 0.6 * dip))\n hand.quaternion.copy(camera.quaternion).multiply(q)\n }\n for (const body of [...bodies]) {\n stepBody(body, dt)\n if (body.age > LIFETIME_S) removeBody(body)\n }\n },\n get inHand() {\n return inHand\n },\n get casings() {\n return bodies.filter((b) => b.kind === 'casing').length\n },\n get magazines() {\n return bodies.filter((b) => b.kind === 'magazine').length\n },\n dispose() {\n for (const body of [...bodies]) removeBody(body)\n hand.removeFromParent()\n brass.dispose()\n shell.dispose()\n steel.dispose()\n },\n }\n}\n","import type { DamageType, DestructibleSpec, DestructionEvent, Hit, JointSpec, ObjectState, ToolKind, Vec3 } from './destruction'\n\n/**\n * What a game module implements for an object whose behaviour it owns (a vehicle with its own panel deformation, a creature, a machine). The\n * world (`DestructionWorld.register`) hosts it next to its own objects: raycast, shoot, explode, hit, disassemble, extinguish, update, state,\n * reset and `on` all route to it.\n *\n * Space: the impl receives hits in WORLD space and returns events in WORLD space (it owns its transform; the transform given to `register` or\n * `setTransform` is only used by the world for raycasts and blast range). Every event must carry `object === id` and name parts listed by\n * `describe()`.\n */\nexport interface DestructibleImpl {\n readonly id: string\n readonly name?: string\n /** Parts, joints and structure in the impl's local space, for raycast, inspector and log. Called often: keep it cheap. */\n describe(): DestructibleSpec\n /** Apply one hit (see `IMPACT_CONTRACT` for the fields per type) and return the events it caused. */\n hit(hit: Hit): DestructionEvent[]\n /** Advance fire, melting, collapse and other timed behaviour. */\n update?(dt: number): DestructionEvent[]\n state(): ObjectState\n reset?(): void\n /** Same contract as `DestructionWorld.disassemble`: progress 0..1, or -1 when the tool cannot undo the joint. */\n disassemble?(jointId: string, tool: ToolKind, dt: number): number\n extinguish?(partId?: string): void\n /** Optional: an animation moved a part; `position` / `rotation` (Euler XYZ, radians) are object-local. Keep raycast and hit shapes in sync. */\n setPartPose?(partId: string, position: Vec3, rotation?: Vec3): void\n /** Plain JSON of the impl's own state, stored in `DestructionSnapshot.impls`. */\n serialize?(): unknown\n load?(data: unknown): void\n}\n\n/** The fields a weapon or hazard must put in a `Hit`, per damage type. THE impact contract. */\nexport interface ImpactContract {\n required: string[]\n optional: string[]\n note: string\n}\n\nexport const IMPACT_CONTRACT: Record<DamageType, ImpactContract> = {\n ballistic: { required: ['type', 'point', 'direction', 'energy', 'caliber'], optional: ['space', 'source'], note: 'bullets and pellets: joules and diameter in millimetres' },\n blunt: { required: ['type', 'point', 'energy'], optional: ['direction', 'radius', 'space', 'source'], note: 'contact radius in metres (default 3 cm)' },\n slash: { required: ['type', 'point', 'energy'], optional: ['direction', 'radius', 'space', 'source'], note: 'axes, knives, machetes' },\n explosive: { required: ['type', 'point', 'energy', 'radius'], optional: ['space', 'source'], note: 'point is the centre of the blast, radius the range in metres' },\n fire: { required: ['type', 'point', 'temperature', 'radius'], optional: ['duration', 'space', 'source'], note: 'flame temperature in °C; duration in seconds (call every frame with `dt`)' },\n heat: { required: ['type', 'point', 'temperature', 'radius'], optional: ['duration', 'space', 'source'], note: 'heat without flame (cutting torch, hot plate)' },\n}\n\n/** Problems with a hit according to the impact contract (empty when it is valid). */\nexport const checkHit = (hit: Hit): string[] => {\n const c = IMPACT_CONTRACT[hit.type]\n if (!c) return [`unknown damage type \"${String(hit.type)}\"`]\n const out: string[] = []\n for (const f of c.required) {\n const v = (hit as unknown as Record<string, unknown>)[f]\n if (v === undefined || (Array.isArray(v) ? v.some((n) => !Number.isFinite(n)) : typeof v === 'number' && !Number.isFinite(v))) out.push(`${hit.type} hit needs \"${f}\"`)\n }\n return out\n}\n\nexport interface CheckOptions {\n /**\n * Ids of every material the impl may use (the contracts package does not know the materials of your world: pass the ids of\n * `world.materials`, or the built-in plus your own). When omitted, the material check is skipped.\n */\n materials?: Iterable<string>\n}\n\nconst finiteJson = (v: unknown, path: string, out: string[]) => {\n if (typeof v === 'number') {\n if (!Number.isFinite(v)) out.push(`${path} is not a finite number`)\n } else if (Array.isArray(v)) v.forEach((x, i) => finiteJson(x, `${path}[${i}]`, out))\n else if (v && typeof v === 'object') for (const [k, x] of Object.entries(v)) finiteJson(x, `${path}.${k}`, out)\n else if (typeof v === 'function' || typeof v === 'symbol' || typeof v === 'bigint') out.push(`${path} is not JSON`)\n}\n\n/**\n * Contract checker for the test room (it needs no world): `describe()` is valid, a 500 J ballistic hit at a part centre returns well-formed events of this impl, `state()`\n * matches `describe()`, hit points never go negative, `update(0.016)` returns an array and every event is JSON-serializable. It hits the impl\n * (and calls `reset()` afterwards when there is one).\n */\nexport const checkDestructible = (impl: DestructibleImpl, options: CheckOptions = {}): { ok: boolean; problems: string[] } => {\n const problems: string[] = []\n const known = options.materials ? new Set(options.materials) : null\n let spec: DestructibleSpec | undefined\n try {\n spec = impl.describe()\n } catch (e) {\n return { ok: false, problems: [`describe() threw: ${String(e)}`] }\n }\n if (!spec || !Array.isArray(spec.parts) || spec.parts.length === 0) return { ok: false, problems: ['describe() must return at least one part'] }\n const ids = new Set<string>()\n for (const p of spec.parts) {\n if (ids.has(p.id)) problems.push(`duplicate part id \"${p.id}\"`)\n ids.add(p.id)\n if (known && !known.has(p.material)) problems.push(`part \"${p.id}\" has unknown material \"${p.material}\"`)\n if (!p.shape || !['box', 'cylinder', 'sphere'].includes(p.shape.kind)) problems.push(`part \"${p.id}\" has no valid shape`)\n if (!Array.isArray(p.position) || p.position.length !== 3) problems.push(`part \"${p.id}\" has no position`)\n }\n const jointIds = new Set<string>()\n for (const j of (spec.joints ?? []) as JointSpec[]) {\n if (!ids.has(j.a) || !ids.has(j.b)) problems.push(`joint \"${j.id ?? `${j.a}~${j.b}`}\" references an unknown part`)\n const jid = j.id ?? `${j.a}~${j.b}`\n if (jointIds.has(jid)) problems.push(`duplicate joint id \"${jid}\"`)\n jointIds.add(jid)\n }\n const checkState = (label: string) => {\n let st: ObjectState\n try {\n st = impl.state()\n } catch (e) {\n problems.push(`state() threw ${label}: ${String(e)}`)\n return\n }\n const sids = st.parts.map((p) => p.id).sort().join(',')\n if (sids !== [...ids].sort().join(',')) problems.push(`state() part ids do not match describe() ${label}`)\n for (const p of st.parts) if (!(p.hp >= 0)) problems.push(`part \"${p.id}\" has negative or invalid hp ${label}`)\n }\n const checkEvents = (events: unknown, label: string) => {\n if (!Array.isArray(events)) {\n problems.push(`${label} must return an array`)\n return\n }\n const evs = events as DestructionEvent[]\n evs.forEach((e, i) => {\n if (e.object !== impl.id) problems.push(`${label} event ${i} (${e.type}) has object \"${String(e.object)}\", expected \"${impl.id}\"`)\n const part = (e as { part?: string }).part\n if (part !== undefined && !ids.has(part)) problems.push(`${label} event ${i} (${e.type}) names unknown part \"${part}\"`)\n })\n const bad: string[] = []\n finiteJson(evs, 'events', bad)\n problems.push(...bad.map((b) => `${label}: ${b}`))\n try {\n const s = JSON.stringify(evs)\n if (JSON.stringify(JSON.parse(s)) !== s) problems.push(`${label} events do not survive a JSON round trip`)\n } catch (e) {\n problems.push(`${label} events are not JSON-serializable: ${String(e)}`)\n }\n }\n checkState('before the hit')\n const target = spec.parts[0]\n try {\n const hit: Hit = { type: 'ballistic', point: [target.position[0], target.position[1], target.position[2]], direction: [0, 0, -1], energy: 500, caliber: 9 }\n checkEvents(impl.hit(hit), 'hit()')\n } catch (e) {\n problems.push(`hit() threw: ${String(e)}`)\n }\n checkState('after the hit')\n if (impl.update) {\n try {\n checkEvents(impl.update(0.016), 'update()')\n } catch (e) {\n problems.push(`update() threw: ${String(e)}`)\n }\n checkState('after update')\n }\n try {\n impl.reset?.()\n } catch (e) {\n problems.push(`reset() threw: ${String(e)}`)\n }\n return { ok: problems.length === 0, problems }\n}\n","import type { DestructibleSpec } from './destruction'\n\nexport interface CheckSpecOptions {\n /** Known material ids. When given, every part's material must be one of them. */\n materials?: Iterable<string>\n}\n\nexport interface SpecReport {\n /** False when there is at least one problem (warnings do not count). */\n ok: boolean\n problems: string[]\n /** Things that are legal but probably wrong, e.g. structural parts that cannot reach an anchored part. */\n warnings: string[]\n}\n\nconst STRUCTURE_ROLES = ['foundation', 'column', 'beam', 'slab', 'wall', 'partition', 'roof', 'stair', 'none']\nconst BEARS = [true, false, 'a_on_b', 'b_on_a']\n\nconst finite = (n: unknown): n is number => typeof n === 'number' && Number.isFinite(n)\nconst positive = (n: unknown): boolean => finite(n) && n > 0\nconst vec3 = (v: unknown): boolean => Array.isArray(v) && v.length === 3 && v.every(finite)\nconst nonNegative = (n: unknown): boolean => n === undefined || (finite(n) && n >= 0)\n\n/**\n * Static checks on a `DestructibleSpec` (no world needed), for items that give a `spec` instead of an `impl`: unique part ids, known materials\n * (when `options.materials` is given), joints that reference existing, different parts, finite positive sizes, non-negative mass / hp / capacity,\n * valid structure roles and `bears` directions. A structural part with no path of joints to an anchored part is a warning, not a problem: it\n * is allowed, it just falls.\n */\nexport const checkSpec = (spec: DestructibleSpec, options: CheckSpecOptions = {}): SpecReport => {\n const problems: string[] = []\n const warnings: string[] = []\n const materials = options.materials ? new Set(options.materials) : null\n const parts = Array.isArray(spec?.parts) ? spec.parts : []\n if (!Array.isArray(spec?.parts) || parts.length === 0) problems.push('the spec needs at least one part')\n const ids = new Set<string>()\n for (const p of parts) {\n const id = String(p?.id ?? '')\n const label = `part \"${id}\"`\n if (id === '') problems.push('a part has no id')\n else if (ids.has(id)) problems.push(`duplicate part id \"${id}\"`)\n ids.add(id)\n if (materials && !materials.has(p?.material)) problems.push(`${label} has unknown material \"${String(p?.material)}\"`)\n else if (typeof p?.material !== 'string' || p.material === '') problems.push(`${label} needs a material`)\n const s = p?.shape\n if (s?.kind === 'box') {\n if (!Array.isArray(s.size) || s.size.length !== 3 || !s.size.every(positive)) problems.push(`${label} box size must be three finite positive numbers`)\n } else if (s?.kind === 'cylinder') {\n if (!positive(s.radius) || !positive(s.height)) problems.push(`${label} cylinder radius and height must be finite and positive`)\n } else if (s?.kind === 'sphere') {\n if (!positive(s.radius)) problems.push(`${label} sphere radius must be finite and positive`)\n } else problems.push(`${label} has an unknown shape`)\n if (!vec3(p?.position)) problems.push(`${label} needs a finite position [x, y, z]`)\n if (p?.rotation !== undefined && !vec3(p.rotation)) problems.push(`${label} has an invalid rotation`)\n for (const f of ['mass', 'hp', 'thickness'] as const) if (!nonNegative(p?.[f])) problems.push(`${label} ${f} must be a finite number >= 0`)\n if (p?.fill !== undefined && !(finite(p.fill) && p.fill >= 0 && p.fill <= 1)) problems.push(`${label} fill must be between 0 and 1`)\n if (p?.structure) {\n if (!STRUCTURE_ROLES.includes(p.structure.role)) problems.push(`${label} has an invalid structure role \"${String(p.structure.role)}\"`)\n if (!nonNegative(p.structure.capacity)) problems.push(`${label} structure capacity must be a finite number >= 0`)\n }\n if (p?.contains && !nonNegative(p.contains.liters)) problems.push(`${label} contains.liters must be a finite number >= 0`)\n }\n\n const jointIds = new Set<string>()\n const edges: Array<[string, string]> = []\n for (const j of spec?.joints ?? []) {\n const id = j.id ?? `${j.a}~${j.b}`\n const label = `joint \"${id}\"`\n if (jointIds.has(id)) problems.push(`duplicate joint id \"${id}\"`)\n jointIds.add(id)\n if (!ids.has(j.a)) problems.push(`${label} references unknown part \"${String(j.a)}\"`)\n if (!ids.has(j.b)) problems.push(`${label} references unknown part \"${String(j.b)}\"`)\n if (j.a === j.b) problems.push(`${label} joins part \"${String(j.a)}\" to itself`)\n if (j.bears !== undefined && !BEARS.includes(j.bears)) problems.push(`${label} has an invalid bears \"${String(j.bears)}\"`)\n if (!nonNegative(j.strength)) problems.push(`${label} strength must be a finite number >= 0`)\n if (!nonNegative(j.seconds)) problems.push(`${label} seconds must be a finite number >= 0`)\n if (j.bears !== false && ids.has(j.a) && ids.has(j.b) && j.a !== j.b) edges.push([j.a, j.b])\n }\n\n // structural parts must reach an anchored part over the joints (only when the spec lists its joints: otherwise they are inferred later)\n const structural = parts.filter((p) => p?.structure && p.structure.role !== 'none')\n if (structural.length && spec.joints) {\n const anchored = parts.filter((p) => p.anchored || p.structure?.role === 'foundation').map((p) => p.id)\n const adj = new Map<string, string[]>()\n for (const [a, b] of edges) {\n adj.set(a, [...(adj.get(a) ?? []), b])\n adj.set(b, [...(adj.get(b) ?? []), a])\n }\n const seen = new Set(anchored)\n const queue = [...anchored]\n while (queue.length) {\n for (const n of adj.get(queue.pop()!) ?? []) {\n if (seen.has(n)) continue\n seen.add(n)\n queue.push(n)\n }\n }\n const lost = structural.filter((p) => !seen.has(p.id)).map((p) => p.id)\n if (lost.length) warnings.push(`structural part(s) ${lost.map((i) => `\"${i}\"`).join(', ')} cannot reach an anchored part, so they will fall`)\n }\n return { ok: problems.length === 0, problems, warnings }\n}\n","import type { Hit, Vec3 } from './destruction'\n\n/**\n * A ballistic shot (one per pellet) as a weapon module produces it. Plain data: any damage model can consume it (`shotToHit` makes the `Hit`).\n */\nexport interface Shot {\n origin: Vec3\n /** Unit vector. */\n direction: Vec3\n /** Muzzle energy in joules. */\n energy: number\n /** Bullet diameter in millimetres. */\n caliber: number\n /** snake_case calibre id, e.g. `9x19`. */\n caliberId: string\n /** Muzzle speed in m/s. */\n speed: number\n /** Energy at a distance in metres, with the calibre's drag. */\n energyAt(distance: number): number\n pellet: number\n /** snake_case weapon id. */\n weapon: string\n source?: string\n}\n\n/** One use of a non-firearm (melee swing, flame tick, heat tick, throw, tool tick, extinguisher tick). */\nexport type Use =\n | { kind: 'melee'; damage: 'blunt' | 'slash'; energy: number; radius: number; reach: number; origin: Vec3; direction: Vec3 }\n | { kind: 'flame'; temperature: number; radius: number; range: number; cone: boolean; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'heat'; temperature: number; radius: number; range: number; duration: number; origin: Vec3; direction: Vec3 }\n | {\n kind: 'throw'\n energy: number\n radius: number\n fuse: number\n velocity: Vec3\n origin: Vec3\n fire?: { temperature: number; radius: number; seconds: number }\n /** Explosive id (`m67`, `molotov`, `pg7v`...): the host looks the numbers up in the arsenal. Absent on a plain thrown object. */\n explosive?: string\n /** What sets it off: `timer` after `fuse` seconds, `impact` on the first hit once armed. */\n trigger?: 'timer' | 'impact'\n /** Metres the projectile must fly before an impact sets it off; closer, it hits without exploding (rocket launchers). */\n armDistance?: number\n /** Radius in metres of the wounding area (`radius` is the lethal one). */\n injuryRadius?: number\n /** Seconds the blast stuns whoever is inside the injury radius (flashbang). */\n stunSeconds?: number\n /** Seconds the thrower held it after pulling the pin: `fuse` is what was left of the full fuse when it left the hand. */\n cooked?: number\n /** Went off in the thrower's hand (held past the fuse): no velocity, `fuse` is 0 and the blast is at `origin`. */\n inHand?: boolean\n }\n /** An explosive set down where the trigger is pulled (mine, C4, charge): it waits for its trigger instead of flying. */\n | {\n kind: 'place'\n explosive: string\n /** `wire`: something trips it; `remote`: the player fires it; `timer`: after `fuse` seconds. */\n triggers: readonly ('timer' | 'wire' | 'remote')[]\n energy: number\n /** Lethal radius in metres. */\n radius: number\n injuryRadius: number\n /** Cone the blast goes through, in front of `direction` (mine); absent for a blast in every direction. */\n cone?: { halfAngleDeg: number; length: number }\n /** The wire a `wire` charge stretches from where it is set down: metres out, degrees from its facing (counter-clockwise from above) and metres above it. */\n tripwire?: { length: number; angleDeg: number; height: number }\n fuse?: number\n origin: Vec3\n direction: Vec3\n }\n /** The blast behind a rocket launcher: dangerous inside `radius` metres, in the cone around `direction` (pointing away from the target). */\n | { kind: 'backblast'; radius: number; halfAngleDeg: number; origin: Vec3; direction: Vec3 }\n | { kind: 'tool'; tool: string; reach: number; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'extinguish'; range: number; coolC: number; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'hand'; reach: number; origin: Vec3; direction: Vec3 }\n\n/**\n * The `Hit` a ballistic shot makes at `point` (world space): the energy is what is left of the shot at that distance from its origin\n * (`shot.energyAt`), the direction and calibre come from the shot. `normal` (the surface normal at the point, when the caller knows it) does not\n * change the hit; it is accepted so that callers can pass what their raycast returned and so that a stricter implementation could use it.\n */\nexport const shotToHit = (shot: Shot, point: Vec3, normal?: Vec3): Hit => {\n void normal\n const dx = point[0] - shot.origin[0]\n const dy = point[1] - shot.origin[1]\n const dz = point[2] - shot.origin[2]\n const distance = Math.hypot(dx, dy, dz)\n return {\n type: 'ballistic',\n point: [point[0], point[1], point[2]],\n direction: [shot.direction[0], shot.direction[1], shot.direction[2]],\n energy: shot.energyAt(distance),\n caliber: shot.caliber,\n source: shot.source ?? shot.weapon,\n }\n}\n","import type { Vec3 } from './destruction'\n\n/** Pose of one part (or of the whole item) at a key: position offset in metres and Euler XYZ rotation in radians, both relative to the rest pose. */\nexport interface AnimationPose {\n position?: Vec3\n rotation?: Vec3\n}\n\nexport interface AnimationKey {\n /** Seconds from the start of the clip. */\n t: number\n /** Pose of the item's root. */\n position?: Vec3\n rotation?: Vec3\n /** Poses of named parts: the key is a destruction part id (a pistol `reload` moves `mag`; a car door `open` rotates `door_l`). */\n parts?: Record<string, AnimationPose>\n}\n\nexport interface AnimationEventSpec {\n /** Seconds from the start of the clip. */\n t: number\n /** snake_case type the host maps (`sound`, `eject_casing`, `door_latch`...). */\n type: string\n data?: Record<string, unknown>\n}\n\n/** A use animation a module brings with its item. Poses between keys are interpolated by the player (the test room does it linearly). */\nexport interface AnimationClipSpec {\n /** snake_case: `reload`, `open`, `drink`... Unique within the item. */\n id: string\n /** Seconds. */\n duration: number\n keys: AnimationKey[]\n events?: AnimationEventSpec[]\n}\n\n/** What an item exposes when it brings its own animations. */\nexport interface ItemAnimationContract {\n animations: AnimationClipSpec[]\n}\n\nconst finite3 = (v: unknown): boolean => Array.isArray(v) && v.length === 3 && v.every((n) => typeof n === 'number' && Number.isFinite(n))\n\n/**\n * Problems with a clip (empty when it is valid): a snake_case id, a positive finite duration, at least one key, key and event times inside\n * `[0, duration]` and not going backwards, finite vectors, every named part one of `partIds`, event types that are non-empty strings and\n * JSON-serializable event data.\n */\nexport const checkAnimation = (clip: AnimationClipSpec, partIds: Iterable<string>): { ok: boolean; problems: string[] } => {\n const problems: string[] = []\n const parts = new Set(partIds)\n const id = String(clip?.id ?? '')\n if (!/^[a-z][a-z0-9_]*$/.test(id)) problems.push(`clip id \"${id}\" must be snake_case`)\n const label = `clip \"${id}\"`\n if (!(typeof clip?.duration === 'number' && Number.isFinite(clip.duration) && clip.duration > 0)) problems.push(`${label} needs a positive finite duration`)\n const dur = typeof clip?.duration === 'number' && clip.duration > 0 ? clip.duration : Infinity\n if (!Array.isArray(clip?.keys) || clip.keys.length === 0) {\n problems.push(`${label} needs at least one key`)\n return { ok: false, problems }\n }\n let prev = -Infinity\n clip.keys.forEach((k, i) => {\n if (!(typeof k.t === 'number' && Number.isFinite(k.t)) || k.t < 0 || k.t > dur + 1e-9) problems.push(`${label} key ${i} has t=${String(k.t)} outside 0..${dur}`)\n else if (k.t < prev) problems.push(`${label} key ${i} goes back in time (${k.t} < ${prev})`)\n else prev = k.t\n for (const f of ['position', 'rotation'] as const) if (k[f] !== undefined && !finite3(k[f])) problems.push(`${label} key ${i} has an invalid ${f}`)\n for (const [pid, pose] of Object.entries(k.parts ?? {})) {\n if (!parts.has(pid)) problems.push(`${label} key ${i} moves unknown part \"${pid}\"`)\n for (const f of ['position', 'rotation'] as const) if (pose?.[f] !== undefined && !finite3(pose[f])) problems.push(`${label} key ${i} part \"${pid}\" has an invalid ${f}`)\n }\n })\n let prevEv = -Infinity\n ;(clip.events ?? []).forEach((e, i) => {\n if (!(typeof e.t === 'number' && Number.isFinite(e.t)) || e.t < 0 || e.t > dur + 1e-9) problems.push(`${label} event ${i} has t=${String(e.t)} outside 0..${dur}`)\n else if (e.t < prevEv) problems.push(`${label} event ${i} goes back in time`)\n else prevEv = e.t\n if (typeof e.type !== 'string' || e.type === '') problems.push(`${label} event ${i} needs a type`)\n try {\n JSON.stringify(e.data ?? {})\n } catch {\n problems.push(`${label} event ${i} data is not JSON`)\n }\n })\n return { ok: problems.length === 0, problems }\n}\n","import type { AnimationClipSpec, AnimationEventSpec, AnimationPose } from './animation'\nimport { checkAnimation } from './animation'\nimport type { HostEvent } from './module'\n\n/** Clips a tool can bring, one per move of its cycle. A tool brings the ones it has; a missing clip is simply not played. */\nexport const TOOL_CLIP = {\n DRAW: 'draw',\n SHOT: 'shot',\n MISFIRE: 'misfire',\n EMPTY: 'empty',\n CYCLE: 'cycle',\n RELOAD: 'reload',\n FEED: 'feed',\n FAULT: 'fault',\n CLEAR: 'clear',\n SAFETY_ON: 'safety_on',\n SAFETY_OFF: 'safety_off',\n MODE: 'mode',\n /** A throwable with the pin out, held until it is thrown. */\n COOK: 'cook',\n /** The stock folds, unfolds, slides in or out (variants `fold`, `unfold`, `collapse`, `extend`). */\n STOCK: 'stock',\n /** A light or a laser is switched (variants `on`, `off`). */\n TOGGLE: 'toggle',\n} as const\nexport type ToolClipId = (typeof TOOL_CLIP)[keyof typeof TOOL_CLIP]\n\n/** What a renderer does when a rule event arrives. `variant` picks `<clip>_<variant>` when the tool has it, else `<clip>`. */\nexport type ToolAnimationStep =\n | { readonly type: 'play'; readonly clip: ToolClipId; readonly variant?: string; readonly duration?: number; readonly repeat?: number }\n /** Move the clip that is playing to the marker (a clip event `stage` with `data.stage`) the rule just reached. */\n | { readonly type: 'sync'; readonly stage: string }\n /** The rule says the phase is over: the clip jumps to its end if it is still running. */\n | { readonly type: 'finish'; readonly clip: ToolClipId }\n\nconst stockVariant = (event: Extract<HostEvent, { type: 'stock' }>): string => {\n const isFolding = event.kind === undefined ? false : event.kind.includes('fold')\n if (event.state === 'collapsed') return isFolding ? 'fold' : 'collapse'\n return isFolding ? 'unfold' : 'extend'\n}\n\n/** The move a host event asks of the tool in hand, or null when it has no motion. */\nexport const toolAnimationStep = (event: HostEvent): ToolAnimationStep | null => {\n switch (event.type) {\n case 'tool':\n return { type: 'play', clip: TOOL_CLIP.DRAW, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'shot':\n return { type: 'play', clip: TOOL_CLIP.SHOT, repeat: Math.max(1, event.rounds ?? 1) }\n case 'misfire':\n return { type: 'play', clip: TOOL_CLIP.MISFIRE }\n case 'empty':\n return { type: 'play', clip: TOOL_CLIP.EMPTY }\n case 'mode':\n return { type: 'play', clip: TOOL_CLIP.MODE, variant: event.mode }\n case 'fault':\n return { type: 'play', clip: TOOL_CLIP.FAULT, variant: event.fault }\n case 'clear':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.CLEAR }\n return { type: 'play', clip: TOOL_CLIP.CLEAR, variant: event.fault, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'safety':\n return { type: 'play', clip: event.on ? TOOL_CLIP.SAFETY_ON : TOOL_CLIP.SAFETY_OFF }\n case 'cycle':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.CYCLE }\n return { type: 'play', clip: TOOL_CLIP.CYCLE, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'reload':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.RELOAD }\n return { type: 'play', clip: TOOL_CLIP.RELOAD, ...(event.kind === undefined ? {} : { variant: event.kind }), ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'stage':\n return { type: 'sync', stage: event.stage }\n case 'feed':\n return { type: 'play', clip: TOOL_CLIP.FEED }\n case 'cook':\n if (event.phase === 'start') return { type: 'play', clip: TOOL_CLIP.COOK, duration: event.fuse }\n return { type: 'finish', clip: TOOL_CLIP.COOK }\n case 'stock':\n return { type: 'play', clip: TOOL_CLIP.STOCK, variant: stockVariant(event), ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'toggle':\n return { type: 'play', clip: TOOL_CLIP.TOGGLE, variant: event.on ? 'on' : 'off' }\n default:\n return null\n }\n}\n\n/** Where a renderer puts the poses: every part of the tool by id (the ids the clips move), and the whole tool. Poses are offsets from rest. */\nexport interface ToolRig {\n setPartPose(partId: string, pose: AnimationPose): void\n setRootPose?(pose: AnimationPose): void\n}\n\n/** Clips by id, with the variants as `<clip>_<variant>`. */\nexport type ToolClipSet = Readonly<Record<string, AnimationClipSpec>>\n\n/** A renderer's tool animator: feed it the host events and the frame time. */\nexport interface ToolAnimator {\n handle(event: HostEvent): void\n update(dt: number): void\n /** Ids of the clips playing now. */\n readonly playing: readonly string[]\n dispose(): void\n}\n\nexport const STAGE_EVENT = 'stage'\n\n/** The clip with its times (keys and events) scaled so that it lasts `duration` seconds. */\nexport const scaleClip = (clip: AnimationClipSpec, duration: number): AnimationClipSpec => {\n const factor = clip.duration > 0 ? duration / clip.duration : 1\n return {\n ...clip,\n duration,\n keys: clip.keys.map((key) => ({ ...key, t: key.t * factor })),\n ...(clip.events ? { events: clip.events.map((event) => ({ ...event, t: event.t * factor })) } : {}),\n }\n}\n\nconst ZERO: [number, number, number] = [0, 0, 0]\nconst mix = (from: readonly number[], to: readonly number[], fraction: number): [number, number, number] => [\n (from[0] ?? 0) + ((to[0] ?? 0) - (from[0] ?? 0)) * fraction,\n (from[1] ?? 0) + ((to[1] ?? 0) - (from[1] ?? 0)) * fraction,\n (from[2] ?? 0) + ((to[2] ?? 0) - (from[2] ?? 0)) * fraction,\n]\n\n/** Pose of the whole tool (`partId` undefined) or of one part at `time`, linear between keys; a key that does not name it means rest. */\nexport const sampleClip = (clip: AnimationClipSpec, partId: string | undefined, time: number): { position: [number, number, number]; rotation: [number, number, number] } => {\n const points = clip.keys.map((key) => {\n const pose = partId === undefined ? key : key.parts?.[partId]\n return { t: key.t, position: pose?.position ?? ZERO, rotation: pose?.rotation ?? ZERO }\n })\n const first = points[0]\n if (!first || first.t > 0) points.unshift({ t: 0, position: ZERO, rotation: ZERO })\n const last = points[points.length - 1]\n if (!last) return { position: ZERO, rotation: ZERO }\n if (time >= last.t) return { position: mix(last.position, last.position, 0), rotation: mix(last.rotation, last.rotation, 0) }\n const index = Math.max(0, points.findIndex((point, i) => time >= point.t && time < (points[i + 1]?.t ?? Infinity)))\n const from = points[index]\n const to = points[index + 1]\n if (!from || !to) return { position: ZERO, rotation: ZERO }\n const fraction = to.t > from.t ? (time - from.t) / (to.t - from.t) : 0\n return { position: mix(from.position, to.position, fraction), rotation: mix(from.rotation, to.rotation, fraction) }\n}\n\n/** Problems with a clip set (empty when valid): each key is the clip id (or `<clip>_<variant>`), every clip passes `checkAnimation`, and a `stage` event names its stage. */\nexport const checkToolClips = (clips: ToolClipSet, partIds: Iterable<string>): { ok: boolean; problems: string[] } => {\n const parts = [...partIds]\n const problems: string[] = []\n for (const [key, clip] of Object.entries(clips)) {\n if (clip.id !== key) problems.push(`clip \"${key}\" has the id \"${clip.id}\"`)\n if (!(clip.duration > 0)) problems.push(`clip \"${key}\" has no duration`)\n problems.push(...checkAnimation(clip, parts).problems)\n for (const event of clip.events ?? []) if (event.type === STAGE_EVENT && typeof event.data?.stage !== 'string') problems.push(`clip \"${key}\" has a stage event without data.stage`)\n }\n return { ok: problems.length === 0, problems }\n}\n\ninterface Instance {\n readonly name: string\n readonly clip: AnimationClipSpec\n time: number\n delay: number\n fired: number\n}\n\nexport interface ToolClipPlayerOptions {\n clips: ToolClipSet\n rig: ToolRig\n /** Called for each clip event as its time passes (`eject_casing`, `drop_magazine`, `stage`...). */\n onEvent?(event: AnimationEventSpec, clip: string): void\n /** Seconds between the rounds of a `repeat` (a burst): default 0.1. */\n repeatInterval?(): number\n}\n\n/** The default player of a tool's clips: runs the steps of `toolAnimationStep` against a rig, scaled to the duration the rule gives. */\nexport interface ToolClipPlayer {\n apply(step: ToolAnimationStep): void\n update(dt: number): void\n readonly playing: readonly string[]\n}\n\nexport const createToolClipPlayer = (options: ToolClipPlayerOptions): ToolClipPlayer => {\n const { clips, rig, onEvent } = options\n let instances: Instance[] = []\n\n const find = (clip: string, variant?: string): { name: string; clip: AnimationClipSpec } | undefined => {\n const name = variant !== undefined && clips[`${clip}_${variant}`] ? `${clip}_${variant}` : clip\n const found = clips[name]\n return found ? { name, clip: found } : undefined\n }\n\n const render = (instance: Instance): void => {\n const time = Math.min(instance.time, instance.clip.duration)\n const root = sampleClip(instance.clip, undefined, time)\n if (instance.clip.keys.some((key) => key.position || key.rotation)) rig.setRootPose?.(root)\n const touched = new Set(instance.clip.keys.flatMap((key) => Object.keys(key.parts ?? {})))\n for (const id of touched) rig.setPartPose(id, sampleClip(instance.clip, id, time))\n }\n\n const fireEvents = (instance: Instance, upTo: number): void => {\n const events = instance.clip.events ?? []\n while (instance.fired < events.length && (events[instance.fired]?.t ?? Infinity) <= upTo + 1e-9) {\n const event = events[instance.fired]\n instance.fired += 1\n if (event) onEvent?.(event, instance.name)\n }\n }\n\n return {\n apply(step) {\n if (step.type === 'sync') {\n for (const instance of instances) {\n const marker = (instance.clip.events ?? []).find((event) => event.type === STAGE_EVENT && event.data?.stage === step.stage)\n if (marker && instance.time < marker.t) instance.time = marker.t\n }\n return\n }\n if (step.type === 'finish') {\n for (const instance of instances) {\n if (instance.name !== step.clip && !instance.name.startsWith(`${step.clip}_`)) continue\n fireEvents(instance, instance.clip.duration)\n instance.time = instance.clip.duration\n }\n return\n }\n const found = find(step.clip, step.variant)\n if (!found) return\n const clip = step.duration && step.duration > 0 ? scaleClip(found.clip, step.duration) : found.clip\n const interval = options.repeatInterval?.() ?? 0.1\n instances = instances.filter((existing) => existing.name !== found.name || existing.delay > 0)\n for (let round = 0; round < (step.repeat ?? 1); round++) {\n instances.push({ name: found.name, clip, time: 0, delay: round * interval, fired: 0 })\n }\n },\n update(dt) {\n for (const instance of instances) {\n const carried = instance.delay > 0 ? dt - instance.delay : dt\n if (instance.delay > 0) {\n instance.delay = Math.max(0, instance.delay - dt)\n if (instance.delay > 0) continue\n }\n instance.time += carried\n fireEvents(instance, instance.time)\n render(instance)\n }\n instances = instances.filter((instance) => instance.delay > 0 || instance.time < instance.clip.duration)\n },\n get playing() {\n return instances.map((instance) => instance.name)\n },\n }\n}\n","import type { Vec3 } from './destruction'\n\n/**\n * The bench of a module: controls, layers and counters it declares as data. The host keeps the values, draws them in a generic way and hands\n * every change back through `ModuleHost.bench`. Nothing here is specific to a kind of module.\n */\nexport type ControlValue = number | boolean | string\n\nexport interface ChoiceOption {\n readonly id: string\n readonly name: string\n}\n\ninterface ControlBase {\n /** snake_case, unique across the module's controls, layers and metrics. */\n readonly id: string\n /** Display name, already translated for the locale the host asked for. */\n readonly name: string\n readonly hint?: string\n readonly hidden?: boolean\n}\n\nexport interface NumberControl extends ControlBase {\n readonly kind: 'number'\n readonly min: number\n readonly max: number\n readonly step?: number\n readonly unit?: string\n readonly default: number\n}\n\nexport interface BooleanControl extends ControlBase {\n readonly kind: 'boolean'\n readonly default: boolean\n}\n\nexport interface ChoiceControl extends ControlBase {\n readonly kind: 'choice'\n readonly options: readonly ChoiceOption[]\n readonly default: string\n}\n\n/** A button: no value, only the press. */\nexport interface ActionControl extends ControlBase {\n readonly kind: 'action'\n}\n\nexport type ModuleControl = NumberControl | BooleanControl | ChoiceControl | ActionControl\n\n/** Something of the module the viewer turns on or off (smoke, flash, casings). */\nexport interface ModuleLayer {\n readonly id: string\n readonly name: string\n /** On unless `false`. */\n readonly default?: boolean\n}\n\n/** Pulled: the room calls read only when it samples (~4 Hz, or on TestRoom.metrics()). */\nexport interface ModuleMetric {\n readonly id: string\n readonly name: string\n readonly unit?: string\n /** Budget: the host shows a bar and warns past it. */\n readonly max?: number\n readonly digits?: number\n read(): number | string\n}\n\nexport type BenchChange =\n | { readonly kind: 'control'; readonly id: string; readonly value: ControlValue }\n | { readonly kind: 'layer'; readonly id: string; readonly on: boolean }\n | { readonly kind: 'action'; readonly id: string }\n\nexport interface ControlPatch {\n readonly hidden?: boolean\n readonly disabled?: boolean\n readonly options?: readonly ChoiceOption[]\n readonly value?: ControlValue\n}\n\n/** What the host lends a module that declares a bench: the current values and the changes. */\nexport interface ModuleBench {\n value(id: string): ControlValue | undefined\n layer(id: string): boolean\n /** Right after attach returns, the host sends one change per control (not actions) and per layer, in declaration order. */\n onChange(listener: (change: BenchChange) => void): () => void\n /** `value` sets without emitting (no echo loops); `options` falls back to the first option if the value is no longer offered. */\n patch(id: string, patch: ControlPatch): void\n /** Move the host camera (a near / middle / far choice). */\n look(eye: Vec3, target: Vec3): void\n}\n\nexport interface BenchReport {\n readonly ok: boolean\n readonly problems: readonly string[]\n}\n\nexport interface BenchDeclaration {\n readonly controls?: readonly ModuleControl[]\n readonly layers?: readonly ModuleLayer[]\n readonly metrics?: readonly ModuleMetric[]\n}\n\nconst SNAKE_CASE = /^[a-z][a-z0-9_]*$/\nconst finite = (n: unknown): n is number => typeof n === 'number' && Number.isFinite(n)\n\nfunction checkControl(control: ModuleControl, problems: string[]): void {\n const label = `control \"${control.id}\"`\n if (control.kind === 'number') {\n if (!finite(control.min) || !finite(control.max) || control.min >= control.max) problems.push(`${label} needs min < max`)\n if (control.step !== undefined && !(finite(control.step) && control.step > 0)) problems.push(`${label} needs a step > 0`)\n if (!finite(control.default) || control.default < control.min || control.default > control.max) problems.push(`${label} default ${String(control.default)} is outside ${control.min}..${control.max}`)\n return\n }\n if (control.kind !== 'choice') return\n if (control.options.length === 0) {\n problems.push(`${label} needs at least one option`)\n return\n }\n const seen = new Set<string>()\n for (const option of control.options) {\n if (seen.has(option.id)) problems.push(`${label} repeats option \"${option.id}\"`)\n seen.add(option.id)\n }\n if (!seen.has(control.default)) problems.push(`${label} default \"${control.default}\" is not among its options`)\n}\n\n/** snake_case ids unique across controls, layers and metrics; min < max; step > 0; default in range; options non-empty, unique, default among them; metric max > 0. */\nexport function checkBench(declared: BenchDeclaration): BenchReport {\n const problems: string[] = []\n const ids = new Set<string>()\n const claim = (kind: string, id: string): void => {\n if (!SNAKE_CASE.test(id)) problems.push(`${kind} id \"${id}\" must be snake_case`)\n if (ids.has(id)) problems.push(`duplicate id \"${id}\" across controls, layers and metrics`)\n ids.add(id)\n }\n for (const control of declared.controls ?? []) {\n claim('control', control.id)\n checkControl(control, problems)\n }\n for (const layer of declared.layers ?? []) claim('layer', layer.id)\n for (const metric of declared.metrics ?? []) {\n claim('metric', metric.id)\n if (metric.max !== undefined && !(finite(metric.max) && metric.max > 0)) problems.push(`metric \"${metric.id}\" needs a max > 0`)\n }\n return { ok: problems.length === 0, problems }\n}\n","import { STAGE_EVENT } from '@adatechnology/game-contracts'\nimport type { AnimationClipSpec, AnimationEventSpec, AnimationPose } from '@adatechnology/game-contracts'\n\nexport type Axis = 'x' | 'y' | 'z'\ntype Channel = 'position' | 'rotation'\n\n/** The gallery's `tw(delay, duration, e => part.property = from + (to - from) * e)`: one axis of one part, eased, then held at `to`. */\nexport interface Tween {\n readonly part: string\n readonly channel: Channel\n readonly axis: Axis\n readonly start: number\n readonly duration: number\n readonly from: number\n readonly to: number\n}\n\n/** The part id of the whole weapon in a clip's tweens. */\nexport const ROOT = 'root'\n\nconst AXIS_INDEX: Record<Axis, number> = { x: 0, y: 1, z: 2 }\n// the gallery eases with this curve; keys are linear, so each tween is sampled at this many steps (largest error 0.4% of the move)\nconst EASE_STEPS = 10\n\nexport const ease = (progress: number): number => (progress < 0.5 ? 2 * progress * progress : 1 - (-2 * progress + 2) ** 2 / 2)\n\nexport const move = (part: string, axis: Axis, start: number, duration: number, from: number, to: number): Tween => ({ part, channel: 'position', axis, start, duration, from, to })\nexport const turn = (part: string, axis: Axis, start: number, duration: number, from: number, to: number): Tween => ({ part, channel: 'rotation', axis, start, duration, from, to })\n\n/** A step of the clip at `t` the host maps (`muzzle_flash`, `eject_casing`, `drop_magazine`...). */\nexport const cue = (t: number, type: string, data?: Record<string, unknown>): AnimationEventSpec => ({ t, type, ...(data ? { data } : {}) })\n\nexport const stage = (id: string, t: number): AnimationEventSpec => ({ t, type: STAGE_EVENT, data: { stage: id } })\n\nconst valueAt = (tweens: readonly Tween[], t: number, includeInstants: boolean): number => {\n let value = 0\n for (const tween of tweens) {\n if (tween.start > t || (tween.duration === 0 && (tween.start === t ? !includeInstants : false))) continue\n if (tween.duration === 0 || t >= tween.start + tween.duration) value = tween.to\n else value = tween.from + (tween.to - tween.from) * ease((t - tween.start) / tween.duration)\n }\n return value\n}\n\nconst round = (value: number): number => Math.round(value * 1e6) / 1e6\n\n/** Builds a clip from tweens and cue events: one key at every start, end and sample of a tween, and a step (two keys at one time) for an instant set. */\nexport function composeClip(id: string, tweens: readonly Tween[], events: readonly AnimationEventSpec[] = [], minDuration = 0): AnimationClipSpec {\n const ordered = [...tweens].sort((a, b) => a.start - b.start)\n const duration = Math.max(minDuration, 0.001, ...ordered.map((tween) => tween.start + tween.duration), ...events.map((event) => event.t))\n const times = new Set<number>([0, duration])\n for (const tween of ordered) {\n times.add(round(tween.start))\n if (tween.duration > 0) for (let step = 1; step <= EASE_STEPS; step++) times.add(round(tween.start + (tween.duration * step) / EASE_STEPS))\n }\n const instants = new Set(ordered.filter((tween) => tween.duration === 0).map((tween) => round(tween.start)))\n const channels = new Map<string, Tween[]>()\n for (const tween of ordered) {\n const key = `${tween.part}|${tween.channel}|${tween.axis}`\n channels.set(key, [...(channels.get(key) ?? []), tween])\n }\n const sampleKey = (t: number, includeInstants: boolean): AnimationClipSpec['keys'][number] => {\n const poses = new Map<string, { position: [number, number, number]; rotation: [number, number, number] }>()\n for (const [key, list] of channels) {\n const [part, channel, axis] = key.split('|') as [string, Channel, Axis]\n const pose = poses.get(part) ?? { position: [0, 0, 0], rotation: [0, 0, 0] }\n pose[channel][AXIS_INDEX[axis]] = round(valueAt(list, t, includeInstants))\n poses.set(part, pose)\n }\n const root = poses.get(ROOT)\n poses.delete(ROOT)\n const parts: Record<string, AnimationPose> = {}\n for (const [part, pose] of poses) parts[part] = pose\n return { t, ...(root ? { position: root.position, rotation: root.rotation } : {}), ...(poses.size ? { parts } : {}) }\n }\n const keys: AnimationClipSpec['keys'] = []\n for (const t of [...times].sort((a, b) => a - b)) {\n if (instants.has(t)) keys.push(sampleKey(t, false))\n keys.push(sampleKey(t, true))\n }\n const sorted = [...events].sort((a, b) => a.t - b.t)\n return { id, duration, keys, ...(sorted.length ? { events: sorted } : {}) }\n}\n\n/** The same clip under another id (the clip set keys are the ids). */\nexport const renamed = (clip: AnimationClipSpec, id: string): AnimationClipSpec => ({ ...clip, id })\n","import type { AnimationClipSpec } from '@adatechnology/game-contracts'\nimport { ROOT, composeClip, cue, move, stage, turn } from './clip-builder'\nimport type { ClipContext } from './context'\n\nconst PI = Math.PI\n// the SDK's own motions (the gallery has none for accessories): seconds when the rule does not give the duration, and the sizes of the moves\nconst STOCK_SECONDS = 0.6\nconst TOGGLE_SECONDS = 0.14\nconst TOGGLE_TILT = 0.02\nconst LAUNCHER_SLIDE = 0.05\nconst LAUNCHER_RELOAD = { open: 0, loaded: 0.4, close: 0.8, end: 1.05, slide: 0.3, back: 0.25 }\nconst LAUNCHER_KICK = 0.03\n\n/** The stock folds a half turn about the side of the rule, or slides in along the weapon; the pose is held at the end, so the stock stays where the rule put it. */\nexport function stockClips(context: ClipContext): AnimationClipSpec[] {\n const { stock, stockMove } = context.parts\n if (!stock || !stockMove) return []\n if (stockMove.kind === 'fold') {\n return [\n composeClip('stock_fold', [turn('stock', stockMove.axis, 0, STOCK_SECONDS, 0, PI)]),\n composeClip('stock_unfold', [turn('stock', stockMove.axis, 0, STOCK_SECONDS, PI, 0)]),\n ]\n }\n return [\n composeClip('stock_collapse', [move('stock', 'x', 0, STOCK_SECONDS, 0, stockMove.travel)]),\n composeClip('stock_extend', [move('stock', 'x', 0, STOCK_SECONDS, stockMove.travel, 0)]),\n ]\n}\n\n/** A light or a laser is switched: the weapon tilts a hair and comes back. */\nexport const toggleClip = (): AnimationClipSpec => composeClip('toggle', [turn(ROOT, 'z', 0, TOGGLE_SECONDS / 2, 0, TOGGLE_TILT), turn(ROOT, 'z', TOGGLE_SECONDS / 2, TOGGLE_SECONDS / 2, TOGGLE_TILT, 0)])\n\n/**\n * The launcher under the barrel: its shot flashes at its own muzzle and kicks the weapon, and its reload goes through the stages of the rule (`breech_open`, `round_in`, `breech_close`):\n * the tube slides forward, takes the round and slides back. Only on a weapon with a place for one.\n */\nexport function launcherClips(context: ClipContext): AnimationClipSpec[] {\n if (!context.parts.ugl) return []\n const { open, loaded, close, end, slide, back } = LAUNCHER_RELOAD\n const reload = composeClip(\n 'reload_ugl',\n [move('ugl', 'x', open, slide, 0, LAUNCHER_SLIDE), move('ugl', 'x', close, back, LAUNCHER_SLIDE, 0)],\n [stage('breech_open', open), stage('round_in', loaded), stage('breech_close', close)],\n end,\n )\n const shot = composeClip('shot_ugl', [move(ROOT, 'x', 0, 0.04, 0, -LAUNCHER_KICK), move(ROOT, 'x', 0.04, 0.2, -LAUNCHER_KICK, 0)], [cue(0, 'muzzle_flash', { at: 'ugl' })])\n return [reload, shot]\n}\n","import type { AnimationEventSpec } from '@adatechnology/game-contracts'\nimport type { ModelParts } from '../models/types'\nimport { cue, move } from './clip-builder'\nimport type { Tween } from './clip-builder'\n\n/** The magazine goes out, drops away, and a new one rises into the well: the page's `magSwap`, which takes 0.82 s. */\nexport const MAGAZINE_SWAP_SECONDS = 0.82\n/** The new magazine starts to rise here (the `magazine_in` stage). */\nexport const MAGAZINE_IN_AT = 0.45\n\nexport function magazineSwap(parts: ModelParts, start: number): { tweens: Tween[]; events: AnimationEventSpec[]; end: number } {\n const direction = parts.magDir || -1\n const drop = parts.magDrop || 0.15\n return {\n tweens: [\n move('mag', 'y', start, 0.16, 0, direction * drop * 0.6),\n move('mag', 'y', start + 0.16, 0, 0, direction * drop * 2.2),\n move('mag', 'y', start + MAGAZINE_IN_AT, 0.3, direction * drop * 2.2, 0),\n ],\n events: [cue(start + 0.16, 'drop_magazine', { up: direction > 0 })],\n end: start + MAGAZINE_SWAP_SECONDS,\n }\n}\n","import type { CaseType, ReloadFamily } from '@adatechnology/game-weapons'\nimport type { ModelFamily, ModelParts } from '../models/types'\n\n/** What the clips of a weapon are written from: its model (parts and mechanism), its calibre's case and how its rule reloads it. */\nexport interface ClipContext {\n readonly parts: ModelParts\n readonly family: ModelFamily\n readonly caseType: CaseType\n readonly reloadFamily: ReloadFamily | undefined\n}\n\n/** Recoil strength by case size, when the model has none of its own (the page's `kickOf`). */\nexport const KICK_BY_CASE: Record<CaseType, number> = { shell: 1.6, big: 2.4, tiny: 0.3, pistol: 0.7, rifle: 1.1 }\n\nexport const kickOf = (context: ClipContext): number => context.parts.kick ?? KICK_BY_CASE[context.caseType]\n\n/** Families whose slide or bolt blows back with each shot. */\nexport const BLOWBACK: ReadonlySet<ModelFamily> = new Set(['pistol', 'rifle', 'semiint', 'semi12', 'p90', 'belt'])\nexport const HAS_CYCLE: ReadonlySet<ModelFamily> = new Set(['pump', 'bolt', 'boltmag', 'lever'])\n// the gallery's travel of the pump, of the bolt and of the lever, and the bolt handle's turn (page values)\nexport const PUMP_TRAVEL = -0.075\nexport const BOLT_TRAVEL = -0.07\nexport const BOLT_TURN = -1.15\nexport const LEVER_TURN = -0.85\n\n/** How far the slide or bolt travels back (the page's `-(P.stroke || .06)`). */\nexport const strokeOf = (parts: ModelParts): number => -(parts.stroke || 0.06)\n\n/** The part that blows back: the slide of a pistol, the bolt of the rest. */\nexport const blowbackPart = (context: ClipContext): 'slide' | 'bolt' => (context.family === 'pistol' ? 'slide' : 'bolt')\n","import type { AnimationClipSpec } from '@adatechnology/game-contracts'\nimport { composeClip, cue, move, turn } from './clip-builder'\nimport type { Tween } from './clip-builder'\nimport { magazineSwap } from './magazine-clips'\nimport { BOLT_TRAVEL, BOLT_TURN, LEVER_TURN, PUMP_TRAVEL, blowbackPart, strokeOf } from './context'\nimport type { ClipContext } from './context'\n\n/** The bolt handle turns up, the bolt runs back and forth with the handle, and the handle turns down: the page's `cycleBolt` from `start`. */\nexport function boltStroke(start: number, hold = 0): Tween[] {\n return [\n turn('boltHandle', 'x', start, 0.09, 0, BOLT_TURN),\n move('boltHandle', 'x', start + 0.1, 0.12, 0, BOLT_TRAVEL),\n move('bolt', 'x', start + 0.1, 0.12, 0, BOLT_TRAVEL),\n move('boltHandle', 'x', start + 0.26 + hold, 0.12, BOLT_TRAVEL, 0),\n move('bolt', 'x', start + 0.26 + hold, 0.12, BOLT_TRAVEL, 0),\n turn('boltHandle', 'x', start + 0.4 + hold, 0.09, BOLT_TURN, 0),\n ]\n}\n\n/** The manual action after each shot: the pump slides, the bolt cycles or the lever works. The gallery's times (0.5, 0.82 and 0.55 s) are the rule's `timings.cycle`. */\nexport function cycleClip(context: ClipContext): AnimationClipSpec | undefined {\n const { parts, family } = context\n if (family === 'pump' && parts.pump) return composeClip('cycle', [move('pump', 'x', 0.22, 0.11, 0, PUMP_TRAVEL), move('pump', 'x', 0.36, 0.11, PUMP_TRAVEL, 0)], [cue(0.3, 'eject_casing', { down: false })], 0.5)\n if ((family === 'bolt' || family === 'boltmag') && parts.bolt && parts.boltHandle) return composeClip('cycle', boltStroke(0.3), [cue(0.5, 'eject_casing', { down: false })], 0.82)\n if (family === 'lever' && parts.lever) return composeClip('cycle', [turn('lever', 'z', 0.22, 0.13, 0, LEVER_TURN), turn('lever', 'z', 0.38, 0.13, LEVER_TURN, 0)], [cue(0.3, 'eject_casing', { down: false })], 0.55)\n return undefined\n}\n\n// where the slide sits when a fault is cleared, as a fraction of its travel, and what is thrown out\nconst STUCK_AT: Record<string, number> = { stovepipe: 0.35, double_feed: 0.6, misfire: 0, failure_to_extract: 0 }\n// the page's clear of a bolt gun holds the bolt back 0.04 s longer than its cycle (eject at 0.22, handle down at 0.44)\nconst CLEAR_HOLD = 0.04\n\n/** Clearing a jam on a mechanism that blows back: the slide goes all the way back, throws out what was stuck and returns. */\nfunction clearBlowback(context: ClipContext, fault: string): AnimationClipSpec {\n const { parts, family } = context\n const part = blowbackPart(context)\n const travel = strokeOf(parts)\n const stuck = travel * (STUCK_AT[fault] ?? 0)\n const swap = fault === 'double_feed' && parts.mag ? magazineSwap(parts, 0) : undefined\n const start = swap?.end ?? 0\n const tweens: Tween[] = [...(swap?.tweens ?? [])]\n const events = [...(swap?.events ?? [])]\n if (family === 'belt' && parts.cover) {\n tweens.push(turn('cover', 'z', start, 0.18, 0, 0.9), turn('cover', 'z', start + 0.3, 0.15, 0.9, 0))\n return composeClip(`clear_${fault}`, [...tweens, ...slideOut(part, stuck, travel, start + 0.5)], [...events, cue(start + 0.5 + 0.1, 'fly_jam', { jam: fault })])\n }\n return composeClip(`clear_${fault}`, [...tweens, ...slideOut(part, stuck, travel, start)], [...events, cue(start + 0.1, 'fly_jam', { jam: fault })])\n}\n\nconst slideOut = (part: 'slide' | 'bolt', from: number, travel: number, start: number): Tween[] => [move(part, 'x', start, 0.12, from, travel), move(part, 'x', start + 0.2, 0.07, travel, 0)]\n\n/** Clearing on a manual action: the same stroke as a cycle, throwing out what was stuck halfway through. */\nfunction clearManual(context: ClipContext, fault: string): AnimationClipSpec | undefined {\n const { parts, family } = context\n const fly = (t: number) => [cue(t, 'fly_jam', { jam: fault })]\n if (family === 'pump' && parts.pump) return composeClip(`clear_${fault}`, [move('pump', 'x', 0, 0.12, 0, PUMP_TRAVEL), move('pump', 'x', 0.2, 0.12, PUMP_TRAVEL, 0)], fly(0.12), 0.4)\n if ((family === 'bolt' || family === 'boltmag') && parts.bolt && parts.boltHandle) return composeClip(`clear_${fault}`, boltStroke(0, CLEAR_HOLD), fly(0.22), 0.6)\n if (family === 'lever' && parts.lever) return composeClip(`clear_${fault}`, [turn('lever', 'z', 0, 0.13, 0, LEVER_TURN), turn('lever', 'z', 0.16, 0.13, LEVER_TURN, 0)], fly(0.1), 0.35)\n return undefined\n}\n\n/** One clear clip per fault the rule can raise. Mechanisms without a bolt or slide (revolver, break, launcher) only throw out what was stuck. */\nexport function clearClips(context: ClipContext): AnimationClipSpec[] {\n return ['misfire', 'stovepipe', 'double_feed', 'failure_to_extract'].map((fault) => {\n const manual = clearManual(context, fault)\n if (manual) return manual\n const part = blowbackPart(context)\n if (context.parts[part] && ['pistol', 'rifle', 'semiint', 'semi12', 'p90', 'belt'].includes(context.family)) return clearBlowback(context, fault)\n return composeClip(`clear_${fault}`, [], [cue(0, 'fly_jam', { jam: fault })], 0.1)\n })\n}\n","import type { AnimationClipSpec, AnimationEventSpec } from '@adatechnology/game-contracts'\nimport { RELOAD_STAGES } from '@adatechnology/game-weapons'\nimport type { ReloadKind } from '@adatechnology/game-weapons'\nimport { ROOT, composeClip, cue, move, renamed, stage, turn } from './clip-builder'\nimport type { Tween } from './clip-builder'\nimport { BOLT_TRAVEL, BOLT_TURN, LEVER_TURN, PUMP_TRAVEL, strokeOf } from './context'\nimport type { ClipContext } from './context'\nimport { boltStroke } from './cycle-clips'\nimport { magazineSwap } from './magazine-clips'\n\nconst KINDS: readonly ReloadKind[] = ['tactical', 'empty', 'one_by_one']\n\n/** Charging handle pulled and released (the page's `charge`): the bolt goes back 0.12 s, then forward 0.06 s, from `start`. */\nconst charge = (context: ClipContext, start: number): Tween[] => {\n const travel = strokeOf(context.parts)\n return [move('bolt', 'x', start, 0.12, 0, travel), move('bolt', 'x', start + 0.18, 0.06, travel, 0)]\n}\n\ninterface Draft {\n tweens: Tween[]\n events: AnimationEventSpec[]\n end: number\n}\n\nconst cycleWithoutEject = (start: number): Draft => ({ tweens: boltStroke(start), events: [], end: start + 0.55 })\n\n/** Reloads that take a magazine: swap it (0.82 s), then what the mechanism needs. `kind` `empty` also works the action. */\nfunction magazineReload(context: ClipContext, kind: ReloadKind): Draft {\n const { parts, family } = context\n const swap = magazineSwap(parts, 0)\n const draft: Draft = { tweens: [...swap.tweens], events: [...swap.events], end: swap.end }\n if (family === 'pistol') {\n if (kind === 'empty' && parts.slide) {\n draft.tweens.push(move('slide', 'x', 0, 0, 0, strokeOf(parts)), move('slide', 'x', swap.end, 0.05, strokeOf(parts), 0))\n draft.end += 0.12\n }\n } else if (family === 'boltmag') {\n const stroke = cycleWithoutEject(swap.end)\n draft.tweens.push(...stroke.tweens)\n draft.end = stroke.end\n } else if (kind === 'empty' && parts.bolt) {\n draft.tweens.push(...charge(context, swap.end))\n draft.end += 0.35\n }\n return draft\n}\n\n/** Revolver: crane opens, spent cases fall, rounds go in (all at once with a speed loader), crane closes: 1.3 s. */\nfunction revolverReload(kind: ReloadKind): Draft {\n const events = [cue(0.32, 'eject_casing', { from: 'chambers', down: false })]\n if (kind !== 'one_by_one') events.push(cue(0.7, 'move_in', { from: 'chambers' }))\n return { tweens: [turn('crane', 'x', 0, 0.22, 0, -1.25), turn('crane', 'x', 1.05, 0.2, -1.25, 0)], events, end: 1.3 }\n}\n\n/** Break action: the barrels fold down, both cases drop, two shells go in and the barrels close: 1.2 s. */\nconst breakReload = (): Draft => ({\n tweens: [turn('barrels', 'z', 0, 0.2, 0, -0.5), turn('barrels', 'z', 1.0, 0.15, -0.5, 0)],\n events: [cue(0.25, 'eject_casing', { from: 'breech', down: false }), cue(0.65, 'move_in', { from: 'breech' })],\n end: 1.2,\n})\n\n/** Belt: the cover lifts, the belt box swaps, the cover closes and the bolt is charged: 1.55 s. */\nconst beltReload = (context: ClipContext): Draft => ({\n tweens: [turn('cover', 'z', 0, 0.2, 0, 0.9), move('belt', 'z', 0.2, 0.25, 0, -0.3), move('belt', 'z', 0.55, 0.3, -0.3, 0), turn('cover', 'z', 0.9, 0.18, 0.9, 0), ...charge(context, 1.15)],\n events: [],\n end: 1.55,\n})\n\n// loading round by round has no fixed length (the rule sets it by the rounds), so these are written over one unit and stretched to the rule's duration\nconst UNIT = 1\n\nfunction tubeReload(context: ClipContext, kind: ReloadKind): Draft {\n const { parts, family } = context\n const draft: Draft = { tweens: [], events: [], end: UNIT }\n if (kind !== 'empty') return draft\n if (family === 'pump' && parts.pump) draft.tweens.push(move('pump', 'x', 0.88, 0.05, 0, PUMP_TRAVEL), move('pump', 'x', 0.94, 0.05, PUMP_TRAVEL, 0))\n else if (family === 'lever' && parts.lever) draft.tweens.push(turn('lever', 'z', 0.87, 0.06, 0, LEVER_TURN), turn('lever', 'z', 0.94, 0.06, LEVER_TURN, 0))\n else if (parts.bolt) draft.tweens.push(move('bolt', 'x', 0.88, 0.07, 0, strokeOf(parts)), move('bolt', 'x', 0.95, 0.04, strokeOf(parts), 0))\n return draft\n}\n\n/** Bolt action loaded from the top: the bolt opens, rounds go in one by one, the bolt closes. */\nfunction boltReload(context: ClipContext): Draft {\n if (!context.parts.boltHandle || !context.parts.bolt) return { tweens: [], events: [], end: UNIT }\n return {\n tweens: [\n turn('boltHandle', 'x', 0, 0.05, 0, BOLT_TURN),\n move('boltHandle', 'x', 0.05, 0.07, 0, BOLT_TRAVEL),\n move('bolt', 'x', 0.05, 0.07, 0, BOLT_TRAVEL),\n move('boltHandle', 'x', 0.86, 0.07, BOLT_TRAVEL, 0),\n move('bolt', 'x', 0.86, 0.07, BOLT_TRAVEL, 0),\n turn('boltHandle', 'x', 0.93, 0.05, BOLT_TURN, 0),\n ],\n events: [],\n end: UNIT,\n }\n}\n\n/** A semi-automatic with an internal magazine: the bolt back, rounds in from the top, the bolt forward. */\nfunction internalMagazineReload(context: ClipContext): Draft {\n const travel = strokeOf(context.parts)\n return { tweens: context.parts.bolt ? [move('bolt', 'x', 0, 0.04, 0, travel), move('bolt', 'x', 0.89, 0.04, travel, 0)] : [], events: [], end: UNIT }\n}\n\n/** The rocket launchers and flamethrowers: a round slid in, a disposable tube dropped and a new one seated, a hinged breech, or a tank swapped (needle sweeps). */\nfunction heavyReload(context: ClipContext): Draft {\n const { parts, family } = context\n if (family === 'flame') return { tweens: parts.gauge ? [turn('gauge', 'z', 0, 1, -2.4, 0)] : [], events: [], end: 1.1 }\n if (parts.disposable) {\n return {\n tweens: [move(ROOT, 'y', 0.6, 0, 0, -0.6), move(ROOT, 'y', 0.6, 0.5, -0.6, 0)],\n events: [cue(0, 'drop_tube'), cue(0.6, 'seat_tube')],\n end: 1.15,\n }\n }\n if (parts.round) {\n return {\n tweens: [move('round', 'x', 0, 0.55, 0.45, 0), move('round', 'y', 0, 0.55, 0.12, 0)],\n events: [cue(0, 'show_round')],\n end: 0.6,\n }\n }\n return {\n tweens: [turn('breech_0', 'y', 0, 0.25, 0, -1.6), turn('breech_0', 'y', 0.76, 0.22, -1.6, 0)],\n events: [cue(0.3, 'breech_round')],\n end: 1.05,\n }\n}\n\nconst isTube = (context: ClipContext): boolean => ['pump', 'semi12', 'lever'].includes(context.family)\n\nfunction draftFor(context: ClipContext, kind: ReloadKind): Draft | undefined {\n const { parts, family } = context\n if (family === 'rocket' || family === 'flame') return heavyReload(context)\n if (parts.mag) return magazineReload(context, kind)\n if (family === 'revolver' && parts.crane) return revolverReload(kind)\n if (family === 'break' && parts.barrels) return breakReload()\n if (family === 'belt' && parts.cover && parts.belt) return beltReload(context)\n if (isTube(context)) return tubeReload(context, kind)\n if (family === 'bolt') return boltReload(context)\n if (family === 'semiint') return internalMagazineReload(context)\n return undefined\n}\n\n/** The stages of the rule's reload as markers of the clip, at the fractions the rule puts them. */\nconst markers = (context: ClipContext, kind: ReloadKind, duration: number): AnimationEventSpec[] =>\n context.reloadFamily ? RELOAD_STAGES[context.reloadFamily][kind].map((entry) => stage(entry.stage, entry.at * duration)) : []\n\n/** `reload` (a magazine swap or the like), `reload_empty` and `reload_one_by_one`, each only when it differs from the first. */\nexport function reloadClips(context: ClipContext): AnimationClipSpec[] {\n const clips: AnimationClipSpec[] = []\n let first: AnimationClipSpec | undefined\n for (const kind of KINDS) {\n const draft = draftFor(context, kind)\n if (!draft) return []\n const clip = composeClip(kind === 'tactical' ? 'reload' : `reload_${kind}`, draft.tweens, [...draft.events, ...markers(context, kind, draft.end)], draft.end)\n if (!first) first = clip\n else if (JSON.stringify({ ...clip, id: first.id }) === JSON.stringify(first)) continue\n clips.push(clip)\n }\n return clips.length > 0 ? clips : first ? [renamed(first, 'reload')] : []\n}\n\n/** One more round goes in while a tube, a top-loaded or a revolver loads round by round. */\nexport function feedClip(context: ClipContext): AnimationClipSpec | undefined {\n const { family } = context\n if (family === 'revolver') return composeClip('feed', [], [cue(0, 'move_in', { from: 'chambers', next: true })], 0.24)\n if (family === 'bolt' || family === 'semiint') return composeClip('feed', [], [cue(0, 'move_in', { from: 'topLoad' })], 0.24)\n if (isTube(context)) return composeClip('feed', [], [cue(0, 'move_in', { from: 'loadPort' })], 0.24)\n return undefined\n}\n","import type { AnimationClipSpec } from '@adatechnology/game-contracts'\nimport { ROOT, composeClip, cue, move, turn } from './clip-builder'\nimport type { Tween } from './clip-builder'\nimport { BLOWBACK, blowbackPart, kickOf, strokeOf } from './context'\nimport type { ClipContext } from './context'\n\n// how far the slide stays back for each fault, as a fraction of its travel: the page's `k` (stovepipe .35, double feed .6)\nconst FAULT_SLIDE_BACK: Record<string, number> = { stovepipe: 0.35, double_feed: 0.6 }\n\n/** The trigger finger: the trigger turns back 0.35 rad and returns (the page's `pull`). */\nconst pullTrigger = (context: ClipContext): Tween[] => (context.parts.trigger ? [turn('trigger', 'z', 0, 0.04, 0, 0.35), turn('trigger', 'z', 0.06, 0.08, 0.35, 0)] : [])\n\n/** The whole weapon kicks back and tilts up, then settles (the page's `recoil`). */\nconst recoil = (context: ClipContext): Tween[] => {\n const kick = kickOf(context)\n return [\n move(ROOT, 'x', 0, 0.03, 0, -0.014 * kick),\n turn(ROOT, 'z', 0, 0.03, 0, 0.045 * kick),\n move(ROOT, 'x', 0.03, 0.18, -0.014 * kick, 0),\n turn(ROOT, 'z', 0.03, 0.18, 0.045 * kick, 0),\n ]\n}\n\n/** A rotary gun turns its barrels a sixth of a turn with each shot; six barrels look the same every sixth, so the next shot starts over from rest. */\nconst spinBarrels = (context: ClipContext): Tween[] => (context.parts.barrels && context.family === 'belt' ? [turn('barrels', 'x', 0, 0.03, 0, Math.PI / 3)] : [])\n\nconst hammerFall = (context: ClipContext): Tween[] => (context.parts.hammer && context.family !== 'revolver' ? [turn('hammer', 'z', 0, 0.02, 0, -0.5), turn('hammer', 'z', 0.05, 0.06, -0.5, 0)] : [])\n\n/** What every shot does, then what the mechanism does by family. `locked` leaves the pistol slide back, as after the last round. */\nfunction shotClip(id: string, context: ClipContext, locked: boolean): AnimationClipSpec {\n const { parts, family } = context\n const tweens = [...pullTrigger(context), ...recoil(context), ...hammerFall(context), ...spinBarrels(context)]\n const events = [cue(0, 'muzzle_flash')]\n if (BLOWBACK.has(family)) {\n const part = blowbackPart(context)\n const travel = strokeOf(parts)\n if (parts[part]) {\n tweens.push(move(part, 'x', 0, 0.025, 0, travel))\n if (!locked) tweens.push(move(part, 'x', 0.025, 0.045, travel, 0))\n }\n events.push(cue(0.012, 'eject_casing', { down: family === 'p90' || family === 'belt' }))\n } else if (family === 'revolver' && parts.cylinder && parts.hammer) {\n tweens.push(turn('cylinder', 'x', 0, 0.05, 0, Math.PI / 3), turn('hammer', 'z', 0, 0.05, 0, 0.5), turn('hammer', 'z', 0.05, 0.03, 0.5, -0.5), turn('hammer', 'z', 0.12, 0.08, -0.5, 0))\n }\n return composeClip(id, tweens, events)\n}\n\n/** A weapon with a mechanism that moves between shots (pump, bolt, lever) leaves that to the `cycle` clip, which the rule times. */\nexport function shotClips(context: ClipContext): AnimationClipSpec[] {\n const clips = [shotClip('shot', context, false)]\n if (context.family === 'pistol') clips.push(shotClip('shot_last', context, true))\n return clips\n}\n\n/** The trigger pulls and the hammer falls on a round that does not fire. */\nconst dudTweens = (context: ClipContext): Tween[] => [...pullTrigger(context), ...(context.parts.hammer ? [turn('hammer', 'z', 0, 0.03, 0, -0.5)] : [])]\n\n/** A dud that does not stop the weapon (revolver, break action): the cylinder of a revolver still turns. */\nexport function misfireClip(context: ClipContext): AnimationClipSpec {\n const tweens = dudTweens(context)\n if (context.family === 'revolver' && context.parts.cylinder) tweens.push(turn('cylinder', 'x', 0, 0.07, 0, Math.PI / 3))\n return composeClip('misfire', tweens)\n}\n\nexport const emptyClip = (context: ClipContext): AnimationClipSpec => composeClip('empty', pullTrigger(context))\n\n/**\n * A jam after the shot: the slide is stopped part of the way back (`FAULT_SLIDE_BACK`) and the case sticks in the port of a stovepipe. The clip lasts as long\n * as the shot's, so that it holds the slide where the shot would have returned it.\n */\nexport function faultClips(context: ClipContext): AnimationClipSpec[] {\n const { parts, family } = context\n const misfire = composeClip('fault_misfire', dudTweens(context))\n const part = blowbackPart(context)\n if (!BLOWBACK.has(family) || !parts[part]) return [misfire]\n const travel = strokeOf(parts)\n const stopped = Object.entries(FAULT_SLIDE_BACK).map(([fault, back]) =>\n composeClip(`fault_${fault}`, [move(part, 'x', 0, 0.025, 0, travel), move(part, 'x', 0.025, 0.04, travel, travel * back)], fault === 'stovepipe' ? [cue(0.03, 'stuck_case')] : [], 0.25),\n )\n return [misfire, ...stopped]\n}\n\n/** The selector or safety lever flicks over: on turns it down, off brings it back. The gallery draws the lever and does not move it. */\nexport function safetyClips(context: ClipContext): AnimationClipSpec[] {\n if (!context.parts.safety) return []\n return [composeClip('safety_on', [turn('safety', 'z', 0, 0.12, 0, -0.6)]), composeClip('safety_off', [turn('safety', 'z', 0, 0.12, -0.6, 0)]), composeClip('mode', [turn('safety', 'z', 0, 0.07, 0, 0.4), turn('safety', 'z', 0.07, 0.07, 0.4, 0)])]\n}\n\n/** Raising the weapon: it comes up from low with the muzzle down. The gallery shows no hands, so this is the SDK's own motion. */\nexport const drawClip = (): AnimationClipSpec => composeClip('draw', [move(ROOT, 'y', 0, 0.35, -0.1, 0), turn(ROOT, 'z', 0, 0.35, -0.6, 0)])\n","import type { AnimationClipSpec, ToolClipSet } from '@adatechnology/game-contracts'\nimport type { ClipContext } from './context'\nimport { launcherClips, stockClips, toggleClip } from './accessory-clips'\nimport { clearClips, cycleClip } from './cycle-clips'\nimport { feedClip, reloadClips } from './reload-clips'\nimport { drawClip, emptyClip, faultClips, misfireClip, safetyClips, shotClips } from './shot-clips'\n\n/** Every clip a weapon model brings, by the ids `toolAnimationStep` asks for (`shot`, `cycle`, `reload`, `reload_empty`, `fault_<id>`, `clear_<id>`...). */\nexport function buildToolClips(context: ClipContext): ToolClipSet {\n const clips: Array<AnimationClipSpec | undefined> = [\n ...shotClips(context),\n misfireClip(context),\n emptyClip(context),\n cycleClip(context),\n ...reloadClips(context),\n feedClip(context),\n ...faultClips(context),\n ...clearClips(context),\n ...safetyClips(context),\n drawClip(),\n ...stockClips(context),\n toggleClip(),\n ...launcherClips(context),\n ]\n const set: Record<string, AnimationClipSpec> = {}\n for (const clip of clips) if (clip) set[clip.id] = clip\n return set\n}\n","import type { FaultId, FireMode, MountKind, ReloadStageId, StockDef, WeaponEvent } from '@adatechnology/game-weapons'\nimport type { HostEvent } from '@adatechnology/game-contracts'\n\n/**\n * The weapon event a host event stands for, so `mechanicalSoundOf` can pick its sound: reload stages, cycle, dry fire and misfire, jam, clear, safety, mode and feed.\n * Shots that fired a projectile have their own sound (`computeShotSound`), so they are not here.\n */\nexport const weaponEventOf = (event: HostEvent): WeaponEvent | undefined => {\n switch (event.type) {\n case 'misfire':\n return { type: 'misfire', at: 0 }\n case 'stage':\n return { type: 'reload_stage', stage: event.stage as ReloadStageId, at: 0 }\n case 'empty':\n case 'feed':\n return { type: event.type, at: 0 }\n case 'cycle':\n return { type: 'cycle', phase: event.phase, at: 0 }\n case 'mode':\n return { type: 'mode', mode: event.mode as FireMode, at: 0 }\n case 'fault':\n return { type: 'fault', fault: event.fault as FaultId, at: 0 }\n case 'clear':\n return { type: 'clear', fault: event.fault as FaultId, phase: event.phase, at: 0 }\n case 'safety':\n return { type: 'safety', on: event.on, at: 0 }\n case 'attachment':\n return { type: 'attachment', action: event.action, id: event.attachment, mount: event.mount as MountKind, at: 0 }\n case 'toggle':\n return { type: 'toggle', id: event.attachment, on: event.on, at: 0 }\n case 'stock':\n return { type: 'stock', state: event.state, kind: (event.kind ?? 'fold') as StockDef['kind'], at: 0 }\n case 'underbarrel':\n return { type: 'underbarrel', on: event.on, at: 0 }\n default:\n return undefined\n }\n}\n","import type { ActiveEmitter, EmitterKind } from '@adatechnology/game-interactables'\nimport type { CanvasFactory, ThreeLib, ThreeNS } from './types'\n\nexport interface EffectsOptions {\n /** Where the particle objects are added (the `Points` of every kind, the water streams and the flame ring). Required. */\n scene: ThreeNS.Object3D\n /**\n * Camera whose vertical field of view sizes the sprites, read again every `update` so zoom and fov changes follow. Required: pass the\n * camera the scene is rendered with (a `PerspectiveCamera` fits), or a function returning the current one (`null` = 90 degree lens).\n */\n camera: PerspectiveLike | (() => PerspectiveLike | null) | null\n /** Total particles alive at once, shared by all kinds (split by weight). Default 800. */\n maxParticles?: number\n /** Used to paint the soft sprite on a canvas. Without it (or without a 2D context) a data texture is generated. */\n document?: CanvasFactory\n /** Seed of the random spread. Default 1. */\n seed?: number\n /** Wind vector [x, z] in m/s that bends smoke and steam. Default [0, 0]. */\n wind?: [number, number]\n /** Viewport height in pixels, used to size the point sprites. Update with `setViewHeight` on resize. Default 720. */\n viewHeight?: number\n /** Height (m) water streams fall to when the emitter has no `reach`. Default 0. */\n floorY?: number\n /** Most water streams drawn at once (one draw call each). Default 6. */\n maxStreams?: number\n /** Most gas flame rings drawn at once (all rings share one draw call). Default 16. */\n maxFlames?: number\n}\n\n/** What the effects read from a camera. */\nexport interface PerspectiveLike {\n /** Vertical field of view in degrees. */\n fov: number\n zoom?: number\n}\n\nexport interface EffectsStats {\n alive: number\n capacity: number\n byKind: Record<PoolKind, number>\n}\n\nexport type PoolKind = 'smoke' | 'steam' | 'fire' | 'water' | 'spark'\n\nexport interface Effects {\n /**\n * Spawns for the active emitters and advances every particle by `dt` seconds, sizing the sprites for the camera given to\n * `createEffects` (or `setCamera`). No allocations per frame once warmed up. `camera` overrides it for this call (deprecated).\n */\n update(dt: number, emitters: readonly ActiveEmitter[], camera?: PerspectiveLike): void\n /** Replace the camera used for the sprite size (or `null` to go back to a 90 degree lens). */\n setCamera(camera: PerspectiveLike | (() => PerspectiveLike | null) | null): void\n setWind(x: number, z: number): void\n setViewHeight(px: number): void\n stats(): EffectsStats\n /** The Points objects (one per kind). */\n objects: Record<PoolKind, ThreeNS.Points>\n /** Water stream meshes (tapered, translucent, following the gravity arc) and the one mesh holding every gas flame ring. */\n meshes: { group: ThreeNS.Group; streams: ThreeNS.Mesh[]; flames: ThreeNS.Mesh }\n clear(): void\n dispose(): void\n}\n\nconst POOLS: PoolKind[] = ['smoke', 'steam', 'fire', 'water', 'spark']\nconst WEIGHT: Record<PoolKind, number> = { smoke: 0.27, steam: 0.15, fire: 0.2, water: 0.28, spark: 0.1 }\n\ninterface Pool {\n kind: PoolKind\n cap: number\n count: number\n pos: Float32Array\n vel: Float32Array\n age: Float32Array\n life: Float32Array\n size0: Float32Array\n size1: Float32Array\n tint: Float32Array\n flags: Uint8Array\n /** Water only: the height at which the particle ends (splashes, droplets). */\n ground: Float32Array\n aSize: ThreeNS.BufferAttribute\n aAlpha: ThreeNS.BufferAttribute\n aColor: ThreeNS.BufferAttribute\n aPos: ThreeNS.BufferAttribute\n points: ThreeNS.Points\n}\n\nconst VERT = /* glsl */ `\nattribute float aSize;\nattribute float aAlpha;\nattribute vec3 aColor;\nuniform float uScale;\nvarying float vAlpha;\nvarying vec3 vColor;\nvoid main() {\n vAlpha = aAlpha;\n vColor = aColor;\n vec4 mv = modelViewMatrix * vec4(position, 1.0);\n gl_PointSize = max(aSize * uScale / max(-mv.z, 0.05), 1.0);\n gl_Position = projectionMatrix * mv;\n}\n`\nconst FRAG = /* glsl */ `\nuniform sampler2D uMap;\nvarying float vAlpha;\nvarying vec3 vColor;\nvoid main() {\n vec4 t = texture2D(uMap, gl_PointCoord);\n gl_FragColor = vec4(vColor, vAlpha * t.a);\n}\n`\n\nfunction mulberry(seed: number): () => number {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) >>> 0\n let t = a\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/** Soft round sprite (alpha only matters). Canvas when possible, otherwise generated data. */\nfunction makeSprite(THREE: ThreeLib, doc: CanvasFactory | undefined): ThreeNS.Texture {\n const N = 64\n try {\n const canvas = doc?.createElement('canvas')\n const ctx = canvas?.getContext?.('2d')\n if (canvas && ctx && ctx.createRadialGradient) {\n canvas.width = N\n canvas.height = N\n const g = ctx.createRadialGradient(N / 2, N / 2, 0, N / 2, N / 2, N / 2)\n g.addColorStop(0, 'rgba(255,255,255,1)')\n g.addColorStop(0.4, 'rgba(255,255,255,0.55)')\n g.addColorStop(1, 'rgba(255,255,255,0)')\n ctx.fillStyle = g\n ctx.fillRect(0, 0, N, N)\n const tex = new THREE.CanvasTexture(canvas)\n return tex\n }\n } catch {\n // fall through to the data texture\n }\n const data = new Uint8Array(N * N * 4)\n for (let y = 0; y < N; y++) {\n for (let x = 0; x < N; x++) {\n const d = Math.hypot(x + 0.5 - N / 2, y + 0.5 - N / 2) / (N / 2)\n const a = d >= 1 ? 0 : Math.pow(1 - d, 1.6)\n const i = (y * N + x) * 4\n data[i] = data[i + 1] = data[i + 2] = 255\n data[i + 3] = Math.round(a * 255)\n }\n }\n const tex = new THREE.DataTexture(data, N, N, THREE.RGBAFormat)\n tex.needsUpdate = true\n return tex\n}\n\n/** Vertical streaks of water (alpha only matters); scrolled along the stream to show the flow. */\nfunction makeStreaks(THREE: ThreeLib): ThreeNS.DataTexture {\n const W = 16\n const H = 64\n const data = new Uint8Array(W * H * 4)\n const hash = (x: number, y: number): number => {\n let h = Math.imul(x + 1, 374761393) ^ Math.imul(y + 7, 668265263)\n h = Math.imul(h ^ (h >>> 13), 1274126177)\n return ((h ^ (h >>> 16)) >>> 0) / 4294967296\n }\n for (let y = 0; y < H; y++) {\n for (let x = 0; x < W; x++) {\n const col = 0.35 + 0.65 * hash(x, 0)\n const row = 0.55 + 0.45 * Math.sin(((y / H) * 3 + hash(x, 1) * 6) * Math.PI * 2)\n const i = (y * W + x) * 4\n data[i] = data[i + 1] = data[i + 2] = 255\n data[i + 3] = Math.round(255 * Math.min(1, col * row * 1.3))\n }\n }\n const tex = new THREE.DataTexture(data, W, H, THREE.RGBAFormat)\n tex.wrapS = THREE.RepeatWrapping\n tex.wrapT = THREE.RepeatWrapping\n tex.needsUpdate = true\n return tex\n}\n\n/**\n * Pooled particle effects: smoke, steam, fire (and the blue gas `flame` ring), water streams with drips, and sparks.\n * One `Points` per kind, fixed-size buffers, swap-remove; the total alive never exceeds `maxParticles`.\n */\nexport function createEffects(THREE: ThreeLib, options: EffectsOptions): Effects\n/** @deprecated Pass `{ scene, camera, ... }` as the one options argument. */\nexport function createEffects(THREE: ThreeLib, scene: ThreeNS.Object3D, options?: Partial<EffectsOptions>): Effects\nexport function createEffects(THREE: ThreeLib, a: EffectsOptions | ThreeNS.Object3D, b: Partial<EffectsOptions> = {}): Effects {\n const legacy = !!(a as ThreeNS.Object3D).isObject3D\n const options: Partial<EffectsOptions> = legacy ? { ...b, scene: a as ThreeNS.Object3D } : (a as EffectsOptions)\n const scene = options.scene\n if (!scene) throw new Error('createEffects: options.scene is required')\n if (!legacy && options.camera === undefined) throw new Error('createEffects: options.camera is required (pass null for a 90 degree lens)')\n const total = Math.max(POOLS.length, Math.floor(options.maxParticles ?? 800))\n const rand = mulberry(options.seed ?? 1)\n const wind: [number, number] = [options.wind?.[0] ?? 0, options.wind?.[1] ?? 0]\n const sprite = makeSprite(THREE, options.document)\n let viewHeight = options.viewHeight ?? 720\n let cameraSource: PerspectiveLike | (() => PerspectiveLike | null) | null = options.camera ?? null\n let camera: PerspectiveLike | null = typeof cameraSource === 'function' ? cameraSource() : cameraSource\n const scale = { value: 0 }\n /** Point size in pixels is size * viewHeight / (2 tan(fov / 2)) / distance. */\n const refreshScale = (cam: PerspectiveLike | null): void => {\n const fov = cam ? 2 * Math.atan(Math.tan((Math.min(Math.max(cam.fov, 1), 175) * Math.PI) / 360) / Math.max(cam.zoom ?? 1, 0.01)) : Math.PI / 2\n scale.value = viewHeight / (2 * Math.tan(fov / 2))\n }\n refreshScale(camera)\n\n const pools = {} as Record<PoolKind, Pool>\n const objects = {} as Record<PoolKind, ThreeNS.Points>\n let used = 0\n POOLS.forEach((kind, i) => {\n const cap = i === POOLS.length - 1 ? Math.max(1, total - used) : Math.max(1, Math.floor(total * WEIGHT[kind]))\n used += cap\n const geo = new THREE.BufferGeometry()\n const aPos = new THREE.BufferAttribute(new Float32Array(cap * 3), 3)\n const aSize = new THREE.BufferAttribute(new Float32Array(cap), 1)\n const aAlpha = new THREE.BufferAttribute(new Float32Array(cap), 1)\n const aColor = new THREE.BufferAttribute(new Float32Array(cap * 3), 3)\n for (const a of [aPos, aSize, aAlpha, aColor]) a.setUsage(THREE.DynamicDrawUsage)\n geo.setAttribute('position', aPos)\n geo.setAttribute('aSize', aSize)\n geo.setAttribute('aAlpha', aAlpha)\n geo.setAttribute('aColor', aColor)\n geo.setDrawRange(0, 0)\n const additive = kind === 'fire' || kind === 'spark'\n const mat = new THREE.ShaderMaterial({\n uniforms: { uMap: { value: sprite }, uScale: scale },\n vertexShader: VERT,\n fragmentShader: FRAG,\n transparent: true,\n depthWrite: false,\n blending: additive ? THREE.AdditiveBlending : THREE.NormalBlending,\n })\n const points = new THREE.Points(geo, mat)\n points.frustumCulled = false\n points.name = `effects:${kind}`\n scene.add(points)\n objects[kind] = points\n pools[kind] = {\n kind,\n cap,\n count: 0,\n pos: new Float32Array(cap * 3),\n vel: new Float32Array(cap * 3),\n age: new Float32Array(cap),\n life: new Float32Array(cap),\n size0: new Float32Array(cap),\n size1: new Float32Array(cap),\n tint: new Float32Array(cap),\n flags: new Uint8Array(cap),\n ground: new Float32Array(cap).fill(-1e9),\n aSize,\n aAlpha,\n aColor,\n aPos,\n points,\n }\n })\n\n /** Fractional spawns carried over per emitter id (the Map only grows with distinct ids and is pruned by stamp). */\n const debt = new Map<string, { carry: number; stamp: number }>()\n let stamp = 0\n let clock = 0\n\n const spawn = (p: Pool, x: number, y: number, z: number, vx: number, vy: number, vz: number, life: number, s0: number, s1: number, tint: number, flag = 0, ground = -1e9): void => {\n if (p.count >= p.cap) return\n const i = p.count++\n p.pos[i * 3] = x\n p.pos[i * 3 + 1] = y\n p.pos[i * 3 + 2] = z\n p.vel[i * 3] = vx\n p.vel[i * 3 + 1] = vy\n p.vel[i * 3 + 2] = vz\n p.age[i] = 0\n p.life[i] = life\n p.size0[i] = s0\n p.size1[i] = s1\n p.tint[i] = tint\n p.flags[i] = flag\n p.ground[i] = ground\n }\n\n const emitFrom = (e: ActiveEmitter, n: number): void => {\n const k = Math.min(1, Math.max(0, e.intensity))\n const size = e.size > 0 ? e.size : 0.2\n const [px, py, pz] = e.pos\n for (let j = 0; j < n; j++) {\n switch (e.kind) {\n case 'smoke':\n // thick, slow, wide plume\n spawn(pools.smoke, px + (rand() - 0.5) * size * 0.6, py, pz + (rand() - 0.5) * size * 0.6, (rand() - 0.5) * 0.2, 0.45 + rand() * 0.45, (rand() - 0.5) * 0.2, 2.8 + rand() * 1.8, size * 0.6, size * 2.6, 0.3 + rand() * 0.25, 0)\n break\n case 'steam':\n spawn(pools.steam, px + (rand() - 0.5) * size * 0.5, py, pz + (rand() - 0.5) * size * 0.5, (rand() - 0.5) * 0.12, 0.3 + rand() * 0.3, (rand() - 0.5) * 0.12, 1.3 + rand() * 1.1, size * 0.3, size * 1.3, 0.92, 0)\n break\n case 'fire':\n spawn(pools.fire, px + (rand() - 0.5) * size * 0.7, py, pz + (rand() - 0.5) * size * 0.7, (rand() - 0.5) * 0.25, 0.8 + rand() * 0.9 * k, (rand() - 0.5) * 0.25, 0.35 + rand() * 0.4, size * 0.75, size * 0.15, rand(), 0)\n break\n case 'flame': {\n // soft blue glow over the ring (the ring of little flames itself is a mesh)\n const a = rand() * Math.PI * 2\n const r = size * 0.8\n spawn(pools.fire, px + Math.cos(a) * r, py + 0.01, pz + Math.sin(a) * r, 0, 0.06 + rand() * 0.1, 0, 0.14 + rand() * 0.12, size * 0.55, size * 0.15, rand(), 1)\n break\n }\n case 'spark': {\n const a = rand() * Math.PI * 2\n const up = 0.4 + rand() * 0.6\n const sp = 1.2 + rand() * 2\n spawn(pools.spark, px, py, pz, Math.cos(a) * sp * (1 - up * 0.5), up * sp * 1.4, Math.sin(a) * sp * (1 - up * 0.5), 0.35 + rand() * 0.5, size * 0.18, size * 0.05, rand(), 0)\n break\n }\n case 'water':\n break\n }\n }\n }\n\n // ---- water: a tapered translucent stream along the gravity arc, droplets around it and a splash where it lands ----------------\n interface Arc {\n x: number\n y: number\n z: number\n vx: number\n vy: number\n vz: number\n /** Flight time to the landing height. */\n t: number\n stopY: number\n r0: number\n r1: number\n }\n const arc: Arc = { x: 0, y: 0, z: 0, vx: 0, vy: 0, vz: 0, t: 0, stopY: 0, r0: 0, r1: 0 }\n const floorY = options.floorY ?? 0\n const arcOf = (e: ActiveEmitter, k: number): boolean => {\n let [dx, dy, dz] = e.dir\n const len = Math.hypot(dx, dy, dz)\n if (len < 1e-6) {\n dx = 0\n dy = -1\n dz = 0\n } else {\n dx /= len\n dy /= len\n dz /= len\n }\n const speed = 0.7 + 1.8 * k\n const stopY = e.reach !== undefined ? Math.max(e.pos[1] - e.reach, floorY) : floorY\n const drop = e.pos[1] - stopY\n if (drop < 0.02) return false\n const vy = dy * speed\n arc.x = e.pos[0]\n arc.y = e.pos[1]\n arc.z = e.pos[2]\n arc.vx = dx * speed\n arc.vy = vy\n arc.vz = dz * speed\n arc.t = Math.min(2.5, (vy + Math.sqrt(vy * vy + 19.6 * drop)) / 9.8)\n arc.stopY = stopY\n const size = e.size > 0 ? e.size : 0.05\n if (size < 0.1) {\n // a tap: a thin jet that narrows as it speeds up\n arc.r0 = Math.max(0.004, size * 0.5)\n arc.r1 = arc.r0 * 0.55\n } else {\n // a shower or a leak: a spray that opens a little\n arc.r0 = size * 0.45\n arc.r1 = arc.r0 * 1.2\n }\n return true\n }\n\n const emitWater = (e: ActiveEmitter, k: number, nSpray: number, nSplash: number, nMist: number): void => {\n const size = e.size > 0 ? e.size : 0.05\n const wide = size >= 0.1\n for (let j = 0; j < nSpray; j++) {\n const s = rand()\n const t = s * arc.t\n const r = (arc.r0 + (arc.r1 - arc.r0) * s) * (0.7 + rand() * 0.5)\n const a = rand() * Math.PI * 2\n const ox = Math.cos(a) * r\n const oz = Math.sin(a) * r\n spawn(\n pools.water,\n arc.x + arc.vx * t + ox,\n arc.y + arc.vy * t - 4.9 * t * t,\n arc.z + arc.vz * t + oz,\n arc.vx + (wide ? ox * 1.2 : 0) + (rand() - 0.5) * 0.25,\n arc.vy - 9.8 * t,\n arc.vz + (wide ? oz * 1.2 : 0) + (rand() - 0.5) * 0.25,\n 0.22 + rand() * 0.25,\n 0.011 + rand() * 0.012,\n 0.009 + rand() * 0.008,\n rand(),\n 2,\n arc.stopY,\n )\n }\n const ex = arc.x + arc.vx * arc.t\n const ez = arc.z + arc.vz * arc.t\n for (let j = 0; j < nSplash; j++) {\n const a = rand() * Math.PI * 2\n const r = arc.r1 * Math.sqrt(rand())\n const sp = (wide ? 0.5 : 0.25) + rand() * 0.7\n spawn(pools.water, ex + Math.cos(a) * r, arc.stopY + 0.005, ez + Math.sin(a) * r, Math.cos(a) * sp, 0.9 + rand() * 1.3, Math.sin(a) * sp, 0.3 + rand() * 0.25, 0.014 + rand() * 0.018, 0.01, rand(), 3, arc.stopY)\n }\n for (let j = 0; j < nMist; j++) {\n const a = rand() * Math.PI * 2\n const r = arc.r1 * 1.4 * Math.sqrt(rand())\n spawn(pools.water, ex + Math.cos(a) * r, arc.stopY + 0.02, ez + Math.sin(a) * r, Math.cos(a) * 0.15, 0.18 + rand() * 0.15, Math.sin(a) * 0.15, 0.7 + rand() * 0.5, 0.06 + size * 0.2, 0.2 + size * 0.5, rand(), 4, arc.stopY)\n }\n void k\n }\n\n const emitDrip = (e: ActiveEmitter, n: number): void => {\n const size = e.size > 0 ? e.size : 0.05\n const stopY = e.reach !== undefined ? Math.max(e.pos[1] - e.reach, floorY) : floorY\n for (let j = 0; j < n; j++) {\n const sx = (rand() - 0.5) * 0.01\n const sz = (rand() - 0.5) * 0.01\n spawn(pools.water, e.pos[0] + sx, e.pos[1], e.pos[2] + sz, e.dir[0] * 0.08, e.dir[1] * 0.08, e.dir[2] * 0.08, 1.4, size * 0.22, size * 0.2, rand(), 1, stopY)\n }\n }\n\n const RATE: Record<EmitterKind, number> = { smoke: 42, steam: 48, fire: 150, flame: 55, spark: 40, water: 0 }\n\n // Stream meshes ----------------------------------------------------------------------------------------------------------------\n const SEG = 12\n const SIDES = 8\n const maxStreams = Math.max(0, Math.floor(options.maxStreams ?? 6))\n const streaksTex = makeStreaks(THREE)\n const streamMat = new THREE.MeshBasicMaterial({ color: 0x9cccff, map: streaksTex, vertexColors: true, transparent: true, opacity: 0.8, depthWrite: false, side: THREE.DoubleSide })\n const streamIndex: number[] = []\n for (let i = 0; i < SEG; i++) {\n for (let m = 0; m < SIDES; m++) {\n const a = i * (SIDES + 1) + m\n const b = a + SIDES + 1\n streamIndex.push(a, b, a + 1, a + 1, b, b + 1)\n }\n }\n const group = new THREE.Group()\n group.name = 'effects:meshes'\n scene.add(group)\n const streams: ThreeNS.Mesh[] = []\n for (let i = 0; i < maxStreams; i++) {\n const geo = new THREE.BufferGeometry()\n const n = (SEG + 1) * (SIDES + 1)\n geo.setAttribute('position', new THREE.BufferAttribute(new Float32Array(n * 3), 3).setUsage(THREE.DynamicDrawUsage))\n geo.setAttribute('color', new THREE.BufferAttribute(new Float32Array(n * 4), 4).setUsage(THREE.DynamicDrawUsage))\n const uv = new Float32Array(n * 2)\n geo.setAttribute('uv', new THREE.BufferAttribute(uv, 2).setUsage(THREE.DynamicDrawUsage))\n geo.setIndex(streamIndex)\n const mesh = new THREE.Mesh(geo, streamMat)\n mesh.frustumCulled = false\n mesh.visible = false\n mesh.name = `effects:stream${i}`\n group.add(mesh)\n streams.push(mesh)\n }\n\n const writeStream = (mesh: ThreeNS.Mesh, k: number): void => {\n const geo = mesh.geometry\n const pos = (geo.getAttribute('position') as ThreeNS.BufferAttribute).array as Float32Array\n const col = (geo.getAttribute('color') as ThreeNS.BufferAttribute).array as Float32Array\n const uv = (geo.getAttribute('uv') as ThreeNS.BufferAttribute).array as Float32Array\n for (let i = 0; i <= SEG; i++) {\n const s = i / SEG\n const t = s * arc.t\n const cx = arc.x + arc.vx * t\n const cy = arc.y + arc.vy * t - 4.9 * t * t\n const cz = arc.z + arc.vz * t\n let tx = arc.vx\n let ty = arc.vy - 9.8 * t\n let tz = arc.vz\n const tl = Math.hypot(tx, ty, tz) || 1\n tx /= tl\n ty /= tl\n tz /= tl\n // binormal = tangent x up, normal = tangent x binormal\n let bx = tz\n const by = 0\n let bz = -tx\n const bl = Math.hypot(bx, bz)\n if (bl < 1e-4) {\n bx = 1\n bz = 0\n } else {\n bx /= bl\n bz /= bl\n }\n const nx = ty * bz - tz * by\n const ny = tz * bx - tx * bz\n const nz = tx * by - ty * bx\n const r = arc.r0 + (arc.r1 - arc.r0) * s\n const alpha = Math.min(1, s * 7) * (0.95 - 0.3 * s) * Math.min(1, 0.55 + k)\n for (let m = 0; m <= SIDES; m++) {\n const a = (m / SIDES) * Math.PI * 2\n const ca = Math.cos(a) * r\n const sa = Math.sin(a) * r\n const v = i * (SIDES + 1) + m\n pos[v * 3] = cx + bx * ca + nx * sa\n pos[v * 3 + 1] = cy + by * ca + ny * sa\n pos[v * 3 + 2] = cz + bz * ca + nz * sa\n col[v * 4] = col[v * 4 + 1] = col[v * 4 + 2] = 1\n col[v * 4 + 3] = alpha\n uv[v * 2] = (m / SIDES) * 3\n uv[v * 2 + 1] = s * arc.t * 2.2\n }\n }\n ;(geo.getAttribute('position') as ThreeNS.BufferAttribute).needsUpdate = true\n ;(geo.getAttribute('color') as ThreeNS.BufferAttribute).needsUpdate = true\n ;(geo.getAttribute('uv') as ThreeNS.BufferAttribute).needsUpdate = true\n mesh.visible = true\n }\n\n // Gas flame rings: every burner is a ring of small blue cones; all rings share one dynamic mesh (one draw call) ------------------\n const CONES = 16\n const maxFlames = Math.max(0, Math.floor(options.maxFlames ?? 16))\n const flameGeo = new THREE.BufferGeometry()\n const flamePos = new THREE.BufferAttribute(new Float32Array(maxFlames * CONES * 4 * 3), 3).setUsage(THREE.DynamicDrawUsage)\n const flameCol = new THREE.BufferAttribute(new Float32Array(maxFlames * CONES * 4 * 3), 3).setUsage(THREE.DynamicDrawUsage)\n flameGeo.setAttribute('position', flamePos)\n flameGeo.setAttribute('color', flameCol)\n const flameIdx: number[] = []\n for (let i = 0; i < maxFlames * CONES; i++) {\n const v = i * 4\n flameIdx.push(v, v + 1, v + 3, v + 1, v + 2, v + 3, v + 2, v, v + 3)\n }\n flameGeo.setIndex(flameIdx)\n flameGeo.setDrawRange(0, 0)\n const flames = new THREE.Mesh(\n flameGeo,\n new THREE.MeshBasicMaterial({ vertexColors: true, transparent: true, blending: THREE.AdditiveBlending, depthWrite: false, side: THREE.DoubleSide }),\n )\n flames.frustumCulled = false\n flames.visible = false\n flames.name = 'effects:flames'\n group.add(flames)\n\n const hashOf = (id: string): number => {\n let h = 2166136261\n for (let i = 0; i < id.length; i++) h = Math.imul(h ^ id.charCodeAt(i), 16777619)\n return ((h >>> 0) % 1000) / 1000\n }\n\n const writeFlame = (slot: number, e: ActiveEmitter, time: number): void => {\n const pa = flamePos.array as Float32Array\n const ca = flameCol.array as Float32Array\n const k = Math.min(1, Math.max(0, e.intensity))\n const size = e.size > 0 ? e.size : 0.05\n const R = size * 0.8\n const bw = Math.max(0.004, size * 0.13)\n const phase = hashOf(e.id) * 40\n for (let c = 0; c < CONES; c++) {\n const a = (c / CONES) * Math.PI * 2\n const ux = Math.cos(a)\n const uz = Math.sin(a)\n const bx = e.pos[0] + ux * R\n const bz = e.pos[2] + uz * R\n const by = e.pos[1]\n const h = (0.025 + size * 0.45) * k * (0.55 + 0.45 * Math.abs(Math.sin(time * 19 + c * 2.3 + phase)))\n const v = (slot * CONES + c) * 4\n // base triangle: tangent +, tangent -, radial out; apex leans slightly inwards\n const tx = -uz * bw\n const tz = ux * bw\n pa.set([bx + tx, by, bz + tz, bx - tx, by, bz - tz, bx + ux * bw * 0.9, by, bz + uz * bw * 0.9, bx - ux * h * 0.12, by + h, bz - uz * h * 0.12], v * 3)\n const lo = 0.3 * k\n ca.set([0.2 * k, 0.45 * k, 1 * k, 0.2 * k, 0.45 * k, 1 * k, 0.2 * k, 0.45 * k, 1 * k, 0.02 * lo, 0.1 * lo, 0.5 * lo], v * 3)\n }\n }\n\n const advance = (p: Pool, dt: number): void => {\n let i = 0\n const swayX = wind[0]\n const swayZ = wind[1]\n while (i < p.count) {\n p.age[i] += dt\n const age = p.age[i]\n const life = p.life[i]\n if (age >= life || (p.kind === 'water' && p.pos[i * 3 + 1] < p.ground[i])) {\n // swap-remove\n const last = --p.count\n if (i !== last) {\n p.pos.copyWithin(i * 3, last * 3, last * 3 + 3)\n p.vel.copyWithin(i * 3, last * 3, last * 3 + 3)\n p.age[i] = p.age[last]\n p.life[i] = p.life[last]\n p.size0[i] = p.size0[last]\n p.size1[i] = p.size1[last]\n p.tint[i] = p.tint[last]\n p.flags[i] = p.flags[last]\n p.ground[i] = p.ground[last]\n }\n continue\n }\n const j = i * 3\n switch (p.kind) {\n case 'smoke':\n case 'steam':\n p.vel[j] += (swayX - p.vel[j]) * Math.min(1, dt * 0.8)\n p.vel[j + 2] += (swayZ - p.vel[j + 2]) * Math.min(1, dt * 0.8)\n break\n case 'water':\n if (p.flags[i] !== 4) p.vel[j + 1] -= 9.8 * dt\n break\n case 'spark':\n p.vel[j + 1] -= 7 * dt\n break\n case 'fire':\n p.vel[j] += (swayX * 0.1 - p.vel[j]) * Math.min(1, dt * 2)\n break\n }\n p.pos[j] += p.vel[j] * dt\n p.pos[j + 1] += p.vel[j + 1] * dt\n p.pos[j + 2] += p.vel[j + 2] * dt\n if (p.kind === 'water' && p.pos[j + 1] < p.ground[i]) {\n // landed: stay on the surface and fade out this frame\n p.pos[j + 1] = p.ground[i]\n p.age[i] = p.life[i]\n }\n i++\n }\n }\n\n const write = (p: Pool): void => {\n const n = p.count\n const pa = p.aPos.array as Float32Array\n const sa = p.aSize.array as Float32Array\n const aa = p.aAlpha.array as Float32Array\n const ca = p.aColor.array as Float32Array\n for (let i = 0; i < n; i++) {\n const u = p.age[i] / p.life[i]\n const j = i * 3\n pa[j] = p.pos[j]\n pa[j + 1] = p.pos[j + 1]\n pa[j + 2] = p.pos[j + 2]\n sa[i] = p.size0[i] + (p.size1[i] - p.size0[i]) * u\n let alpha: number\n switch (p.kind) {\n case 'smoke':\n alpha = 0.55 * Math.min(1, u * 8) * (1 - u)\n ca[j] = ca[j + 1] = ca[j + 2] = p.tint[i]\n break\n case 'steam':\n alpha = 0.4 * Math.min(1, u * 6) * (1 - u)\n ca[j] = ca[j + 1] = ca[j + 2] = p.tint[i]\n break\n case 'fire':\n alpha = (p.flags[i] ? 0.95 : 0.8) * (1 - u * u)\n if (p.flags[i]) {\n ca[j] = 0.25 + 0.15 * p.tint[i]\n ca[j + 1] = 0.5 + 0.2 * p.tint[i]\n ca[j + 2] = 1\n } else {\n // yellow core -> orange -> red as it rises\n ca[j] = 1\n ca[j + 1] = Math.max(0.15, 0.85 - u * 0.7 - p.tint[i] * 0.1)\n ca[j + 2] = Math.max(0, 0.25 - u * 0.25)\n }\n break\n case 'spark':\n alpha = 1 - u\n ca[j] = 1\n ca[j + 1] = 0.75 - u * 0.4\n ca[j + 2] = 0.3\n break\n default: {\n const f = p.flags[i]\n alpha = f === 4 ? 0.16 * (1 - u) : f === 3 ? 0.8 * (1 - u * 0.5) : f === 2 ? 0.65 * (1 - u * 0.6) : 0.8\n ca[j] = f === 4 ? 0.85 : 0.5\n ca[j + 1] = f === 4 ? 0.92 : 0.74\n ca[j + 2] = 1\n }\n }\n aa[i] = alpha\n }\n p.aPos.needsUpdate = true\n p.aSize.needsUpdate = true\n p.aAlpha.needsUpdate = true\n p.aColor.needsUpdate = true\n p.points.geometry.setDrawRange(0, n)\n }\n\n return {\n objects,\n meshes: { group, streams, flames },\n update(dt, emitters, cam) {\n camera = cam ?? (typeof cameraSource === 'function' ? cameraSource() : cameraSource)\n refreshScale(camera)\n const step = Math.min(Math.max(dt, 0), 0.1)\n stamp++\n clock += step\n streaksTex.offset.y = -(clock * 2.4) % 1\n let nStreams = 0\n let nFlames = 0\n const due = (key: string, rate: number): number => {\n let d = debt.get(key)\n if (!d) {\n d = { carry: 0, stamp }\n debt.set(key, d)\n }\n d.stamp = stamp\n d.carry += rate * step\n const n = Math.floor(d.carry)\n d.carry -= n\n return n\n }\n for (let i = 0; i < emitters.length; i++) {\n const e = emitters[i]\n if (!(e.intensity > 0)) continue\n const k = Math.min(1, e.intensity)\n const size = e.size > 0 ? e.size : 0.05\n if (e.kind === 'water') {\n if (k < 0.25) {\n const n = due(e.id, 3 + k * 10)\n if (n > 0) emitDrip(e, n)\n } else if (arcOf(e, k)) {\n const nSpray = due(e.id, (60 + 260 * Math.min(size, 0.4)) * k)\n const nSplash = due(`${e.id}#s`, (45 + 90 * Math.min(size, 0.4)) * k)\n const nMist = due(`${e.id}#m`, 6 * k * (1 + size * 4))\n emitWater(e, k, nSpray, nSplash, nMist)\n if (nStreams < streams.length) writeStream(streams[nStreams++], k)\n }\n continue\n }\n if (e.kind === 'flame' && nFlames < maxFlames) writeFlame(nFlames++, e, clock)\n const n = due(e.id, RATE[e.kind] * k)\n if (n > 0) emitFrom(e, n)\n }\n for (let i = nStreams; i < streams.length; i++) streams[i].visible = false\n flames.visible = nFlames > 0\n flameGeo.setDrawRange(0, nFlames * CONES * 9)\n flamePos.needsUpdate = true\n flameCol.needsUpdate = true\n if (debt.size > emitters.length * 3 + 8) {\n for (const [id, d] of debt) if (d.stamp !== stamp) debt.delete(id)\n }\n for (const kind of POOLS) {\n advance(pools[kind], step)\n write(pools[kind])\n }\n },\n setWind(x, z) {\n wind[0] = x\n wind[1] = z\n },\n setCamera(cam) {\n cameraSource = cam\n camera = typeof cam === 'function' ? cam() : cam\n refreshScale(camera)\n },\n setViewHeight(px) {\n viewHeight = px\n refreshScale(camera)\n },\n stats() {\n const byKind = {} as Record<PoolKind, number>\n let alive = 0\n let capacity = 0\n for (const kind of POOLS) {\n byKind[kind] = pools[kind].count\n alive += pools[kind].count\n capacity += pools[kind].cap\n }\n return { alive, capacity, byKind }\n },\n clear() {\n for (const kind of POOLS) {\n pools[kind].count = 0\n write(pools[kind])\n }\n debt.clear()\n for (const m of streams) m.visible = false\n flames.visible = false\n },\n dispose() {\n for (const kind of POOLS) {\n scene.remove(objects[kind])\n objects[kind].geometry.dispose()\n ;(objects[kind].material as ThreeNS.Material).dispose()\n }\n scene.remove(group)\n for (const m of streams) m.geometry.dispose()\n flameGeo.dispose()\n ;(flames.material as ThreeNS.Material).dispose()\n streamMat.dispose()\n streaksTex.dispose()\n sprite.dispose()\n },\n }\n}\n","import type { ThreeLib, ThreeNS, Vec3 } from './types'\n\n/**\n * Points of a hanging cord between `a` and `b` (n points including both ends, n >= 2). The deepest point sits `sag` meters below\n * the straight line between the ends, on a real catenary (y = a cosh(x/a)); when the ends differ in height the curve is\n * measured against the straight line between them.\n */\nexport function catenary(a: Vec3, b: Vec3, sag: number, n = 12): Vec3[] {\n const count = Math.max(2, Math.floor(n))\n const span = Math.hypot(b[0] - a[0], b[2] - a[2]) || Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2])\n const depth = Math.max(0, sag)\n const out: Vec3[] = []\n // Solve depth = c (cosh(span / 2c) - 1) for c by bisection (depth grows as c shrinks).\n let shape: (s: number) => number = () => 0\n if (depth > 1e-6 && span > 1e-6) {\n let lo = 1e-4\n let hi = span * 1000\n for (let i = 0; i < 80; i++) {\n const c = (lo + hi) / 2\n const d = c * (Math.cosh(span / (2 * c)) - 1)\n if (d > depth) lo = c\n else hi = c\n }\n const c = (lo + hi) / 2\n shape = (s) => c * (Math.cosh(((s - 0.5) * span) / c) - Math.cosh(span / (2 * c)))\n }\n for (let i = 0; i < count; i++) {\n const s = i / (count - 1)\n out.push([a[0] + (b[0] - a[0]) * s, a[1] + (b[1] - a[1]) * s + shape(s), a[2] + (b[2] - a[2]) * s])\n }\n return out\n}\n\n/** A thin tube through `points` (Catmull-Rom smoothed) for wires, cords and conduits. */\nexport function createCord(THREE: ThreeLib, points: readonly Vec3[], radius: number, material: ThreeNS.Material, radialSegments = 5): ThreeNS.Mesh {\n if (points.length < 2) throw new Error('createCord needs at least two points')\n const curve = new THREE.CatmullRomCurve3(points.map((p) => new THREE.Vector3(p[0], p[1], p[2])), false, 'centripetal')\n const segments = Math.max(4, (points.length - 1) * 4)\n const mesh = new THREE.Mesh(new THREE.TubeGeometry(curve, segments, radius, radialSegments, false), material)\n mesh.name = 'cord'\n mesh.castShadow = true\n return mesh\n}\n","import type * as ThreeNS from 'three'\nimport type { PropsApi } from '@adatechnology/game-props3d'\n\n/** The host's `THREE` namespace (or any object with the same classes). Always passed in, never imported at runtime. */\nexport type ThreeLib = typeof ThreeNS\nexport type { ThreeNS }\n\nexport type Vec3 = [number, number, number]\n\n/** Material keys the mesh api understands (same as `PropsApi` materials). */\nexport type MaterialKey = 'plain' | 'metal' | 'wood' | 'glass' | 'fabric' | 'plant' | 'water' | 'emissive' | 'atlas_picture' | 'atlas_floor'\n\nexport const MATERIAL_KEYS: readonly MaterialKey[] = ['plain', 'metal', 'wood', 'glass', 'fabric', 'plant', 'water', 'emissive', 'atlas_picture', 'atlas_floor']\n\nexport type Quality = 'high' | 'game'\n\n/**\n * What content packs draw through: the props primitives plus `part`.\n * `part(id, pivot, ry, draw)` runs `draw()` and routes every primitive drawn inside it into the movable part `id`.\n * `pivot` is object-local; the primitives drawn inside `draw` are in the part frame (relative to the pivot, turned by `ry`): the part's\n * group origin sits at `pivot`, turned by `ry` around +y.\n */\nexport interface HouseholdApi extends PropsApi {\n part(id: string, pivot: Vec3, ry: number, draw: () => void): void\n}\n\n/** Anything that can create a canvas (the global `document`, or a fake in tests). */\nexport interface CanvasFactory {\n createElement(tag: 'canvas'): any\n}\n","import { poseOf as enginePoseOf } from '@adatechnology/game-interactables'\nimport type { Motion, World } from '@adatechnology/game-interactables'\nimport type { ThreeLib, Vec3 } from './types'\n\n/** Pure pose of a part at `t`, in the part's own frame (the frame at rest: pivot at the origin, already turned by the part's `ry`). */\nexport interface Pose {\n /** Translation, part frame. */\n position: Vec3\n /** Rotation as a quaternion [x, y, z, w], part frame. */\n quaternion: [number, number, number, number]\n /** Scale per local axis. */\n scale: Vec3\n}\n\n/**\n * The engine's pose math, as a quaternion. This is the engine's own `poseOf` (same default angles and distances), so the rendered\n * part and the engine's `slotPosition`, colliders, mirrors and `fitSweep` always agree. `t` is clamped to [0, 1].\n */\nexport function poseOf(motion: Motion, t: number): Pose {\n const k = Math.min(1, Math.max(0, Number.isFinite(t) ? t : 0))\n const pose = enginePoseOf(motion, k)\n const [x, y, z] = pose.rotation.axis\n const l = Math.hypot(x, y, z) || 1\n const s = Math.sin(pose.rotation.angle / 2)\n return {\n position: [pose.position[0], pose.position[1], pose.position[2]],\n quaternion: [(x / l) * s, (y / l) * s, (z / l) * s, Math.cos(pose.rotation.angle / 2)],\n scale: [pose.scale[0], pose.scale[1], pose.scale[2]],\n }\n}\n\ninterface Rest {\n position: Vec3\n quaternion: [number, number, number, number]\n scale: Vec3\n}\n\n/** Remembers the rest transform of a part group in `userData.rest` (once). */\nexport function rememberRest(group: { position: any; quaternion: any; scale: any; userData: Record<string, any> }): Rest {\n let rest = group.userData.rest as Rest | undefined\n if (!rest) {\n const p = group.position\n const q = group.quaternion\n const s = group.scale\n rest = { position: [p.x, p.y, p.z], quaternion: [q.x, q.y, q.z, q.w], scale: [s.x, s.y, s.z] }\n group.userData.rest = rest\n }\n return rest\n}\n\n/**\n * Poses `group` for a motion at `t`. The rest pose (position at the pivot, rotation `ry`) is saved in `group.userData.rest` the first\n * time, so calling this every frame never drifts. The motion axis lives in the part frame (after `ry`).\n */\nexport function applyPose<G extends import('three').Object3D>(THREE: ThreeLib, group: G, motion: Motion, t: number): G {\n const rest = rememberRest(group)\n const pose = poseOf(motion, t)\n const restQ = new THREE.Quaternion(rest.quaternion[0], rest.quaternion[1], rest.quaternion[2], rest.quaternion[3])\n const delta = new THREE.Quaternion(pose.quaternion[0], pose.quaternion[1], pose.quaternion[2], pose.quaternion[3])\n group.quaternion.copy(restQ).multiply(delta)\n const offset = new THREE.Vector3(pose.position[0], pose.position[1], pose.position[2]).applyQuaternion(restQ)\n group.position.set(rest.position[0] + offset.x, rest.position[1] + offset.y, rest.position[2] + offset.z)\n group.scale.set(rest.scale[0] * pose.scale[0], rest.scale[1] * pose.scale[1], rest.scale[2] * pose.scale[2])\n group.updateMatrix()\n return group\n}\n\nexport interface SyncOptions {\n /** Seconds, drives the idle flutter of sway shaders. Default 0. */\n time?: number\n}\n\n/**\n * Per-frame sync of one world object: every part group takes the motion of its `PartSpec` at the world's current t,\n * and every soft volume swings. A soft volume drives the group in `parts` under its `part` (or, failing that, its own id):\n * meshes patched with `attachSway` get the swing through their shader uniforms (so shadows follow), any other group is rotated\n * around the anchor line.\n */\nexport function syncObject(THREE: ThreeLib, world: World, objectId: string, parts: Record<string, import('three').Object3D>, options: SyncOptions = {}): void {\n const obj = world.get(objectId)\n if (!obj) return\n const motionOf = new Map<string, Motion>()\n for (const p of obj.spec.parts ?? []) {\n motionOf.set(p.id, p.motion)\n const g = parts[p.id]\n if (!g) continue\n const merged = g.userData.merged as { kind: string; apply?: (m: Motion, t: number) => void } | undefined\n if (merged) {\n // parts merged into one mesh: the batch poses every vertex around its own pivot (cloth batches stay at rest)\n merged.apply?.(p.motion, world.partT(objectId, p.id))\n continue\n }\n applyPose(THREE, g, p.motion, world.partT(objectId, p.id))\n }\n for (const soft of obj.spec.soft ?? []) {\n const key = soft.part ?? soft.id\n const g = parts[key] ?? parts[soft.id]\n if (!g) continue\n const { ax, az } = world.sway(objectId, soft.id)\n const batch = g.userData.merged as { kind: string; index?: Record<string, number>; setAt?: (i: number, ax: number, az: number) => void; setTime?: (t: number) => void } | undefined\n if (batch?.kind === 'sway') {\n const i = batch.index?.[soft.id]\n if (i !== undefined) batch.setAt?.(i, ax, az)\n if (options.time !== undefined) batch.setTime?.(options.time)\n continue\n }\n let shaded = false\n g.traverse((o) => {\n const sway = o.userData.sway as { set(ax: number, az: number, time?: number): void } | undefined\n if (sway) {\n sway.set(ax, az, options.time)\n shaded = true\n }\n })\n if (shaded) continue\n rememberRest(g)\n // rotate around the anchor line: the part's pose (if it has a motion) is already applied above\n if (!motionOf.has(key)) applyPose(THREE, g, { kind: 'hinge', angle: 0 }, 0)\n const rot = new THREE.Quaternion().setFromEuler(new THREE.Euler(ax, 0, az, 'XYZ'))\n const anchor = new THREE.Vector3(soft.anchor[0], soft.anchor[1], soft.anchor[2])\n g.position.sub(anchor).applyQuaternion(rot).add(anchor)\n g.quaternion.premultiply(rot)\n g.updateMatrix()\n }\n}\n","import type { Motion, ObjectSpec } from '@adatechnology/game-interactables'\nimport { poseOf } from './pose'\nimport type { ThreeLib, ThreeNS } from './types'\n\nexport interface MergeOptions {\n /** Idle flutter of merged cloth (see `SwayOptions.amplitude`). Default 0.04. */\n swayAmplitude?: number\n}\n\n/** Posed by `syncObject` in place of the part groups it replaced. */\nexport interface PoseBatch {\n kind: 'pose'\n /** Part ids that moved into the batch. */\n ids: string[]\n /** Applies the motion at `t` to every vertex, each around its own pivot. */\n apply(motion: Motion, t: number): void\n}\n\n/** Cloth hanging from a line: every merged cloth swings with its own (ax, az). */\nexport interface SwayBatch {\n kind: 'sway'\n /** Soft volume id -> index. */\n index: Record<string, number>\n setAt(index: number, ax: number, az: number): void\n setTime(time: number): void\n}\n\nexport type MergedGroup = ThreeNS.Group & { userData: { merged: PoseBatch | SwayBatch } }\n\nconst QROT = /* glsl */ `\nvec3 batchRotate(vec4 q, vec3 v) { return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); }\n`\n\nfunction patchProgram<M extends ThreeNS.Material>(material: M, key: string, patchShader: (shader: { uniforms: Record<string, any>; vertexShader: string }) => void, inherit?: ThreeNS.Material): M {\n const previous = material.onBeforeCompile\n material.onBeforeCompile = (shader, renderer) => {\n previous?.call(material, shader, renderer)\n patchShader(shader)\n }\n const inherited = inherit?.customProgramCacheKey\n material.customProgramCacheKey = inherited && inherit ? () => `${inherited.call(inherit)}|${key}` : () => key\n return material\n}\n\n/**\n * `Material.clone()` drops `onBeforeCompile`, `customProgramCacheKey` and (for some classes) `defines`. A merged group must still look\n * like the material the host passed in (a light mask, a fog patch...), so the clone gets them back before the batch patch is chained on.\n */\nfunction cloneKeepingHooks(base: ThreeNS.Material): ThreeNS.Material {\n const clone = base.clone()\n if (base.defines) clone.defines = { ...(clone.defines ?? {}), ...base.defines }\n if (base.onBeforeCompile !== Object.getPrototypeOf(base).onBeforeCompile) clone.onBeforeCompile = base.onBeforeCompile\n clone.userData = { ...base.userData, mergedFrom: base.uuid }\n return clone\n}\n\n/** Material, depth material and distance material patched by the same function, so shadows follow the animation. */\nfunction patchedSet(THREE: ThreeLib, base: ThreeNS.Material, key: string, patchShader: (shader: { uniforms: Record<string, any>; vertexShader: string }) => void) {\n return {\n material: patchProgram(cloneKeepingHooks(base), key, patchShader, base),\n depth: patchProgram(new THREE.MeshDepthMaterial({ depthPacking: THREE.RGBADepthPacking }), key, patchShader),\n distance: patchProgram(new THREE.MeshDistanceMaterial(), key, patchShader),\n }\n}\n\ninterface Piece {\n geometry: ThreeNS.BufferGeometry\n matrix: ThreeNS.Matrix4\n /** Per-vertex extra attributes of this piece. */\n extra: Record<string, number[]>\n}\n\n/** Concatenates pieces (positions and normals moved by their matrices) into one geometry with the extra attributes. */\nfunction concat(THREE: ThreeLib, pieces: Piece[], extraSizes: Record<string, number>): ThreeNS.BufferGeometry {\n let verts = 0\n let idx = 0\n for (const p of pieces) {\n verts += p.geometry.getAttribute('position').count\n idx += p.geometry.index!.count\n }\n const pos = new Float32Array(verts * 3)\n const nor = new Float32Array(verts * 3)\n const col = new Float32Array(verts * 3)\n const uv = new Float32Array(verts * 2)\n const index = new Uint32Array(idx)\n const extra: Record<string, Float32Array> = {}\n for (const [k, n] of Object.entries(extraSizes)) extra[k] = new Float32Array(verts * n)\n const v = new THREE.Vector3()\n const n3 = new THREE.Matrix3()\n let vo = 0\n let io = 0\n for (const p of pieces) {\n const g = p.geometry\n const count = g.getAttribute('position').count\n n3.getNormalMatrix(p.matrix)\n const gp = g.getAttribute('position')\n const gn = g.getAttribute('normal')\n const gc = g.getAttribute('color')\n const gu = g.getAttribute('uv')\n for (let i = 0; i < count; i++) {\n v.fromBufferAttribute(gp, i).applyMatrix4(p.matrix)\n pos.set([v.x, v.y, v.z], (vo + i) * 3)\n v.fromBufferAttribute(gn, i).applyMatrix3(n3).normalize()\n nor.set([v.x, v.y, v.z], (vo + i) * 3)\n col.set([gc.getX(i), gc.getY(i), gc.getZ(i)], (vo + i) * 3)\n uv.set([gu.getX(i), gu.getY(i)], (vo + i) * 2)\n }\n for (const [k, values] of Object.entries(p.extra)) extra[k].set(values, vo * extraSizes[k])\n const gi = g.index!\n for (let i = 0; i < gi.count; i++) index[io + i] = gi.getX(i) + vo\n vo += count\n io += gi.count\n }\n const out = new THREE.BufferGeometry()\n out.setAttribute('position', new THREE.BufferAttribute(pos, 3))\n out.setAttribute('normal', new THREE.BufferAttribute(nor, 3))\n out.setAttribute('color', new THREE.BufferAttribute(col, 3))\n out.setAttribute('uv', new THREE.BufferAttribute(uv, 2))\n for (const [k, n] of Object.entries(extraSizes)) out.setAttribute(k, new THREE.BufferAttribute(extra[k], n))\n out.setIndex(new THREE.BufferAttribute(verts > 65535 ? index : new Uint16Array(index), 1))\n out.computeBoundingSphere()\n out.computeBoundingBox()\n return out\n}\n\nfunction meshesOf(group: ThreeNS.Object3D): ThreeNS.Mesh[] {\n return group.children.filter((c): c is ThreeNS.Mesh => (c as ThreeNS.Mesh).isMesh)\n}\n\n/**\n * Merges parts after `finish()` to cut draw calls (the `mergeParts` option of `createMeshApi`):\n *\n * - parts of one `PartSpec.group` with the same motion (blind slats) become one mesh per material whose vertices carry their own pivot;\n * `syncObject` poses them with one set of uniforms and the shadow materials follow;\n * - `cloth` soft volumes (clothes on a line) become one mesh per material with a per-vertex cloth index and anchor height; each\n * cloth keeps its own swing.\n *\n * The merged group is added to `root`, the part groups are removed, and `parts[id]` points at the merged group for every member.\n * Parts that carry a mirror, that are turned (`ry`) or that stand alone are left as they are.\n */\nexport function mergeParts(THREE: ThreeLib, root: ThreeNS.Group, parts: Record<string, ThreeNS.Group>, spec: ObjectSpec, options: MergeOptions = {}): void {\n const amplitude = options.swayAmplitude ?? 0.04\n const skip = new Set<string>()\n for (const m of spec.mirrors ?? []) if (m.part) skip.add(m.part)\n for (const [id, g] of Object.entries(parts)) if (Math.abs(g.rotation.y) > 1e-9 || g.userData.merged) skip.add(id)\n\n const take = (ids: string[]): ThreeNS.Group[] => ids.map((id) => parts[id])\n const retire = (ids: string[], merged: ThreeNS.Group): void => {\n for (const id of ids) {\n const g = parts[id]\n g.removeFromParent()\n for (const m of meshesOf(g)) m.geometry.dispose()\n parts[id] = merged\n }\n root.add(merged)\n }\n const byMaterial = (groups: ThreeNS.Group[], extra: (g: ThreeNS.Group, count: number) => Record<string, number[]>) => {\n const map = new Map<string, { base: ThreeNS.Material; pieces: Piece[]; mesh: ThreeNS.Mesh }>()\n for (const g of groups) {\n g.updateMatrix()\n for (const mesh of meshesOf(g)) {\n const key = `${String(mesh.userData.material)}|${(mesh.material as ThreeNS.Material).uuid}`\n let e = map.get(key)\n if (!e) {\n e = { base: mesh.material as ThreeNS.Material, pieces: [], mesh }\n map.set(key, e)\n }\n e.pieces.push({ geometry: mesh.geometry, matrix: g.matrix, extra: extra(g, mesh.geometry.getAttribute('position').count) })\n }\n }\n return map\n }\n const finishMesh = (name: string, key: string, geometry: ThreeNS.BufferGeometry, template: ThreeNS.Mesh, set: ReturnType<typeof patchedSet>, group: ThreeNS.Group): void => {\n const mesh = new THREE.Mesh(geometry, set.material)\n mesh.name = `${name}:${key}`\n mesh.userData.material = key\n mesh.castShadow = template.castShadow\n mesh.receiveShadow = template.receiveShadow\n mesh.customDepthMaterial = set.depth\n mesh.customDistanceMaterial = set.distance\n group.add(mesh)\n }\n\n // ---- cloth: one swing per soft volume, merged per material -------------------------------------------------------------------\n const cloths = (spec.soft ?? []).filter((s) => s.kind === 'cloth' && parts[s.part ?? s.id] && !skip.has(s.part ?? s.id))\n const clothPart = (s: { id: string; part?: string }) => s.part ?? s.id\n const toggled = new Set<string>()\n for (const i of spec.interactions ?? []) {\n const a = i.action as { do: string; part?: string }\n if (a.do === 'toggle_part' && a.part) toggled.add(a.part)\n }\n const swing = cloths.filter((s) => !toggled.has(clothPart(s)))\n if (swing.length >= 2) {\n const ids = swing.map(clothPart)\n const index: Record<string, number> = {}\n swing.forEach((s, i) => (index[s.id] = i))\n const indexOfPart = new Map(swing.map((s, i) => [clothPart(s), i]))\n const anchorOfPart = new Map(swing.map((s) => [clothPart(s), s.anchor[1]]))\n const n = swing.length\n const uniforms = { time: { value: 0 }, axz: { value: Array.from({ length: n }, () => new THREE.Vector2()) } }\n const groups = take(ids)\n const partIdOf = new Map(groups.map((g, i) => [g, ids[i]]))\n const plan = byMaterial(groups, (g, count) => {\n const id = partIdOf.get(g)!\n return { swayId: new Array(count).fill(indexOf(indexOfPart, id)), swayAnchor: new Array(count).fill(anchorOfPart.get(id) ?? 0) }\n })\n const merged = new THREE.Group() as unknown as MergedGroup\n merged.name = 'merge:cloth'\n const patch = (shader: { uniforms: Record<string, any>; vertexShader: string }): void => {\n shader.uniforms.swayTime = uniforms.time\n shader.uniforms.swayAxz = uniforms.axz\n shader.vertexShader =\n `attribute float swayId;\\nattribute float swayAnchor;\\nuniform float swayTime;\\nuniform vec2 swayAxz[${n}];\\n` +\n shader.vertexShader.replace(\n '#include <begin_vertex>',\n `#include <begin_vertex>\n{\n vec2 swayA = swayAxz[int(swayId + 0.5)];\n float swayHang = max(swayAnchor - position.y, 0.0);\n float swayFlutter = ${amplitude.toFixed(4)} * sin(swayTime * 1.9 + swayId * 1.7 + position.x * 4.0 + position.z * 3.0 + swayHang * 3.0);\n transformed.x += swayHang * (sin(swayA.y) + swayFlutter);\n transformed.z += swayHang * (-sin(swayA.x) + swayFlutter * 0.6);\n transformed.y += swayHang * (1.0 - cos(swayA.y) * cos(swayA.x));\n}`,\n )\n }\n for (const e of plan.values()) {\n const key = String(e.mesh.userData.material)\n const set = patchedSet(THREE, e.base, `swayBatch:${n}:${amplitude}`, patch)\n finishMesh('merge:cloth', key, concat(THREE, e.pieces, { swayId: 1, swayAnchor: 1 }), e.mesh, set, merged)\n }\n const batch: SwayBatch = {\n kind: 'sway',\n index,\n setAt(i, ax, az) {\n uniforms.axz.value[i].set(ax, az)\n },\n setTime(t) {\n uniforms.time.value = t\n },\n }\n merged.userData.merged = batch\n retire(ids, merged)\n for (const id of ids) skip.add(id)\n }\n\n // ---- grouped parts with identical motion (blind slats) -----------------------------------------------------------------------\n const bySignature = new Map<string, string[]>()\n for (const p of spec.parts ?? []) {\n if (!p.group || !parts[p.id] || skip.has(p.id)) continue\n const sig = `${p.group}|${JSON.stringify(p.motion)}`\n const list = bySignature.get(sig)\n if (list) list.push(p.id)\n else bySignature.set(sig, [p.id])\n }\n for (const [sig, ids] of bySignature) {\n if (ids.length < 2) continue\n const motion = (spec.parts ?? []).find((p) => p.id === ids[0])!.motion\n const uniforms = { q: { value: new THREE.Vector4(0, 0, 0, 1) }, pos: { value: new THREE.Vector3() }, scale: { value: new THREE.Vector3(1, 1, 1) } }\n const groups = take(ids)\n const plan = byMaterial(groups, (g, count) => {\n const pv = new Array<number>(count * 3)\n for (let i = 0; i < count; i++) {\n pv[i * 3] = g.position.x\n pv[i * 3 + 1] = g.position.y\n pv[i * 3 + 2] = g.position.z\n }\n return { batchPivot: pv }\n })\n const merged = new THREE.Group() as unknown as MergedGroup\n merged.name = `merge:${sig.split('|')[0]}`\n const patch = (shader: { uniforms: Record<string, any>; vertexShader: string }): void => {\n shader.uniforms.batchQ = uniforms.q\n shader.uniforms.batchPos = uniforms.pos\n shader.uniforms.batchScale = uniforms.scale\n let src = `attribute vec3 batchPivot;\\nuniform vec4 batchQ;\\nuniform vec3 batchPos;\\nuniform vec3 batchScale;\\n${QROT}${shader.vertexShader}`\n src = src.replace('#include <begin_vertex>', '#include <begin_vertex>\\ntransformed = batchPivot + batchRotate(batchQ, (position - batchPivot) * batchScale) + batchPos;')\n src = src.replace('#include <beginnormal_vertex>', '#include <beginnormal_vertex>\\nobjectNormal = batchRotate(batchQ, objectNormal);')\n shader.vertexShader = src\n }\n for (const e of plan.values()) {\n const key = String(e.mesh.userData.material)\n const set = patchedSet(THREE, e.base, 'poseBatch', patch)\n finishMesh(merged.name, key, concat(THREE, e.pieces, { batchPivot: 3 }), e.mesh, set, merged)\n }\n const batch: PoseBatch = {\n kind: 'pose',\n ids,\n apply(m, t) {\n const pose = poseOf(m, t)\n uniforms.q.value.set(pose.quaternion[0], pose.quaternion[1], pose.quaternion[2], pose.quaternion[3])\n uniforms.pos.value.set(pose.position[0], pose.position[1], pose.position[2])\n uniforms.scale.value.set(pose.scale[0], pose.scale[1], pose.scale[2])\n },\n }\n batch.apply(motion, 0)\n merged.userData.merged = batch\n retire(ids, merged)\n }\n}\n\nfunction indexOf(map: Map<string, number>, id: string): number {\n return map.get(id) ?? 0\n}\n","import type { ObjectSpec } from '@adatechnology/game-interactables'\nimport type { CylinderShape, PropItem, Uv } from '@adatechnology/game-props3d'\nimport type { HouseholdApi, MaterialKey, Quality, ThreeLib, ThreeNS, Vec3 } from './types'\nimport { MATERIAL_KEYS } from './types'\nimport { mergeParts } from './merge'\nimport { rememberRest } from './pose'\n\nexport type MaterialMap = Partial<Record<MaterialKey, ThreeNS.Material>>\n\nexport interface MeshApiOptions {\n /** Materials per key. Missing keys get a default (vertex-colored) material. */\n materials?: MaterialMap\n /** `high`: smoother cylinders and spheres, standard materials. `game`: fewer segments, Lambert materials. Default `high`. */\n quality?: Quality\n /** Cast and receive shadows on the merged meshes. Default true. */\n shadows?: boolean\n /** Make `plane` primitives double sided (applies to the default materials only). Default false. */\n doubleSidedPlanes?: boolean\n /**\n * Cut draw calls: `finish(spec)` merges the parts of one `PartSpec.group` that share a motion (blind slats) and the `cloth` soft\n * volumes (clothes on a line) into one mesh per material (see `mergeParts`). Needs the spec in `finish`. Default: on in `game` quality.\n */\n mergeParts?: boolean\n /** Idle flutter of merged cloth. Default 0.04. */\n swayAmplitude?: number\n /**\n * Material of one draw: called per mesh with its material key and the part id (`null` for the static body). Return the material the\n * host wants there (a per-room light mask, a flickering emissive...); the default is `materials[key]`. Merged groups (blind slats,\n * clothes) keep what you return, including its `onBeforeCompile`, `customProgramCacheKey`, `defines` and `userData`.\n */\n materialFor?: (key: MaterialKey, partId: string | null) => ThreeNS.Material | undefined\n}\n\nexport interface MeshResult {\n /** Root group: static meshes (one per material) plus one child group per part (merged parts share one group, see `mergeParts`). */\n group: ThreeNS.Group\n /** Part groups by id. Origin at the pivot, rotated by the part's `ry`; `userData.rest` holds the rest pose. A merged part maps to the shared group (`userData.merged`). */\n parts: Record<string, ThreeNS.Group>\n /** Real lights requested by the builders (already children of their group). */\n lights: ThreeNS.Light[]\n}\n\nexport interface FinishOptions {\n /** Same as `MeshApiOptions.materialFor`; wins over it for this call. */\n materialFor?: MeshApiOptions['materialFor']\n}\n\nexport interface MeshApi {\n api: HouseholdApi\n /** Builds the groups from everything drawn so far. Call once; the api is spent afterwards. Pass the spec the pack returned to allow `mergeParts`. */\n finish(spec?: ObjectSpec, finishOptions?: FinishOptions): MeshResult\n /** Materials in use (defaults merged with the given ones). */\n materials: Record<MaterialKey, ThreeNS.Material>\n}\n\n/** Default materials: vertex colors everywhere (in `game` quality plain, metal, wood and fabric are one shared Lambert material), glass and water transparent, emissive unlit. */\nexport function createDefaultMaterials(THREE: ThreeLib, quality: Quality = 'high'): Record<MaterialKey, ThreeNS.Material> {\n // three warns about every parameter that is present but undefined: only pass the ones that are set\n const defined = <T extends object>(o: T): T => {\n const out = {} as T\n for (const k of Object.keys(o) as Array<keyof T>) if (o[k] !== undefined) out[k] = o[k]\n return out\n }\n const std = (p: ThreeNS.MeshStandardMaterialParameters): ThreeNS.Material =>\n quality === 'game'\n ? new THREE.MeshLambertMaterial(defined({ vertexColors: true, transparent: p.transparent, opacity: p.opacity, depthWrite: p.depthWrite, side: p.side }))\n : new THREE.MeshStandardMaterial(defined({ vertexColors: true, roughness: 0.85, metalness: 0, ...p }))\n // Lambert has no roughness or metalness: in `game` quality the opaque default materials are one and the same instance, so the\n // mesh api (which merges per material instance) draws plain, metal, wood and fabric together\n const solid = quality === 'game' ? std({}) : null\n return {\n plain: solid ?? std({}),\n metal: solid ?? std({ roughness: 0.35, metalness: 0.7 }),\n wood: solid ?? std({ roughness: 0.8 }),\n glass: std({ roughness: 0.05, transparent: true, opacity: 0.35, depthWrite: false }),\n fabric: solid ?? std({ roughness: 1 }),\n plant: std({ roughness: 0.9, side: THREE.DoubleSide }),\n water: std({ roughness: 0.1, transparent: true, opacity: 0.7, depthWrite: false }),\n emissive: new THREE.MeshBasicMaterial({ vertexColors: true }),\n atlas_picture: std({ roughness: 0.9 }),\n atlas_floor: std({ roughness: 1 }),\n }\n}\n\n/** Growing arrays for one (target, material) pair. */\ninterface Acc {\n pos: number[]\n nor: number[]\n col: number[]\n uv: number[]\n idx: number[]\n}\n\ninterface Target {\n id: string | null\n pivot: Vec3\n ry: number\n acc: Map<string, Acc>\n lights: Array<{ x: number; y: number; z: number; color: number; range: number }>\n}\n\ninterface Template {\n pos: Float32Array\n nor: Float32Array\n uv: Float32Array\n idx: ArrayLike<number>\n}\n\nconst IDENT_UV: Uv = { u0: 0, v0: 0, u1: 1, v1: 1 }\n\n/**\n * Mesh api for content packs. Every primitive is baked (vertex colors) into one `BufferGeometry` per material and per target\n * (the root, or a part), so the draw calls are the number of materials in use plus the same again for each part.\n */\nexport function createMeshApi(THREE: ThreeLib, options: MeshApiOptions = {}): MeshApi {\n const quality: Quality = options.quality ?? 'high'\n const shadows = options.shadows !== false\n const materials = { ...createDefaultMaterials(THREE, quality), ...stripUndefined(options.materials) } as Record<MaterialKey, ThreeNS.Material>\n if (options.doubleSidedPlanes) for (const k of MATERIAL_KEYS) materials[k].side = THREE.DoubleSide\n\n const root: Target = { id: null, pivot: [0, 0, 0], ry: 0, acc: new Map(), lights: [] }\n const partTargets = new Map<string, Target>()\n const stack: Target[] = []\n let current = root\n let finished = false\n\n const templates = new Map<string, Template>()\n const template = (key: string, make: () => ThreeNS.BufferGeometry): Template => {\n let t = templates.get(key)\n if (!t) {\n const g = make()\n t = {\n pos: g.getAttribute('position').array as Float32Array,\n nor: g.getAttribute('normal').array as Float32Array,\n uv: g.getAttribute('uv').array as Float32Array,\n idx: g.index ? (g.index.array as ArrayLike<number>) : Array.from({ length: g.getAttribute('position').count }, (_, i) => i),\n }\n templates.set(key, t)\n }\n return t\n }\n const segs = quality === 'high' ? { cyl: 12, sphereW: 12, sphereH: 8 } : { cyl: 8, sphereW: 8, sphereH: 6 }\n const tBox = () => template('box', () => new THREE.BoxGeometry(1, 1, 1))\n const tCyl = (shape: CylinderShape | undefined) => {\n switch (shape) {\n case 'cyl6':\n return template('cyl6', () => new THREE.CylinderGeometry(1, 1, 1, 6))\n case 'cone':\n return template('cone', () => new THREE.CylinderGeometry(0, 1, 1, segs.cyl))\n case 'sphere':\n return template('sphere', () => new THREE.SphereGeometry(1, segs.sphereW, segs.sphereH))\n default:\n return template('cyl', () => new THREE.CylinderGeometry(1, 1, 1, segs.cyl))\n }\n }\n const tPlane = () => template('plane', () => new THREE.PlaneGeometry(1, 1))\n const tLeaf = (): Template => {\n let t = templates.get('leaf')\n if (!t) {\n // diamond in the xy plane, base at the origin, tip at +y; both faces\n const f = [0, 0, 0, -0.5, 0.4, 0, 0.5, 0.4, 0, 0, 1, 0]\n const pos: number[] = []\n const nor: number[] = []\n const uv: number[] = []\n const idx: number[] = []\n for (const side of [1, -1]) {\n const base = pos.length / 3\n for (let i = 0; i < 4; i++) {\n pos.push(f[i * 3], f[i * 3 + 1], f[i * 3 + 2])\n nor.push(0, 0, side)\n uv.push(f[i * 3] + 0.5, f[i * 3 + 1])\n }\n if (side === 1) idx.push(base, base + 2, base + 1, base + 1, base + 2, base + 3)\n else idx.push(base, base + 1, base + 2, base + 1, base + 3, base + 2)\n }\n // winding for the front face: counter clockwise seen from +z\n t = { pos: new Float32Array(pos), nor: new Float32Array(nor), uv: new Float32Array(uv), idx }\n templates.set('leaf', t)\n }\n return t\n }\n\n const m4 = new THREE.Matrix4()\n const mItem = new THREE.Matrix4()\n const mTotal = new THREE.Matrix4()\n const n3 = new THREE.Matrix3()\n const v = new THREE.Vector3()\n const quat = new THREE.Quaternion()\n const euler = new THREE.Euler()\n const scl = new THREE.Vector3()\n const color = new THREE.Color()\n\n /** Keys that share a material instance share the geometry too: the first key stands for all of them. */\n const canonical = new Map<MaterialKey, MaterialKey>()\n for (const k of MATERIAL_KEYS) {\n const first = MATERIAL_KEYS.find((o) => materials[o] === materials[k]) ?? k\n canonical.set(k, first)\n }\n const accOf = (requested: MaterialKey): Acc => {\n const key = canonical.get(requested) ?? requested\n let a = current.acc.get(key)\n if (!a) {\n a = { pos: [], nor: [], col: [], uv: [], idx: [] }\n current.acc.set(key, a)\n }\n return a\n }\n\n /**\n * Item transform (M.x, M.z, M.ry). Inside a part the coordinates are already relative to the pivot (the `HouseholdApi.part`\n * contract: the pack draws in the part frame), so nothing else is applied: the part group supplies pivot and `ry`.\n */\n const frame = (M: PropItem | undefined): ThreeNS.Matrix4 => {\n mItem.makeRotationY(M?.ry ?? 0)\n mItem.setPosition(M?.x ?? 0, 0, M?.z ?? 0)\n return mItem\n }\n\n const emit = (requested: MaterialKey, M: PropItem | undefined, local: ThreeNS.Matrix4, t: Template, hexColor: number, uv?: Uv): void => {\n const key: MaterialKey = requested in materials ? requested : 'plain'\n const a = accOf(key)\n const total = mTotal.copy(frame(M)).multiply(local)\n n3.getNormalMatrix(total)\n const base = a.pos.length / 3\n color.setHex(hexColor)\n const count = t.pos.length / 3\n const e = total.elements\n const nm = n3.elements\n const u = uv ?? IDENT_UV\n for (let i = 0; i < count; i++) {\n const x = t.pos[i * 3]\n const y = t.pos[i * 3 + 1]\n const z = t.pos[i * 3 + 2]\n a.pos.push(e[0] * x + e[4] * y + e[8] * z + e[12], e[1] * x + e[5] * y + e[9] * z + e[13], e[2] * x + e[6] * y + e[10] * z + e[14])\n const nx = t.nor[i * 3]\n const ny = t.nor[i * 3 + 1]\n const nz = t.nor[i * 3 + 2]\n v.set(nm[0] * nx + nm[3] * ny + nm[6] * nz, nm[1] * nx + nm[4] * ny + nm[7] * nz, nm[2] * nx + nm[5] * ny + nm[8] * nz).normalize()\n a.nor.push(v.x, v.y, v.z)\n a.col.push(color.r, color.g, color.b)\n a.uv.push(u.u0 + t.uv[i * 2] * (u.u1 - u.u0), u.v0 + t.uv[i * 2 + 1] * (u.v1 - u.v0))\n }\n for (let i = 0; i < t.idx.length; i++) a.idx.push(base + t.idx[i])\n }\n\n const compose = (x: number, y: number, z: number, rx: number, ry: number, rz: number, sx: number, sy: number, sz: number): ThreeNS.Matrix4 => {\n euler.set(rx, ry, rz, 'YXZ')\n quat.setFromEuler(euler)\n return m4.compose(v.set(x, y, z), quat, scl.set(sx, sy, sz))\n }\n\n const api: HouseholdApi = {\n box(M, material, x, y, z, w, h, d, col, ry, rx, rz) {\n emit(material as MaterialKey, M, compose(x, y + h / 2, z, rx, ry, rz, w, h, d), tBox(), col)\n },\n cylinder(M, material, x, y, z, r, h, col, rx, rz, shape) {\n const tilted = rx !== 0 || rz !== 0\n const cy = shape === 'sphere' ? y + h / 2 : tilted ? y : y + h / 2\n const sy = shape === 'sphere' ? h / 2 : h\n emit(material as MaterialKey, M, compose(x, cy, z, rx, 0, rz, r, sy, r), tCyl(shape), col)\n },\n leaf(M, x, y, z, w, h, col, ry, rx) {\n emit('plant', M, compose(x, y, z, rx, ry, 0, w, h, 1), tLeaf(), col)\n },\n plane(M, material, x, y, z, w, h, col, ry, rx, rz, uv) {\n emit(material as MaterialKey, M, compose(x, y, z, rx, ry, rz, w, h, 1), tPlane(), col, uv)\n },\n light(M, x, y, z, col, range) {\n const fr = frame(M)\n v.set(x, y, z).applyMatrix4(fr)\n current.lights.push({ x: v.x, y: v.y, z: v.z, color: col, range })\n },\n part(id, pivot, ry, draw) {\n let target = partTargets.get(id)\n if (!target) {\n target = { id, pivot: [pivot[0], pivot[1], pivot[2]], ry, acc: new Map(), lights: [] }\n partTargets.set(id, target)\n }\n stack.push(current)\n current = target\n try {\n draw()\n } finally {\n current = stack.pop() ?? root\n }\n },\n }\n\n const build = (target: Target, into: ThreeNS.Group, materialFor: MeshApiOptions['materialFor']): void => {\n for (const [key, a] of target.acc) {\n if (!a.idx.length) continue\n const g = new THREE.BufferGeometry()\n g.setAttribute('position', new THREE.Float32BufferAttribute(a.pos, 3))\n g.setAttribute('normal', new THREE.Float32BufferAttribute(a.nor, 3))\n g.setAttribute('color', new THREE.Float32BufferAttribute(a.col, 3))\n g.setAttribute('uv', new THREE.Float32BufferAttribute(a.uv, 2))\n g.setIndex(a.pos.length / 3 > 65535 ? new THREE.Uint32BufferAttribute(a.idx, 1) : new THREE.Uint16BufferAttribute(a.idx, 1))\n g.computeBoundingSphere()\n g.computeBoundingBox()\n const mesh = new THREE.Mesh(g, materialFor?.(key as MaterialKey, target.id) ?? materials[key as MaterialKey])\n mesh.name = target.id === null ? `static:${key}` : `part:${target.id}`\n if (target.id !== null) mesh.userData.part = target.id\n mesh.userData.material = key\n mesh.castShadow = shadows\n mesh.receiveShadow = shadows\n into.add(mesh)\n }\n for (const l of target.lights) {\n const light = new THREE.PointLight(l.color, 1, l.range)\n light.position.set(l.x, l.y, l.z)\n into.add(light)\n lightsOut.push(light)\n }\n }\n\n const lightsOut: ThreeNS.Light[] = []\n\n return {\n api,\n materials,\n finish(spec, finishOptions) {\n const materialFor = finishOptions?.materialFor ?? options.materialFor\n if (finished) throw new Error('createMeshApi: finish() was already called')\n finished = true\n const group = new THREE.Group()\n group.name = 'interactable'\n const parts: Record<string, ThreeNS.Group> = {}\n build(root, group, materialFor)\n for (const [id, target] of partTargets) {\n const g = new THREE.Group()\n g.name = `part:${id}`\n g.userData.part = id\n g.position.set(target.pivot[0], target.pivot[1], target.pivot[2])\n g.rotation.y = target.ry\n g.updateMatrix()\n build(target, g, materialFor)\n rememberRest(g)\n group.add(g)\n parts[id] = g\n }\n if (spec && (options.mergeParts ?? quality === 'game')) mergeParts(THREE, group, parts, spec, { swayAmplitude: options.swayAmplitude })\n if (spec) tagDestruction(group, parts, spec)\n return { group, parts, lights: lightsOut }\n },\n }\n}\n\n/**\n * Copies the spec's destruction tags onto the objects: `userData.destructionMaterial` (SDK material id) and, on part groups,\n * `userData.destructionPart` (the part id, the key @adatechnology/game-destruction-three binds by), `userData.destructionPiece` and\n * `userData.destructionJoint`. Static meshes get the object default; the meshes of a part get the part's tags.\n * Parts merged into a shared group (blind slats) carry the tags of the first part of the group.\n */\nfunction tagDestruction(group: ThreeNS.Group, parts: Record<string, ThreeNS.Group>, spec: ObjectSpec): void {\n const body = spec.destruction\n const partGroups = new Set<ThreeNS.Object3D>(Object.values(parts))\n if (body) {\n for (const child of group.children) {\n if (!partGroups.has(child) && (child as ThreeNS.Mesh).isMesh) child.userData.destructionMaterial = body.material\n }\n }\n const done = new Set<ThreeNS.Object3D>()\n for (const ps of spec.parts ?? []) {\n const g = parts[ps.id]\n const d = ps.destruction\n if (!g || !d || done.has(g)) continue\n done.add(g)\n for (const o of [g, ...g.children]) {\n if (o !== g && !(o as ThreeNS.Mesh).isMesh) continue\n o.userData.destructionMaterial = d.material\n o.userData.destructionPart = ps.id\n if (d.piece) o.userData.destructionPiece = d.piece\n if (d.joint) o.userData.destructionJoint = d.joint\n }\n }\n}\n\nfunction stripUndefined<T extends object>(o: T | undefined): Partial<T> {\n const out: Partial<T> = {}\n if (o) for (const k of Object.keys(o) as Array<keyof T>) if (o[k] !== undefined) out[k] = o[k]\n return out\n}\n","import type { ThreeLib, ThreeNS, Vec3 } from './types'\n\n/** `Reflector` from `three/examples/jsm/objects/Reflector.js`, passed by the host. */\nexport type ReflectorConstructor = new (geometry: ThreeNS.BufferGeometry, options?: { textureWidth?: number; textureHeight?: number; clipBias?: number; color?: ThreeNS.ColorRepresentation }) => ThreeNS.Mesh\n\nexport interface MirrorOptions {\n /** Without it every mirror shows the env map only. */\n Reflector?: ReflectorConstructor\n /** Cube / equirect env map for the cheap look. */\n envMap?: ThreeNS.Texture | null\n /** Real reflectors alive at once. Default 1. */\n max?: number\n /** Reflector texture size in pixels. Default 512. */\n resolution?: number\n /** Where reflectors are added. Default: the root ancestor of the registered mesh. */\n scene?: ThreeNS.Object3D\n /** Distance in front of the plane, meters. Default 0.001. */\n offset?: number\n /**\n * three's `Reflector` renders the scene again inside the main `render()`, and that nested render resets `renderer.info` when\n * `info.autoReset` is on, so the counters would only show the reflector pass. With `keepInfo` (default true) the reflector adds\n * what was counted before it back, so `renderer.info.render.calls` covers the whole frame. Skipped when `info.autoReset` is off.\n */\n keepInfo?: boolean\n}\n\n/** The mirror entries of `world.mirrors(...)` (only these fields are read). */\nexport interface MirrorCandidate {\n id: string\n center: Vec3\n normal: Vec3\n}\n\nexport interface Mirrors {\n /** Registers the display mesh of a mirror (world id `objectId:mirrorId`). It gets the env-map material. `normal` is the world normal; default: the mesh's +z. */\n register(id: string, mesh: ThreeNS.Mesh, normal?: Vec3): void\n unregister(id: string): void\n /** Activates real reflectors for the nearest facing registered mirrors among `candidates`. Returns the active ids. */\n update(camera: ThreeNS.Camera, candidates: readonly MirrorCandidate[]): string[]\n /** Ids that currently have a real reflector. */\n active(): string[]\n /** The shared env-map material registered meshes use. */\n envMaterial: ThreeNS.Material\n dispose(): void\n}\n\ninterface Entry {\n mesh: ThreeNS.Mesh\n normal: Vec3 | null\n original: ThreeNS.Material | ThreeNS.Material[]\n}\n\ninterface Slot {\n reflector: ThreeNS.Mesh\n id: string | null\n}\n\n/**\n * Mirrors: every registered mirror shows an env-map material; the nearest `max` that face the camera get a real `Reflector`\n * (pooled and reused), placed `offset` in front of the plane with the mesh's rotation and size.\n */\nexport function createMirrors(THREE: ThreeLib, options: MirrorOptions = {}): Mirrors {\n const max = Math.max(0, Math.floor(options.max ?? 1))\n const resolution = options.resolution ?? 512\n const offset = options.offset ?? 0.001\n const envMaterial = new THREE.MeshStandardMaterial({ color: 0xdfe6ea, metalness: 1, roughness: 0.04, envMap: options.envMap ?? null })\n const entries = new Map<string, Entry>()\n const slots: Slot[] = []\n const geometry = new THREE.PlaneGeometry(1, 1)\n\n const worldNormal = (e: Entry, out: ThreeNS.Vector3): ThreeNS.Vector3 => {\n if (e.normal) return out.set(e.normal[0], e.normal[1], e.normal[2]).normalize()\n e.mesh.updateWorldMatrix(true, false)\n return out.set(0, 0, 1).transformDirection(e.mesh.matrixWorld)\n }\n\n const slotFor = (id: string): Slot | null => {\n if (!options.Reflector) return null\n const existing = slots.find((s) => s.id === id)\n if (existing) return existing\n const free = slots.find((s) => s.id === null)\n if (free) return free\n if (slots.length >= max) return null\n const reflector = new options.Reflector(geometry, { textureWidth: resolution, textureHeight: resolution, clipBias: 0.003 })\n reflector.name = 'mirror:reflector'\n if (options.keepInfo !== false) {\n const original = reflector.onBeforeRender\n reflector.onBeforeRender = function (this: ThreeNS.Mesh, renderer, scene, camera, geo, mat, grp) {\n const info = renderer.info\n if (!info.autoReset) return original.call(this, renderer, scene, camera, geo, mat, grp)\n const before = { calls: info.render.calls, triangles: info.render.triangles, points: info.render.points, lines: info.render.lines }\n original.call(this, renderer, scene, camera, geo, mat, grp)\n info.render.calls += before.calls\n info.render.triangles += before.triangles\n info.render.points += before.points\n info.render.lines += before.lines\n }\n }\n reflector.visible = false\n const s: Slot = { reflector, id: null }\n slots.push(s)\n return s\n }\n\n const release = (s: Slot): void => {\n s.id = null\n s.reflector.visible = false\n }\n\n const pos = new THREE.Vector3()\n const quat = new THREE.Quaternion()\n const scl = new THREE.Vector3()\n const n = new THREE.Vector3()\n const toEye = new THREE.Vector3()\n const box = new THREE.Box3()\n const size = new THREE.Vector3()\n const facing = new THREE.Vector3()\n const flip = new THREE.Quaternion(0, 1, 0, 0)\n\n return {\n envMaterial,\n register(id, mesh, normal) {\n const previous = entries.get(id)\n entries.set(id, { mesh, normal: normal ?? null, original: previous ? previous.original : mesh.material })\n mesh.material = envMaterial\n },\n unregister(id) {\n const e = entries.get(id)\n const s = slots.find((x) => x.id === id)\n if (s) release(s)\n if (e) e.mesh.material = e.original\n entries.delete(id)\n },\n update(camera, candidates) {\n const eye = camera.getWorldPosition(toEye)\n const wanted: Array<{ id: string; d: number }> = []\n for (const c of candidates) {\n const e = entries.get(c.id)\n if (!e) continue\n n.set(c.normal[0], c.normal[1], c.normal[2])\n const dx = eye.x - c.center[0]\n const dy = eye.y - c.center[1]\n const dz = eye.z - c.center[2]\n if (n.x * dx + n.y * dy + n.z * dz <= 0) continue\n wanted.push({ id: c.id, d: dx * dx + dy * dy + dz * dz })\n }\n wanted.sort((a, b) => a.d - b.d)\n const chosen = new Set<string>()\n for (let i = 0; i < wanted.length && chosen.size < max; i++) chosen.add(wanted[i].id)\n for (const s of slots) if (s.id !== null && !chosen.has(s.id)) release(s)\n for (const id of chosen) {\n const s = slotFor(id)\n if (!s) continue\n const e = entries.get(id)!\n e.mesh.updateWorldMatrix(true, false)\n e.mesh.matrixWorld.decompose(pos, quat, scl)\n if (!e.mesh.geometry.boundingBox) e.mesh.geometry.computeBoundingBox()\n box.copy(e.mesh.geometry.boundingBox!)\n box.getSize(size)\n worldNormal(e, n)\n s.reflector.position.copy(pos).addScaledVector(n, offset)\n s.reflector.quaternion.copy(quat)\n // a Reflector only renders for a camera in front of its +z: when the registered normal points the other way, turn it around\n if (facing.set(0, 0, 1).applyQuaternion(quat).dot(n) < 0) s.reflector.quaternion.multiply(flip)\n s.reflector.scale.set(Math.max(size.x * scl.x, 1e-3), Math.max(size.y * scl.y, 1e-3), 1)\n s.id = id\n s.reflector.visible = true\n if (!s.reflector.parent) {\n let top: ThreeNS.Object3D = e.mesh\n while (top.parent) top = top.parent\n ;(options.scene ?? top).add(s.reflector)\n }\n }\n return slots.filter((s) => s.id !== null).map((s) => s.id as string)\n },\n active() {\n return slots.filter((s) => s.id !== null).map((s) => s.id as string)\n },\n dispose() {\n for (const s of slots) s.reflector.removeFromParent()\n slots.length = 0\n for (const e of entries.values()) e.mesh.material = e.original\n entries.clear()\n envMaterial.dispose()\n geometry.dispose()\n },\n }\n}\n","import type { CanvasFactory, ThreeLib, ThreeNS } from './types'\n\nexport interface ScreenOptions {\n /** Where the canvas is created (the global `document`, or a fake). */\n document: CanvasFactory\n /** Canvas size in pixels. Default 128 x 72. */\n w?: number\n h?: number\n /** Seed of the static noise. Default 1. */\n seed?: number\n /** Redraws per second while on. Default 15. */\n fps?: number\n /** Emissive strength while on. Default 1. */\n intensity?: number\n}\n\nexport interface Screen {\n material: ThreeNS.MeshStandardMaterial\n texture: ThreeNS.CanvasTexture\n canvas: any\n readonly on: boolean\n readonly channel: number\n setOn(on: boolean): void\n setChannel(channel: number): void\n /** Advance the animation; redraws the canvas at `fps` while on. */\n update(dt: number): void\n dispose(): void\n}\n\nconst BARS = ['#c0c0c0', '#c0c000', '#00c0c0', '#00c000', '#c000c0', '#c00000', '#0000c0']\n\nfunction mulberry(seed: number): () => number {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) >>> 0\n let t = a\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/**\n * A screen material backed by a canvas texture. Off: black canvas, no emission. On: the channel's content (0 color bars,\n * 1 static noise, 2 animated landscape, higher numbers repeat them with shifted hues) lights the surface.\n */\nexport function createScreen(THREE: ThreeLib, options: ScreenOptions): Screen {\n const w = options.w ?? 128\n const h = options.h ?? 72\n const canvas = options.document.createElement('canvas')\n canvas.width = w\n canvas.height = h\n // the canvas is uploaded to the GPU every redraw: tell the browser so it keeps a CPU-backed canvas (no readback warning)\n const ctx = canvas.getContext('2d', { willReadFrequently: true })\n const rand = mulberry(options.seed ?? 1)\n const period = 1 / Math.max(1, options.fps ?? 15)\n const intensity = options.intensity ?? 1\n\n const texture = new THREE.CanvasTexture(canvas)\n texture.colorSpace = THREE.SRGBColorSpace\n const material = new THREE.MeshStandardMaterial({\n color: 0x050505,\n roughness: 0.25,\n metalness: 0,\n map: texture,\n emissive: 0xffffff,\n emissiveMap: texture,\n emissiveIntensity: 0,\n })\n\n let on = false\n let channel = 0\n let clock = 0\n let acc = 0\n\n const fill = (style: string, x: number, y: number, rw: number, rh: number): void => {\n if (!ctx) return\n ctx.fillStyle = style\n ctx.fillRect(x, y, rw, rh)\n }\n\n const drawBars = (): void => {\n const n = BARS.length\n for (let i = 0; i < n; i++) fill(BARS[(i + channel) % n], Math.floor((i * w) / n), 0, Math.ceil(w / n), Math.floor(h * 0.75))\n fill('#101010', 0, Math.floor(h * 0.75), w, h - Math.floor(h * 0.75))\n const x = ((clock * 20) % (w + 12)) - 12\n fill('#ffffff', x, Math.floor(h * 0.8), 12, Math.floor(h * 0.1))\n }\n\n const drawNoise = (): void => {\n const cell = Math.max(2, Math.floor(w / 48))\n for (let y = 0; y < h; y += cell) {\n for (let x = 0; x < w; x += cell) {\n const g = Math.floor(rand() * 220 + 20)\n fill(`rgb(${g},${g},${g})`, x, y, cell, cell)\n }\n }\n }\n\n const drawScene = (): void => {\n const hue = (channel * 40) % 360\n fill(`hsl(${(200 + hue) % 360},60%,${55 + 10 * Math.sin(clock * 0.3)}%)`, 0, 0, w, Math.floor(h * 0.65))\n fill(`hsl(${(110 + hue) % 360},40%,32%)`, 0, Math.floor(h * 0.65), w, h - Math.floor(h * 0.65))\n const sx = (0.5 + 0.4 * Math.sin(clock * 0.5)) * w\n const sy = (0.3 - 0.15 * Math.cos(clock * 0.5)) * h\n fill('#ffe680', sx - 5, sy - 5, 10, 10)\n const bx = (clock * 25) % (w + 16) - 16\n fill('#e03030', bx, Math.floor(h * 0.7), 16, 10)\n }\n\n const draw = (): void => {\n if (!on) {\n fill('#000000', 0, 0, w, h)\n } else if (channel % 3 === 0) {\n drawBars()\n } else if (channel % 3 === 1) {\n drawNoise()\n } else {\n drawScene()\n }\n texture.needsUpdate = true\n }\n\n const apply = (): void => {\n material.emissiveIntensity = on ? intensity : 0\n material.color.setHex(on ? 0x111111 : 0x000000)\n draw()\n }\n apply()\n\n return {\n material,\n texture,\n canvas,\n get on() {\n return on\n },\n get channel() {\n return channel\n },\n setOn(value) {\n on = !!value\n acc = 0\n apply()\n },\n setChannel(n) {\n channel = Math.max(0, Math.floor(n))\n if (on) draw()\n },\n update(dt) {\n if (!on) return\n clock += dt\n acc += dt\n if (acc >= period) {\n acc %= period\n draw()\n }\n },\n dispose() {\n texture.dispose()\n material.dispose()\n },\n }\n}\n","import type { ThreeLib, ThreeNS } from './types'\n\nexport interface SwayOptions {\n /** Strength of the idle flutter (wind) in meters per meter of hang, 0..1. Default 0.04. */\n amplitude?: number\n /** Local y (geometry space) of the line the cloth hangs from. Default: top of the mesh's bounding box. */\n anchorY?: number\n}\n\nexport interface SwayUniforms {\n time: { value: number }\n ax: { value: number }\n az: { value: number }\n anchorY: { value: number }\n}\n\n/** Shared state of one swaying mesh: the three materials read the same uniforms. */\nexport interface SwayHandle {\n uniforms: SwayUniforms\n /** Sets the swing (radians around x and z) and, optionally, the clock for the idle flutter. */\n set(ax: number, az: number, time?: number): void\n}\n\nconst VERTEX_PATCH = /* glsl */ `\n#include <begin_vertex>\n{\n float swayHang = max(swayAnchorY - position.y, 0.0);\n float swayFlutter = swayAmplitude * sin(swayTime * 1.9 + position.x * 4.0 + position.z * 3.0 + swayHang * 3.0);\n transformed.x += swayHang * (sin(swayAz) + swayFlutter);\n transformed.z += swayHang * (-sin(swayAx) + swayFlutter * 0.6);\n transformed.y += swayHang * (1.0 - cos(swayAz) * cos(swayAx));\n}\n`\n\nconst VERTEX_UNIFORMS = /* glsl */ `\nuniform float swayTime;\nuniform float swayAx;\nuniform float swayAz;\nuniform float swayAnchorY;\nuniform float swayAmplitude;\n`\n\n/** Patches a vertex shader so the vertices hang from the anchor line and swing with the shared uniforms. */\nexport function patchSwayShader(shader: { uniforms: Record<string, any>; vertexShader: string }, uniforms: SwayUniforms, amplitude: number): void {\n shader.uniforms.swayTime = uniforms.time\n shader.uniforms.swayAx = uniforms.ax\n shader.uniforms.swayAz = uniforms.az\n shader.uniforms.swayAnchorY = uniforms.anchorY\n shader.uniforms.swayAmplitude = { value: amplitude }\n shader.vertexShader = VERTEX_UNIFORMS + shader.vertexShader.replace('#include <begin_vertex>', VERTEX_PATCH)\n}\n\nfunction patch<M extends ThreeNS.Material>(material: M, uniforms: SwayUniforms, amplitude: number): M {\n const previous = material.onBeforeCompile\n material.onBeforeCompile = (shader, renderer) => {\n previous?.call(material, shader, renderer)\n patchSwayShader(shader, uniforms, amplitude)\n }\n material.customProgramCacheKey = () => `sway:${amplitude}`\n return material\n}\n\n/**\n * Clones `base` and patches it with a vertex-shader sway (uniforms `time`, `ax`, `az`, `anchorY`). The returned material carries\n * `userData.sway` (a `SwayHandle`), `customDepthMaterial` and `customDistanceMaterial` patched with the same uniforms, so\n * directional / spot shadow maps and point-light shadow cubes follow the animation. Assign it to a mesh, and set\n * `mesh.customDepthMaterial` / `mesh.customDistanceMaterial` from the material (or just use `attachSway`).\n */\nexport function swayMaterial(THREE: ThreeLib, base: ThreeNS.Material, options: SwayOptions = {}): ThreeNS.Material & {\n userData: { sway: SwayHandle; depthMaterial: ThreeNS.MeshDepthMaterial; distanceMaterial: ThreeNS.MeshDistanceMaterial }\n} {\n const amplitude = options.amplitude ?? 0.04\n const uniforms: SwayUniforms = { time: { value: 0 }, ax: { value: 0 }, az: { value: 0 }, anchorY: { value: options.anchorY ?? 0 } }\n const handle: SwayHandle = {\n uniforms,\n set(ax, az, time) {\n uniforms.ax.value = ax\n uniforms.az.value = az\n if (time !== undefined) uniforms.time.value = time\n },\n }\n const material = patch(base.clone(), uniforms, amplitude)\n const depth = patch(new THREE.MeshDepthMaterial({ depthPacking: THREE.RGBADepthPacking }), uniforms, amplitude)\n const distance = patch(new THREE.MeshDistanceMaterial(), uniforms, amplitude)\n material.userData.sway = handle\n material.userData.depthMaterial = depth\n material.userData.distanceMaterial = distance\n return material as any\n}\n\n/**\n * Makes a mesh sway: replaces its material with `swayMaterial(...)` and sets `customDepthMaterial` and `customDistanceMaterial`.\n * `mesh.userData.sway` is the handle `syncObject` drives. Returns the handle.\n */\nexport function attachSway(THREE: ThreeLib, mesh: ThreeNS.Mesh, options: SwayOptions = {}): SwayHandle {\n let anchorY = options.anchorY\n if (anchorY === undefined) {\n if (!mesh.geometry.boundingBox) mesh.geometry.computeBoundingBox()\n anchorY = mesh.geometry.boundingBox ? mesh.geometry.boundingBox.max.y : 0\n }\n const base = Array.isArray(mesh.material) ? mesh.material[0] : mesh.material\n const m = swayMaterial(THREE, base, { ...options, anchorY })\n m.userData.sway.uniforms.anchorY.value = anchorY\n mesh.material = m\n mesh.customDepthMaterial = m.userData.depthMaterial\n mesh.customDistanceMaterial = m.userData.distanceMaterial\n mesh.userData.sway = m.userData.sway\n return m.userData.sway\n}\n","import type { Motion, World } from '@adatechnology/game-interactables'\nimport { createEffects, type Effects, type EffectsOptions } from './effects'\nimport { createCord, catenary } from './cord'\nimport { createMeshApi, type MeshApi, type MeshApiOptions } from './mesh'\nimport { createMirrors, type MirrorOptions, type Mirrors } from './mirrors'\nimport { applyPose, syncObject, type SyncOptions } from './pose'\nimport { createScreen, type Screen, type ScreenOptions } from './screen'\nimport { attachSway, swayMaterial, type SwayHandle, type SwayOptions } from './sway'\nimport type { CanvasFactory, Quality, ThreeLib, ThreeNS, Vec3 } from './types'\n\nexport interface ThreeAdapterOptions {\n /** Default for `createMeshApi` / `createScreen` / `createEffects`. */\n document?: CanvasFactory\n quality?: Quality\n materials?: MeshApiOptions['materials']\n /** `Reflector` and env map for `createMirrors`. */\n Reflector?: MirrorOptions['Reflector']\n envMap?: MirrorOptions['envMap']\n}\n\n/** The package functions with `THREE` and the common options already bound. */\nexport interface ThreeAdapter {\n THREE: ThreeLib\n createMeshApi(options?: MeshApiOptions): MeshApi\n applyPose<G extends ThreeNS.Object3D>(group: G, motion: Motion, t: number): G\n syncObject(world: World, objectId: string, parts: Record<string, ThreeNS.Object3D>, options?: SyncOptions): void\n swayMaterial(base: ThreeNS.Material, options?: SwayOptions): ReturnType<typeof swayMaterial>\n attachSway(mesh: ThreeNS.Mesh, options?: SwayOptions): SwayHandle\n createEffects(options: EffectsOptions): Effects\n /** @deprecated Pass `{ scene, camera, ... }`. */\n createEffects(scene: ThreeNS.Object3D, options?: Partial<EffectsOptions>): Effects\n createScreen(options?: Partial<ScreenOptions>): Screen\n createMirrors(options?: MirrorOptions): Mirrors\n createCord(points: readonly Vec3[], radius: number, material: ThreeNS.Material): ThreeNS.Mesh\n catenary: typeof catenary\n}\n\n/** Binds the host's `THREE` (and shared options) once, so the rest of the host code never passes it around. */\nexport function createThreeAdapter(THREE: ThreeLib, options: ThreeAdapterOptions = {}): ThreeAdapter {\n return {\n THREE,\n createMeshApi: (o = {}) => createMeshApi(THREE, { quality: options.quality, materials: options.materials, ...o }),\n applyPose: (group, motion, t) => applyPose(THREE, group, motion, t),\n syncObject: (world, objectId, parts, o) => syncObject(THREE, world, objectId, parts, o),\n swayMaterial: (base, o) => swayMaterial(THREE, base, o),\n attachSway: (mesh, o) => attachSway(THREE, mesh, o),\n createEffects: ((a: EffectsOptions | ThreeNS.Object3D, o: Partial<EffectsOptions> = {}) =>\n (a as ThreeNS.Object3D).isObject3D\n ? createEffects(THREE, a as ThreeNS.Object3D, { document: options.document, ...o })\n : createEffects(THREE, { document: options.document, ...(a as EffectsOptions) })) as ThreeAdapter['createEffects'],\n createScreen: (o = {}) => {\n const document = o.document ?? options.document\n if (!document) throw new Error('createScreen needs a document (option of createThreeAdapter or of the call)')\n return createScreen(THREE, { ...o, document })\n },\n createMirrors: (o = {}) => createMirrors(THREE, { Reflector: options.Reflector, envMap: options.envMap, ...o }),\n createCord: (points, radius, material) => createCord(THREE, points, radius, material),\n catenary,\n }\n}\n","import { catenary, createCord } from '@adatechnology/game-interactables-three'\nimport { buildBeltBox } from './belt-box'\nimport type { AttachmentModel, AttachmentModelBuilder } from './types'\n\n// the pack hangs behind and below the stock, as worn on the back; the belt runs from it to the feed of the weapon\nconst PACK_AT: [number, number, number] = [-0.55, -0.4, 0.1]\nconst PACK_SIZE: [number, number, number] = [0.3, 0.42, 0.2]\nconst BELT_SAG = 0.14\nconst BELT_POINTS = 16\nconst BELT_ROUND_EVERY = 2\n\n/** The ammunition backpack worn on the back and its belt: the pack, the feed box on the weapon (the belt box of the gallery) and the belt of rounds between them on a catenary. */\nexport const buildAmmoBackpack: AttachmentModelBuilder = ({ kit, frame, model }): AttachmentModel => {\n const { THREE, M, box, cylinderZ } = kit\n const group = kit.group()\n const pack: [number, number, number] = [PACK_AT[0] - frame.position[0], PACK_AT[1] - frame.position[1], PACK_AT[2] - frame.position[2]]\n box(group, ...PACK_SIZE, M.olive, ...pack)\n box(group, PACK_SIZE[0] * 1.02, 0.03, PACK_SIZE[2] * 1.02, M.dark, pack[0], pack[1] + PACK_SIZE[1] / 2, pack[2])\n box(group, 0.04, PACK_SIZE[1] * 0.9, 0.012, M.tan, pack[0] + PACK_SIZE[0] / 2, pack[1], pack[2] - 0.04)\n const feed = kit.pivot(group, 0, 0, 0)\n buildBeltBox(kit, feed)\n const points = catenary([pack[0] + PACK_SIZE[0] / 2, pack[1] + PACK_SIZE[1] * 0.3, pack[2]], [0, 0, 0], BELT_SAG, BELT_POINTS)\n const strip = createCord(THREE, points, 0.0035, M.metal)\n group.add(strip)\n points.forEach((point, index) => {\n if (index % BELT_ROUND_EVERY === 0) cylinderZ(group, 0.0045, 0.02, M.brass, point[0], point[1], point[2], 8)\n })\n return {\n object: group,\n ...(model.parts.belt ? { hides: [model.parts.belt] } : {}),\n dispose() {\n strip.geometry.dispose()\n },\n }\n}\n","import type { AttachmentModelBuilder } from './types'\n\nconst RIBS = 4\n\n/** The vertical grip: a clamp on the rail and a ribbed handle hanging from it, as long as the data says. */\nexport const buildForegrip: AttachmentModelBuilder = ({ kit, attachment }) => {\n const { M, box, cylinderY } = kit\n const length = attachment.dims?.length ?? 0.1\n const group = kit.group()\n box(group, 0.045, 0.014, 0.034, M.dark, 0, -0.007, 0)\n cylinderY(group, 0.0135, length, M.poly, 0, -0.014 - length / 2, 0, 14)\n for (let i = 0; i < RIBS; i++) cylinderY(group, 0.0145, 0.004, M.rubber, 0, -0.03 - i * (length / (RIBS + 1)), 0, 14)\n cylinderY(group, 0.0155, 0.01, M.dark, 0, -0.014 - length, 0, 14)\n return group\n}\n","import type { AttachmentModel, AttachmentModelBuilder } from './types'\n\nconst DEFAULT_RANGE = 120\nconst DEFAULT_COLOR = 0xff0000\nconst BEAM_WIDTH = 0.0025\nconst DOT_RADIUS = 0.012\n\n/**\n * The laser sight: a body with an emitter on its rail, a thin beam along the barrel and a dot where it lands. The host measures how far the beam goes (`raycast`, in metres);\n * with no host the beam reaches the range of the data and there is no dot. Off until it is turned on.\n */\nexport const buildLaser: AttachmentModelBuilder = ({ kit, attachment, frame, raycast }): AttachmentModel => {\n const { THREE, M, box, cylinderX } = kit\n const length = attachment.dims?.length ?? 0.08\n const half = (attachment.dims?.diameter ?? 0.025) / 2\n const range = attachment.laser?.range ?? DEFAULT_RANGE\n const color = attachment.laser?.color ?? DEFAULT_COLOR\n const group = kit.group()\n const offset = frame.side === 0 ? { y: -(half + 0.004), z: 0 } : { y: 0, z: frame.side * (half + 0.004) }\n box(group, 0.03, 0.012, 0.028, M.dark, 0, frame.side === 0 ? -0.002 : 0, 0)\n box(group, length, half * 2, half * 2, M.dark, 0, offset.y, offset.z)\n const emitter = new THREE.MeshBasicMaterial({ color: 0x551111 })\n cylinderX(group, half * 0.5, 0.004, emitter, length / 2 + 0.001, offset.y, offset.z, 10)\n const glow = new THREE.MeshBasicMaterial({ color, transparent: true, opacity: 0.7, blending: THREE.AdditiveBlending, depthWrite: false })\n const beam = new THREE.Mesh(new THREE.BoxGeometry(1, BEAM_WIDTH, BEAM_WIDTH), glow)\n const dot = new THREE.Mesh(new THREE.SphereGeometry(DOT_RADIUS, 10, 8), new THREE.MeshBasicMaterial({ color }))\n const front = length / 2 + 0.004\n beam.position.set(front, offset.y, offset.z)\n dot.position.set(front, offset.y, offset.z)\n beam.visible = false\n dot.visible = false\n group.add(beam, dot)\n const origin = new THREE.Vector3()\n const direction = new THREE.Vector3()\n const scale = new THREE.Vector3()\n let isOn = false\n return {\n object: group,\n setOn(on) {\n isOn = on\n emitter.color.setHex(on ? color : 0x551111)\n beam.visible = on\n if (!on) dot.visible = false\n },\n update() {\n if (!isOn) return\n group.updateWorldMatrix(true, false)\n group.getWorldPosition(origin)\n direction.set(1, 0, 0).transformDirection(group.matrixWorld)\n group.getWorldScale(scale)\n const hit = raycast?.(origin, direction, range) ?? null\n const reach = (hit ?? range) / Math.max(scale.x, 1e-6)\n beam.scale.x = reach\n beam.position.x = front + reach / 2\n dot.visible = hit !== null\n dot.position.x = front + reach\n },\n dispose() {\n beam.geometry.dispose()\n dot.geometry.dispose()\n glow.dispose()\n emitter.dispose()\n dot.material.dispose()\n },\n }\n}\n\n","import type { AttachmentModel, AttachmentModelBuilder } from './types'\n\n// candela of the spot: bright enough to read against the room lights at the range of the data\nconst LIGHT_INTENSITY = 150\nconst LENS_GLOW = 3\nconst DEFAULT_CONE_DEG = 30\nconst DEFAULT_RANGE = 60\n\n/**\n * The weapon light: a body with a lens on its rail, and a real `SpotLight` along the barrel with the cone and the range of the data. Off until it is turned on.\n * The spot stays in the scene (visible, at intensity 0) while the light is fitted: toggling it changes the intensity only, because a change in the number of lights makes three.js\n * recompile every lit material. The one recompile happens when the accessory is fitted or removed, which is rare and already takes seconds of work.\n */\nexport const buildLight: AttachmentModelBuilder = ({ kit, attachment, frame }): AttachmentModel => {\n const { THREE, M, box, cylinderX } = kit\n const length = attachment.dims?.length ?? 0.1\n const radius = (attachment.dims?.diameter ?? 0.03) / 2\n const group = kit.group()\n const offset = frame.side === 0 ? { y: -(radius + 0.004), z: 0 } : { y: 0, z: frame.side * (radius + 0.004) }\n box(group, 0.035, 0.012, 0.03, M.dark, 0, frame.side === 0 ? -0.002 : 0, 0)\n cylinderX(group, radius, length, M.dark, 0, offset.y, offset.z, 14)\n cylinderX(group, radius * 1.08, 0.012, M.metal, length / 2 - 0.006, offset.y, offset.z, 14)\n const lens = new THREE.MeshStandardMaterial({ color: 0xfff2c8, roughness: 0.1, metalness: 0.2, emissive: 0xfff2c8, emissiveIntensity: 0 })\n cylinderX(group, radius * 0.82, 0.004, lens, length / 2 + 0.001, offset.y, offset.z, 14)\n const cone = (attachment.light?.coneDeg ?? DEFAULT_CONE_DEG) * (Math.PI / 180)\n const spot = new THREE.SpotLight(0xfff1d0, LIGHT_INTENSITY, attachment.light?.range ?? DEFAULT_RANGE, cone / 2, 0.35, 1.2)\n spot.position.set(length / 2 + 0.01, offset.y, offset.z)\n spot.intensity = 0\n const target = new THREE.Object3D()\n target.position.set(length / 2 + 1, offset.y, offset.z)\n group.add(spot, target)\n spot.target = target\n return {\n object: group,\n setOn(on) {\n spot.intensity = on ? LIGHT_INTENSITY : 0\n lens.emissiveIntensity = on ? LENS_GLOW : 0\n },\n dispose() {\n lens.dispose()\n spot.dispose()\n },\n }\n}\n","import { buildDrum } from './drum'\nimport type { AttachmentModelBuilder } from './types'\n\nconst EXTENSION_FRACTION = 0.5\nconst MAGAZINE_LEAN = 0.08\n\n/** The drum: the gallery's drum magazine in place of the magazine, in the frame of the magazine pivot so that it moves with the reload. */\nexport const buildDrumMagazine: AttachmentModelBuilder = ({ kit, factoryMagazine }) => {\n const group = kit.group()\n buildDrum(kit, group)\n return { object: group, hangsFrom: 'magazine', hides: factoryMagazine }\n}\n\n/** The extended magazine: a longer floor plate joined under the one the weapon has (+50% of the length of a box magazine). */\nexport const buildExtendedMagazine: AttachmentModelBuilder = ({ kit, model }) => {\n const { M, box } = kit\n const length = Math.max(0.1, (model.parts.magDrop ?? 0.16) - 0.03)\n const extension = length * EXTENSION_FRACTION\n const group = kit.group()\n const lean = Math.sin(MAGAZINE_LEAN) * (length + extension / 2)\n box(group, 0.05, extension + 0.004, 0.024, M.dark, lean, -(Math.cos(MAGAZINE_LEAN) * (length + extension / 2)), 0, MAGAZINE_LEAN)\n box(group, 0.056, 0.007, 0.028, M.dark, lean + Math.sin(MAGAZINE_LEAN) * extension / 2, -(Math.cos(MAGAZINE_LEAN) * (length + extension)) - 0.003, 0)\n return { object: group, hangsFrom: 'magazine' }\n}\n\n/** The dual coupler: the magazine of the weapon copied beside it and strapped to it, so the second one is a short reach away. */\nexport const buildDualCoupler: AttachmentModelBuilder = ({ kit, factoryMagazine }) => {\n const { M, box } = kit\n const group = kit.group()\n const spare = kit.group()\n spare.position.set(0, 0, 0.032)\n for (const piece of factoryMagazine) spare.add(piece.clone(true))\n group.add(spare)\n box(group, 0.05, 0.012, 0.04, M.tape, 0, -0.03, 0.016)\n return { object: group, hangsFrom: 'magazine' }\n}\n","import { buildBrake } from './muzzle-brake'\nimport type { AttachmentModelBuilder } from './types'\n\n/** The muzzle brakes by the gallery's drawing (`brake` 1 and 2) and the compensator, a short tube with slots cut in the top. */\nexport const buildMuzzleBrake = (kind: 1 | 2): AttachmentModelBuilder => ({ kit, frame }) => {\n const group = kit.group()\n buildBrake(kit, group, kind, 0, 0, frame.barrelRadius)\n return group\n}\n\nexport const buildCompensator: AttachmentModelBuilder = ({ kit, frame }) => {\n const { M, box, cylinderX } = kit\n const radius = frame.barrelRadius * 1.9\n const length = 0.07\n const group = kit.group()\n cylinderX(group, radius, length, M.dark, -length / 2, 0, 0, 16)\n for (let i = 0; i < 3; i++) box(group, length * 0.14, radius * 0.9, radius * 0.7, M.hole, -length * 0.2 - i * length * 0.25, radius * 0.75, 0)\n return group\n}\n","import type * as THREE_NS from 'three'\nimport { rail, scope } from '../details'\nimport type { AttachmentBuildContext, AttachmentModel, AttachmentModelBuilder } from './types'\n\ninterface OpticLook {\n /** The page's `scope` kind: 1 red dot, 2 short scope, 3 and 4 long scopes. */\n readonly kind: 1 | 2 | 3 | 4\n /** Colour of the lens for the night and thermal sights. */\n readonly lens?: number\n}\n\nconst OPTICS: Readonly<Record<string, OpticLook>> = {\n red_dot: { kind: 1 },\n holographic_sight: { kind: 1 },\n acog_4x: { kind: 2 },\n scope_3_9x: { kind: 3 },\n scope_6_24x: { kind: 4 },\n night_vision_scope: { kind: 3, lens: 0x35ff6a },\n thermal_scope: { kind: 3, lens: 0xff8a3a },\n pso_1: { kind: 2 },\n fixed_scope_10x: { kind: 4 },\n}\n\nconst ADAPTER_LENGTH = 0.1\nconst ADAPTER_BACK = 0.05\n\nconst tinted = (context: AttachmentBuildContext, group: THREE_NS.Group, color: number): THREE_NS.Material => {\n const { THREE, M } = context.kit\n const lens = new THREE.MeshStandardMaterial({ color, roughness: 0.05, metalness: 0.3, transparent: true, opacity: 0.9, emissive: color, emissiveIntensity: 0.6 })\n group.traverse((node) => {\n const mesh = node as THREE_NS.Mesh\n if (mesh.isMesh && mesh.material === M.lens) mesh.material = lens\n })\n return lens\n}\n\n/** An optic by the gallery's `scope(kind)` (the same drawing the rifles ship with), on a short rail when the top of the weapon has none. */\nexport const buildOptic: AttachmentModelBuilder = (context) => {\n const look = OPTICS[context.attachment.model]\n if (!look) return null\n const { kit, frame } = context\n const group = kit.group()\n scope(kit, group, look.kind, 0, 0, 0)\n if (!frame.hasRail && frame.mount === 'rail_top') rail(kit, group, -ADAPTER_BACK, ADAPTER_LENGTH, -0.003, 0, frame.receiverWidth * 0.68)\n if (look.lens === undefined) return group\n const lens = tinted(context, group, look.lens)\n return { object: group, dispose: (): void => lens.dispose() } satisfies AttachmentModel\n}\n\nexport const OPTIC_MODEL_IDS: readonly string[] = Object.keys(OPTICS)\n","import type * as THREE_NS from 'three'\nimport { catenary, createCord } from '@adatechnology/game-interactables-three'\nimport type { AttachmentModel, AttachmentModelBuilder } from './types'\n\nconst SAG = 0.2\nconst STRAP_RADIUS = 0.007\nconst CORD_POINTS = 12\n\n/** The sling: a swivel at each end and a strap hanging between them on a catenary (the cord of the interactables). Positions are relative to the front swivel. */\nexport const buildSling: AttachmentModelBuilder = ({ kit, frame }): AttachmentModel | null => {\n if (!frame.secondary) return null\n const { THREE, M } = kit\n const group = kit.group()\n const rear: [number, number, number] = [frame.secondary[0] - frame.position[0], frame.secondary[1] - frame.position[1], frame.secondary[2] - frame.position[2]]\n const swivels: THREE_NS.Mesh[] = []\n for (const at of [[0, 0, 0], rear] as const) {\n const swivel = kit.torus(group, new THREE.TorusGeometry(0.006, 0.0015, 6, 12), M.metal, at[0], at[1], at[2])\n swivel.rotation.y = Math.PI / 2\n swivels.push(swivel)\n }\n const strap = createCord(THREE, catenary(rear, [0, 0, 0], SAG, CORD_POINTS), STRAP_RADIUS, M.olive)\n group.add(strap)\n return {\n object: group,\n dispose() {\n strap.geometry.dispose()\n for (const swivel of swivels) swivel.geometry.dispose()\n },\n }\n}\n","import type { AttachmentModelBuilder } from './types'\n\nconst BAFFLES = 5\n\n/**\n * A suppressor: a dark tube with baffle rings and a capped end, from the length and diameter of the data. Screwed on the muzzle it goes past it and the muzzle moves to its end;\n * an integral one is the front of the barrel and ends at the muzzle. The oil filter is the improvised one: a rusty can taped on.\n */\nexport const buildSuppressor: AttachmentModelBuilder = ({ kit, attachment, fitted }) => {\n const { M, cylinderX } = kit\n const length = attachment.dims?.length ?? 0.2\n const radius = (attachment.dims?.diameter ?? 0.045) / 2\n const isImprovised = attachment.id === 'oil_filter_suppressor'\n const group = kit.group()\n const middle = fitted.integral === true ? -length / 2 : length / 2\n cylinderX(group, radius, length, isImprovised ? M.rust : M.dark, middle, 0, 0, 18)\n if (isImprovised) {\n for (const along of [0.2, 0.8]) cylinderX(group, radius * 1.04, 0.012, M.tape, middle - length / 2 + length * along, 0, 0, 18)\n cylinderX(group, radius * 0.7, 0.008, M.rustD, middle + length / 2 - 0.004, 0, 0, 14)\n } else {\n for (let i = 0; i < BAFFLES; i++) cylinderX(group, radius * 1.03, 0.004, M.metal, middle - length / 2 + (length * (i + 0.5)) / BAFFLES, 0, 0, 18)\n cylinderX(group, radius * 0.9, 0.006, M.steel, middle - length / 2 + 0.003, 0, 0, 18)\n }\n cylinderX(group, radius * 0.22, 0.004, M.hole, middle + length / 2 + 0.0005, 0, 0, 12)\n return { object: group, ...(fitted.integral === true ? {} : { muzzleOffset: length }) }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit } from '../kit'\nimport type { AttachmentModel, AttachmentModelBuilder } from './types'\n\ninterface LauncherLook {\n /** Radius of the 40 mm tube and how much of the data length it takes. */\n readonly tubeRadius: number\n readonly tubeFraction: number\n /** The housing around the breech: length (along the weapon), height and width. */\n readonly housing: readonly [number, number, number]\n /** The Soviet and the German ones have a muzzle ring and a front grip; the American one a plain tube. */\n readonly hasFrontGrip: boolean\n}\n\nconst LAUNCHERS: Readonly<Record<string, LauncherLook>> = {\n m203: { tubeRadius: 0.0215, tubeFraction: 0.8, housing: [0.1, 0.05, 0.05], hasFrontGrip: false },\n gp_25: { tubeRadius: 0.023, tubeFraction: 0.78, housing: [0.08, 0.055, 0.05], hasFrontGrip: false },\n ag36: { tubeRadius: 0.02, tubeFraction: 0.8, housing: [0.13, 0.06, 0.05], hasFrontGrip: true },\n}\n\nconst drawFixed = (kit: ModelKit, group: THREE_NS.Object3D, look: LauncherLook, length: number): void => {\n const { M, box, cylinderY } = kit\n const [housingLength, housingHeight, housingWidth] = look.housing\n box(group, housingLength, housingHeight, housingWidth, M.dark, housingLength / 2 - 0.02, -look.tubeRadius, 0)\n // the sights and the trigger of the launcher, under the receiver\n box(group, 0.05, 0.004, 0.012, M.metal, housingLength * 0.45, -look.tubeRadius - housingHeight / 2 - 0.004, 0)\n box(group, 0.004, 0.02, 0.008, M.dark, housingLength * 0.6, -look.tubeRadius - housingHeight / 2 - 0.016, 0)\n if (look.hasFrontGrip) {\n cylinderY(group, 0.012, 0.07, M.poly, length * 0.55, -look.tubeRadius - 0.04, 0, 12)\n box(group, 0.04, 0.01, 0.03, M.dark, length * 0.55, -look.tubeRadius - 0.004, 0)\n }\n}\n\n/**\n * A launcher under the barrel, drawn from the primitives of the kit: the housing and trigger on the weapon, and the 40 mm tube in the sliding pivot the reload clip moves\n * (the barrel of the real ones slides forward to open the breech). The muzzle mark `ugl_muzzle` is where the shot flashes.\n */\nexport const buildUnderbarrelLauncher: AttachmentModelBuilder = ({ kit, attachment, slide }): AttachmentModel | null => {\n const look = LAUNCHERS[attachment.model]\n if (!look || !slide) return null\n const { M, cylinderX } = kit\n const length = attachment.dims?.length ?? 0.35\n const fixed = kit.group()\n drawFixed(kit, fixed, look, length)\n const tubeLength = length * look.tubeFraction\n const start = -0.02\n cylinderX(slide, look.tubeRadius, tubeLength, M.metal, start + tubeLength / 2, -look.tubeRadius, 0, 18)\n cylinderX(slide, look.tubeRadius * 1.12, 0.012, M.dark, start + tubeLength - 0.006, -look.tubeRadius, 0, 18)\n cylinderX(slide, look.tubeRadius * 0.7, 0.004, M.hole, start + tubeLength + 0.0005, -look.tubeRadius, 0, 14)\n const muzzle = kit.mark(slide, start + tubeLength + 0.01, -look.tubeRadius, 0)\n muzzle.name = 'ugl_muzzle'\n return {\n object: fixed,\n muzzle,\n dispose() {\n slide.remove(...slide.children)\n },\n }\n}\n","import { buildAmmoBackpack } from './ammo-backpack'\nimport { buildBipodModel } from './bipod'\nimport { buildForegrip } from './foregrip'\nimport { buildLaser } from './laser'\nimport { buildLight } from './light'\nimport { buildDrumMagazine, buildDualCoupler, buildExtendedMagazine } from './magazine'\nimport { buildCompensator, buildMuzzleBrake } from './muzzle-device'\nimport { OPTIC_MODEL_IDS, buildOptic } from './optic'\nimport { buildSling } from './sling'\nimport { buildSuppressor } from './suppressor'\nimport { buildTripod } from './tripod'\nimport type { AttachmentModelRegistry } from './types'\nimport { buildUnderbarrelLauncher } from './ugl'\n\n/**\n * The model of each accessory by `AttachmentDef.model`. The ports of the gallery (optics, bipod, brakes, drum, belt box, rail) draw what the page draws; the others are creations of the\n * kit. Accessories without a model (the barrel swaps, the integral optics the weapon already draws) are simply not drawn.\n */\nexport const ATTACHMENT_MODELS: AttachmentModelRegistry = {\n ...Object.fromEntries(OPTIC_MODEL_IDS.map((id) => [id, buildOptic])),\n bipod: buildBipodModel,\n muzzle_brake: buildMuzzleBrake(1),\n muzzle_brake_heavy: buildMuzzleBrake(2),\n compensator: buildCompensator,\n suppressor: buildSuppressor,\n oil_filter_suppressor: buildSuppressor,\n integral_suppressor: buildSuppressor,\n vertical_grip: buildForegrip,\n weapon_light: buildLight,\n laser_sight: buildLaser,\n m203: buildUnderbarrelLauncher,\n gp_25: buildUnderbarrelLauncher,\n ag36: buildUnderbarrelLauncher,\n ammo_backpack: buildAmmoBackpack,\n tripod: buildTripod,\n sling: buildSling,\n drum_magazine: buildDrumMagazine,\n extended_magazine: buildExtendedMagazine,\n dual_coupler: buildDualCoupler,\n}\n","import type * as THREE_NS from 'three'\nimport type { AttachmentDef, FittedAttachment } from '@adatechnology/game-weapons'\nimport type { WeaponModel } from '../index'\nimport type { ModelKit } from '../kit'\nimport { mountFrame } from './mount-frames'\nimport { ATTACHMENT_MODELS } from './registry'\nimport type { AttachmentModel, AttachmentModelRegistry, LaserRaycast } from './types'\n\nexport interface FitAttachmentOptions {\n /** The accessories of the game by id: where each gets its `model`, size and light or laser. */\n readonly catalogue: ReadonlyMap<string, AttachmentDef>\n /** Builders that replace or add to the ones the kit ships (see `ATTACHMENT_MODELS`). */\n readonly overrides?: AttachmentModelRegistry\n /** How far the laser beam goes, asked every frame. */\n readonly raycast?: LaserRaycast\n /** Asked every frame: false hides the models of the accessories the rig drew (the bench layer). */\n readonly isDrawn?: () => boolean\n /** Asked every frame: false puts the light and laser out whatever they are set to (the bench layer for the beams). */\n readonly areBeamsOn?: () => boolean\n}\n\n/** The accessories drawn on one model: it follows the list of fitted parts. */\nexport interface AttachmentRig {\n /** Puts the models of what is fitted on the weapon and takes the others off: shows or hides what ships on it, switches the lights and lasers. */\n sync(fitted: readonly FittedAttachment[]): void\n /** Call every frame. */\n update(): void\n /** Ids of the accessories that have a model on the weapon now. */\n readonly drawn: readonly string[]\n dispose(): void\n}\n\ninterface Drawn {\n readonly model: AttachmentModel\n readonly mount: string\n}\n\nconst toModel = (made: AttachmentModel | THREE_NS.Object3D): AttachmentModel => ('object' in made ? made : { object: made })\n\n/** The factory flash hider sits where a muzzle device screws on: it is not drawn under one. */\nconst MUZZLE_DEFAULT = 'muzzle_default'\n\n/**\n * Draws the accessories of `fitted` on the model: the ones the builder drew with the weapon (`parts.fittings`) show or hide with the list, the others are built by the registry\n * (`overrides` over `ATTACHMENT_MODELS`) at the frame of their mount and hang from the wrapper (not from `inner`, whose stretch to the real length would stretch them).\n */\nexport function fitAttachmentModels(model: WeaponModel, fitted: readonly FittedAttachment[], kit: ModelKit, options: FitAttachmentOptions): AttachmentRig {\n const registry: AttachmentModelRegistry = { ...ATTACHMENT_MODELS, ...options.overrides }\n const { parts, root, inner } = model\n const factoryMagazine = parts.mag ? [...parts.mag.children] : []\n const muzzleRest = parts.muzzle ? parts.muzzle.position.x : 0\n const drawn = new Map<string, Drawn>()\n const hiddenBy = new Map<THREE_NS.Object3D, Set<string>>()\n const switchedOn = new Map<string, boolean>()\n\n const hide = (id: string, objects: readonly THREE_NS.Object3D[]): void => {\n for (const object of objects) {\n const owners = hiddenBy.get(object) ?? new Set<string>()\n owners.add(id)\n hiddenBy.set(object, owners)\n object.visible = false\n }\n }\n const unhide = (id: string, objects: readonly THREE_NS.Object3D[]): void => {\n for (const object of objects) {\n const owners = hiddenBy.get(object)\n owners?.delete(id)\n if (!owners || owners.size === 0) {\n hiddenBy.delete(object)\n object.visible = true\n }\n }\n }\n const take = (id: string): void => {\n const entry = drawn.get(id)\n if (!entry) return\n drawn.delete(id)\n switchedOn.delete(id)\n entry.model.object.removeFromParent()\n unhide(id, entry.model.hides ?? [])\n if (parts.uglMuzzle && entry.model.muzzle === parts.uglMuzzle) delete parts.uglMuzzle\n entry.model.dispose?.()\n }\n const place = (part: FittedAttachment, attachment: AttachmentDef): void => {\n const builder = registry[attachment.model] ?? registry[attachment.id]\n const frame = mountFrame(model, part.mount as Parameters<typeof mountFrame>[1])\n if (!builder || !frame) return\n const made = builder({ kit, model, attachment, fitted: part, frame, raycast: options.raycast, factoryMagazine, slide: parts.ugl })\n if (!made) return\n const entry = toModel(made)\n const parent = entry.hangsFrom === 'magazine' && parts.mag ? parts.mag : root\n if (parent === root) entry.object.position.set(...frame.position)\n parent.add(entry.object)\n hide(attachment.id, entry.hides ?? [])\n if (entry.muzzle) parts.uglMuzzle = entry.muzzle\n drawn.set(attachment.id, { model: entry, mount: part.mount })\n }\n\n const shine = (): void => {\n const isDrawn = options.isDrawn?.() ?? true\n const beams = options.areBeamsOn?.() ?? true\n for (const [id, entry] of drawn) {\n entry.model.object.visible = isDrawn\n entry.model.setOn?.(beams && switchedOn.get(id) === true)\n }\n }\n\n const sync = (list: readonly FittedAttachment[]): void => {\n const wanted = new Map(list.map((part) => [part.id, part]))\n for (const id of [...drawn.keys()]) if (!wanted.has(id) || drawn.get(id)?.mount !== wanted.get(id)?.mount) take(id)\n for (const [id, objects] of Object.entries(parts.fittings ?? {})) {\n if (id === MUZZLE_DEFAULT) continue\n for (const object of objects) object.visible = wanted.has(id)\n }\n for (const object of parts.fittings?.[MUZZLE_DEFAULT] ?? []) object.visible = !list.some((part) => part.mount === 'muzzle')\n for (const part of list) {\n const attachment = options.catalogue.get(part.id)\n if (!attachment || drawn.has(part.id) || parts.fittings?.[part.id]) continue\n if (part.integral === true && attachment.kind === 'optic') continue\n place(part, attachment)\n }\n for (const id of drawn.keys()) switchedOn.set(id, wanted.get(id)?.on === true)\n shine()\n if (parts.muzzle) parts.muzzle.position.x = muzzleRest + [...drawn.values()].reduce((sum, entry) => sum + (entry.model.muzzleOffset ?? 0), 0) / inner.scale.x\n }\n\n sync(fitted)\n return {\n sync,\n update() {\n shine()\n for (const entry of drawn.values()) entry.model.update?.()\n },\n get drawn() {\n return [...drawn.keys()]\n },\n dispose() {\n for (const id of [...drawn.keys()]) take(id)\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponModel } from '../index'\nimport { mountFrame } from './mount-frames'\n\nconst LAUNCHER_INTERFACES: ReadonlySet<string> = new Set(['m203', 'gp25', 'ag36'])\n\n/**\n * After the model is built: when the weapon has a place for a launcher under the barrel, adds the empty pivot `ugl` there. The reload clip slides it (the tube of the launcher is drawn\n * inside it when one is fitted); done after the build so that the model the golden hashes is the one the builder made.\n */\nexport function rigUnderbarrel(THREE: typeof THREE_NS, model: WeaponModel, def: Pick<WeaponDef, 'mounts'>): void {\n const place = def.mounts?.find((mount) => mount.kind === 'underbarrel' && mount.interfaces.some((name) => LAUNCHER_INTERFACES.has(name)))\n const frame = place ? mountFrame(model, 'underbarrel') : undefined\n if (!frame) return\n const pivot = new THREE.Group()\n pivot.name = 'ugl'\n pivot.position.set(...frame.position)\n model.root.add(pivot)\n model.parts.ugl = pivot\n}\n","import type * as THREE_NS from 'three'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponModel } from './index'\nimport type { StockMove } from './types'\n\nconst FOLD_AXIS_BY_SIDE: Readonly<Record<string, 'x' | 'y' | 'z'>> = { right: 'y', left: 'y', under: 'z', over: 'z' }\n\n/** Where the hinge of a folding stock sits: at the rear of the receiver, on the side the rule folds it to (z is to the right), under it or over it. */\nconst hingeOf = (model: WeaponModel, side: string): [number, number, number] => {\n const frames = model.parts.frames\n const x = frames?.receiverStart ?? 0\n const halfWidth = (frames?.receiverWidth ?? 0.034) / 2\n const halfHeight = (frames?.receiverHeight ?? 0.06) / 2\n if (side === 'right') return [x, 0, halfWidth]\n if (side === 'left') return [x, 0, -halfWidth]\n if (side === 'under') return [x, -halfHeight, 0]\n return [x, halfHeight, 0]\n}\n\n/**\n * After the model is built: puts the stock the builder drew into one pivot named `stock`, so that the clips can fold it (a half turn about the side of the rule's `foldAxis`)\n * or slide it in (`dimensions.length - lengthCollapsed`). Done after the build so that the model the golden hashes is the one the builder made. A weapon whose stock does not move is left alone.\n */\nexport function rigStock(THREE: typeof THREE_NS, model: WeaponModel, def: Pick<WeaponDef, 'stock' | 'dimensions'>): void {\n const stock = def.stock\n const meshes = model.parts.stockMeshes\n if (!stock || stock.kind === 'fixed' || stock.kind === 'none' || !meshes || meshes.length === 0) return\n const isFolding = stock.kind === 'fold' || stock.kind === 'fold_retract'\n const side = stock.foldAxis ?? 'right'\n const hinge = isFolding ? hingeOf(model, side) : ([0, 0, 0] as [number, number, number])\n const pivot = new THREE.Group()\n pivot.name = 'stock'\n pivot.position.set(...hinge)\n model.inner.add(pivot)\n model.inner.updateMatrixWorld(true)\n for (const mesh of meshes) pivot.attach(mesh)\n const dimensions = def.dimensions\n const travel = dimensions?.lengthCollapsed === undefined ? 0 : (dimensions.length - dimensions.lengthCollapsed) / model.inner.scale.x\n const move: StockMove = isFolding ? { kind: 'fold', axis: FOLD_AXIS_BY_SIDE[side] ?? 'y', travel } : { kind: 'retract', axis: 'x', travel }\n model.parts.stock = pivot\n model.parts.stockMove = move\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit } from './kit'\nimport type { WeaponModel } from './index'\n\ntype Substitution = ReadonlyMap<THREE_NS.Material, THREE_NS.Material>\n\n/** The paint of worn metal by the rule's condition id (`new` and `used` keep the factory finish): the page's `applyQuality`, with its four steps named like the rule's. */\nconst substitutions = (kit: ModelKit, condition: string): Substitution | null => {\n const { M } = kit\n if (condition === 'rusty')\n return new Map<THREE_NS.Material, THREE_NS.Material>([\n [M.metal, M.rust],\n [M.dark, M.rustD],\n [M.steel, M.rust],\n [M.steelL, M.rust],\n ])\n if (condition === 'worn')\n return new Map<THREE_NS.Material, THREE_NS.Material>([\n [M.metal, M.worn],\n [M.dark, M.worn],\n ])\n return null\n}\n\n/** Dresses the model for how worn the weapon is. The first call keeps the finish each mesh came with, so any condition can be put back. */\nexport function applyCondition(kit: ModelKit, model: WeaponModel, condition: string): void {\n const replacement = substitutions(kit, condition)\n const glowing = new Set<THREE_NS.Object3D>(model.parts.glow)\n const paint = condition === 'rusty' ? kit.M.rust.color : condition === 'worn' ? kit.M.worn.color : undefined\n model.root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh) return\n mesh.userData.baseMaterial ??= mesh.material\n const base = mesh.userData.baseMaterial as THREE_NS.Material\n if (glowing.has(mesh)) {\n const material = mesh.material as THREE_NS.MeshStandardMaterial\n mesh.userData.baseColor ??= material.color.clone()\n material.color.copy(paint ?? (mesh.userData.baseColor as THREE_NS.Color))\n return\n }\n mesh.material = replacement?.get(base) ?? base\n })\n}\n","import type * as THREE from 'three'\nimport type { CaliberDef, CartridgeDims } from '@adatechnology/game-weapons'\nimport type { ModelKit } from './kit'\n\n/** The shapes the gallery draws: rimfire, straight rimless (`p`), straight rimmed (`rimp`), bottleneck rimless (`r`), bottleneck rimmed (`rr`) and shotgun shell. */\nexport type CartridgeShape = 'shell' | 'rim' | 'p' | 'rimp' | 'r' | 'rr'\n\n// a bottleneck case narrows to less than this fraction of its diameter at the bullet\nconst BOTTLENECK_RATIO = 0.8\n\n/** The gallery's cartridge type of a calibre, from its case type, rim and dimensions. */\nexport function cartridgeShape(caliber: Pick<CaliberDef, 'caseType' | 'rim'>, dims: CartridgeDims): CartridgeShape {\n if (caliber.caseType === 'shell' || caliber.rim === 'shell') return 'shell'\n if (caliber.rim === 'rimfire') return 'rim'\n const isRimmed = caliber.rim === 'rimmed'\n const isBottleneck = dims.projectileDiameter / dims.caseDiameter < BOTTLENECK_RATIO\n if (isBottleneck) return isRimmed ? 'rr' : 'r'\n return isRimmed ? 'rimp' : 'p'\n}\n\n/** Port of the gallery's `cartridge`: the round standing on its base, in millimetres (the gallery shows it enlarged), brass case and copper or lead bullet. */\nexport function buildCartridge(kit: ModelKit, dims: CartridgeDims, shape: CartridgeShape): THREE.Group {\n const { M, cylinderY } = kit\n const group = kit.group()\n const radius = dims.caseDiameter / 2\n const bulletRadius = dims.projectileDiameter / 2\n const caseLength = dims.caseLength\n if (shape === 'shell') {\n cylinderY(group, radius, caseLength * 0.8, M.shell, 0, caseLength * 0.6, 0, 14)\n cylinderY(group, radius * 1.03, caseLength * 0.22, M.brass, 0, caseLength * 0.11, 0, 14)\n cylinderY(group, radius * 1.08, 1.2, M.brass, 0, 0.6, 0, 14)\n return group\n }\n if (shape === 'rim' || shape === 'rimp' || shape === 'rr') cylinderY(group, radius * 1.15, 1.2, M.brass, 0, 0.6, 0, 14)\n const extra = dims.overallLength - caseLength\n if (shape === 'r' || shape === 'rr') {\n const bodyHeight = caseLength * 0.78\n const shoulder = caseLength * 0.08\n const neck = caseLength - bodyHeight - shoulder\n const neckRadius = bulletRadius + 0.35\n cylinderY(group, radius, bodyHeight, M.brass, 0, bodyHeight / 2, 0, 14)\n cylinderY(group, neckRadius, shoulder, M.brass, 0, bodyHeight + shoulder / 2, 0, 14, radius)\n cylinderY(group, neckRadius, neck, M.brass, 0, bodyHeight + shoulder + neck / 2, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.3, M.copper, 0, caseLength + extra * 0.15, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.7, M.copper, 0, caseLength + extra * 0.3 + extra * 0.35, 0, 14, bulletRadius * 0.12)\n return group\n }\n const bullet = shape === 'rim' || shape === 'rimp' ? M.lead : M.copper\n cylinderY(group, radius, caseLength, M.brass, 0, caseLength / 2, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.45, bullet, 0, caseLength + extra * 0.225, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.55, bullet, 0, caseLength + extra * 0.45 + extra * 0.275, 0, 14, bulletRadius * 0.45)\n return group\n}\n\n/** An empty case in metres, lying along x with the base at the origin: the brass the weapon throws out. */\nexport function buildCasing(kit: ModelKit, dims: CartridgeDims, shape: CartridgeShape): { group: THREE.Group; radius: number; length: number } {\n const { M, cylinderX } = kit\n const group = kit.group()\n const radius = dims.caseDiameter / 2000\n const length = dims.caseLength / 1000\n if (shape === 'shell') {\n const scale = length / 0.07\n cylinderX(group, 0.0105 * scale, 0.05 * scale, M.shell, 0.008 * scale, 0, 0, 14)\n cylinderX(group, 0.011 * scale, 0.016 * scale, M.brass, -0.025 * scale, 0, 0, 14)\n return { group, radius: 0.0105 * scale, length }\n }\n if (shape === 'r' || shape === 'rr') {\n cylinderX(group, radius, length * 0.75, M.brass, -length * 0.12, 0, 0, 12)\n cylinderX(group, radius * 0.62, length * 0.25, M.brass, length * 0.37, 0, 0, 12, radius * 0.55)\n } else cylinderX(group, radius, length, M.brass, 0, 0, 0, 12)\n return { group, radius, length }\n}\n\n/** A live round in metres, lying along x with the base at the origin: what is loaded into a weapon and what a clear throws out. */\nexport function buildRound(kit: ModelKit, dims: CartridgeDims, shape: CartridgeShape): { group: THREE.Group; radius: number } {\n const group = kit.group()\n const cartridge = buildCartridge(kit, dims, shape)\n cartridge.scale.setScalar(0.001)\n cartridge.rotation.z = -Math.PI / 2\n group.add(cartridge)\n return { group, radius: dims.caseDiameter / 2000 }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit } from '../models/kit'\nimport type { Particles } from './particles'\n\nconst PI = Math.PI\n\n/** Flash size by case: shells flash biggest, rimfire smallest (the page's `flashK`). */\nexport const FLASH_BY_CASE = { shell: 1.6, big: 2.6, tiny: 0.5, pistol: 0.8, rifle: 1.2 } as const\n\nexport interface Effects {\n /** The muzzle flash at `position` pointing along `orientation`, with six puffs of smoke. */\n muzzleFlash(position: THREE_NS.Vector3, orientation: THREE_NS.Quaternion, size: number): void\n /** A puff that rises, grows and fades. */\n smoke(position: THREE_NS.Vector3, velocity: THREE_NS.Vector3, size: number, life: number, opacity: number): void\n update(dt: number): void\n dispose(): void\n}\n\nconst FLASH_SECONDS = 0.055\n\n/** The gallery's muzzle flash: a cone, four small cones and a core, additive, over 55 ms, with a short light. */\nexport function createEffects(kit: ModelKit, scene: THREE_NS.Object3D, particles: Particles, random: () => number): Effects {\n const { THREE, M } = kit\n const light = new THREE.PointLight(0xffb060, 0, 3, 2)\n scene.add(light)\n let flash: { group: THREE_NS.Group; age: number } | null = null\n\n const buildFlash = (size: number): THREE_NS.Group => {\n const group = new THREE.Group()\n const cone = new THREE.Mesh(new THREE.ConeGeometry(0.013 * size, 0.085 * size, 10, 1, true), M.flashA)\n cone.rotation.z = -PI / 2\n cone.position.x = 0.042 * size\n group.add(cone)\n for (let i = 0; i < 4; i++) {\n const angle = (i * PI) / 2 + random() * 0.6\n const spike = new THREE.Mesh(new THREE.ConeGeometry(0.005 * size, 0.04 * size, 6), M.flashA)\n spike.position.set(0.012 * size, Math.cos(angle) * 0.016 * size, Math.sin(angle) * 0.016 * size)\n spike.rotation.set(angle, 0, 0)\n spike.rotateZ(-PI / 2)\n group.add(spike)\n }\n const core = new THREE.Mesh(new THREE.SphereGeometry(0.016 * size, 12, 8), M.flashB)\n core.position.x = 0.008 * size\n group.add(core)\n return group\n }\n\n const endFlash = (): void => {\n if (!flash) return\n flash.group.removeFromParent()\n flash.group.traverse((child) => {\n const mesh = child as THREE_NS.Mesh\n if (mesh.isMesh) mesh.geometry.dispose()\n })\n flash = null\n light.intensity = 0\n }\n\n const effects: Effects = {\n muzzleFlash(position, orientation, size) {\n endFlash()\n const group = buildFlash(size)\n group.position.copy(position)\n group.quaternion.copy(orientation)\n group.rotateX(random() * PI)\n scene.add(group)\n flash = { group, age: 0 }\n light.position.copy(position)\n light.intensity = 4 * size\n light.distance = 2 * size\n for (let i = 0; i < 6; i++) {\n const velocity = new THREE.Vector3(0.15 + random() * 0.35, 0.03 + random() * 0.12, (random() - 0.5) * 0.14).applyQuaternion(orientation)\n effects.smoke(position, velocity, 0.013 * size, 1.3 + random() * 0.6, 0.45)\n }\n },\n smoke(position, velocity, size, life, opacity) {\n const puff = new THREE.Mesh(new THREE.SphereGeometry(size, 10, 8), M.smokeP.clone())\n puff.position.copy(position)\n particles.spawn(puff, velocity, { gravity: -0.08, life, fadeFrom: opacity, grow: 2.1, drag: 2.2, radius: -1, ownsGeometry: true })\n },\n update(dt) {\n if (!flash) return\n flash.age += dt\n flash.group.scale.setScalar(0.6 + Math.min(1, flash.age / FLASH_SECONDS) * 0.9)\n if (flash.age >= FLASH_SECONDS) endFlash()\n },\n dispose() {\n endFlash()\n light.removeFromParent()\n light.dispose()\n },\n }\n return effects\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit } from '../models/kit'\nimport type { ModelParts } from '../models/types'\nimport { buildFlyingRocket } from '../models/launcher-rounds'\nimport type { Effects } from './effects'\nimport type { Particles } from './particles'\n\nconst PI = Math.PI\n\n/** What the launchers' and flamethrowers' effects need from the viewmodel. */\nexport interface HeavyContext {\n kit: ModelKit\n scene: THREE_NS.Object3D\n particles: Particles\n effects: Effects\n random: () => number\n parts: ModelParts\n /** Weapon forward in the world, and the world position of a part. */\n forward(): THREE_NS.Vector3\n positionOf(part: THREE_NS.Object3D): THREE_NS.Vector3\n orientation(): THREE_NS.Quaternion\n /** Runs `step(progress)` every frame for `seconds`, then `done`. */\n every(seconds: number, step: (progress: number, dt: number) => void, done?: () => void): void\n groundAt(x: number, z: number): number\n}\n\nconst flameMaterials = (kit: ModelKit): THREE_NS.MeshBasicMaterial[] => {\n const { THREE } = kit\n return [\n new THREE.MeshBasicMaterial({ color: 0xff7a22, transparent: true, opacity: 0.9, depthWrite: false }),\n new THREE.MeshBasicMaterial({ color: 0xffc040, transparent: true, opacity: 0.9, depthWrite: false }),\n new THREE.MeshBasicMaterial({ color: 0xc8361a, transparent: true, opacity: 0.8, depthWrite: false }),\n new THREE.MeshBasicMaterial({ color: 0xfff0b0, transparent: true, opacity: 0.9, blending: THREE.AdditiveBlending, depthWrite: false }),\n ]\n}\n\nconst spread = (context: HeavyContext, x: number, y: number, z: number): THREE_NS.Vector3 =>\n new context.kit.THREE.Vector3((context.random() - 0.5) * x, (context.random() - 0.5) * y, (context.random() - 0.5) * z)\n\n/** The gallery's `flameBit` and `smokeBit`, which the rocket's backblast and the flame jet share. */\nfunction createBits(context: HeavyContext): { flame(position: THREE_NS.Vector3, velocity: THREE_NS.Vector3, size: number, life: number): void; smoke(position: THREE_NS.Vector3, velocity: THREE_NS.Vector3, size: number, life: number, opacity: number): void; dispose(): void } {\n const { kit, particles, random } = context\n const { THREE } = kit\n const palette = flameMaterials(kit)\n return {\n flame(position, velocity, size, life) {\n const bit = new THREE.Mesh(new THREE.IcosahedronGeometry(size, 1), (palette[Math.floor(random() * 4)] as THREE_NS.Material).clone())\n bit.position.copy(position)\n bit.rotation.set(random() * 3, random() * 3, 0)\n particles.spawn(bit, velocity, { gravity: -1.4, life, fadeFrom: 0.9, grow: 2.2, drag: 1.4, radius: -1, spin: new THREE.Vector3(3, 4, 2), ownsGeometry: true })\n },\n smoke(position, velocity, size, life, opacity) {\n context.effects.smoke(position, velocity, size, life, opacity)\n },\n dispose: () => palette.forEach((material) => material.dispose()),\n }\n}\n\n/** A rocket leaving the tube: backblast smoke and fire at the rear, then the round flying out along the barrel, gaining speed, with a trail. */\nexport function launchRocket(context: HeavyContext): void {\n const { kit, scene, parts, random } = context\n const { THREE } = kit\n const bits = createBits(context)\n const forward = context.forward()\n const muzzle = context.positionOf(parts.muzzle as THREE_NS.Object3D)\n const rear = context.positionOf(parts.rear as THREE_NS.Object3D)\n for (let i = 0; i < 26; i++) bits.smoke(rear.clone(), forward.clone().multiplyScalar(-(1.5 + random() * 3)).add(spread(context, 1.4, 0.8, 1.4)), 0.03 + random() * 0.03, 1.8 + random() * 1.4, 0.5)\n for (let i = 0; i < 14; i++) bits.flame(rear.clone(), forward.clone().multiplyScalar(-(2 + random() * 2)).add(spread(context, 1, 0.6, 1)), 0.02, 0.25)\n const rocket = parts.makeRound ? parts.makeRound() : buildFlyingRocket(kit, parts.launcherType)\n if (parts.round) parts.round.visible = false\n rocket.quaternion.copy(context.orientation())\n rocket.position.copy(muzzle)\n scene.add(rocket)\n const exhaust = new THREE.Mesh(new THREE.ConeGeometry(0.018, 0.12, 8, 1, true), new THREE.MeshBasicMaterial({ color: 0xffc040, transparent: true, opacity: 0.9, depthWrite: false }))\n exhaust.rotation.z = PI / 2\n exhaust.position.x = -0.08\n rocket.add(exhaust)\n const light = new THREE.PointLight(0xff9a40, 3, 2.5)\n rocket.add(light)\n context.every(\n 1.6,\n (progress, dt) => {\n const flight = progress * 1.6\n const distance = 1.2 * flight + (flight > 0.25 ? 9 * (flight - 0.25) ** 2 : 0)\n rocket.position.copy(muzzle).addScaledVector(forward, distance)\n rocket.rotation.x += 0.25 * dt * 60\n exhaust.scale.set(1, 0.6 + random() * 0.8, 1)\n if (random() < 0.9) bits.smoke(rocket.position.clone().addScaledVector(forward, -0.12), spread(context, 0.1, 0, 0.1).setY(0.05), 0.02 + random() * 0.015, 2.2, 0.5)\n },\n () => {\n rocket.removeFromParent()\n exhaust.geometry.dispose()\n ;(exhaust.material as THREE_NS.Material).dispose()\n light.dispose()\n bits.dispose()\n },\n )\n}\n\n/** A second of flame from the nozzle: bits of fire thrown forward and up, smoke downwind and burning droplets that light the ground where they land. */\nexport function flameJet(context: HeavyContext, dt: number, scale: number): void {\n const { kit, particles, random, parts } = context\n const { THREE } = kit\n const bits = createBits(context)\n const forward = context.forward()\n const muzzle = context.positionOf(parts.muzzle as THREE_NS.Object3D)\n const count = Math.floor(dt * 420 * scale)\n for (let i = 0; i < count; i++) {\n const speed = (2.2 + random() * 1.1) * scale\n bits.flame(muzzle.clone().addScaledVector(forward, random() * speed * Math.min(dt, 0.3)), forward.clone().multiplyScalar(speed).add(new THREE.Vector3((random() - 0.5) * 0.35, (random() - 0.3) * 0.3, (random() - 0.5) * 0.35)), 0.02 + random() * 0.022, 0.4 + random() * 0.35)\n }\n if (random() < 0.5) bits.smoke(muzzle.clone().addScaledVector(forward, 1.1 * scale + random() * 0.4), new THREE.Vector3(forward.x * 0.6, 0.35, forward.z * 0.6), 0.03, 1.6, 0.4)\n if (random() < 0.18) {\n const droplet = new THREE.Mesh(new THREE.SphereGeometry(0.006, 6, 4), new THREE.MeshBasicMaterial({ color: 0xff7a22 }))\n droplet.position.copy(muzzle).addScaledVector(forward, 0.3 + random() * 0.5)\n particles.spawn(droplet, forward.clone().multiplyScalar(1.2 * scale).add(new THREE.Vector3(0, 0.2, 0)), { life: 3, radius: 0.003, ownsGeometry: true, onGround: (position) => groundFire(context, bits, position) })\n }\n bits.dispose()\n}\n\n/** Three small flames where a burning droplet landed, flickering for four seconds and smoking. */\nfunction groundFire(context: HeavyContext, bits: ReturnType<typeof createBits>, position: THREE_NS.Vector3): void {\n const { kit, scene, random } = context\n const { THREE } = kit\n const fire = new THREE.Group()\n fire.position.set(position.x, context.groundAt(position.x, position.z) + 0.005, position.z)\n scene.add(fire)\n const materials = flameMaterials(kit)\n const flames = [0, 1, 2].map((index) => {\n const flame = new THREE.Mesh(new THREE.ConeGeometry(0.02, 0.07, 6), (materials[index % 2] as THREE_NS.Material).clone())\n flame.position.set((random() - 0.5) * 0.04, 0.035, (random() - 0.5) * 0.04)\n fire.add(flame)\n return flame\n })\n let clock = 0\n context.every(\n 4,\n (progress, dt) => {\n clock += dt\n flames.forEach((flame, index) => flame.scale.set(1 - progress * 0.7, (0.6 + Math.sin(clock * 20 + index * 2) * 0.35) * (1 - progress), 1 - progress * 0.7))\n if (random() < 0.08) bits.smoke(fire.position.clone().add(new THREE.Vector3(0, 0.08, 0)), new THREE.Vector3(0, 0.15, 0), 0.015, 1.2, 0.25)\n },\n () => {\n fire.removeFromParent()\n flames.forEach((flame) => {\n flame.geometry.dispose()\n ;(flame.material as THREE_NS.Material).dispose()\n })\n materials.forEach((material) => material.dispose())\n },\n )\n}\n","import type * as THREE_NS from 'three'\n\ntype Three = typeof THREE_NS\n\nexport type ParticleKind = 'casing' | 'magazine' | 'round' | 'other'\n\nexport interface ParticleOptions {\n kind?: ParticleKind\n /** Seconds before it is removed (default 2). */\n life?: number\n /** Gravity (default 9.8; negative lets smoke rise). */\n gravity?: number\n bounce?: number\n /** Fraction of the speed lost per second. */\n drag?: number\n /** Floor contact radius; negative: no contact (smoke, flames). */\n radius?: number\n spin?: THREE_NS.Vector3\n /** Opacity at birth: it fades to zero over its life. */\n fadeFrom?: number\n /** Growth per second as a fraction of the size. */\n grow?: number\n /** Called when it comes to rest on the floor. */\n onRest?: (object: THREE_NS.Object3D) => void\n /** Called instead of bouncing when it reaches the floor; the particle is removed. */\n onGround?: (position: THREE_NS.Vector3) => void\n /** The geometry of the object is its own (not shared with a model) and goes with it. */\n ownsGeometry?: boolean\n}\n\ninterface Particle extends Required<Pick<ParticleOptions, 'life' | 'gravity' | 'bounce' | 'drag' | 'radius' | 'grow' | 'kind'>> {\n object: THREE_NS.Object3D\n velocity: THREE_NS.Vector3\n spin: THREE_NS.Vector3\n age: number\n resting: boolean\n fadeFrom: number | undefined\n onRest: ParticleOptions['onRest']\n onGround: ParticleOptions['onGround']\n ownsGeometry: boolean\n bounces: number\n}\n\nconst MAX_PARTICLES = 900\nconst FLOOR_FRICTION = 0.45\n\n/** The gallery's particles (casings, magazines, smoke, flames): thrown with a velocity and a spin, bouncing on the floor under them until they rest or die. */\nexport interface Particles {\n spawn(object: THREE_NS.Object3D, velocity: THREE_NS.Vector3, options?: ParticleOptions): void\n update(dt: number): void\n count(kind: ParticleKind): number\n /** Called when something bounces: `casing` or `magazine` (for the sound). */\n onBounce?: (kind: ParticleKind) => void\n dispose(): void\n}\n\nconst disposeOwned = (object: THREE_NS.Object3D): void => {\n object.traverse((child) => {\n const mesh = child as THREE_NS.Mesh\n if (mesh.isMesh) mesh.geometry.dispose()\n })\n}\n\nexport function createParticles(THREE: Three, scene: THREE_NS.Object3D, groundAt: (x: number, z: number) => number): Particles {\n let list: Particle[] = []\n const remove = (particle: Particle): void => {\n particle.object.removeFromParent()\n if (particle.ownsGeometry) disposeOwned(particle.object)\n if (particle.fadeFrom !== undefined) ((particle.object as THREE_NS.Mesh).material as THREE_NS.Material).dispose()\n list = list.filter((other) => other !== particle)\n }\n const api: Particles = {\n spawn(object, velocity, options = {}) {\n scene.add(object)\n list.push({\n object,\n velocity,\n spin: options.spin ?? new THREE.Vector3(),\n age: 0,\n resting: false,\n life: options.life ?? 2,\n gravity: options.gravity ?? 9.8,\n bounce: options.bounce ?? 0.3,\n drag: options.drag ?? 0,\n radius: options.radius ?? 0.003,\n grow: options.grow ?? 0,\n kind: options.kind ?? 'other',\n fadeFrom: options.fadeFrom,\n onRest: options.onRest,\n onGround: options.onGround,\n ownsGeometry: options.ownsGeometry ?? false,\n bounces: 0,\n })\n const oldest = list[0]\n if (list.length > MAX_PARTICLES && oldest) remove(oldest)\n },\n update(dt) {\n for (const particle of [...list]) {\n particle.age += dt\n if (particle.age > particle.life) {\n remove(particle)\n continue\n }\n const { object } = particle\n if (particle.fadeFrom !== undefined) ((object as THREE_NS.Mesh).material as THREE_NS.Material).opacity = Math.max(0, particle.fadeFrom * (1 - particle.age / particle.life))\n if (particle.resting) continue\n particle.velocity.y -= particle.gravity * dt\n if (particle.drag) particle.velocity.multiplyScalar(Math.max(0, 1 - particle.drag * dt))\n object.position.addScaledVector(particle.velocity, dt)\n object.rotation.x += particle.spin.x * dt\n object.rotation.y += particle.spin.y * dt\n object.rotation.z += particle.spin.z * dt\n if (particle.grow) object.scale.multiplyScalar(1 + particle.grow * dt)\n if (particle.radius < 0) continue\n const floor = groundAt(object.position.x, object.position.z) + particle.radius\n if (object.position.y >= floor || particle.velocity.y >= 0) continue\n if (particle.onGround) {\n particle.onGround(object.position.clone())\n remove(particle)\n continue\n }\n object.position.y = floor\n particle.velocity.y *= -particle.bounce\n particle.velocity.x *= FLOOR_FRICTION\n particle.velocity.z *= FLOOR_FRICTION\n particle.spin.multiplyScalar(FLOOR_FRICTION)\n if (particle.bounces++ < 4 && Math.abs(particle.velocity.y) >= 0.18) api.onBounce?.(particle.kind)\n if (Math.abs(particle.velocity.y) < 0.18) {\n particle.resting = true\n particle.onRest?.(object)\n }\n }\n },\n count: (kind) => list.filter((particle) => particle.kind === kind).length,\n dispose() {\n for (const particle of [...list]) remove(particle)\n },\n }\n return api\n}\n","import type * as THREE_NS from 'three'\nimport type { AnimationPose, ToolRig } from '@adatechnology/game-contracts'\nimport { partRegistry } from '../models/part-registry'\nimport type { WeaponModel } from '../models'\n\n/** The rig of a model: clip poses are offsets from the rest the parts had when the rig was made, as the contract says. */\nexport function createModelRig(model: WeaponModel): ToolRig {\n const registry = partRegistry(model.parts)\n const rest = new Map<THREE_NS.Object3D, { position: THREE_NS.Vector3; rotation: THREE_NS.Euler }>()\n for (const part of [...registry.values(), model.root]) rest.set(part, { position: part.position.clone(), rotation: part.rotation.clone() })\n const apply = (object: THREE_NS.Object3D, pose: AnimationPose): void => {\n const base = rest.get(object)\n if (!base) return\n const [dx, dy, dz] = pose.position ?? [0, 0, 0]\n const [rx, ry, rz] = pose.rotation ?? [0, 0, 0]\n object.position.set(base.position.x + dx, base.position.y + dy, base.position.z + dz)\n object.rotation.set(base.rotation.x + rx, base.rotation.y + ry, base.rotation.z + rz)\n }\n return {\n setPartPose(partId, pose) {\n const part = registry.get(partId)\n if (part) apply(part, pose)\n },\n setRootPose: (pose) => apply(model.root, pose),\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { CartridgeDims, CaseType, WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponModel } from '../models'\nimport type { CartridgeShape } from '../models/cartridge'\nimport type { AttachmentRig } from '../models/attachments/fit'\nimport type { ModelKit } from '../models/kit'\nimport type { Effects } from './effects'\nimport type { Particles } from './particles'\nimport type { WeaponAudio } from '../audio'\nimport type { FxLayers } from './layers'\n\n/** What the viewmodel shares with the handlers of the clip events. */\nexport interface FxWorld {\n readonly kit: ModelKit\n readonly scene: THREE_NS.Object3D\n readonly particles: Particles\n readonly effects: Effects\n readonly random: () => number\n readonly audio: WeaponAudio | null\n readonly layers: FxLayers\n groundAt(x: number, z: number): number\n /** Runs `step(e)` for `seconds` from `delay` seconds on, with `e` the eased progress, then `done`. */\n schedule(delay: number, seconds: number, step: (eased: number) => void, done?: () => void): void\n}\n\n/** The weapon in the hands: the model, how it is held and what its calibre makes (the case and the round, in metres). */\nexport interface Session {\n readonly id: string\n readonly def: WeaponDef\n readonly model: WeaponModel\n /** How much the model is scaled down to sit in the hands. */\n readonly holderScale: number\n readonly lengthMetres: number\n readonly caseType: CaseType\n readonly kit: ModelKit\n readonly cartridge: { dims: CartridgeDims; shape: CartridgeShape } | null\n stuckCase: THREE_NS.Object3D | null\n nextChamber: number\n /** The accessories drawn on the model, and what was fitted when they were last synced (to see a change). */\n attachments: AttachmentRig | null\n attachmentsSignature: string\n}\n\n/** World position of a part of the model. */\nexport const worldPositionOf = (session: Session, part: THREE_NS.Object3D, out: THREE_NS.Vector3): THREE_NS.Vector3 => {\n session.model.root.updateWorldMatrix(true, true)\n return part.getWorldPosition(out)\n}\n\n/** A direction or offset written in the weapon's own axes (x along the barrel, y up, z to the right) in the world; `scaled` follows the model's size. */\nexport const toWorld = (session: Session, vector: THREE_NS.Vector3, scaled = false): THREE_NS.Vector3 => {\n const quaternion = session.model.root.getWorldQuaternion(new session.kit.THREE.Quaternion())\n const world = vector.clone().applyQuaternion(quaternion)\n return scaled ? world.multiplyScalar(session.holderScale) : world\n}\n","import type * as THREE_NS from 'three'\nimport type { AnimationEventSpec } from '@adatechnology/game-contracts'\nimport { buildCasing, buildRound } from '../models/cartridge'\nimport { FLASH_BY_CASE } from './effects'\nimport { toWorld, worldPositionOf } from './session'\nimport type { FxWorld, Session } from './session'\n\nconst PI = Math.PI\n// the flash of a 40 mm launcher, a little under the one of a rocket tube\nconst UGL_FLASH = 1.6\n\nconst restFlat = (object: THREE_NS.Object3D): void => {\n object.rotation.x = 0\n object.rotation.z = 0\n}\n\n/** The handlers of the events a clip carries (`muzzle_flash`, `eject_casing`, `drop_magazine`, `move_in`...): the effects the page spawns around the moving parts. */\nexport function createClipEventHandler(world: FxWorld, session: Session): (event: AnimationEventSpec) => void {\n const { kit, particles, effects, random } = world\n const { THREE } = kit\n const { parts, root } = session.model\n const vector = (x: number, y: number, z: number): THREE_NS.Vector3 => new THREE.Vector3(x, y, z)\n const positionOf = (part: THREE_NS.Object3D): THREE_NS.Vector3 => worldPositionOf(session, part, new THREE.Vector3())\n const reach = Math.max(0.55, Math.min(1.2, session.lengthMetres))\n\n const throwCase = (mark: THREE_NS.Object3D, velocity: THREE_NS.Vector3, spin: THREE_NS.Vector3, tilt = 0): void => {\n if (!session.cartridge || !world.layers.casings) return\n const casing = buildCasing(kit, session.cartridge.dims, session.cartridge.shape)\n casing.group.position.copy(positionOf(mark))\n casing.group.rotation.set(0, random() * 0.6 - 0.3, tilt)\n particles.spawn(casing.group, velocity, { kind: 'casing', life: 25, radius: casing.radius, bounce: 0.35, spin, onRest: restFlat, ownsGeometry: true })\n }\n\n const ejectFromPort = (down: boolean): void => {\n if (!parts.eject) return\n const local = down ? vector((random() - 0.5) * 0.3, -0.4, (random() - 0.5) * 0.3) : vector(-0.2 - random() * 0.4, (0.9 + random() * 0.5) * reach, (1 + random() * 0.6) * reach)\n throwCase(parts.eject, toWorld(session, local), vector(random() * 30, random() * 30, random() * 30))\n }\n\n const ejectAll = (marks: THREE_NS.Object3D[] | undefined, spent: (index: number) => { velocity: THREE_NS.Vector3; spin: THREE_NS.Vector3; tilt: number }): void => {\n marks?.forEach((mark, index) => {\n const { velocity, spin, tilt } = spent(index)\n throwCase(mark, toWorld(session, velocity), spin, tilt)\n })\n }\n\n /** A round slides from `from` to `to` (world points) in a quarter of a second, in the weapon's own space so that it follows the weapon. */\n const moveIn = (from: THREE_NS.Vector3, to: THREE_NS.Vector3, tilt: number): void => {\n if (!session.cartridge) return\n const { group } = buildRound(kit, session.cartridge.dims, session.cartridge.shape)\n const start = root.worldToLocal(from.clone())\n const end = root.worldToLocal(to.clone())\n group.rotation.z = tilt\n group.position.copy(start)\n root.add(group)\n world.schedule(0, 0.24, (eased) => group.position.lerpVectors(start, end, eased), () => {\n group.removeFromParent()\n group.traverse((child) => {\n const mesh = child as THREE_NS.Mesh\n if (mesh.isMesh) mesh.geometry.dispose()\n })\n })\n }\n\n const offsetFrom = (point: THREE_NS.Vector3, x: number, y: number, z: number): THREE_NS.Vector3 => point.clone().add(toWorld(session, vector(x, y, z), true))\n\n const feedRound = (from: string, next: boolean): void => {\n if (from === 'loadPort' && parts.loadPort) {\n const port = positionOf(parts.loadPort)\n moveIn(offsetFrom(port, -0.03, -0.08, 0.07), port, 0.25)\n } else if (from === 'topLoad' && parts.topLoad) {\n const point = positionOf(parts.topLoad)\n moveIn(offsetFrom(point, 0, 0.07, 0), point, 0)\n } else if (from === 'chambers' && parts.chambers) {\n const marks = next ? [parts.chambers[session.nextChamber++ % parts.chambers.length]] : parts.chambers\n for (const mark of marks) {\n if (!mark) continue\n const point = positionOf(mark)\n moveIn(offsetFrom(point, -0.07, 0, 0), offsetFrom(point, 0.006, 0, 0), 0)\n }\n } else if (from === 'breech' && parts.breech) {\n for (const mark of parts.breech) {\n const point = positionOf(mark)\n moveIn(offsetFrom(point, -0.09, 0.05, 0), offsetFrom(point, 0.02, -0.01, 0), -0.5)\n }\n }\n }\n\n const dropMagazine = (up: boolean): void => {\n if (!parts.mag || !world.layers.magazines) return\n root.updateWorldMatrix(true, true)\n const copy = parts.mag.clone(true)\n parts.mag.matrixWorld.decompose(copy.position, copy.quaternion, copy.scale)\n particles.spawn(copy, toWorld(session, vector(up ? -0.25 : 0.05, up ? 0.9 : -0.3, 0.18)), { kind: 'magazine', life: 25, radius: 0.014, bounce: 0.15, spin: vector(1.5, 0.5, 2.5), onRest: (object) => object.rotation.set(0, object.rotation.y, PI / 2) })\n }\n\n const stuckCase = (): void => {\n if (!session.cartridge || !parts.eject) return\n const casing = buildCasing(kit, session.cartridge.dims, session.cartridge.shape)\n const at = root.worldToLocal(offsetFrom(positionOf(parts.eject), 0, casing.length * 0.35, 0))\n casing.group.position.copy(at)\n casing.group.rotation.set(0, 0, PI / 2 - 0.25)\n root.add(casing.group)\n session.stuckCase = casing.group\n }\n\n const flyJam = (jam: string): void => {\n const stuck = session.stuckCase\n session.stuckCase = null\n if (stuck) {\n root.updateWorldMatrix(true, true)\n stuck.updateWorldMatrix(true, false)\n stuck.matrixWorld.decompose(stuck.position, stuck.quaternion, stuck.scale)\n particles.spawn(stuck, toWorld(session, vector(-0.2, 1.2, 1.3)), { kind: 'casing', life: 25, radius: 0.006, bounce: 0.3, spin: vector(9, 14, 7), onRest: restFlat, ownsGeometry: true })\n } else if (jam === 'misfire' && session.cartridge && parts.eject) {\n const round = buildRound(kit, session.cartridge.dims, session.cartridge.shape)\n round.group.position.copy(positionOf(parts.eject))\n particles.spawn(round.group, toWorld(session, vector(-0.2, 1.1, 1.2)), { kind: 'round', life: 25, radius: round.radius, bounce: 0.3, spin: vector(8, 12, 6), onRest: restFlat, ownsGeometry: true })\n } else ejectFromPort(false)\n }\n\n return (event) => {\n const data = event.data ?? {}\n switch (event.type) {\n case 'muzzle_flash':\n if (data.at === 'ugl') {\n if (parts.uglMuzzle && world.layers.muzzleFlash) effects.muzzleFlash(positionOf(parts.uglMuzzle), root.getWorldQuaternion(new THREE.Quaternion()), UGL_FLASH)\n } else if (parts.muzzle && world.layers.muzzleFlash) effects.muzzleFlash(positionOf(parts.muzzle), root.getWorldQuaternion(new THREE.Quaternion()), session.def.action.kind === 'launcher' ? 2.2 : FLASH_BY_CASE[session.caseType])\n break\n case 'eject_casing':\n if (data.from === 'chambers') ejectAll(parts.chambers, () => ({ velocity: vector(-0.5 - random() * 0.3, -0.1 + random() * 0.3, (random() - 0.5) * 0.25), spin: vector(10, 20, 5), tilt: 0 }))\n else if (data.from === 'breech') ejectAll(parts.breech, () => ({ velocity: vector(-1, 0.9, (random() - 0.5) * 0.2), spin: vector(3, 8, 12), tilt: -0.5 }))\n else ejectFromPort(data.down === true)\n break\n case 'drop_magazine':\n dropMagazine(data.up === true)\n break\n case 'move_in':\n feedRound(String(data.from), data.next === true)\n break\n case 'stuck_case':\n stuckCase()\n break\n case 'fly_jam':\n flyJam(String(data.jam))\n break\n case 'show_round':\n if (parts.round) parts.round.visible = true\n break\n case 'drop_tube':\n dropTube()\n break\n case 'seat_tube':\n root.visible = true\n break\n case 'breech_round':\n breechRound()\n break\n default:\n break\n }\n }\n\n function dropTube(): void {\n root.updateWorldMatrix(true, true)\n const old = root.clone(true)\n root.matrixWorld.decompose(old.position, old.quaternion, old.scale)\n root.visible = false\n particles.spawn(old, toWorld(session, vector(0.2, 0.4, 0.6)), { life: 8, radius: 0.05, bounce: 0.2, spin: vector(0, 0.8, 2.5) })\n }\n\n function breechRound(): void {\n const make = parts.makeRound\n if (!make) return\n const shell = make()\n session.model.inner.add(shell)\n shell.position.set(-0.25, 0, 0)\n world.schedule(0.02, 0.4, (eased) => (shell.position.x = -0.25 + 0.6 * eased), () => {\n shell.removeFromParent()\n })\n }\n}\n","import type * as THREE_NS from 'three'\nimport { createToolClipPlayer, toolAnimationStep } from '@adatechnology/game-contracts'\nimport type { AnimationPose, HostEvent, HostTool, HostToolAttachment, ToolAnimationStep, ToolClipPlayer } from '@adatechnology/game-contracts'\nimport { createRng, muzzleEnergy } from '@adatechnology/game-weapons'\nimport type { Arsenal, CaliberDef, FittedAttachment, MountKind, WeaponDef } from '@adatechnology/game-weapons'\nimport { ease } from '../animation/clip-builder'\nimport { buildToolClips } from '../animation/clip-set'\nimport type { WeaponAudio } from '../audio'\nimport { weaponEventOf } from '../audio/host-events'\nimport { buildWeaponModelById } from '../models'\nimport { fitAttachmentModels } from '../models/attachments/fit'\nimport type { AttachmentModelRegistry, LaserRaycast } from '../models/attachments/types'\nimport { rigUnderbarrel } from '../models/attachments/rig-underbarrel'\nimport { rigStock } from '../models/rig-stock'\nimport { attachmentsKey } from '../attachments-key'\nimport { VIEWMODEL_NODE_NAME } from '../laser-raycast'\nimport { applyCondition } from '../models/condition'\nimport { cartridgeShape } from '../models/cartridge'\nimport { modelKit } from '../models/kit'\nimport { createEffects } from './effects'\nimport { createLayers } from './layers'\nimport type { FxLayers } from './layers'\nimport { flameJet, launchRocket } from './heavy'\nimport type { HeavyContext } from './heavy'\nimport { createParticles } from './particles'\nimport { createModelRig } from './rig'\nimport type { FxWorld, Session } from './session'\nimport { toWorld, worldPositionOf } from './session'\nimport { createClipEventHandler } from './viewmodel-events'\n\nconst PI = Math.PI\n// where the weapon sits against the camera: right, down and ahead; long guns are drawn smaller so they do not fill the view\nconst HAND_OFFSET: [number, number, number] = [0.2, -0.2, -0.42]\nconst HEAT_DISPLAY_MAX_FALLBACK = 120\n// the launcher has no calibre: its shot is the game's `explosao` class, at the volume of a mid-sized blast\nconst LAUNCH_VOLUME = 0.6\n\nexport interface ViewmodelOptions {\n THREE: typeof THREE_NS\n scene: THREE_NS.Scene\n camera: THREE_NS.Camera\n arsenal: Arsenal\n groundAt: (x: number, z: number) => number\n audio: WeaponAudio | null\n /** Seed of the scatter of casings, smoke and sparks. */\n seed?: number\n /** The tool as it is now, for what no event announces: the barrel heat and the fuel burning. */\n tool?: () => HostTool\n /** Wear of the weapon (`new`, `used`, `worn`, `rusty`). */\n condition?: string\n /** What is drawn: read at the moment of each event, so the bench can change it live. */\n layers?: FxLayers\n /** Metres between the shooter and the listener, for the distance muffling of the shot sound (default 0). */\n soundDistance?: () => number\n /** Builders of accessory models that replace or add to the ones the kit ships. */\n attachmentModels?: AttachmentModelRegistry\n /** How far a laser beam goes (metres) from a point along a direction, or null when it hits nothing. */\n raycast?: LaserRaycast\n}\n\n/** The weapon in the hands for the models the gallery drew: it follows the camera, plays the clips of the rule's events, and throws casings, magazines and smoke. */\nexport interface Viewmodel {\n /** Puts the weapon in the hands; false (and the hands stay as they were) when the gallery has no model for it. */\n equip(weapon: string): boolean\n /** Takes the weapon out of the hands. */\n unequip(): void\n handle(event: HostEvent, tool: HostTool): void\n update(dt: number): void\n setCondition(condition: string): void\n readonly inHand: string | null\n readonly casings: number\n readonly magazines: number\n dispose(): void\n}\n\ninterface Task {\n delay: number\n seconds: number\n elapsed: number\n step: (progress: number, dt: number) => void\n done: (() => void) | undefined\n}\n\nconst fittedOf = (parts: readonly HostToolAttachment[]): FittedAttachment[] =>\n parts.map((part) => ({ id: part.id, mount: part.mount as MountKind, ...(part.integral ? { integral: true } : {}), ...(part.on === undefined ? {} : { on: part.on }) }))\n\n/** The pose the stock pivot holds when the stock is collapsed: a half turn about its axis, or the slide along the weapon. */\nconst collapsedStockPose = (move: NonNullable<Session['model']['parts']['stockMove']>): AnimationPose => {\n if (move.kind === 'retract') return { position: [move.travel, 0, 0] }\n return { rotation: [move.axis === 'x' ? PI : 0, move.axis === 'y' ? PI : 0, move.axis === 'z' ? PI : 0] }\n}\n\n// the shot of the launcher under the barrel and its reload have clips of their own; the rest of the weapon's clips play as they are\nconst underbarrelStep = (step: ToolAnimationStep, tool: HostTool): ToolAnimationStep => (tool.underbarrelActive && step.type === 'play' && (step.clip === 'shot' || step.clip === 'reload') ? { ...step, variant: 'ugl' } : step)\n\nconst caliberOf = (arsenal: Arsenal, def: WeaponDef): CaliberDef | undefined => (def.action.kind === 'firearm' ? arsenal.calibers.get(def.action.caliber) : undefined)\n\nexport function createViewmodel(options: ViewmodelOptions): Viewmodel {\n const { THREE, scene, camera, arsenal, groundAt, audio } = options\n const kit = modelKit(THREE)\n const random = createRng(options.seed ?? 1)\n const layers = options.layers ?? createLayers()\n const distance = (): number => options.soundDistance?.() ?? 0\n const particles = createParticles(THREE, scene, groundAt)\n particles.onBounce = (kind) => (kind === 'casing' ? audio?.clink() : kind === 'magazine' ? audio?.thud() : undefined)\n const effects = createEffects(kit, scene, particles, random)\n const hand = new THREE.Group()\n hand.name = VIEWMODEL_NODE_NAME\n scene.add(hand)\n const holder = new THREE.Group()\n holder.quaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), PI / 2)\n hand.add(holder)\n let tasks: Task[] = []\n let session: Session | null = null\n let player: ToolClipPlayer | null = null\n let condition = options.condition ?? 'new'\n let lastAmmo = 0\n let smokeDebt = 0\n\n const world: FxWorld = {\n kit,\n scene,\n particles,\n effects,\n random,\n audio,\n layers,\n groundAt,\n schedule: (delay, seconds, step, done) => void tasks.push({ delay, seconds, elapsed: 0, step: (progress) => step(ease(progress)), done }),\n }\n\n const heatMax = arsenal.rules.heat.displayMax || HEAT_DISPLAY_MAX_FALLBACK\n\n const release = (): void => {\n if (!session) return\n session.attachments?.dispose()\n session.model.root.removeFromParent()\n player = null\n session = null\n tasks = []\n }\n\n const heavy = (current: Session): HeavyContext => ({\n kit,\n scene,\n particles,\n effects,\n random,\n parts: current.model.parts,\n forward: () => toWorld(current, new THREE.Vector3(1, 0, 0)).normalize(),\n positionOf: (part) => worldPositionOf(current, part, new THREE.Vector3()),\n orientation: () => current.model.root.getWorldQuaternion(new THREE.Quaternion()),\n every: (seconds, step, done) => void tasks.push({ delay: 0, seconds, elapsed: 0, step, done }),\n groundAt,\n })\n\n const equip = (weapon: string): boolean => {\n const def = arsenal.weapons.get(weapon)\n const model = def ? buildWeaponModelById(THREE, weapon) : undefined\n if (!def || !model) return false\n release()\n rigStock(THREE, model, def)\n rigUnderbarrel(THREE, model, def)\n const length = new THREE.Box3().setFromObject(model.root).getSize(new THREE.Vector3()).x\n const scale = length > 0.8 ? 0.55 : length > 0.4 ? 0.75 : 1\n holder.scale.setScalar(scale)\n holder.position.set(0, 0, Math.min(0.25, 0.25 * length * scale))\n holder.add(model.root)\n const caliber = caliberOf(arsenal, def)\n const dims = caliber?.cartridge\n session = {\n id: weapon,\n def,\n model,\n holderScale: scale,\n lengthMetres: length,\n caseType: caliber?.caseType ?? 'rifle',\n kit,\n cartridge: caliber && dims ? { dims, shape: cartridgeShape(caliber, dims) } : null,\n stuckCase: null,\n nextChamber: 0,\n attachments: null,\n attachmentsSignature: '',\n }\n const hostTool = options.tool?.()\n const onTool = hostTool?.weapon === weapon ? hostTool : undefined\n const fitted = onTool?.attachments ? fittedOf(onTool.attachments) : [...(def.fitted ?? [])]\n session.attachments = fitAttachmentModels(model, fitted, kit, { catalogue: arsenal.attachments, isDrawn: () => layers.attachments, areBeamsOn: () => layers.beams, ...(options.attachmentModels ? { overrides: options.attachmentModels } : {}), ...(options.raycast ? { raycast: options.raycast } : {}) })\n session.attachmentsSignature = attachmentsKey(onTool?.attachments)\n const action = def.action\n const reloadFamily = action.kind === 'firearm' || action.kind === 'flame' || action.kind === 'launcher' ? action.family : undefined\n const rpm = action.kind === 'firearm' ? action.rpm : 0\n const rig = createModelRig(model)\n player = createToolClipPlayer({\n clips: buildToolClips({ parts: model.parts, family: model.parts.family, caseType: session.caseType, reloadFamily }),\n rig,\n onEvent: createClipEventHandler(world, session),\n repeatInterval: () => (rpm > 0 ? 60 / rpm : 0.1),\n })\n if (model.parts.stockMove && onTool?.stock === 'collapsed') rig.setPartPose('stock', collapsedStockPose(model.parts.stockMove))\n applyCondition(kit, model, condition)\n lastAmmo = options.tool?.().ammo ?? 0\n return true\n }\n\n const syncAttachments = (current: Session, tool: HostTool | undefined): void => {\n if (!current.attachments || tool?.weapon !== current.id || !tool.attachments) return\n const signature = attachmentsKey(tool.attachments)\n if (signature === current.attachmentsSignature) return\n current.attachmentsSignature = signature\n current.attachments.sync(fittedOf(tool.attachments))\n }\n\n const place = (): void => {\n const [x, y, z] = HAND_OFFSET\n hand.position.set(x, y, z).applyQuaternion(camera.quaternion).add(camera.position)\n hand.quaternion.copy(camera.quaternion)\n hand.updateMatrixWorld(true)\n }\n\n const glow = (tool: HostTool | undefined): void => {\n if (!session) return\n const heat = (tool?.heat ?? 0) * heatMax\n const level = Math.max(0, Math.min(1, (heat - 50) / 50))\n for (const mesh of session.model.parts.glow) {\n const material = mesh.material as THREE_NS.MeshStandardMaterial\n material.emissive.setRGB(level, 0.2 * level * level, 0.02 * level * level)\n material.emissiveIntensity = 2.2 * level\n }\n }\n\n const handleShot = (current: Session, event: Extract<HostEvent, { type: 'shot' }>, tool: HostTool): void => {\n if (tool.underbarrelActive && current.model.parts.uglMuzzle) {\n audio?.play('explosion', LAUNCH_VOLUME, distance())\n return\n }\n const action = current.def.action\n if (action.kind === 'launcher') {\n launchRocket(heavy(current))\n audio?.play('explosion', LAUNCH_VOLUME, distance())\n }\n if (action.kind !== 'firearm') return\n const caliber = caliberOf(arsenal, current.def)\n if (!caliber) return\n audio?.shot(muzzleEnergy(caliber) * (caliber.pellets ?? 1), current.def.category, { caliber, distance: distance(), ...(event.suppressed === true ? { suppressed: true } : {}) })\n }\n\n return {\n equip,\n unequip: release,\n handle(event, tool) {\n if (event.type === 'explosion') return\n if (event.type === 'tool') equip(event.weapon)\n if (!session || !player || event.weapon !== session.id) return\n const current = session\n if (event.type === 'shot') handleShot(current, event, tool)\n else if (event.type === 'reload' && event.phase === 'start') current.nextChamber = 0\n else if (event.type === 'clear' && event.phase === 'end') current.stuckCase = null\n const mechanical = weaponEventOf(event)\n if (mechanical) audio?.event(mechanical)\n const step = toolAnimationStep(event)\n if (!step) return\n const last = step.type === 'play' && step.clip === 'shot' && current.model.parts.family === 'pistol' && tool.ammo === 0\n player.apply(last ? { ...step, variant: 'last' } : underbarrelStep(step, tool))\n },\n update(dt) {\n if (session) {\n place()\n player?.update(dt)\n const tool = options.tool?.()\n syncAttachments(session, tool)\n session.attachments?.update()\n glow(tool)\n if (tool && session.def.action.kind === 'flame') {\n if (tool.ammo < lastAmmo) flameJet(heavy(session), dt, session.model.parts.launcherType === 'flame' ? 1 : 0.6)\n lastAmmo = tool.ammo\n }\n if (tool && tool.heat !== undefined && tool.heat * heatMax > 10 && session.model.parts.muzzle) {\n smokeDebt += dt * tool.heat * heatMax * 0.1\n while (smokeDebt > 1) {\n smokeDebt -= 1\n const k = 0.5 + (tool.heat * heatMax) / 60\n effects.smoke(worldPositionOf(session, session.model.parts.muzzle, new THREE.Vector3()), new THREE.Vector3((random() - 0.5) * 0.03, 0.07 + random() * 0.08, (random() - 0.5) * 0.03), 0.007 * k, 1.6 + random(), Math.min(0.42, 0.14 + k * 0.1))\n }\n }\n }\n for (const task of [...tasks]) {\n task.elapsed += dt\n if (task.elapsed < task.delay) continue\n const progress = task.seconds > 0 ? Math.min(1, (task.elapsed - task.delay) / task.seconds) : 1\n task.step(progress, dt)\n if (progress >= 1) {\n task.done?.()\n tasks = tasks.filter((other) => other !== task)\n }\n }\n effects.update(dt)\n particles.update(dt)\n },\n setCondition(next) {\n condition = next\n if (session) applyCondition(kit, session.model, condition)\n },\n get inHand() {\n return session?.id ?? null\n },\n get casings() {\n return particles.count('casing')\n },\n get magazines() {\n return particles.count('magazine')\n },\n dispose() {\n release()\n particles.dispose()\n effects.dispose()\n hand.removeFromParent()\n },\n }\n}\n","import type { HostEvent, HostTool } from '@adatechnology/game-contracts'\nimport { createBoxFx } from './box-fx'\nimport type { WeaponFxOptions } from './box-fx'\nimport { hasWeaponModel } from './models'\nimport { createLayers } from './fx/layers'\nimport type { FxLayers } from './fx/layers'\nimport { createViewmodel } from './fx/viewmodel'\n\nexport type { WeaponFxOptions } from './box-fx'\nexport type { FxLayers } from './fx/layers'\n\n/** The weapon in the hands, its fire and reload motion, ejected casings and dropped magazines, and their sounds. */\nexport interface WeaponFx {\n /** Feed every tool event of the host, with the tool as it is after the event. */\n handle(event: HostEvent, tool: HostTool): void\n update(dt: number): void\n /** Dresses the weapon for its wear (`new`, `used`, `worn`, `rusty`); the gallery models show it in their metal. */\n setCondition(condition: string): void\n /** What is drawn (casings, magazines, muzzle flash): change a field and the next event follows it. */\n readonly layers: FxLayers\n /** Weapon shown in the hands, or null. */\n readonly inHand: string | null\n /** Casings and magazines currently on the floor or in the air. */\n readonly casings: number\n readonly magazines: number\n dispose(): void\n}\n\n/**\n * The presentation of the tool in the hands. The weapons the gallery drew (`MODEL_ENTRIES`) get their model and the clips the rule's events call for\n * (fire, cycle, jam, clear, safety, the seven reloads); the generic archetypes keep their low-poly prop.\n */\nexport function createWeaponFx(options: WeaponFxOptions): WeaponFx {\n const layers = options.layers ?? createLayers()\n const box = createBoxFx({ ...options, layers })\n const model = createViewmodel({\n layers,\n ...(options.soundDistance ? { soundDistance: options.soundDistance } : {}),\n THREE: options.THREE,\n scene: options.scene,\n camera: options.camera,\n arsenal: options.arsenal,\n groundAt: options.groundAt,\n audio: options.audio ?? null,\n ...(options.seed === undefined ? {} : { seed: options.seed }),\n ...(options.tool ? { tool: options.tool } : {}),\n ...(options.condition ? { condition: options.condition } : {}),\n ...(options.attachmentModels ? { attachmentModels: options.attachmentModels } : {}),\n ...(options.raycast ? { raycast: options.raycast } : {}),\n })\n return {\n handle(event, tool) {\n if (event.type === 'explosion') return\n if (event.type === 'tool') {\n if (hasWeaponModel(event.weapon)) box.unequip()\n else model.unequip()\n }\n if (model.inHand !== null || (event.type === 'tool' && hasWeaponModel(event.weapon))) model.handle(event, tool)\n else box.handle(event, tool)\n },\n update(dt) {\n box.update(dt)\n model.update(dt)\n },\n setCondition: (condition) => model.setCondition(condition),\n layers,\n get inHand() {\n return model.inHand ?? box.inHand\n },\n get casings() {\n return box.casings + model.casings\n },\n get magazines() {\n return box.magazines + model.magazines\n },\n dispose() {\n box.dispose()\n model.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, PartShape, PartSpec, TestableItem, Vec3 } from '@adatechnology/game-contracts'\nimport type { ExplosiveDef } from '@adatechnology/game-weapons'\n\n/** Prefix of the item ids of the explosives that sit in the world (`world_fuel_barrel`). */\nexport const WORLD_EXPLOSIVE_PREFIX = 'world_'\n\ninterface WorldShape {\n readonly shape: PartShape\n readonly position: Vec3\n readonly color: number\n}\n\n// The game's drum (jogo.js addExplo 68141: radius 0.3, height 0.9); the P13 cylinder and the car tank are real measures.\nconst SHAPES: Readonly<Record<string, WorldShape>> = {\n fuel_barrel: { shape: { kind: 'cylinder', radius: 0.3, height: 0.9 }, position: [0, 0.45, 0], color: 0x2f5f9a },\n propane_p13: { shape: { kind: 'cylinder', radius: 0.15, height: 0.48 }, position: [0, 0.24, 0], color: 0xcfd3d8 },\n car_fuel_tank: { shape: { kind: 'box', size: [0.9, 0.25, 0.5] }, position: [0, 0.4, 0], color: 0x4b4f55 },\n}\n\n/** The ids of the explosives of the arsenal that the area puts in the world. */\nexport const WORLD_EXPLOSIVE_IDS: readonly string[] = Object.keys(SHAPES)\n\n// A hollow steel shell: thin and light, so a bullet or a blast breaks it (the weight of a solid steel part would hold it together).\nconst SHELL = { thickness: 0.001, fill: 0.03 }\n\n/** The part of a world explosive: the energy, the reach and the chain of the explosive def, which is what `explosivePart` of game-destruction builds. */\nconst explosivePart = (def: ExplosiveDef, shape: WorldShape): PartSpec => ({\n id: 'tank',\n material: 'steel',\n shape: shape.shape,\n position: shape.position,\n ...SHELL,\n explodes: { energy: def.energy, radius: def.injuryRadius, ...(def.chain ? { chain: { ...def.chain } } : {}) },\n})\n\nconst meshOf = (THREE: typeof THREE_NS, shape: WorldShape): THREE_NS.Mesh => {\n const geometry = shape.shape.kind === 'cylinder' ? new THREE.CylinderGeometry(shape.shape.radius, shape.shape.radius, shape.shape.height, 16) : shape.shape.kind === 'box' ? new THREE.BoxGeometry(...shape.shape.size) : new THREE.SphereGeometry(0.2)\n const mesh = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({ color: shape.color, roughness: 0.55, metalness: 0.5 }))\n mesh.name = 'tank'\n mesh.userData.destructionPart = 'tank'\n mesh.position.set(...shape.position)\n mesh.castShadow = true\n mesh.receiveShadow = true\n return mesh\n}\n\n/** An explosive of the arsenal standing in the world: it goes off by a bullet, fire or another blast, after the delay its `chain` gives. */\nexport const worldExplosiveItem = (def: ExplosiveDef, name: string): TestableItem | undefined => {\n const shape = SHAPES[def.id]\n if (!shape) return undefined\n const spec: DestructibleSpec = { name, parts: [explosivePart(def, shape)], joints: [], tags: ['explosive'] }\n return {\n id: `${WORLD_EXPLOSIVE_PREFIX}${def.id}`,\n name,\n build: (THREE: unknown) => {\n const group = new (THREE as typeof THREE_NS).Group()\n group.add(meshOf(THREE as typeof THREE_NS, shape))\n return group\n },\n spec,\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { AreaPlacement, BenchChange, DestructibleSpec, HostTool, ModuleArea, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, TestableItem, TestableModule, Vec3 } from '@adatechnology/game-contracts'\nimport { createArsenal } from '@adatechnology/game-weapons'\nimport type { Arsenal, WeaponDef } from '@adatechnology/game-weapons'\nimport { createAccessoryBench, accessoryControls, accessoryLayers, accessoryMetrics } from './accessory-bench'\nimport { accessoryTextOf } from './accessory-text'\nimport { createWeaponAudio } from './audio'\nimport type { WeaponAudio } from './audio'\nimport { createWeaponFx } from './fx'\nimport type { WeaponFx } from './fx'\nimport { createLaserRaycast } from './laser-raycast'\nimport { ARCHETYPE_MODELS, hasWeaponModel } from './models'\nimport type { AttachmentModelRegistry } from './models/attachments/types'\nimport { BODY_ACTIONS, buildModeledProp, buildProp, buildTripodMountedProp, modeledPropSpec, weaponProp } from './props'\nimport type { WeaponProp } from './props'\nimport { WORLD_EXPLOSIVE_IDS, WORLD_EXPLOSIVE_PREFIX, worldExplosiveItem } from './world-explosives'\n\nexport interface WeaponsTestModuleOptions {\n /** `en` or `pt-BR` (default). */\n locale?: string\n /** The arsenal to lay out (default `createArsenal` with the locale). */\n arsenal?: Arsenal\n /** Play sounds (default true; silent anyway where there is no AudioContext). */\n sound?: boolean\n /** Wear of the weapon in the hands, which the gallery models show in their metal: `new` (default), `used`, `worn` or `rusty`. */\n condition?: string\n /** Seed of the scatter of casings and smoke (default 1). */\n seed?: number\n /** Builders of accessory models that replace or add to the ones the kit ships (by the `model` of the accessory). */\n attachmentModels?: AttachmentModelRegistry\n}\n\n/** Prefix of the item ids of the weapon props (`weapon_pistol_9mm`). */\nexport const WEAPON_ITEM_PREFIX = 'weapon_'\n// must not start with WEAPON_ITEM_PREFIX: hosts and tests tell the props apart by it\nexport const COUNTER_ITEM_ID = 'counter_weapons'\n\n// how loud an explosion is: a base plus what its reach adds (the game's `explosao` class is at full volume for a blast of 15 m or more)\nconst EXPLOSION_VOLUME_BASE = 0.4\nconst EXPLOSION_VOLUME_PER_METRE = 0.04\nconst SOUND_DISTANCE_MAX = 200\n/** Longest safety fuse the bench offers, metres: one metre burns 131 s, enough to see a delayed trap. */\nconst FUSE_LENGTH_MAX = 1\nconst DEFAULT_FUSE_LENGTH = 0.03\nconst COUNTER = { length: 4.8, depth: 1.6, height: 0.9 }\n// four columns on the free left side of the room, in two rows: counters fill in this order\nconst COUNTER_X = [-6.5, -9, -11.5, -14]\nconst COUNTER_Z = [-1, 5.5]\n// the M134 mounted on its tripod stands apart from the counters, in front of the targets and pointing at them\nexport const MOUNTED_M134_ITEM_ID = 'm134_tripod'\nconst MOUNTED_M134 = { weaponId: 'm134', at: [-3.5, 0, 2] as Vec3, rotationY: Math.PI / 2 }\n// props closer than this to a counter end have nothing next to them on one side\nconst END_MARGIN = 0.5\n// the strip of counter a weapon lying across it takes: most are slim, a few are wide (a tripod, two fuel tanks, a bow limb)\nconst DEFAULT_PITCH = 0.16\nconst PITCH_BY_ID: Readonly<Record<string, number>> = { browning_m2: 0.5, m134: 0.45, m2_flamethrower: 0.45, bow: 0.3, crossbow: 0.3 }\n// the explosives of the world stand together in the far corner (the player is at the other end, 17 m away): a bullet, fire or blast starts the chain reaction\nconst WORLD_EXPLOSIVES: Array<{ id: string; at: Vec3 }> = [\n { id: 'fuel_barrel', at: [10, 0, -8] },\n { id: 'fuel_barrel', at: [11.2, 0, -8] },\n { id: 'propane_p13', at: [10.6, 0, -9.3] },\n { id: 'car_fuel_tank', at: [8.6, 0, -9.3] },\n]\n// targets in front of the brick wall of the room, at shooting distances\nconst TARGETS: Array<{ id: string; at: Vec3 }> = [\n { id: 'target_steel_plate', at: [-1.5, 0, -7] },\n { id: 'target_plywood', at: [0, 0, -7] },\n { id: 'target_concrete', at: [1.5, 0, -7] },\n]\n\nconst EMPTY_TOOL: HostTool = { weapon: '', category: '', ammo: 0, capacity: 0, reserve: 0, reloading: false }\n\ninterface Text {\n group: string\n name: string\n counter: string\n targets: Record<string, string>\n reloadStart: string\n reloadEnd: string\n worldExplosives: Record<string, string>\n mountedM134: string\n condition: string\n conditionHint: string\n conditions: Record<string, string>\n ammoQuality: string\n ammoQualityHint: string\n ammoQualities: Record<string, string>\n soundDistance: string\n soundDistanceHint: string\n fuseLength: string\n fuseLengthHint: string\n layers: Record<'muzzle_flash' | 'casings' | 'magazines', string>\n metrics: Record<'casings_live' | 'magazines_live' | 'heat', string>\n}\n\nconst TEXT: Record<string, Text> = {\n en: {\n group: 'Weapons',\n name: 'Weapons area',\n counter: 'Weapon counter',\n targets: { target_steel_plate: 'Steel plate target', target_plywood: 'Plywood target', target_concrete: 'Concrete block target' },\n reloadStart: 'Reload started: {weapon} ({ammo}/{capacity})',\n reloadEnd: 'Reload done: {weapon} ({ammo}/{capacity})',\n worldExplosives: { fuel_barrel: 'Fuel barrel', propane_p13: 'Propane cylinder (P13)', car_fuel_tank: 'Car fuel tank' },\n mountedM134: 'M134 Minigun on its tripod',\n condition: 'Weapon condition',\n conditionHint: 'Wear of the weapon: it jams more and the metal shows it',\n conditions: { new: 'New', used: 'Used', worn: 'Worn', rusty: 'Rusty' },\n ammoQuality: 'Ammunition',\n ammoQualityHint: 'Reloaded rounds misfire more often',\n ammoQualities: { factory: 'Factory', reloaded: 'Reloaded' },\n soundDistance: 'Sound distance',\n soundDistanceHint: 'How far the listener is from the shot: farther is quieter and duller',\n fuseLength: 'Dynamite fuse length',\n fuseLengthHint: 'Metres of safety fuse (131 s per metre): a long one is set down lit, for a delayed trap',\n layers: { muzzle_flash: 'Muzzle flash', casings: 'Ejected casings', magazines: 'Dropped magazines' },\n metrics: { casings_live: 'Casings in the scene', magazines_live: 'Magazines in the scene', heat: 'Barrel heat' },\n },\n 'pt-BR': {\n group: 'Armas',\n name: 'Área de armas',\n counter: 'Balcão de armas',\n targets: { target_steel_plate: 'Alvo: chapa de aço', target_plywood: 'Alvo: compensado', target_concrete: 'Alvo: bloco de concreto' },\n reloadStart: 'Recarga iniciada: {weapon} ({ammo}/{capacity})',\n reloadEnd: 'Recarga completa: {weapon} ({ammo}/{capacity})',\n worldExplosives: { fuel_barrel: 'Barril de combustível', propane_p13: 'Botijão de gás (P13)', car_fuel_tank: 'Tanque de combustível do carro' },\n mountedM134: 'M134 Minigun no tripé',\n condition: 'Estado da arma',\n conditionHint: 'Desgaste da arma: trava mais e o metal mostra',\n conditions: { new: 'Nova', used: 'Usada', worn: 'Gasta', rusty: 'Enferrujada' },\n ammoQuality: 'Munição',\n ammoQualityHint: 'Munição recarregada falha mais',\n ammoQualities: { factory: 'De fábrica', reloaded: 'Recarregada' },\n soundDistance: 'Distância do som',\n soundDistanceHint: 'Quão longe o ouvinte está do tiro: mais longe soa mais baixo e abafado',\n fuseLength: 'Pavio da dinamite',\n fuseLengthHint: 'Metros de pavio de segurança (131 s por metro): um longo é posto no chão aceso, para armadilha com atraso',\n layers: { muzzle_flash: 'Clarão do cano', casings: 'Cápsulas ejetadas', magazines: 'Pentes que caem' },\n metrics: { casings_live: 'Cápsulas na cena', magazines_live: 'Pentes na cena', heat: 'Calor do cano' },\n },\n}\nconst textOf = (locale: string): Text => TEXT[locale] ?? (TEXT.en as Text)\nconst fill = (template: string, vars: Record<string, string | number>): string => template.replace(/\\{(\\w+)\\}/g, (_, key: string) => String(vars[key] ?? ''))\n\nconst counterProp = (name: string): WeaponProp => {\n const { length, depth, height } = COUNTER\n return {\n spec: {\n name,\n parts: [\n { id: 'top', material: 'wood_soft', shape: { kind: 'box', size: [depth, 0.05, length] }, position: [0, height - 0.025, 0] },\n { id: 'side_a', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, -length / 2 + 0.05], anchored: true },\n { id: 'side_b', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, length / 2 - 0.05], anchored: true },\n ],\n joints: [\n { a: 'top', b: 'side_a', kind: 'screw' },\n { a: 'top', b: 'side_b', kind: 'screw' },\n ],\n tags: ['furniture'],\n },\n colors: { top: 0x8a5a30, side_a: 0x6b4426, side_b: 0x6b4426 },\n }\n}\n\nconst targetProp = (id: string, name: string): WeaponProp => {\n const face: Record<string, [string, Vec3, number]> = {\n target_steel_plate: ['steel', [0.5, 0.5, 0.01], 0xb5bcc4],\n target_plywood: ['plywood', [0.6, 0.8, 0.018], 0xc9a26b],\n target_concrete: ['concrete', [0.4, 0.2, 0.2], 0x9a9a94],\n }\n const [material, size, color] = face[id]\n const spec: DestructibleSpec = {\n name,\n parts: [\n { id: 'post', material: 'steel', shape: { kind: 'box', size: [0.05, 1.1, 0.05] }, position: [0, 0.55, -0.05], anchored: true },\n { id: 'face', material, shape: { kind: 'box', size }, position: [0, 1.1 + size[1] / 2, 0] },\n ],\n joints: [{ a: 'post', b: 'face', kind: 'bolt' }],\n tags: ['target'],\n }\n return { spec, colors: { post: 0x3a3d42, face: color } }\n}\n\n/** A weapon on the counters: the gallery model when it drew one (one rigid body of its measures), the low-poly prop of its category when it did not. */\nconst weaponItem = (def: WeaponDef, name: string): TestableItem => {\n const id = `${WEAPON_ITEM_PREFIX}${def.id}`\n if (!hasWeaponModel(def.id)) return asItem(id, name, weaponProp(def, name), { weapon: def.id, movable: true })\n return {\n id,\n name,\n build: (THREE: unknown) => buildModeledProp(THREE as typeof THREE_NS, def, name) as THREE_NS.Group,\n spec: (root: unknown) => modeledPropSpec(root, def, name),\n weapon: def.id,\n movable: true,\n }\n}\n\n/** The M134 standing on a tripod: the support the `tripod` accessory gives, as a prop of its own (aim at it and press H to take the gun). */\nconst mountedM134Item = (def: WeaponDef, name: string): TestableItem => ({\n id: MOUNTED_M134_ITEM_ID,\n name,\n build: (THREE: unknown) => buildTripodMountedProp(THREE as typeof THREE_NS, def, name) as THREE_NS.Group,\n spec: (root: unknown) => modeledPropSpec(root, def, name),\n weapon: def.id,\n movable: false,\n})\n\nconst asItem = (id: string, name: string, prop: WeaponProp, extra: Partial<TestableItem> = {}): TestableItem => ({\n id,\n name,\n build: (THREE: unknown) => buildProp(THREE as typeof THREE_NS, prop),\n spec: prop.spec,\n ...extra,\n})\n\n/** Where the counters go and where each weapon lies on them: weapons side by side across the counters in order, each taking its strip, until the counter is full. */\nexport function weaponsLayout(weaponItemIds: string[], pitchOf: (itemId: string) => number = () => DEFAULT_PITCH): AreaPlacement[] {\n const usable = COUNTER.length - 2 * END_MARGIN\n const slots = COUNTER_Z.flatMap((z) => COUNTER_X.map((x) => ({ x, z })))\n const counterOf: Array<{ x: number; z: number; used: number }> = []\n const placements: AreaPlacement[] = []\n for (const item of weaponItemIds) {\n const pitch = pitchOf(item)\n let counter = counterOf[counterOf.length - 1]\n if (!counter || counter.used + pitch > usable + 1e-9) {\n const slot = slots[counterOf.length]\n if (!slot) throw new Error(`weapons area: ${weaponItemIds.length} weapons do not fit on ${slots.length} counters of ${usable.toFixed(2)} m`)\n if (pitch > usable + 1e-9) throw new Error(`weapons area: \"${item}\" takes ${pitch} m and a counter holds ${usable.toFixed(2)} m`)\n counter = { ...slot, used: 0 }\n counterOf.push(counter)\n }\n placements.push({ item, position: [counter.x, COUNTER.height + 0.01, counter.z - COUNTER.length / 2 + END_MARGIN + counter.used + pitch / 2], asleep: true })\n counter.used += pitch\n }\n const counters: AreaPlacement[] = counterOf.map(({ x, z }) => ({ item: COUNTER_ITEM_ID, position: [x, 0, z], surface: { halfSize: [COUNTER.depth / 2, COUNTER.length / 2], height: COUNTER.height } }))\n const targets: AreaPlacement[] = TARGETS.map((target) => ({ item: target.id, position: target.at }))\n const explosives: AreaPlacement[] = WORLD_EXPLOSIVES.map((explosive) => ({ item: `${WORLD_EXPLOSIVE_PREFIX}${explosive.id}`, position: explosive.at }))\n return [...counters, ...placements, ...targets, ...explosives]\n}\n\n/**\n * The weapons test area as a `TestableModule` of @adatechnology/game-contracts: every weapon of the arsenal on counters, the real model of each one the gallery drew (aim at one and\n * press H to equip it), targets at shooting distance, and, through `attach`, the weapon in the hands with its fire and reload motion,\n * ejected casings, dropped magazines and sounds, driven by the host's tool events.\n */\nexport function createWeaponsTestModule(options: WeaponsTestModuleOptions = {}): TestableModule & { readonly audio: WeaponAudio | null; readonly fx: WeaponFx | null } {\n const locale = options.locale ?? 'pt-BR'\n const arsenal = options.arsenal ?? createArsenal({ locale })\n const text = textOf(locale)\n const accessoryText = accessoryTextOf(locale)\n const audio = options.sound === false ? null : createWeaponAudio(undefined, options.seed === undefined ? {} : { seed: options.seed })\n const weaponDefs = [...arsenal.weapons.values()].filter((def) => !BODY_ACTIONS.has(def.id))\n // An archetype wearing the model of a brand weapon is the same thing twice on the counters: it stays in the catalogue (the hands still take it) but is not laid out.\n const weaponIds = weaponDefs.filter((def) => !(def.id in ARCHETYPE_MODELS)).map((def) => `${WEAPON_ITEM_PREFIX}${def.id}`)\n const pitchOf = (itemId: string): number => PITCH_BY_ID[itemId.slice(WEAPON_ITEM_PREFIX.length)] ?? DEFAULT_PITCH\n const worldExplosives = WORLD_EXPLOSIVE_IDS.flatMap((id) => {\n const def = arsenal.explosives.get(id)\n const item = def ? worldExplosiveItem(def, text.worldExplosives[id] ?? id) : undefined\n return item ? [item] : []\n })\n const worldExplosiveIds = new Set(worldExplosives.map((item) => item.id))\n const mountedM134Def = arsenal.weapons.get(MOUNTED_M134.weaponId)\n const mountedM134 = mountedM134Def && hasWeaponModel(mountedM134Def.id) ? [mountedM134Item(mountedM134Def, text.mountedM134)] : []\n let fx: WeaponFx | null = null\n let host: ModuleHost | null = null\n let soundDistance = 0\n const heatPercent = (): number => Math.min(100, (host?.tool().heat ?? 0) * 100)\n return {\n id: 'weapons_area',\n name: text.name,\n group: text.group,\n audio,\n get fx() {\n return fx\n },\n items: () => [\n ...weaponDefs.map((def) => weaponItem(def, arsenal.name(def.id))),\n asItem(COUNTER_ITEM_ID, text.counter, counterProp(text.counter), { movable: false }),\n ...TARGETS.map((target) => asItem(target.id, text.targets[target.id] ?? target.id, targetProp(target.id, text.targets[target.id] ?? target.id), { movable: false })),\n ...worldExplosives,\n ...mountedM134,\n ],\n area: (): ModuleArea => ({\n placements: [\n ...weaponsLayout(weaponIds, pitchOf).filter((placement) => !placement.item.startsWith(WORLD_EXPLOSIVE_PREFIX) || worldExplosiveIds.has(placement.item)),\n ...mountedM134.map((item) => ({ item: item.id, position: MOUNTED_M134.at, rotationY: MOUNTED_M134.rotationY, asleep: true })),\n ],\n view: { eye: [-3.4, 1.9, 9.2], target: [-9, 0.9, 1.6] },\n }),\n controls: (): ModuleControl[] => [\n {\n kind: 'choice',\n id: 'condition',\n name: text.condition,\n hint: text.conditionHint,\n options: arsenal.rules.conditions.map((entry) => ({ id: entry.id, name: text.conditions[entry.id] ?? entry.id })),\n default: options.condition ?? arsenal.rules.defaultCondition,\n },\n {\n kind: 'choice',\n id: 'ammo_quality',\n name: text.ammoQuality,\n hint: text.ammoQualityHint,\n options: arsenal.rules.ammoQualities.map((entry) => ({ id: entry.id, name: text.ammoQualities[entry.id] ?? entry.id })),\n default: arsenal.rules.defaultAmmoQuality,\n },\n { kind: 'number', id: 'sound_distance', name: text.soundDistance, hint: text.soundDistanceHint, unit: 'm', min: 0, max: SOUND_DISTANCE_MAX, step: 5, default: 0 },\n { kind: 'number', id: 'fuse_length', name: text.fuseLength, hint: text.fuseLengthHint, unit: 'm', min: 0.01, max: FUSE_LENGTH_MAX, step: 0.01, default: arsenal.explosives.get('dynamite')?.fuseLength ?? DEFAULT_FUSE_LENGTH },\n ...accessoryControls(accessoryText),\n ],\n layers: (): ModuleLayer[] => [...(['muzzle_flash', 'casings', 'magazines'] as const).map((id) => ({ id, name: text.layers[id] })), ...accessoryLayers(accessoryText)],\n metrics: (): ModuleMetric[] => [\n { id: 'casings_live', name: text.metrics.casings_live, read: () => fx?.casings ?? 0 },\n { id: 'magazines_live', name: text.metrics.magazines_live, read: () => fx?.magazines ?? 0 },\n { id: 'heat', name: text.metrics.heat, unit: '%', max: 100, digits: 0, read: heatPercent },\n ...accessoryMetrics(accessoryText, () => host?.tool() ?? EMPTY_TOOL),\n ],\n attach(lent) {\n host = lent\n const created = createWeaponFx({\n THREE: lent.THREE as typeof THREE_NS,\n scene: lent.scene as THREE_NS.Scene,\n camera: lent.camera as THREE_NS.Camera,\n arsenal,\n groundAt: lent.groundAt,\n audio,\n tool: lent.tool,\n soundDistance: () => soundDistance,\n raycast: createLaserRaycast(lent.THREE as typeof THREE_NS, lent.scene as THREE_NS.Scene, lent.camera as THREE_NS.Camera),\n ...(options.attachmentModels ? { attachmentModels: options.attachmentModels } : {}),\n ...(options.condition ? { condition: options.condition } : {}),\n ...(options.seed === undefined ? {} : { seed: options.seed }),\n })\n fx = created\n const camera = lent.camera as THREE_NS.Camera\n const accessories = createAccessoryBench({ arsenal, host: lent, text: accessoryText })\n const offBench = lent.bench?.onChange((change: BenchChange) => {\n if (accessories.handleChange(change)) return\n if (change.kind === 'layer') {\n if (change.id === 'attachments') created.layers.attachments = change.on\n else if (change.id === 'beams') created.layers.beams = change.on\n else if (change.id === 'muzzle_flash') created.layers.muzzleFlash = change.on\n else if (change.id === 'casings') created.layers.casings = change.on\n else if (change.id === 'magazines') created.layers.magazines = change.on\n } else if (change.kind === 'control' && typeof change.value === 'string') {\n if (change.id === 'condition') {\n created.setCondition(change.value)\n lent.configureTool?.({ condition: change.value })\n } else if (change.id === 'ammo_quality') lent.configureTool?.({ ammo_quality: change.value })\n } else if (change.kind === 'control' && change.id === 'sound_distance' && typeof change.value === 'number') soundDistance = change.value\n else if (change.kind === 'control' && change.id === 'fuse_length' && typeof change.value === 'number') lent.configureTool?.({ fuse_length: String(change.value) })\n })\n const offEvents = lent.on((event) => {\n if (event.type === 'explosion') {\n const away = Math.hypot(event.point[0] - camera.position.x, event.point[1] - camera.position.y, event.point[2] - camera.position.z)\n audio?.play('explosion', Math.min(1, EXPLOSION_VOLUME_BASE + event.radius * EXPLOSION_VOLUME_PER_METRE), away)\n return\n }\n const tool = lent.tool()\n created.handle(event, tool)\n if (event.type === 'reload') lent.log(fill(event.phase === 'start' ? text.reloadStart : text.reloadEnd, { weapon: arsenal.name(event.weapon), ammo: tool.ammo, capacity: tool.capacity }), { weapon: event.weapon, phase: event.phase })\n })\n const offFrame = lent.onFrame((dt) => created.update(dt))\n created.handle({ type: 'tool', weapon: lent.tool().weapon }, lent.tool())\n return () => {\n accessories.dispose()\n offBench?.()\n offEvents()\n offFrame()\n created.dispose()\n audio?.dispose()\n fx = null\n host = null\n }\n },\n }\n}\n"],"mappings":"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c;QACZ;QACA;QACA;QACA;QACA;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;QACA;QACA;QACA;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;QACA;QACA;QACA;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;QACA;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,SAAW;MACb;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;QACA;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,SAAW;MACb;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;QACA;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,SAAW;MACb;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;QACA;MACF;MACA,YAAc;QACZ;QACA;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,SAAW;MACb;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;QACA;MACF;MACA,YAAc;QACZ;QACA;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,SAAW;MACb;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;QACA;MACF;MACA,YAAc;QACZ;QACA;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,SAAW;QACX,QAAU;QACV,cAAgB;MAClB;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;QACA;MACF;MACA,YAAc;QACZ;QACA;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,SAAW;QACX,QAAU;QACV,cAAgB;MAClB;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,SAAW;MACb;MACA,WAAa;MACb,SAAW,CAAC;IACd;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,SAAW;MACb;MACA,WAAa;MACb,SAAW,CAAC;IACd;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,SAAW;MACb;MACA,WAAa;MACb,SAAW,CAAC;IACd;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,MAAQ;QACN,QAAU;MACZ;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;QACA;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;UACP,MAAQ;QACV;QACA;UACE,MAAQ;UACR,KAAO;UACP,MAAQ;QACV;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;QACA;MACF;MACA,UAAY;MACZ,MAAQ;QACN,QAAU;MACZ;MACA,SAAW,CAAC;IACd;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;MACF;MACA,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;QACA;MACF;MACA,UAAY;MACZ,MAAQ;QACN,QAAU;MACZ;MACA,SAAW,CAAC;IACd;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;MACF;MACA,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;QACA;MACF;MACA,UAAY;MACZ,MAAQ;QACN,QAAU;MACZ;MACA,SAAW,CAAC;IACd;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;QACA;QACA;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,SAAW;QACX,OAAS;QACT,aAAe;QACf,cAAgB;MAClB;MACA,MAAQ;QACN,QAAU;QACV,UAAY;MACd;MACA,SAAW,CAAC;IACd;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;QACA;QACA;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,OAAS;QACT,OAAS;QACT,aAAe;MACjB;MACA,MAAQ;QACN,QAAU;QACV,UAAY;MACd;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;UACP,MAAQ;QACV;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,YAAc;QACZ;QACA;QACA;QACA;QACA;QACA;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,YAAc;QACZ;QACA;QACA;QACA;QACA;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;QACA;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,cAAgB;MAChB,YAAc;QACZ;QACA;QACA;QACA;QACA;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,YAAc;QACZ;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,YAAc;QACZ;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;MACF;MACA,UAAY;MACZ,YAAc;QACZ;QACA;QACA;QACA;QACA;QACA;QACA;QACA;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;MACF;MACA,OAAS;MACT,YAAc;QACZ;QACA;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;MACF;MACA,YAAc;QACZ;MACF;MACA,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,MAAQ;QACN,QAAU;QACV,UAAY;MACd;MACA,WAAa;MACb,SAAW;QACT;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;UACP,MAAQ;QACV;QACA;UACE,MAAQ;UACR,KAAO;QACT;QACA;UACE,MAAQ;UACR,KAAO;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,QAAU;QACR;MACF;MACA,YAAc;QACZ;MACF;MACA,MAAQ;MACR,SAAW;MACX,OAAS;MACT,SAAW;QACT;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,SAAW;MACb;MACA,WAAa;MACb,SAAW,CAAC;IACd;EACF;ACrkCA,MAAA,qBAAA;IACE;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,QAAU;QACV,QAAU;QACV,QAAU;QACV,OAAS;QACT,KAAO;QACP,OAAS;MACX;MACA,MAAQ;IACV;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,QAAU;QACV,QAAU;QACV,QAAU;QACV,OAAS;QACT,KAAO;QACP,OAAS;MACX;MACA,MAAQ;IACV;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;UACA;QACF;QACA,OAAS;QACT,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;UACA;QACF;QACA,OAAS;QACT,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MA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ACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,SAAW;MACX,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,SAAW;MACX,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,SAAW;MACX,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,SAAW;QACT;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,SAAW;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,SAAW;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;MACF;IACF;EACF;AC3oBA,MAAA,qBAAA;IACE;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;MACR,UAAY;QACV;MACF;MACA,MAAQ;MACR,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;MACR,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;QACA;QACA;MACF;MACA,OAAS;QACP,MAAQ;QACR,MAAQ;QACR,WAAa;UACX;UACA;QACF;MACF;MACA,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,YAAc;MACd,UAAY;MACZ,eAAiB;MACjB,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,MAAQ;MACR,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,MAAQ;QACN,cAAgB;QAChB,QAAU;MACZ;MACA,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,UAAY;QACV,QAAU;QACV,UAAY;QACZ,QAAU;MACZ;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,WAAa;QACX;QACA;MACF;MACA,aAAe;MACf,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;QACA;QACA;MACF;MACA,OAAS;QACP,MAAQ;QACR,MAAQ;QACR,WAAa;UACX;UACA;QACF;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;QACA;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,MAAQ;UACN;UACA;QACF;QACA,WAAa;QACb,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;QACA;QACA;MACF;MACA,OAAS;QACP,MAAQ;QACR,MAAQ;QACR,WAAa;MACf;MACA,SAAW;QACT;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;QACA;MACF;MACA,OAAS;QACP,MAAQ;QACR,WAAa;MACf;MACA,SAAW;QACT;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;MACF;IACF;EACF;ACxaA,MAAA,4BAAA;IACE;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,WAAa;QACb,QAAU;QACV,QAAU;QACV,MAAQ;QACR,YAAc;QACd,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,WAAa;QACb,QAAU;QACV,QAAU;QACV,MAAQ;QACR,YAAc;QACd,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,WAAa;QACb,QAAU;QACV,QAAU;QACV,MAAQ;QACR,YAAc;QACd,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;QACA;MACF;MACA,WAAa;MACb,SAAW;QACT;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,WAAa;QACb,QAAU;QACV,QAAU;QACV,MAAQ;QACR,YAAc;QACd,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;QACA;MACF;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;EACF;ACpGA,MAAA,mBAAA;IACE;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU,CAAC;MACX,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;QACX;QACA,KAAO;QACP,iBAAmB;UACjB;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU,CAAC;MACX,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU,CAAC;MACX,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,OAAS;QACT,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;YACA;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;YACA;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;YACA;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;YACA;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;YACA;UACF;UACA,SAAW;YACT;YACA;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;YACA;UACF;UACA,SAAW;YACT;YACA;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;YACA;UACF;UACA,SAAW;YACT;YACA;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;YACA;UACF;UACA,SAAW;YACT;YACA;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,OAAS;QACT,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;UACT,UAAY;QACd;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;UACT,UAAY;QACd;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;YACA;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,aAAe;MACjB;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,aAAe;MACjB;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;YACA;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;UACT,UAAY;QACd;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;QACA;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;QACP,iBAAmB;UACjB;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;UACT,UAAY;QACd;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,YAAc;QACd,UAAY;QACZ,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,QAAU;QACV,OAAS;QACT,gBAAkB;QAClB,WAAa;QACb,QAAU;UACR;UACA;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,OAAS;QACT,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;UACT,UAAY;QACd;MACF;MACA,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;MACjB;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;UACA;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;UACA;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;UACT,UAAY;QACd;MACF;MACA,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;UACT,UAAY;QACd;MACF;MACA,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;MACA,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,aAAe;MACjB;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;UACA;QACF;QACA,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;MACV;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU;QACR;UACE,IAAM;UACN,OAAS;QACX;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;MACX,OAAS;QACP,MAAQ;QACR,UAAY;MACd;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,MAAQ;UACN,WAAa;UACb,aAAe;QACjB;QACA,UAAY;UACV;UACA;QACF;QACA,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;MACA,QAAU;QACR;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;QACA;UACE,MAAQ;UACR,YAAc;YACZ;UACF;UACA,SAAW;YACT;UACF;QACF;MACF;MACA,QAAU,CAAC;IACb;EACF;ACt1OA,MAAA,oBAAA;IACE;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,YAAc;QACd,UAAY;QACZ,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,QAAU;QACV,OAAS;QACT,gBAAkB;QAClB,WAAa;QACb,uBAAyB;QACzB,QAAU;UACR;UACA;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,YAAc;QACd,UAAY;QACZ,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,QAAU;QACV,YAAc;QACd,OAAS;QACT,gBAAkB;QAClB,WAAa;QACb,uBAAyB;QACzB,QAAU;UACR;UACA;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,YAAc;QACd,UAAY;QACZ,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,QAAU;QACV,YAAc;QACd,OAAS;QACT,gBAAkB;QAClB,WAAa;QACb,uBAAyB;QACzB,QAAU;UACR;UACA;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,YAAc;QACd,UAAY;QACZ,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,QAAU;QACV,OAAS;QACT,gBAAkB;QAClB,WAAa;QACb,uBAAyB;QACzB,QAAU;UACR;UACA;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;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","names":["place","result","length","explosive","EPS","stage","part","distance","spread","window","result","handled","distance","scope","metal","distance","sound","sum","box","length","box","box","length","PI","length","box","box","box","PI","round","box","box","round","PI","length","box","box","box","PI","slide","metal","box","PI","box","slide","PI","box","metal","box","length","box","box","PI","box","box","box","PI","box","box","length","box","PI","box","length","box","length","sum","box","length","caliberOf","round","PI","slide","c","box","box","length","box","length","dot","DEFAULT_RANGE","box","length","box","length","box","length","swivel","length","length","box","slide","sum","move","length","PI","PI","distance","PI","round","PI","HAND_OFFSET","fittedOf","move","distance","length","box","SHAPES","length"]}