@eveshipfit/ui-ingame 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -2,8 +2,8 @@ import './style.css';
2
2
  import { c } from "react/compiler-runtime";
3
3
  import { Activity, Fragment, createContext, useContext, useDeferredValue, useEffect, useEffectEvent, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
4
4
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
5
- import { UNIFORM, formatClock, formatDuration, formatNumber, useAttribute, useAttributeTooltip, useBayContents, useBayUsage, useBoosters, useBrowse, useCanFit, useChargeSearch, useChargeTree, useChargedModules, useCharges, useDamageProfiles, useDrag, useDroneRoom, useEngine, useFighterTubeUsage, useFighterTubes, useFit, useFitHistory, useFitPrice, useFitStore, useHardpoints, useHasRoom, useHullRefuses, useHullTree, useImages, useImplantSearch, useImplantTree, useImplants, useInfo, useLocalFits, useMissingSkills, useModes, useModuleSearch, useModuleTree, usePersonalFits, usePlacement, usePreview, useRackUsage, useRefusal, useSde, useShowInfo, useShownSnapshot, useSlots, useSnapshot, useStats, useType, useTypeBonuses, useTypePrice } from "@eveshipfit/react-hooks";
6
- import { baseValue, squadronSize, tubeTakes } from "@eveshipfit/fitting";
5
+ import { UNIFORM, formatAttribute, formatClock, formatDuration, formatNumber, useAttribute, useAttributeTooltip, useBayContents, useBayUsage, useBoosters, useBrowse, useCanFit, useChargeSearch, useChargeTree, useChargedModules, useCharges, useDamageProfiles, useDrag, useDroneRoom, useEngine, useFighterTubeUsage, useFighterTubes, useFit, useFitHistory, useFitPrice, useFitStore, useHardpoints, useHasRoom, useHullRefuses, useHullTree, useImages, useImplantSearch, useImplantTree, useImplants, useInfo, useLocalFits, useMissingSkills, useModes, useModuleSearch, useModuleTree, useMutate, usePersonalFits, usePlacement, usePreview, useRackUsage, useRefusal, useSde, useShowInfo, useShownSnapshot, useSlots, useSnapshot, useStats, useType, useTypeBonuses, useTypePrice } from "@eveshipfit/react-hooks";
6
+ import { baseValue, canMutate, mutaplasmidsOf, mutationRanges, mutationRollOf, parseItemLink, parseMutationText, rollFits, rollMutation, squadronSize, tubeTakes } from "@eveshipfit/fitting";
7
7
  // src/primitives/Dialog/Dialog.module.css
8
8
  var Dialog_module_default = {
9
9
  "close": "kwi1cG_close",
@@ -978,7 +978,7 @@ function SlotPress(t0) {
978
978
  className,
979
979
  "aria-label": label,
980
980
  onClick: onPress,
981
- onKeyDown: _temp$22
981
+ onKeyDown: _temp$23
982
982
  });
983
983
  $[0] = className;
984
984
  $[1] = label;
@@ -987,7 +987,7 @@ function SlotPress(t0) {
987
987
  } else t1 = $[3];
988
988
  return t1;
989
989
  }
990
- function _temp$22(event) {
990
+ function _temp$23(event) {
991
991
  if (event.key !== "Enter" && event.key !== " ") return;
992
992
  event.preventDefault();
993
993
  event.currentTarget.dispatchEvent(new MouseEvent("click", {
@@ -1008,6 +1008,7 @@ var WheelSlot_module_default = {
1008
1008
  "frame": "T6VD6G_frame",
1009
1009
  "icon": "T6VD6G_icon",
1010
1010
  "module": "T6VD6G_module",
1011
+ "mutated": "T6VD6G_mutated",
1011
1012
  "press": "T6VD6G_press",
1012
1013
  "slot": "T6VD6G_slot"
1013
1014
  };
@@ -1031,7 +1032,7 @@ const ammoBars = [
1031
1032
  3.6
1032
1033
  ];
1033
1034
  const emptyIconScale = { rig: 1.2 };
1034
- function WheelSlot({ rack, angle, typeId, typeName, chargeTypeId, chargeable = false, state = "online", activatable = false, available = true, preview = false, tooltip, onPress, onDragStart, onDragEnd, label, actions: showActions = true, onUnfit, onRemoveCharge, onTogglePower, onShowInfo, onShowChargeInfo, className, style, ...props }) {
1035
+ function WheelSlot({ rack, angle, typeId, typeName, chargeTypeId, chargeable = false, state = "online", activatable = false, available = true, preview = false, mutated = false, tooltip, onPress, onDragStart, onDragEnd, label, actions: showActions = true, onUnfit, onRemoveCharge, onTogglePower, onShowInfo, onShowChargeInfo, className, style, ...props }) {
1035
1036
  const images = useImages();
1036
1037
  const texture = (name) => ({ "--texture": `url(${images.uiTexture(name)})` });
1037
1038
  const fitted = typeId !== void 0;
@@ -1106,6 +1107,7 @@ function WheelSlot({ rack, angle, typeId, typeName, chargeTypeId, chargeable = f
1106
1107
  className: WheelSlot_module_default.frame,
1107
1108
  style: texture(frameTexture(fitted, preview, state, activatable))
1108
1109
  }),
1110
+ fitted && mutated && /* @__PURE__ */ jsx("span", { className: WheelSlot_module_default.mutated }),
1109
1111
  fitted && chargeable && ammoBars.map((offset) => /* @__PURE__ */ jsx("span", {
1110
1112
  className: WheelSlot_module_default.ammo,
1111
1113
  style: { "--offset": `${offset}deg` },
@@ -1401,7 +1403,7 @@ function useDecoded(src) {
1401
1403
  image.decode().then(() => {
1402
1404
  decoded.add(src);
1403
1405
  setReady(src);
1404
- }, _temp$21);
1406
+ }, _temp$22);
1405
1407
  };
1406
1408
  t1 = [src];
1407
1409
  $[0] = src;
@@ -1421,7 +1423,7 @@ function useDecoded(src) {
1421
1423
  } else t2 = $[5];
1422
1424
  return t2;
1423
1425
  }
1424
- function _temp$21() {}
1426
+ function _temp$22() {}
1425
1427
  function WheelGauge(t0) {
1426
1428
  const $ = c(15);
1427
1429
  const { resource, used, total, valueText } = t0;
@@ -1896,18 +1898,18 @@ function Menu(t0) {
1896
1898
  role: "menu",
1897
1899
  tabIndex: -1,
1898
1900
  onToggle: t4,
1899
- onKeyDown: _temp$20,
1901
+ onKeyDown: _temp$21,
1900
1902
  onClick: stopped,
1901
1903
  onDoubleClick: stopped,
1902
1904
  onPointerDown: stopped,
1903
1905
  onMouseDown: stopped,
1904
- onContextMenu: _temp2$10,
1906
+ onContextMenu: _temp2$11,
1905
1907
  children: opened.entries.map((entry, index) => entry === "separator" ? /* @__PURE__ */ jsx("hr", { className: ContextMenu_module_default.separator }, index) : /* @__PURE__ */ jsxs("button", {
1906
1908
  type: "button",
1907
1909
  role: "menuitem",
1908
1910
  tabIndex: -1,
1909
1911
  onClick: () => select(entry),
1910
- onPointerMove: _temp3$5,
1912
+ onPointerMove: _temp3$6,
1911
1913
  children: [/* @__PURE__ */ jsx("span", {
1912
1914
  className: ContextMenu_module_default.icon,
1913
1915
  children: entry.icon && /* @__PURE__ */ jsx(Icon, { name: entry.icon })
@@ -1920,14 +1922,14 @@ function Menu(t0) {
1920
1922
  } else t3 = $[7];
1921
1923
  return t3;
1922
1924
  }
1923
- function _temp3$5(event_2) {
1925
+ function _temp3$6(event_2) {
1924
1926
  return event_2.currentTarget.focus();
1925
1927
  }
1926
- function _temp2$10(event_1) {
1928
+ function _temp2$11(event_1) {
1927
1929
  event_1.preventDefault();
1928
1930
  event_1.stopPropagation();
1929
1931
  }
1930
- function _temp$20(event_0) {
1932
+ function _temp$21(event_0) {
1931
1933
  event_0.stopPropagation();
1932
1934
  walk(event_0);
1933
1935
  }
@@ -2779,8 +2781,8 @@ function RemoteCapacitorTransmitter(props) {
2779
2781
  return t2;
2780
2782
  }
2781
2783
  // src/components/FittingWheel/ModuleLines/parts/Bonus.tsx
2782
- const percent = unit("%");
2783
- function useBonus(name, itemRef, { decimals = 0, fixed, format = percent } = {}) {
2784
+ const percent$1 = unit("%");
2785
+ function useBonus(name, itemRef, { decimals = 0, fixed, format = percent$1 } = {}) {
2784
2786
  const { value, text } = useAttribute(name, {
2785
2787
  of: itemRef,
2786
2788
  decimals,
@@ -2804,7 +2806,7 @@ function BonusLine$1(t0) {
2804
2806
  itemRef,
2805
2807
  name,
2806
2808
  decimals: 0,
2807
- format: percent,
2809
+ format: percent$1,
2808
2810
  hideZero: true
2809
2811
  });
2810
2812
  $[0] = itemRef;
@@ -2825,7 +2827,7 @@ function SensorStrengths(t0) {
2825
2827
  if ($[0] !== strengths) {
2826
2828
  t4 = Symbol.for("react.early_return_sentinel");
2827
2829
  bb0: {
2828
- const shown = strengths.filter(_temp$19);
2830
+ const shown = strengths.filter(_temp$20);
2829
2831
  if (shown.length === 0) {
2830
2832
  t4 = null;
2831
2833
  break bb0;
@@ -2833,7 +2835,7 @@ function SensorStrengths(t0) {
2833
2835
  T0 = Attribute;
2834
2836
  t3 = "ECMResistance";
2835
2837
  t1 = ModuleTooltip_module_default.block;
2836
- t2 = shown.map(_temp2$9);
2838
+ t2 = shown.map(_temp2$10);
2837
2839
  }
2838
2840
  $[0] = strengths;
2839
2841
  $[1] = T0;
@@ -2873,14 +2875,14 @@ function SensorStrengths(t0) {
2873
2875
  return t6;
2874
2876
  }
2875
2877
  /** The four ECM jammer strengths, like "5.8 Gravimetric ECM Jammer Strength". */
2876
- function _temp2$9(strength) {
2878
+ function _temp2$10(strength) {
2877
2879
  return /* @__PURE__ */ jsxs("span", { children: [
2878
2880
  strength.text,
2879
2881
  " ",
2880
2882
  strength.displayName
2881
2883
  ] }, strength.name);
2882
2884
  }
2883
- function _temp$19(t0) {
2885
+ function _temp$20(t0) {
2884
2886
  const { value } = t0;
2885
2887
  return value;
2886
2888
  }
@@ -2927,15 +2929,15 @@ function Cloak(t0) {
2927
2929
  itemRef,
2928
2930
  name: "maxVelocityModifier",
2929
2931
  decimals: 0,
2930
- format: _temp$18
2932
+ format: _temp$19
2931
2933
  });
2932
2934
  $[0] = itemRef;
2933
2935
  $[1] = t1;
2934
2936
  } else t1 = $[1];
2935
2937
  return t1;
2936
2938
  }
2937
- function _temp$18(value, format) {
2938
- return percent((value - 1) * 100, format);
2939
+ function _temp$19(value, format) {
2940
+ return percent$1((value - 1) * 100, format);
2939
2941
  }
2940
2942
  // src/components/FittingWheel/ModuleLines/CommandBonus.tsx
2941
2943
  function CommandBonus(t0) {
@@ -2948,7 +2950,7 @@ function CommandBonus(t0) {
2948
2950
  name: "commandBonus",
2949
2951
  decimals: 2,
2950
2952
  fixed: true,
2951
- format: percent,
2953
+ format: percent$1,
2952
2954
  layout: nameFirst
2953
2955
  });
2954
2956
  $[0] = itemRef;
@@ -3668,7 +3670,7 @@ function Resistance$1(t0) {
3668
3670
  const t1 = useLayers(itemRef);
3669
3671
  let t2;
3670
3672
  if ($[0] !== t1) {
3671
- const layers = t1.filter(_temp2$8);
3673
+ const layers = t1.filter(_temp2$9);
3672
3674
  t2 = layers.map((layer) => /* @__PURE__ */ jsx(Layer, {
3673
3675
  ...layer,
3674
3676
  withIcon: layers.length > 1
@@ -3679,11 +3681,11 @@ function Resistance$1(t0) {
3679
3681
  return t2;
3680
3682
  }
3681
3683
  /** The resistances a module gives, for every layer. */
3682
- function _temp2$8(t0) {
3684
+ function _temp2$9(t0) {
3683
3685
  const { resistances } = t0;
3684
- return resistances.some(_temp$17);
3686
+ return resistances.some(_temp$18);
3685
3687
  }
3686
- function _temp$17(t0) {
3688
+ function _temp$18(t0) {
3687
3689
  const { value } = t0;
3688
3690
  return value !== 1;
3689
3691
  }
@@ -3693,13 +3695,13 @@ function DamageControl(t0) {
3693
3695
  const t1 = useLayers(itemRef);
3694
3696
  let t2;
3695
3697
  if ($[0] !== t1) {
3696
- t2 = t1.map(_temp3$4);
3698
+ t2 = t1.map(_temp3$5);
3697
3699
  $[0] = t1;
3698
3700
  $[1] = t2;
3699
3701
  } else t2 = $[1];
3700
3702
  return t2;
3701
3703
  }
3702
- function _temp3$4(layer) {
3704
+ function _temp3$5(layer) {
3703
3705
  return /* @__PURE__ */ jsx(Layer, {
3704
3706
  ...layer,
3705
3707
  withIcon: true
@@ -3864,7 +3866,7 @@ function useResistance(name, itemRef) {
3864
3866
  return t1;
3865
3867
  }
3866
3868
  function _temp5$1(resonance, format) {
3867
- return percent((1 - resonance) * 100, format);
3869
+ return percent$1((1 - resonance) * 100, format);
3868
3870
  }
3869
3871
  // src/components/FittingWheel/ModuleLines/ResistanceBonus.tsx
3870
3872
  function ResistanceBonus(t0) {
@@ -3890,7 +3892,7 @@ function ResistanceBonus(t0) {
3890
3892
  t3,
3891
3893
  t4,
3892
3894
  t5
3893
- ].filter(_temp$16);
3895
+ ].filter(_temp$17);
3894
3896
  const [first] = bonuses;
3895
3897
  if (first === void 0) {
3896
3898
  t6 = null;
@@ -3900,7 +3902,7 @@ function ResistanceBonus(t0) {
3900
3902
  t6 = /* @__PURE__ */ jsxs(Attribute, {
3901
3903
  name: first.name,
3902
3904
  children: [
3903
- percent(first.value ?? 0, { decimals: 0 }),
3905
+ percent$1(first.value ?? 0, { decimals: 0 }),
3904
3906
  " ",
3905
3907
  first.displayName
3906
3908
  ]
@@ -3925,7 +3927,7 @@ function ResistanceBonus(t0) {
3925
3927
  className: ModuleTooltip_module_default.block,
3926
3928
  children: ["Resistance Bonus:", /* @__PURE__ */ jsx("span", {
3927
3929
  className: ModuleTooltip_module_default.bonuses,
3928
- children: bonuses.map(_temp2$7)
3930
+ children: bonuses.map(_temp2$8)
3929
3931
  })]
3930
3932
  });
3931
3933
  $[7] = bonuses;
@@ -3933,14 +3935,14 @@ function ResistanceBonus(t0) {
3933
3935
  } else t7 = $[8];
3934
3936
  return t7;
3935
3937
  }
3936
- function _temp2$7(t0) {
3938
+ function _temp2$8(t0) {
3937
3939
  const { name, text } = t0;
3938
3940
  return /* @__PURE__ */ jsx(Bonus, {
3939
3941
  name,
3940
3942
  text
3941
3943
  }, name);
3942
3944
  }
3943
- function _temp$16(bonus) {
3945
+ function _temp$17(bonus) {
3944
3946
  return bonus.value;
3945
3947
  }
3946
3948
  // src/components/FittingWheel/ModuleLines/SensorBooster.tsx
@@ -4041,15 +4043,15 @@ function SignatureSuppressor(t0) {
4041
4043
  itemRef,
4042
4044
  name: "signatureSuppressorSignatureRadiusBonusPassive",
4043
4045
  decimals: 0,
4044
- format: _temp$15
4046
+ format: _temp$16
4045
4047
  });
4046
4048
  $[0] = itemRef;
4047
4049
  $[1] = t1;
4048
4050
  } else t1 = $[1];
4049
4051
  return t1;
4050
4052
  }
4051
- function _temp$15(value, format) {
4052
- return percent((1 - value) * 100, format);
4053
+ function _temp$16(value, format) {
4054
+ return percent$1((1 - value) * 100, format);
4053
4055
  }
4054
4056
  // src/components/FittingWheel/ModuleLines/Smartbomb.tsx
4055
4057
  const hp = unit(" HP");
@@ -4149,7 +4151,7 @@ function StasisWebifier(props) {
4149
4151
  t0 = {
4150
4152
  of: props.itemRef,
4151
4153
  decimals: 0,
4152
- format: _temp$14
4154
+ format: _temp$15
4153
4155
  };
4154
4156
  $[0] = props.itemRef;
4155
4157
  $[1] = t0;
@@ -4179,8 +4181,8 @@ function StasisWebifier(props) {
4179
4181
  } else t3 = $[8];
4180
4182
  return t3;
4181
4183
  }
4182
- function _temp$14(value, format) {
4183
- return percent(-value, format);
4184
+ function _temp$15(value, format) {
4185
+ return percent$1(-value, format);
4184
4186
  }
4185
4187
  // src/components/FittingWheel/ModuleLines/TrackingComputer.tsx
4186
4188
  function TrackingComputer(props) {
@@ -4242,7 +4244,7 @@ function BonusLine(t0) {
4242
4244
  name,
4243
4245
  decimals: 0,
4244
4246
  fallback: 0,
4245
- format: percent,
4247
+ format: percent$1,
4246
4248
  layout: nameFirst
4247
4249
  });
4248
4250
  $[0] = itemRef;
@@ -4516,8 +4518,8 @@ function ModuleLines(props) {
4516
4518
  // src/components/FittingWheel/ModuleTooltip.tsx
4517
4519
  /** What EVE shows when hovering a fitted module. */
4518
4520
  function ModuleTooltip(t0) {
4519
- const $ = c(21);
4520
- const { rack, itemRef, typeId, chargeTypeId, state, maxState } = t0;
4521
+ const $ = c(24);
4522
+ const { rack, itemRef, typeId, mutatedFrom, chargeTypeId, state, maxState } = t0;
4521
4523
  let t1;
4522
4524
  if ($[0] !== maxState || $[1] !== rack || $[2] !== state) {
4523
4525
  t1 = moduleStatus(rack, state, maxState);
@@ -4534,56 +4536,64 @@ function ModuleTooltip(t0) {
4534
4536
  $[5] = t2;
4535
4537
  } else t2 = $[5];
4536
4538
  let t3;
4537
- if ($[6] !== chargeTypeId || $[7] !== itemRef) {
4538
- t3 = chargeTypeId !== void 0 && /* @__PURE__ */ jsx(ChargeRow, {
4539
+ if ($[6] !== mutatedFrom) {
4540
+ t3 = mutatedFrom !== void 0 && /* @__PURE__ */ jsx(MutatedFrom, { typeId: mutatedFrom });
4541
+ $[6] = mutatedFrom;
4542
+ $[7] = t3;
4543
+ } else t3 = $[7];
4544
+ let t4;
4545
+ if ($[8] !== chargeTypeId || $[9] !== itemRef) {
4546
+ t4 = chargeTypeId !== void 0 && /* @__PURE__ */ jsx(ChargeRow, {
4539
4547
  itemRef,
4540
4548
  typeId: chargeTypeId
4541
4549
  });
4542
- $[6] = chargeTypeId;
4543
- $[7] = itemRef;
4544
- $[8] = t3;
4545
- } else t3 = $[8];
4546
- let t4;
4547
- if ($[9] !== itemRef || $[10] !== state || $[11] !== typeId) {
4548
- t4 = /* @__PURE__ */ jsx(ModuleLines, {
4550
+ $[8] = chargeTypeId;
4551
+ $[9] = itemRef;
4552
+ $[10] = t4;
4553
+ } else t4 = $[10];
4554
+ let t5;
4555
+ if ($[11] !== itemRef || $[12] !== state || $[13] !== typeId) {
4556
+ t5 = /* @__PURE__ */ jsx(ModuleLines, {
4549
4557
  typeId,
4550
4558
  itemRef,
4551
4559
  state
4552
4560
  });
4553
- $[9] = itemRef;
4554
- $[10] = state;
4555
- $[11] = typeId;
4556
- $[12] = t4;
4557
- } else t4 = $[12];
4558
- let t5;
4559
- if ($[13] !== status.text || $[14] !== status.tone) {
4560
- t5 = /* @__PURE__ */ jsx("span", {
4561
+ $[11] = itemRef;
4562
+ $[12] = state;
4563
+ $[13] = typeId;
4564
+ $[14] = t5;
4565
+ } else t5 = $[14];
4566
+ let t6;
4567
+ if ($[15] !== status.text || $[16] !== status.tone) {
4568
+ t6 = /* @__PURE__ */ jsx("span", {
4561
4569
  className: ModuleTooltip_module_default.status,
4562
4570
  "data-tone": status.tone,
4563
4571
  children: status.text
4564
4572
  });
4565
- $[13] = status.text;
4566
- $[14] = status.tone;
4567
- $[15] = t5;
4568
- } else t5 = $[15];
4569
- let t6;
4570
- if ($[16] !== t2 || $[17] !== t3 || $[18] !== t4 || $[19] !== t5) {
4571
- t6 = /* @__PURE__ */ jsxs("span", {
4573
+ $[15] = status.text;
4574
+ $[16] = status.tone;
4575
+ $[17] = t6;
4576
+ } else t6 = $[17];
4577
+ let t7;
4578
+ if ($[18] !== t2 || $[19] !== t3 || $[20] !== t4 || $[21] !== t5 || $[22] !== t6) {
4579
+ t7 = /* @__PURE__ */ jsxs("span", {
4572
4580
  className: ModuleTooltip_module_default.tooltip,
4573
4581
  children: [
4574
4582
  t2,
4575
4583
  t3,
4576
4584
  t4,
4577
- t5
4585
+ t5,
4586
+ t6
4578
4587
  ]
4579
4588
  });
4580
- $[16] = t2;
4581
- $[17] = t3;
4582
- $[18] = t4;
4583
- $[19] = t5;
4584
- $[20] = t6;
4585
- } else t6 = $[20];
4586
- return t6;
4589
+ $[18] = t2;
4590
+ $[19] = t3;
4591
+ $[20] = t4;
4592
+ $[21] = t5;
4593
+ $[22] = t6;
4594
+ $[23] = t7;
4595
+ } else t7 = $[23];
4596
+ return t7;
4587
4597
  }
4588
4598
  function TypeRow(t0) {
4589
4599
  const $ = c(5);
@@ -4614,6 +4624,24 @@ function TypeRow(t0) {
4614
4624
  } else t3 = $[4];
4615
4625
  return t3;
4616
4626
  }
4627
+ function MutatedFrom(t0) {
4628
+ const $ = c(2);
4629
+ const { typeId } = t0;
4630
+ const base = useType(typeId);
4631
+ if (base === void 0) return null;
4632
+ const t1 = `Mutated ${base.name}`;
4633
+ let t2;
4634
+ if ($[0] !== t1) {
4635
+ t2 = /* @__PURE__ */ jsx("span", {
4636
+ className: `${ModuleTooltip_module_default.iconless} ${ModuleTooltip_module_default.status}`,
4637
+ "data-tone": "muted",
4638
+ children: t1
4639
+ });
4640
+ $[0] = t1;
4641
+ $[1] = t2;
4642
+ } else t2 = $[1];
4643
+ return t2;
4644
+ }
4617
4645
  /** The loaded charge, with how many; crystals and scripts without. */
4618
4646
  function ChargeRow(t0) {
4619
4647
  const $ = c(5);
@@ -4712,7 +4740,7 @@ const rackNames = {
4712
4740
  };
4713
4741
  /** What a slot of the fit shows, and what clicking, dragging and dropping on it does. */
4714
4742
  function useFittingSlot(rack, index, content, available, t0) {
4715
- const $ = c(124);
4743
+ const $ = c(144);
4716
4744
  const readOnly = t0 === void 0 ? false : t0;
4717
4745
  const store = useFitStore();
4718
4746
  const sde = useSde();
@@ -4724,6 +4752,7 @@ function useFittingSlot(rack, index, content, available, t0) {
4724
4752
  const shownCopy = useRef(false);
4725
4753
  const { browse } = useBrowse();
4726
4754
  const { show: showInfo } = useShowInfo();
4755
+ const { show: showMutate } = useMutate();
4727
4756
  const { open, menu } = useContextMenu();
4728
4757
  const item = content?.item;
4729
4758
  const stats = content?.stats;
@@ -4785,16 +4814,18 @@ function useFittingSlot(rack, index, content, available, t0) {
4785
4814
  const t4 = content?.preview;
4786
4815
  const t5 = item?.type_id;
4787
4816
  const t6 = type?.name;
4788
- const t7 = charges.length > 0;
4789
- const t8 = stats?.state;
4790
- const t9 = stats?.maxState === "active" || stats?.maxState === "overload";
4791
- const t10 = empty ? `Empty ${rackNames[rack]}` : type && stats && `${type.name}, ${stats.state}`;
4792
- let t11;
4817
+ const t7 = item?.mutation !== void 0;
4818
+ const t8 = charges.length > 0;
4819
+ const t9 = stats?.state;
4820
+ const t10 = stats?.maxState === "active" || stats?.maxState === "overload";
4821
+ const t11 = empty ? `Empty ${rackNames[rack]}` : type && stats && `${type.name}, ${stats.state}`;
4822
+ let t12;
4793
4823
  if ($[18] !== content || $[19] !== item || $[20] !== rack || $[21] !== ref || $[22] !== stats) {
4794
- t11 = item && stats && ref !== void 0 && !content.preview ? /* @__PURE__ */ jsx(ModuleTooltip, {
4824
+ t12 = item && stats && ref !== void 0 && !content.preview ? /* @__PURE__ */ jsx(ModuleTooltip, {
4795
4825
  rack,
4796
4826
  itemRef: ref,
4797
4827
  typeId: item.type_id,
4828
+ mutatedFrom: item.mutation?.base,
4798
4829
  chargeTypeId: item.charge?.type_id,
4799
4830
  state: stats.state,
4800
4831
  maxState: stats.maxState
@@ -4804,108 +4835,150 @@ function useFittingSlot(rack, index, content, available, t0) {
4804
4835
  $[20] = rack;
4805
4836
  $[21] = ref;
4806
4837
  $[22] = stats;
4807
- $[23] = t11;
4808
- } else t11 = $[23];
4809
- let t12;
4810
- if ($[24] !== available || $[25] !== chargeTypeId || $[26] !== t10 || $[27] !== t11 || $[28] !== t4 || $[29] !== t5 || $[30] !== t6 || $[31] !== t7 || $[32] !== t8 || $[33] !== t9) {
4811
- t12 = {
4838
+ $[23] = t12;
4839
+ } else t12 = $[23];
4840
+ let t13;
4841
+ if ($[24] !== available || $[25] !== chargeTypeId || $[26] !== t10 || $[27] !== t11 || $[28] !== t12 || $[29] !== t4 || $[30] !== t5 || $[31] !== t6 || $[32] !== t7 || $[33] !== t8 || $[34] !== t9) {
4842
+ t13 = {
4812
4843
  available,
4813
4844
  preview: t4,
4814
4845
  typeId: t5,
4815
4846
  typeName: t6,
4847
+ mutated: t7,
4816
4848
  chargeTypeId,
4817
- chargeable: t7,
4818
- state: t8,
4819
- activatable: t9,
4820
- label: t10,
4821
- tooltip: t11
4849
+ chargeable: t8,
4850
+ state: t9,
4851
+ activatable: t10,
4852
+ label: t11,
4853
+ tooltip: t12
4822
4854
  };
4823
4855
  $[24] = available;
4824
4856
  $[25] = chargeTypeId;
4825
4857
  $[26] = t10;
4826
4858
  $[27] = t11;
4827
- $[28] = t4;
4828
- $[29] = t5;
4829
- $[30] = t6;
4830
- $[31] = t7;
4831
- $[32] = t8;
4832
- $[33] = t9;
4833
- $[34] = t12;
4834
- } else t12 = $[34];
4835
- const shown = t12;
4859
+ $[28] = t12;
4860
+ $[29] = t4;
4861
+ $[30] = t5;
4862
+ $[31] = t6;
4863
+ $[32] = t7;
4864
+ $[33] = t8;
4865
+ $[34] = t9;
4866
+ $[35] = t13;
4867
+ } else t13 = $[35];
4868
+ const shown = t13;
4836
4869
  if (readOnly) {
4837
- let t13;
4838
- if ($[35] !== shown) {
4839
- t13 = {
4870
+ let t14;
4871
+ if ($[36] !== shown) {
4872
+ t14 = {
4840
4873
  ...shown,
4841
4874
  actions: false
4842
4875
  };
4843
- $[35] = shown;
4844
- $[36] = t13;
4845
- } else t13 = $[36];
4846
- return t13;
4876
+ $[36] = shown;
4877
+ $[37] = t14;
4878
+ } else t14 = $[37];
4879
+ return t14;
4847
4880
  }
4848
- let t13;
4849
- if ($[37] !== ref || $[38] !== store) {
4850
- t13 = ref === void 0 ? void 0 : () => store.remove(ref);
4851
- $[37] = ref;
4852
- $[38] = store;
4853
- $[39] = t13;
4854
- } else t13 = $[39];
4855
- const unfit = t13;
4856
4881
  let t14;
4857
- if ($[40] !== item || $[41] !== ref || $[42] !== showInfo || $[43] !== side) {
4858
- t14 = item && ref !== void 0 ? (element) => showInfo({
4882
+ if ($[38] !== ref || $[39] !== store) {
4883
+ t14 = ref === void 0 ? void 0 : () => store.remove(ref);
4884
+ $[38] = ref;
4885
+ $[39] = store;
4886
+ $[40] = t14;
4887
+ } else t14 = $[40];
4888
+ const unfit = t14;
4889
+ let t15;
4890
+ if ($[41] !== item || $[42] !== ref || $[43] !== showInfo || $[44] !== side) {
4891
+ t15 = item && ref !== void 0 ? (element) => showInfo({
4859
4892
  typeId: item.type_id,
4860
4893
  ref
4861
4894
  }, {
4862
4895
  element,
4863
4896
  side
4864
4897
  }) : void 0;
4865
- $[40] = item;
4866
- $[41] = ref;
4867
- $[42] = showInfo;
4868
- $[43] = side;
4869
- $[44] = t14;
4870
- } else t14 = $[44];
4871
- const showModuleInfo = t14;
4872
- let t15;
4873
- if ($[45] !== chargeTypeId || $[46] !== ref || $[47] !== showInfo || $[48] !== side) {
4874
- t15 = chargeTypeId !== void 0 && ref !== void 0 ? (element_0) => showInfo({
4898
+ $[41] = item;
4899
+ $[42] = ref;
4900
+ $[43] = showInfo;
4901
+ $[44] = side;
4902
+ $[45] = t15;
4903
+ } else t15 = $[45];
4904
+ const showModuleInfo = t15;
4905
+ let t16;
4906
+ if ($[46] !== chargeTypeId || $[47] !== ref || $[48] !== showInfo || $[49] !== side) {
4907
+ t16 = chargeTypeId !== void 0 && ref !== void 0 ? (element_0) => showInfo({
4875
4908
  typeId: chargeTypeId,
4876
4909
  ref
4877
4910
  }, {
4878
4911
  element: element_0,
4879
4912
  side
4880
4913
  }) : void 0;
4881
- $[45] = chargeTypeId;
4882
- $[46] = ref;
4883
- $[47] = showInfo;
4884
- $[48] = side;
4885
- $[49] = t15;
4886
- } else t15 = $[49];
4887
- const showChargeInfo = t15;
4888
- let t16;
4889
- if ($[50] !== ref || $[51] !== store) {
4890
- t16 = ref === void 0 ? void 0 : () => store.setCharge(ref, void 0);
4891
- $[50] = ref;
4892
- $[51] = store;
4893
- $[52] = t16;
4894
- } else t16 = $[52];
4895
- const removeCharge = t16;
4914
+ $[46] = chargeTypeId;
4915
+ $[47] = ref;
4916
+ $[48] = showInfo;
4917
+ $[49] = side;
4918
+ $[50] = t16;
4919
+ } else t16 = $[50];
4920
+ const showChargeInfo = t16;
4896
4921
  let t17;
4897
- if ($[53] !== ref || $[54] !== stats || $[55] !== store || $[56] !== switchable) {
4898
- t17 = switchable && stats.maxState !== "offline" ? () => store.setState(ref, stats.state === "offline" ? "online" : "offline") : void 0;
4899
- $[53] = ref;
4900
- $[54] = stats;
4901
- $[55] = store;
4902
- $[56] = switchable;
4903
- $[57] = t17;
4904
- } else t17 = $[57];
4905
- const togglePower = t17;
4922
+ if ($[51] !== ref || $[52] !== store) {
4923
+ t17 = ref === void 0 ? void 0 : () => store.setCharge(ref, void 0);
4924
+ $[51] = ref;
4925
+ $[52] = store;
4926
+ $[53] = t17;
4927
+ } else t17 = $[53];
4928
+ const removeCharge = t17;
4906
4929
  let t18;
4907
- if ($[58] !== available || $[59] !== browse || $[60] !== chargeTypeId || $[61] !== content?.preview || $[62] !== open || $[63] !== rack || $[64] !== removeCharge || $[65] !== showChargeInfo || $[66] !== showModuleInfo || $[67] !== stats?.state || $[68] !== togglePower || $[69] !== unfit) {
4908
- t18 = (event) => {
4930
+ let unmutated;
4931
+ if ($[54] !== item || $[55] !== sde) {
4932
+ unmutated = sde.type(item?.mutation?.base ?? item?.type_id ?? -1);
4933
+ t18 = item !== void 0 && unmutated !== void 0 && canMutate(sde, unmutated) && (item.mutation === void 0 || mutationRollOf(sde, item) !== void 0);
4934
+ $[54] = item;
4935
+ $[55] = sde;
4936
+ $[56] = t18;
4937
+ $[57] = unmutated;
4938
+ } else {
4939
+ t18 = $[56];
4940
+ unmutated = $[57];
4941
+ }
4942
+ const mutable = t18;
4943
+ let t19;
4944
+ if ($[58] !== index || $[59] !== item || $[60] !== mutable || $[61] !== rack || $[62] !== ref || $[63] !== sde || $[64] !== showMutate || $[65] !== side || $[66] !== store || $[67] !== unmutated) {
4945
+ t19 = mutable && ref !== void 0 ? (element_1) => {
4946
+ const slot_0 = {
4947
+ type: rack,
4948
+ index
4949
+ };
4950
+ if (item.mutation === void 0) store.setMutation(ref, rollMutation(sde, unmutated.id, mutaplasmidsOf(sde, unmutated.id)[0].id, "base"));
4951
+ showMutate(slot_0, {
4952
+ element: element_1,
4953
+ side
4954
+ });
4955
+ } : void 0;
4956
+ $[58] = index;
4957
+ $[59] = item;
4958
+ $[60] = mutable;
4959
+ $[61] = rack;
4960
+ $[62] = ref;
4961
+ $[63] = sde;
4962
+ $[64] = showMutate;
4963
+ $[65] = side;
4964
+ $[66] = store;
4965
+ $[67] = unmutated;
4966
+ $[68] = t19;
4967
+ } else t19 = $[68];
4968
+ const mutate = t19;
4969
+ let t20;
4970
+ if ($[69] !== ref || $[70] !== stats || $[71] !== store || $[72] !== switchable) {
4971
+ t20 = switchable && stats.maxState !== "offline" ? () => store.setState(ref, stats.state === "offline" ? "online" : "offline") : void 0;
4972
+ $[69] = ref;
4973
+ $[70] = stats;
4974
+ $[71] = store;
4975
+ $[72] = switchable;
4976
+ $[73] = t20;
4977
+ } else t20 = $[73];
4978
+ const togglePower = t20;
4979
+ let t21;
4980
+ if ($[74] !== available || $[75] !== browse || $[76] !== chargeTypeId || $[77] !== content?.preview || $[78] !== item?.mutation || $[79] !== mutate || $[80] !== open || $[81] !== rack || $[82] !== ref || $[83] !== removeCharge || $[84] !== showChargeInfo || $[85] !== showModuleInfo || $[86] !== stats?.state || $[87] !== store || $[88] !== togglePower || $[89] !== unfit) {
4981
+ t21 = (event) => {
4909
4982
  if (!available || content?.preview) return;
4910
4983
  const anchor = event.currentTarget.querySelector("[data-slot-anchor]") ?? event.currentTarget;
4911
4984
  open(event, [
@@ -4926,6 +4999,15 @@ function useFittingSlot(rack, index, content, available, t0) {
4926
4999
  onSelect: removeCharge
4927
5000
  },
4928
5001
  "separator",
5002
+ mutate && {
5003
+ label: item?.mutation ? "Edit Mutation" : "Mutate",
5004
+ onSelect: () => mutate(anchor)
5005
+ },
5006
+ item?.mutation && ref !== void 0 && {
5007
+ label: "Remove Mutation",
5008
+ onSelect: () => store.setMutation(ref, void 0)
5009
+ },
5010
+ "separator",
4929
5011
  {
4930
5012
  label: "Set Filter for Slot",
4931
5013
  onSelect: () => browse(rack)
@@ -4942,36 +5024,40 @@ function useFittingSlot(rack, index, content, available, t0) {
4942
5024
  }
4943
5025
  ]);
4944
5026
  };
4945
- $[58] = available;
4946
- $[59] = browse;
4947
- $[60] = chargeTypeId;
4948
- $[61] = content?.preview;
4949
- $[62] = open;
4950
- $[63] = rack;
4951
- $[64] = removeCharge;
4952
- $[65] = showChargeInfo;
4953
- $[66] = showModuleInfo;
4954
- $[67] = stats?.state;
4955
- $[68] = togglePower;
4956
- $[69] = unfit;
4957
- $[70] = t18;
4958
- } else t18 = $[70];
4959
- const t19 = dragging === void 0;
4960
- let t20;
4961
- if ($[71] !== browse || $[72] !== empty || $[73] !== rack || $[74] !== ref || $[75] !== stats || $[76] !== store || $[77] !== switchable) {
4962
- t20 = switchable ? (event_0) => store.setState(ref, nextState(stats.state, stats.maxState, event_0.shiftKey)) : empty ? () => browse(rack) : void 0;
4963
- $[71] = browse;
4964
- $[72] = empty;
4965
- $[73] = rack;
4966
- $[74] = ref;
4967
- $[75] = stats;
4968
- $[76] = store;
4969
- $[77] = switchable;
4970
- $[78] = t20;
4971
- } else t20 = $[78];
4972
- let t21;
4973
- if ($[79] !== ref || $[80] !== start || $[81] !== type?.name) {
4974
- t21 = ref === void 0 ? void 0 : (event_1) => {
5027
+ $[74] = available;
5028
+ $[75] = browse;
5029
+ $[76] = chargeTypeId;
5030
+ $[77] = content?.preview;
5031
+ $[78] = item?.mutation;
5032
+ $[79] = mutate;
5033
+ $[80] = open;
5034
+ $[81] = rack;
5035
+ $[82] = ref;
5036
+ $[83] = removeCharge;
5037
+ $[84] = showChargeInfo;
5038
+ $[85] = showModuleInfo;
5039
+ $[86] = stats?.state;
5040
+ $[87] = store;
5041
+ $[88] = togglePower;
5042
+ $[89] = unfit;
5043
+ $[90] = t21;
5044
+ } else t21 = $[90];
5045
+ const t22 = dragging === void 0;
5046
+ let t23;
5047
+ if ($[91] !== browse || $[92] !== empty || $[93] !== rack || $[94] !== ref || $[95] !== stats || $[96] !== store || $[97] !== switchable) {
5048
+ t23 = switchable ? (event_0) => store.setState(ref, nextState(stats.state, stats.maxState, event_0.shiftKey)) : empty ? () => browse(rack) : void 0;
5049
+ $[91] = browse;
5050
+ $[92] = empty;
5051
+ $[93] = rack;
5052
+ $[94] = ref;
5053
+ $[95] = stats;
5054
+ $[96] = store;
5055
+ $[97] = switchable;
5056
+ $[98] = t23;
5057
+ } else t23 = $[98];
5058
+ let t24;
5059
+ if ($[99] !== ref || $[100] !== start || $[101] !== type?.name) {
5060
+ t24 = ref === void 0 ? void 0 : (event_1) => {
4975
5061
  event_1.dataTransfer.effectAllowed = "copyMove";
4976
5062
  event_1.dataTransfer.setData("text/plain", type?.name ?? "");
4977
5063
  start({
@@ -4979,14 +5065,14 @@ function useFittingSlot(rack, index, content, available, t0) {
4979
5065
  ref
4980
5066
  });
4981
5067
  };
4982
- $[79] = ref;
4983
- $[80] = start;
4984
- $[81] = type?.name;
4985
- $[82] = t21;
4986
- } else t21 = $[82];
4987
- let t22;
4988
- if ($[83] !== dragging || $[84] !== index || $[85] !== rack || $[86] !== show || $[87] !== showItem || $[88] !== takes || $[89] !== target) {
4989
- t22 = (event_2) => {
5068
+ $[99] = ref;
5069
+ $[100] = start;
5070
+ $[101] = type?.name;
5071
+ $[102] = t24;
5072
+ } else t24 = $[102];
5073
+ let t25;
5074
+ if ($[103] !== dragging || $[104] !== index || $[105] !== rack || $[106] !== show || $[107] !== showItem || $[108] !== takes || $[109] !== target) {
5075
+ t25 = (event_2) => {
4990
5076
  if (!takes(dragging)) return;
4991
5077
  if (dragging.type === "item") {
4992
5078
  showItem(dragging.ref, copies(event_2));
@@ -4998,28 +5084,28 @@ function useFittingSlot(rack, index, content, available, t0) {
4998
5084
  index
4999
5085
  }), target);
5000
5086
  };
5001
- $[83] = dragging;
5002
- $[84] = index;
5003
- $[85] = rack;
5004
- $[86] = show;
5005
- $[87] = showItem;
5006
- $[88] = takes;
5007
- $[89] = target;
5008
- $[90] = t22;
5009
- } else t22 = $[90];
5010
- let t23;
5011
- if ($[91] !== clear || $[92] !== target) {
5012
- t23 = (event_3) => {
5087
+ $[103] = dragging;
5088
+ $[104] = index;
5089
+ $[105] = rack;
5090
+ $[106] = show;
5091
+ $[107] = showItem;
5092
+ $[108] = takes;
5093
+ $[109] = target;
5094
+ $[110] = t25;
5095
+ } else t25 = $[110];
5096
+ let t26;
5097
+ if ($[111] !== clear || $[112] !== target) {
5098
+ t26 = (event_3) => {
5013
5099
  if (event_3.currentTarget.contains(event_3.relatedTarget)) return;
5014
5100
  clear(target);
5015
5101
  };
5016
- $[91] = clear;
5017
- $[92] = target;
5018
- $[93] = t23;
5019
- } else t23 = $[93];
5020
- let t24;
5021
- if ($[94] !== dragging || $[95] !== showItem || $[96] !== takes) {
5022
- t24 = (event_4) => {
5102
+ $[111] = clear;
5103
+ $[112] = target;
5104
+ $[113] = t26;
5105
+ } else t26 = $[113];
5106
+ let t27;
5107
+ if ($[114] !== dragging || $[115] !== showItem || $[116] !== takes) {
5108
+ t27 = (event_4) => {
5023
5109
  if (!takes(dragging)) return;
5024
5110
  allowDrop(event_4, dragging);
5025
5111
  if (dragging.type !== "item") return;
@@ -5027,14 +5113,14 @@ function useFittingSlot(rack, index, content, available, t0) {
5027
5113
  if (copy_0) event_4.dataTransfer.dropEffect = "copy";
5028
5114
  if (copy_0 !== shownCopy.current) showItem(dragging.ref, copy_0);
5029
5115
  };
5030
- $[94] = dragging;
5031
- $[95] = showItem;
5032
- $[96] = takes;
5033
- $[97] = t24;
5034
- } else t24 = $[97];
5035
- let t25;
5036
- if ($[98] !== clear || $[99] !== dragging || $[100] !== end || $[101] !== index || $[102] !== rack || $[103] !== store || $[104] !== takes || $[105] !== target) {
5037
- t25 = (event_5) => {
5116
+ $[114] = dragging;
5117
+ $[115] = showItem;
5118
+ $[116] = takes;
5119
+ $[117] = t27;
5120
+ } else t27 = $[117];
5121
+ let t28;
5122
+ if ($[118] !== clear || $[119] !== dragging || $[120] !== end || $[121] !== index || $[122] !== rack || $[123] !== store || $[124] !== takes || $[125] !== target) {
5123
+ t28 = (event_5) => {
5038
5124
  if (!takes(dragging)) return;
5039
5125
  event_5.preventDefault();
5040
5126
  clear(target);
@@ -5052,55 +5138,55 @@ function useFittingSlot(rack, index, content, available, t0) {
5052
5138
  });
5053
5139
  end();
5054
5140
  };
5055
- $[98] = clear;
5056
- $[99] = dragging;
5057
- $[100] = end;
5058
- $[101] = index;
5059
- $[102] = rack;
5060
- $[103] = store;
5061
- $[104] = takes;
5062
- $[105] = target;
5063
- $[106] = t25;
5064
- } else t25 = $[106];
5065
- let t26;
5066
- if ($[107] !== end || $[108] !== menu || $[109] !== removeCharge || $[110] !== showChargeInfo || $[111] !== showModuleInfo || $[112] !== shown || $[113] !== t18 || $[114] !== t19 || $[115] !== t20 || $[116] !== t21 || $[117] !== t22 || $[118] !== t23 || $[119] !== t24 || $[120] !== t25 || $[121] !== togglePower || $[122] !== unfit) {
5067
- t26 = {
5141
+ $[118] = clear;
5142
+ $[119] = dragging;
5143
+ $[120] = end;
5144
+ $[121] = index;
5145
+ $[122] = rack;
5146
+ $[123] = store;
5147
+ $[124] = takes;
5148
+ $[125] = target;
5149
+ $[126] = t28;
5150
+ } else t28 = $[126];
5151
+ let t29;
5152
+ if ($[127] !== end || $[128] !== menu || $[129] !== removeCharge || $[130] !== showChargeInfo || $[131] !== showModuleInfo || $[132] !== shown || $[133] !== t21 || $[134] !== t22 || $[135] !== t23 || $[136] !== t24 || $[137] !== t25 || $[138] !== t26 || $[139] !== t27 || $[140] !== t28 || $[141] !== togglePower || $[142] !== unfit) {
5153
+ t29 = {
5068
5154
  ...shown,
5069
5155
  menu,
5070
- onContextMenu: t18,
5071
- actions: t19,
5072
- onPress: t20,
5073
- onDragStart: t21,
5156
+ onContextMenu: t21,
5157
+ actions: t22,
5158
+ onPress: t23,
5159
+ onDragStart: t24,
5074
5160
  onDragEnd: end,
5075
- onDragEnter: t22,
5076
- onDragLeave: t23,
5077
- onDragOver: t24,
5078
- onDrop: t25,
5161
+ onDragEnter: t25,
5162
+ onDragLeave: t26,
5163
+ onDragOver: t27,
5164
+ onDrop: t28,
5079
5165
  onUnfit: unfit,
5080
5166
  onShowInfo: showModuleInfo,
5081
5167
  onShowChargeInfo: showChargeInfo,
5082
5168
  onRemoveCharge: removeCharge,
5083
5169
  onTogglePower: togglePower
5084
5170
  };
5085
- $[107] = end;
5086
- $[108] = menu;
5087
- $[109] = removeCharge;
5088
- $[110] = showChargeInfo;
5089
- $[111] = showModuleInfo;
5090
- $[112] = shown;
5091
- $[113] = t18;
5092
- $[114] = t19;
5093
- $[115] = t20;
5094
- $[116] = t21;
5095
- $[117] = t22;
5096
- $[118] = t23;
5097
- $[119] = t24;
5098
- $[120] = t25;
5099
- $[121] = togglePower;
5100
- $[122] = unfit;
5101
- $[123] = t26;
5102
- } else t26 = $[123];
5103
- return t26;
5171
+ $[127] = end;
5172
+ $[128] = menu;
5173
+ $[129] = removeCharge;
5174
+ $[130] = showChargeInfo;
5175
+ $[131] = showModuleInfo;
5176
+ $[132] = shown;
5177
+ $[133] = t21;
5178
+ $[134] = t22;
5179
+ $[135] = t23;
5180
+ $[136] = t24;
5181
+ $[137] = t25;
5182
+ $[138] = t26;
5183
+ $[139] = t27;
5184
+ $[140] = t28;
5185
+ $[141] = togglePower;
5186
+ $[142] = unfit;
5187
+ $[143] = t29;
5188
+ } else t29 = $[143];
5189
+ return t29;
5104
5190
  }
5105
5191
  function allowDrop(event, dragging) {
5106
5192
  event.preventDefault();
@@ -5125,7 +5211,7 @@ function FittingAugmentations(t0) {
5125
5211
  const boosters = useBoosters();
5126
5212
  let t1;
5127
5213
  if ($[0] !== implants || $[1] !== readOnly) {
5128
- t1 = !readOnly || implants.some(_temp$13);
5214
+ t1 = !readOnly || implants.some(_temp$14);
5129
5215
  $[0] = implants;
5130
5216
  $[1] = readOnly;
5131
5217
  $[2] = t1;
@@ -5180,7 +5266,7 @@ function FittingAugmentations(t0) {
5180
5266
  } else t5 = $[15];
5181
5267
  return t5;
5182
5268
  }
5183
- function _temp$13(slot) {
5269
+ function _temp$14(slot) {
5184
5270
  return slot.item !== void 0;
5185
5271
  }
5186
5272
  function FittingAugmentation(t0) {
@@ -5620,9 +5706,9 @@ function FittingCentre() {
5620
5706
  })
5621
5707
  },
5622
5708
  "separator",
5623
- fit.items.some(_temp$12) && {
5709
+ fit.items.some(_temp$13) && {
5624
5710
  label: "Strip Fitting",
5625
- onSelect: () => store.remove(...store.getSnapshot().fit.items.flatMap(_temp2$6))
5711
+ onSelect: () => store.remove(...store.getSnapshot().fit.items.flatMap(_temp2$7))
5626
5712
  }
5627
5713
  ]);
5628
5714
  };
@@ -5714,10 +5800,10 @@ function FittingCentre() {
5714
5800
  } else t8 = $[43];
5715
5801
  return t8;
5716
5802
  }
5717
- function _temp2$6(item_0, ref) {
5803
+ function _temp2$7(item_0, ref) {
5718
5804
  return keptOnStrip.has(item_0.slot.type) ? [] : [ref];
5719
5805
  }
5720
- function _temp$12(item_1) {
5806
+ function _temp$13(item_1) {
5721
5807
  return !keptOnStrip.has(item_1.slot.type);
5722
5808
  }
5723
5809
  const copiedRacks = [
@@ -5831,7 +5917,7 @@ function FittingModes(t0) {
5831
5917
  if (modes.length === 0) return null;
5832
5918
  let t1;
5833
5919
  if ($[0] !== modes) {
5834
- t1 = modes.map(_temp3$3);
5920
+ t1 = modes.map(_temp3$4);
5835
5921
  $[0] = modes;
5836
5922
  $[1] = t1;
5837
5923
  } else t1 = $[1];
@@ -5856,7 +5942,7 @@ function FittingModes(t0) {
5856
5942
  } else t3 = $[8];
5857
5943
  return t3;
5858
5944
  }
5859
- function _temp3$3(t0) {
5945
+ function _temp3$4(t0) {
5860
5946
  const { id, name } = t0;
5861
5947
  return {
5862
5948
  typeId: id,
@@ -6017,6 +6103,107 @@ function ServiceSlot({ typeId, typeName, state = "online", available = true, pre
6017
6103
  })]
6018
6104
  });
6019
6105
  }
6106
+ // src/components/ItemInfo/anchoredCard.ts
6107
+ /** Opens a popover card next to `anchor`; closes it when the anchor goes away or the page scrolls under it. */
6108
+ function useAnchoredCard(anchor, onClose) {
6109
+ const $ = c(18);
6110
+ const card = useRef(null);
6111
+ const t0 = useId();
6112
+ let t1;
6113
+ if ($[0] !== t0) {
6114
+ let t2;
6115
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
6116
+ t2 = /[^\w-]/g;
6117
+ $[2] = t2;
6118
+ } else t2 = $[2];
6119
+ t1 = t0.replace(t2, "");
6120
+ $[0] = t0;
6121
+ $[1] = t1;
6122
+ } else t1 = $[1];
6123
+ const anchorName = `--item-info-${t1}`;
6124
+ const close = useEffectEvent(onClose);
6125
+ let t2;
6126
+ if ($[3] !== anchor?.element || $[4] !== anchorName) {
6127
+ t2 = () => {
6128
+ const element = anchor?.element;
6129
+ if (!(element instanceof HTMLElement)) return;
6130
+ const inline = element.style.getPropertyValue("anchor-name");
6131
+ const own = getComputedStyle(element).getPropertyValue("anchor-name");
6132
+ element.style.setProperty("anchor-name", own && own !== "none" ? `${own}, ${anchorName}` : anchorName);
6133
+ return () => element.style.setProperty("anchor-name", inline);
6134
+ };
6135
+ $[3] = anchor?.element;
6136
+ $[4] = anchorName;
6137
+ $[5] = t2;
6138
+ } else t2 = $[5];
6139
+ let t3;
6140
+ if ($[6] !== anchor || $[7] !== anchorName) {
6141
+ t3 = [anchor, anchorName];
6142
+ $[6] = anchor;
6143
+ $[7] = anchorName;
6144
+ $[8] = t3;
6145
+ } else t3 = $[8];
6146
+ useLayoutEffect(t2, t3);
6147
+ let t4;
6148
+ if ($[9] !== anchor?.element || $[10] !== close) {
6149
+ t4 = () => {
6150
+ card.current?.showPopover();
6151
+ const element_0 = anchor?.element;
6152
+ if (element_0 === void 0) return;
6153
+ const gone = new MutationObserver(() => {
6154
+ if (!element_0.isConnected) close();
6155
+ });
6156
+ gone.observe(document.body, {
6157
+ childList: true,
6158
+ subtree: true
6159
+ });
6160
+ const hidden = new ResizeObserver((t5) => {
6161
+ const [entry] = t5;
6162
+ if (entry?.contentRect.width === 0 && entry.contentRect.height === 0) close();
6163
+ });
6164
+ hidden.observe(element_0);
6165
+ const onScroll = (event) => {
6166
+ if (!(event.target instanceof Node && card.current?.contains(event.target))) close();
6167
+ };
6168
+ document.addEventListener("scroll", onScroll, {
6169
+ capture: true,
6170
+ passive: true
6171
+ });
6172
+ return () => {
6173
+ gone.disconnect();
6174
+ hidden.disconnect();
6175
+ document.removeEventListener("scroll", onScroll, { capture: true });
6176
+ };
6177
+ };
6178
+ $[9] = anchor?.element;
6179
+ $[10] = close;
6180
+ $[11] = t4;
6181
+ } else t4 = $[11];
6182
+ let t5;
6183
+ if ($[12] !== anchor) {
6184
+ t5 = [anchor];
6185
+ $[12] = anchor;
6186
+ $[13] = t5;
6187
+ } else t5 = $[13];
6188
+ useEffect(t4, t5);
6189
+ let t6;
6190
+ if ($[14] !== anchorName) {
6191
+ t6 = { "--item-info-anchor": anchorName };
6192
+ $[14] = anchorName;
6193
+ $[15] = t6;
6194
+ } else t6 = $[15];
6195
+ const t7 = t6;
6196
+ let t8;
6197
+ if ($[16] !== t7) {
6198
+ t8 = {
6199
+ card,
6200
+ style: t7
6201
+ };
6202
+ $[16] = t7;
6203
+ $[17] = t8;
6204
+ } else t8 = $[17];
6205
+ return t8;
6206
+ }
6020
6207
  // src/components/ItemInfo/ItemInfo.module.css
6021
6208
  var ItemInfo_module_default = {
6022
6209
  "card": "TufZMa_card",
@@ -6038,7 +6225,7 @@ var ItemInfo_module_default = {
6038
6225
  "variationIcon": "TufZMa_variationIcon",
6039
6226
  "variations": "TufZMa_variations"
6040
6227
  };
6041
- // src/components/ItemInfo/ItemInfo.tsx
6228
+ // src/components/ItemInfo/slotName.ts
6042
6229
  const slotNames$1 = {
6043
6230
  high: "High Slot",
6044
6231
  medium: "Mid Slot",
@@ -6053,6 +6240,13 @@ const slotNames$1 = {
6053
6240
  booster: "Booster Slot",
6054
6241
  cargo: "Cargo"
6055
6242
  };
6243
+ /** A slot as EVE names it, like "Mid Slot 2". */
6244
+ function slotName(slot) {
6245
+ const name = slotNames$1[slot.type] ?? slot.type;
6246
+ if (!("index" in slot)) return name;
6247
+ return `${name} ${slot.type === "implant" || slot.type === "booster" ? slot.index : slot.index + 1}`;
6248
+ }
6249
+ // src/components/ItemInfo/ItemInfo.tsx
6056
6250
  /** EVE's Show Info of what `useShowInfo` shows, next to what asked for it. */
6057
6251
  function ItemInfo() {
6058
6252
  const $ = c(4);
@@ -6074,207 +6268,133 @@ function ItemInfo() {
6074
6268
  return t1;
6075
6269
  }
6076
6270
  function InfoCard(t0) {
6077
- const $ = c(63);
6271
+ const $ = c(50);
6078
6272
  const { shown: t1, onClose } = t0;
6079
6273
  const { target, anchor } = t1;
6080
6274
  const info = useInfo(target);
6081
6275
  const { type, fitted, ship, variations } = info;
6082
6276
  const price = useTypePrice(target.typeId);
6083
- const card = useRef(null);
6084
- const t2 = useId();
6085
- let t3;
6086
- if ($[0] !== t2) {
6087
- let t4;
6088
- if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
6089
- t4 = /[^\w-]/g;
6090
- $[2] = t4;
6091
- } else t4 = $[2];
6092
- t3 = t2.replace(t4, "");
6093
- $[0] = t2;
6094
- $[1] = t3;
6095
- } else t3 = $[1];
6096
- const anchorName = `--item-info-${t3}`;
6277
+ const { card, style } = useAnchoredCard(anchor, onClose);
6097
6278
  const tabId = useId();
6098
6279
  const [picked, setPicked] = useState("attributes");
6099
- let t4;
6100
- if ($[3] !== variations.length) {
6101
- t4 = variations.length > 1 ? ["attributes", "variations"] : ["attributes"];
6102
- $[3] = variations.length;
6103
- $[4] = t4;
6104
- } else t4 = $[4];
6105
- const tabs = t4;
6280
+ let t2;
6281
+ if ($[0] !== variations.length) {
6282
+ t2 = variations.length > 1 ? ["attributes", "variations"] : ["attributes"];
6283
+ $[0] = variations.length;
6284
+ $[1] = t2;
6285
+ } else t2 = $[1];
6286
+ const tabs = t2;
6106
6287
  const tab = tabs.includes(picked) ? picked : "attributes";
6107
- let t5;
6108
- if ($[5] !== anchor?.element || $[6] !== anchorName) {
6109
- t5 = () => {
6110
- const element = anchor?.element;
6111
- if (!(element instanceof HTMLElement)) return;
6112
- const inline = element.style.getPropertyValue("anchor-name");
6113
- const own = getComputedStyle(element).getPropertyValue("anchor-name");
6114
- element.style.setProperty("anchor-name", own && own !== "none" ? `${own}, ${anchorName}` : anchorName);
6115
- return () => element.style.setProperty("anchor-name", inline);
6288
+ let t3;
6289
+ if ($[2] !== onClose) {
6290
+ t3 = (event) => {
6291
+ if (event.newState === "closed") onClose();
6116
6292
  };
6117
- $[5] = anchor?.element;
6118
- $[6] = anchorName;
6119
- $[7] = t5;
6120
- } else t5 = $[7];
6293
+ $[2] = onClose;
6294
+ $[3] = t3;
6295
+ } else t3 = $[3];
6296
+ const t4 = `Info on ${type?.name ?? ""}`;
6297
+ const t5 = anchor?.side;
6121
6298
  let t6;
6122
- if ($[8] !== anchor || $[9] !== anchorName) {
6123
- t6 = [anchor, anchorName];
6124
- $[8] = anchor;
6125
- $[9] = anchorName;
6126
- $[10] = t6;
6127
- } else t6 = $[10];
6128
- useLayoutEffect(t5, t6);
6299
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
6300
+ t6 = /* @__PURE__ */ jsx(Icon, { name: "close" });
6301
+ $[4] = t6;
6302
+ } else t6 = $[4];
6129
6303
  let t7;
6130
- if ($[11] !== anchor?.element || $[12] !== onClose) {
6131
- t7 = () => {
6132
- card.current?.showPopover();
6133
- const element_0 = anchor?.element;
6134
- if (element_0 === void 0) return;
6135
- const gone = new MutationObserver(() => {
6136
- if (!element_0.isConnected) onClose();
6137
- });
6138
- gone.observe(document.body, {
6139
- childList: true,
6140
- subtree: true
6141
- });
6142
- const hidden = new ResizeObserver((t8) => {
6143
- const [entry] = t8;
6144
- if (entry?.contentRect.width === 0 && entry.contentRect.height === 0) onClose();
6145
- });
6146
- hidden.observe(element_0);
6147
- const onScroll = (event) => {
6148
- if (!(event.target instanceof Node && card.current?.contains(event.target))) onClose();
6149
- };
6150
- document.addEventListener("scroll", onScroll, {
6151
- capture: true,
6152
- passive: true
6153
- });
6154
- return () => {
6155
- gone.disconnect();
6156
- hidden.disconnect();
6157
- document.removeEventListener("scroll", onScroll, { capture: true });
6158
- };
6159
- };
6160
- $[11] = anchor?.element;
6161
- $[12] = onClose;
6162
- $[13] = t7;
6163
- } else t7 = $[13];
6304
+ if ($[5] !== onClose) {
6305
+ t7 = /* @__PURE__ */ jsx("button", {
6306
+ type: "button",
6307
+ className: ItemInfo_module_default.close,
6308
+ "aria-label": "Close",
6309
+ onClick: onClose,
6310
+ children: t6
6311
+ });
6312
+ $[5] = onClose;
6313
+ $[6] = t7;
6314
+ } else t7 = $[6];
6164
6315
  let t8;
6165
- if ($[14] !== anchor || $[15] !== onClose) {
6166
- t8 = [anchor, onClose];
6167
- $[14] = anchor;
6168
- $[15] = onClose;
6169
- $[16] = t8;
6170
- } else t8 = $[16];
6171
- useEffect(t7, t8);
6172
- let t9;
6173
- if ($[17] !== onClose) {
6174
- t9 = (event_0) => {
6175
- if (event_0.newState === "closed") onClose();
6176
- };
6177
- $[17] = onClose;
6178
- $[18] = t9;
6179
- } else t9 = $[18];
6180
- const t10 = `Info on ${type?.name ?? ""}`;
6181
- const t11 = anchor?.side;
6182
- let t12;
6183
- if ($[19] !== anchorName) {
6184
- t12 = { "--item-info-anchor": anchorName };
6185
- $[19] = anchorName;
6186
- $[20] = t12;
6187
- } else t12 = $[20];
6188
- const t13 = t12;
6189
- let t14;
6190
- if ($[21] === Symbol.for("react.memo_cache_sentinel")) {
6191
- t14 = /* @__PURE__ */ jsx(Icon, { name: "close" });
6192
- $[21] = t14;
6193
- } else t14 = $[21];
6194
- let t15;
6195
- if ($[22] !== onClose) {
6196
- t15 = /* @__PURE__ */ jsx("button", {
6197
- type: "button",
6198
- className: ItemInfo_module_default.close,
6199
- "aria-label": "Close",
6200
- onClick: onClose,
6201
- children: t14
6202
- });
6203
- $[22] = onClose;
6204
- $[23] = t15;
6205
- } else t15 = $[23];
6206
- let t16;
6207
- if ($[24] !== target.typeId) {
6208
- t16 = /* @__PURE__ */ jsx("span", {
6316
+ if ($[7] !== target.typeId) {
6317
+ t8 = /* @__PURE__ */ jsx("span", {
6209
6318
  className: ItemInfo_module_default.typeIcon,
6210
6319
  children: /* @__PURE__ */ jsx(TypeIcon, {
6211
6320
  typeId: target.typeId,
6212
6321
  size: 64
6213
6322
  })
6214
6323
  });
6215
- $[24] = target.typeId;
6216
- $[25] = t16;
6217
- } else t16 = $[25];
6218
- const t17 = type?.name;
6219
- let t18;
6220
- if ($[26] !== t17) {
6221
- t18 = /* @__PURE__ */ jsx("h2", {
6324
+ $[7] = target.typeId;
6325
+ $[8] = t8;
6326
+ } else t8 = $[8];
6327
+ const t9 = type?.name;
6328
+ let t10;
6329
+ if ($[9] !== t9) {
6330
+ t10 = /* @__PURE__ */ jsx("h2", {
6222
6331
  className: ItemInfo_module_default.name,
6223
- children: t17
6332
+ children: t9
6224
6333
  });
6225
- $[26] = t17;
6226
- $[27] = t18;
6227
- } else t18 = $[27];
6228
- let t19;
6229
- if ($[28] !== price) {
6230
- t19 = price !== void 0 && /* @__PURE__ */ jsxs("span", {
6334
+ $[9] = t9;
6335
+ $[10] = t10;
6336
+ } else t10 = $[10];
6337
+ let t11;
6338
+ if ($[11] !== info.mutatedFrom) {
6339
+ t11 = info.mutatedFrom !== void 0 && /* @__PURE__ */ jsxs("span", {
6340
+ className: ItemInfo_module_default.muted,
6341
+ children: ["Mutated ", info.mutatedFrom.name]
6342
+ });
6343
+ $[11] = info.mutatedFrom;
6344
+ $[12] = t11;
6345
+ } else t11 = $[12];
6346
+ let t12;
6347
+ if ($[13] !== price) {
6348
+ t12 = price !== void 0 && /* @__PURE__ */ jsxs("span", {
6231
6349
  className: ItemInfo_module_default.muted,
6232
6350
  children: [formatNumber(price, { decimals: 0 }), " ISK Est. price"]
6233
6351
  });
6234
- $[28] = price;
6235
- $[29] = t19;
6236
- } else t19 = $[29];
6237
- let t20;
6238
- if ($[30] !== fitted || $[31] !== ship) {
6239
- t20 = ship ? "Hull" : fitted === void 0 ? "Not fitted" : `${fitted.charge ? "Loaded" : "Fitted"} · ${slotName(fitted.slot)}`;
6240
- $[30] = fitted;
6241
- $[31] = ship;
6242
- $[32] = t20;
6243
- } else t20 = $[32];
6244
- let t21;
6245
- if ($[33] !== t20) {
6246
- t21 = /* @__PURE__ */ jsx("span", { children: t20 });
6247
- $[33] = t20;
6248
- $[34] = t21;
6249
- } else t21 = $[34];
6250
- let t22;
6251
- if ($[35] !== t18 || $[36] !== t19 || $[37] !== t21) {
6252
- t22 = /* @__PURE__ */ jsxs("div", {
6352
+ $[13] = price;
6353
+ $[14] = t12;
6354
+ } else t12 = $[14];
6355
+ let t13;
6356
+ if ($[15] !== fitted || $[16] !== ship) {
6357
+ t13 = ship ? "Hull" : fitted === void 0 ? "Not fitted" : `${fitted.charge ? "Loaded" : "Fitted"} · ${slotName(fitted.slot)}`;
6358
+ $[15] = fitted;
6359
+ $[16] = ship;
6360
+ $[17] = t13;
6361
+ } else t13 = $[17];
6362
+ let t14;
6363
+ if ($[18] !== t13) {
6364
+ t14 = /* @__PURE__ */ jsx("span", { children: t13 });
6365
+ $[18] = t13;
6366
+ $[19] = t14;
6367
+ } else t14 = $[19];
6368
+ let t15;
6369
+ if ($[20] !== t10 || $[21] !== t11 || $[22] !== t12 || $[23] !== t14) {
6370
+ t15 = /* @__PURE__ */ jsxs("div", {
6253
6371
  className: ItemInfo_module_default.title,
6254
6372
  children: [
6255
- t18,
6256
- t19,
6257
- t21
6373
+ t10,
6374
+ t11,
6375
+ t12,
6376
+ t14
6258
6377
  ]
6259
6378
  });
6260
- $[35] = t18;
6261
- $[36] = t19;
6262
- $[37] = t21;
6263
- $[38] = t22;
6264
- } else t22 = $[38];
6265
- let t23;
6266
- if ($[39] !== t16 || $[40] !== t22) {
6267
- t23 = /* @__PURE__ */ jsxs("header", {
6379
+ $[20] = t10;
6380
+ $[21] = t11;
6381
+ $[22] = t12;
6382
+ $[23] = t14;
6383
+ $[24] = t15;
6384
+ } else t15 = $[24];
6385
+ let t16;
6386
+ if ($[25] !== t15 || $[26] !== t8) {
6387
+ t16 = /* @__PURE__ */ jsxs("header", {
6268
6388
  className: ItemInfo_module_default.header,
6269
- children: [t16, t22]
6389
+ children: [t8, t15]
6270
6390
  });
6271
- $[39] = t16;
6272
- $[40] = t22;
6273
- $[41] = t23;
6274
- } else t23 = $[41];
6275
- let t24;
6276
- if ($[42] !== tab || $[43] !== tabId || $[44] !== tabs) {
6277
- t24 = /* @__PURE__ */ jsx("div", {
6391
+ $[25] = t15;
6392
+ $[26] = t8;
6393
+ $[27] = t16;
6394
+ } else t16 = $[27];
6395
+ let t17;
6396
+ if ($[28] !== tab || $[29] !== tabId || $[30] !== tabs) {
6397
+ t17 = /* @__PURE__ */ jsx("div", {
6278
6398
  className: ItemInfo_module_default.tabs,
6279
6399
  role: "tablist",
6280
6400
  children: tabs.map((name) => /* @__PURE__ */ jsx("button", {
@@ -6284,72 +6404,73 @@ function InfoCard(t0) {
6284
6404
  role: "tab",
6285
6405
  "aria-selected": name === tab,
6286
6406
  onClick: () => setPicked(name),
6287
- children: tabLabels[name]
6407
+ children: tabLabels$1[name]
6288
6408
  }, name))
6289
6409
  });
6290
- $[42] = tab;
6291
- $[43] = tabId;
6292
- $[44] = tabs;
6293
- $[45] = t24;
6294
- } else t24 = $[45];
6295
- const t25 = `${tabId}-${tab}`;
6296
- let t26;
6297
- if ($[46] !== anchor || $[47] !== info || $[48] !== tab || $[49] !== target) {
6298
- t26 = tab === "attributes" ? /* @__PURE__ */ jsx(Attributes, { attributes: info.attributes }) : /* @__PURE__ */ jsx(Variations, {
6410
+ $[28] = tab;
6411
+ $[29] = tabId;
6412
+ $[30] = tabs;
6413
+ $[31] = t17;
6414
+ } else t17 = $[31];
6415
+ const t18 = `${tabId}-${tab}`;
6416
+ let t19;
6417
+ if ($[32] !== anchor || $[33] !== info || $[34] !== tab || $[35] !== target) {
6418
+ t19 = tab === "attributes" ? /* @__PURE__ */ jsx(Attributes, { attributes: info.attributes }) : /* @__PURE__ */ jsx(Variations, {
6299
6419
  shown: {
6300
6420
  target,
6301
6421
  anchor
6302
6422
  },
6303
6423
  info
6304
6424
  });
6305
- $[46] = anchor;
6306
- $[47] = info;
6307
- $[48] = tab;
6308
- $[49] = target;
6309
- $[50] = t26;
6310
- } else t26 = $[50];
6311
- let t27;
6312
- if ($[51] !== t25 || $[52] !== t26) {
6313
- t27 = /* @__PURE__ */ jsx("div", {
6425
+ $[32] = anchor;
6426
+ $[33] = info;
6427
+ $[34] = tab;
6428
+ $[35] = target;
6429
+ $[36] = t19;
6430
+ } else t19 = $[36];
6431
+ let t20;
6432
+ if ($[37] !== t18 || $[38] !== t19) {
6433
+ t20 = /* @__PURE__ */ jsx("div", {
6314
6434
  className: ItemInfo_module_default.panel,
6315
6435
  role: "tabpanel",
6316
- "aria-labelledby": t25,
6317
- children: t26
6436
+ "aria-labelledby": t18,
6437
+ children: t19
6318
6438
  });
6319
- $[51] = t25;
6320
- $[52] = t26;
6321
- $[53] = t27;
6322
- } else t27 = $[53];
6323
- let t28;
6324
- if ($[54] !== t10 || $[55] !== t11 || $[56] !== t13 || $[57] !== t15 || $[58] !== t23 || $[59] !== t24 || $[60] !== t27 || $[61] !== t9) {
6325
- t28 = /* @__PURE__ */ jsxs("section", {
6439
+ $[37] = t18;
6440
+ $[38] = t19;
6441
+ $[39] = t20;
6442
+ } else t20 = $[39];
6443
+ let t21;
6444
+ if ($[40] !== card || $[41] !== style || $[42] !== t16 || $[43] !== t17 || $[44] !== t20 || $[45] !== t3 || $[46] !== t4 || $[47] !== t5 || $[48] !== t7) {
6445
+ t21 = /* @__PURE__ */ jsxs("section", {
6326
6446
  ref: card,
6327
6447
  className: ItemInfo_module_default.card,
6328
6448
  popover: "auto",
6329
- onToggle: t9,
6330
- "aria-label": t10,
6331
- "data-side": t11,
6332
- style: t13,
6449
+ onToggle: t3,
6450
+ "aria-label": t4,
6451
+ "data-side": t5,
6452
+ style,
6333
6453
  children: [
6334
- t15,
6335
- t23,
6336
- t24,
6337
- t27
6454
+ t7,
6455
+ t16,
6456
+ t17,
6457
+ t20
6338
6458
  ]
6339
6459
  });
6340
- $[54] = t10;
6341
- $[55] = t11;
6342
- $[56] = t13;
6343
- $[57] = t15;
6344
- $[58] = t23;
6345
- $[59] = t24;
6346
- $[60] = t27;
6347
- $[61] = t9;
6348
- $[62] = t28;
6349
- } else t28 = $[62];
6350
- return t28;
6460
+ $[40] = card;
6461
+ $[41] = style;
6462
+ $[42] = t16;
6463
+ $[43] = t17;
6464
+ $[44] = t20;
6465
+ $[45] = t3;
6466
+ $[46] = t4;
6467
+ $[47] = t5;
6468
+ $[48] = t7;
6469
+ $[49] = t21;
6470
+ } else t21 = $[49];
6471
+ return t21;
6351
6472
  }
6352
- const tabLabels = {
6473
+ const tabLabels$1 = {
6353
6474
  attributes: "Attributes",
6354
6475
  variations: "Variations"
6355
6476
  };
@@ -6394,7 +6515,7 @@ function Attributes(t0) {
6394
6515
  } else t2 = $[6];
6395
6516
  return t2;
6396
6517
  }
6397
- const PREVIEW_TARGET = "item-info";
6518
+ const PREVIEW_TARGET$1 = "item-info";
6398
6519
  /** By meta group; when fitted, hovering one previews it in place of the fitted one, and double clicking fits it there. */
6399
6520
  function Variations(t0) {
6400
6521
  const $ = c(25);
@@ -6411,7 +6532,7 @@ function Variations(t0) {
6411
6532
  let t3;
6412
6533
  if ($[0] !== preview || $[1] !== release) {
6413
6534
  t3 = () => {
6414
- preview.clear(PREVIEW_TARGET);
6535
+ preview.clear(PREVIEW_TARGET$1);
6415
6536
  release();
6416
6537
  };
6417
6538
  $[0] = preview;
@@ -6446,8 +6567,8 @@ function Variations(t0) {
6446
6567
  const swap = (draft) => fitted.charge ? draft.setCharge(ref, type.id) : draft.setType(ref, type.id);
6447
6568
  return {
6448
6569
  hover: (hovering_0) => {
6449
- if (hovering_0) preview.show(swap, PREVIEW_TARGET);
6450
- else preview.clear(PREVIEW_TARGET);
6570
+ if (hovering_0) preview.show(swap, PREVIEW_TARGET$1);
6571
+ else preview.clear(PREVIEW_TARGET$1);
6451
6572
  },
6452
6573
  activate: () => {
6453
6574
  swap(store);
@@ -6475,7 +6596,7 @@ function Variations(t0) {
6475
6596
  const swapper = t6;
6476
6597
  let t7;
6477
6598
  if ($[18] !== anchor || $[19] !== sde || $[20] !== show || $[21] !== swapper || $[22] !== target.typeId || $[23] !== variations) {
6478
- const groups = Map.groupBy(variations, _temp$11);
6599
+ const groups = Map.groupBy(variations, _temp$12);
6479
6600
  t7 = /* @__PURE__ */ jsx("ul", {
6480
6601
  className: ItemInfo_module_default.list,
6481
6602
  children: [...groups].map((t8) => {
@@ -6498,110 +6619,1319 @@ function Variations(t0) {
6498
6619
  })] }, metaGroupId ?? 0);
6499
6620
  })
6500
6621
  });
6501
- $[18] = anchor;
6502
- $[19] = sde;
6503
- $[20] = show;
6504
- $[21] = swapper;
6505
- $[22] = target.typeId;
6506
- $[23] = variations;
6507
- $[24] = t7;
6508
- } else t7 = $[24];
6509
- return t7;
6510
- }
6511
- function _temp$11(type_0) {
6512
- return type_0.metaGroupId;
6622
+ $[18] = anchor;
6623
+ $[19] = sde;
6624
+ $[20] = show;
6625
+ $[21] = swapper;
6626
+ $[22] = target.typeId;
6627
+ $[23] = variations;
6628
+ $[24] = t7;
6629
+ } else t7 = $[24];
6630
+ return t7;
6631
+ }
6632
+ function _temp$12(type_0) {
6633
+ return type_0.metaGroupId;
6634
+ }
6635
+ function Variation(t0) {
6636
+ const $ = c(20);
6637
+ const { type, current, onHover, onActivate, onInfo } = t0;
6638
+ let t1;
6639
+ if ($[0] !== type.id) {
6640
+ t1 = /* @__PURE__ */ jsx("span", {
6641
+ className: ItemInfo_module_default.variationIcon,
6642
+ children: /* @__PURE__ */ jsx(TypeIcon, { typeId: type.id })
6643
+ });
6644
+ $[0] = type.id;
6645
+ $[1] = t1;
6646
+ } else t1 = $[1];
6647
+ let t2;
6648
+ if ($[2] !== type.name) {
6649
+ t2 = /* @__PURE__ */ jsx("span", { children: type.name });
6650
+ $[2] = type.name;
6651
+ $[3] = t2;
6652
+ } else t2 = $[3];
6653
+ let t3;
6654
+ if ($[4] !== t1 || $[5] !== t2) {
6655
+ t3 = /* @__PURE__ */ jsxs(Fragment$1, { children: [t1, t2] });
6656
+ $[4] = t1;
6657
+ $[5] = t2;
6658
+ $[6] = t3;
6659
+ } else t3 = $[6];
6660
+ const label = t3;
6661
+ const t4 = current || void 0;
6662
+ let t5;
6663
+ if ($[7] !== current || $[8] !== label || $[9] !== onActivate || $[10] !== onHover) {
6664
+ t5 = current || onActivate === void 0 ? /* @__PURE__ */ jsx("div", {
6665
+ className: ItemInfo_module_default.variation,
6666
+ children: label
6667
+ }) : /* @__PURE__ */ jsx("button", {
6668
+ type: "button",
6669
+ className: ItemInfo_module_default.variation,
6670
+ title: "Double click to fit this instead",
6671
+ onDoubleClick: onActivate,
6672
+ onKeyDown: (event) => {
6673
+ if (event.key !== "Enter") return;
6674
+ event.preventDefault();
6675
+ onActivate();
6676
+ },
6677
+ onMouseEnter: () => onHover?.(true),
6678
+ onMouseLeave: () => onHover?.(false),
6679
+ onFocus: () => onHover?.(true),
6680
+ onBlur: () => onHover?.(false),
6681
+ children: label
6682
+ });
6683
+ $[7] = current;
6684
+ $[8] = label;
6685
+ $[9] = onActivate;
6686
+ $[10] = onHover;
6687
+ $[11] = t5;
6688
+ } else t5 = $[11];
6689
+ const t6 = `Show Info on ${type.name}`;
6690
+ let t7;
6691
+ if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
6692
+ t7 = /* @__PURE__ */ jsx(Icon, { name: "module-info" });
6693
+ $[12] = t7;
6694
+ } else t7 = $[12];
6695
+ let t8;
6696
+ if ($[13] !== onInfo || $[14] !== t6) {
6697
+ t8 = /* @__PURE__ */ jsx("button", {
6698
+ type: "button",
6699
+ className: ItemInfo_module_default.info,
6700
+ "aria-label": t6,
6701
+ onClick: onInfo,
6702
+ children: t7
6703
+ });
6704
+ $[13] = onInfo;
6705
+ $[14] = t6;
6706
+ $[15] = t8;
6707
+ } else t8 = $[15];
6708
+ let t9;
6709
+ if ($[16] !== t4 || $[17] !== t5 || $[18] !== t8) {
6710
+ t9 = /* @__PURE__ */ jsxs("li", {
6711
+ className: ItemInfo_module_default.row,
6712
+ "aria-current": t4,
6713
+ children: [t5, t8]
6714
+ });
6715
+ $[16] = t4;
6716
+ $[17] = t5;
6717
+ $[18] = t8;
6718
+ $[19] = t9;
6719
+ } else t9 = $[19];
6720
+ return t9;
6721
+ }
6722
+ // src/components/Mutate/Mutate.module.css
6723
+ var Mutate_module_default = {
6724
+ "button": "yNZdnG_button",
6725
+ "card": "yNZdnG_card",
6726
+ "caret": "yNZdnG_caret",
6727
+ "change": "yNZdnG_change",
6728
+ "chart": "yNZdnG_chart",
6729
+ "chartAxis": "yNZdnG_chartAxis",
6730
+ "chartBar": "yNZdnG_chartBar",
6731
+ "chartBase": "yNZdnG_chartBase",
6732
+ "chartBehind": "yNZdnG_chartBehind",
6733
+ "chartName": "yNZdnG_chartName",
6734
+ "chartRange": "yNZdnG_chartRange",
6735
+ "chartRoll": "yNZdnG_chartRoll",
6736
+ "chartRow": "yNZdnG_chartRow",
6737
+ "chartTitle": "yNZdnG_chartTitle",
6738
+ "dice": "yNZdnG_dice",
6739
+ "error": "yNZdnG_error",
6740
+ "field": "yNZdnG_field",
6741
+ "icon": "yNZdnG_icon",
6742
+ "import": "yNZdnG_import",
6743
+ "label": "yNZdnG_label",
6744
+ "menu": "yNZdnG_menu",
6745
+ "more": "yNZdnG_more",
6746
+ "name": "yNZdnG_name",
6747
+ "option": "yNZdnG_option",
6748
+ "options": "yNZdnG_options",
6749
+ "panel": "yNZdnG_panel",
6750
+ "picker": "yNZdnG_picker",
6751
+ "roll": "yNZdnG_roll",
6752
+ "select": "yNZdnG_select",
6753
+ "selected": "yNZdnG_selected",
6754
+ "slider": "yNZdnG_slider",
6755
+ "stat": "yNZdnG_stat",
6756
+ "stats": "yNZdnG_stats",
6757
+ "toolbar": "yNZdnG_toolbar",
6758
+ "value": "yNZdnG_value"
6759
+ };
6760
+ // src/components/Mutate/MutaplasmidPicker.tsx
6761
+ /** A dropdown of mutaplasmids, with a chart of how far the one pointed at rolls each stat. */
6762
+ function MutaplasmidPicker(t0) {
6763
+ const $ = c(25);
6764
+ const { mutaplasmids, roll, onChoose } = t0;
6765
+ const sde = useSde();
6766
+ const id = useId();
6767
+ const root = useRef(null);
6768
+ const list = useRef(null);
6769
+ const button = useRef(null);
6770
+ const [open, setOpen] = useState(false);
6771
+ const [active, setActive] = useState(roll.mutaplasmid);
6772
+ let t1;
6773
+ if ($[0] !== sde) {
6774
+ t1 = (mutaplasmid) => sde.type(mutaplasmid.id)?.name ?? String(mutaplasmid.id);
6775
+ $[0] = sde;
6776
+ $[1] = t1;
6777
+ } else t1 = $[1];
6778
+ const names = shortNames(mutaplasmids.map(t1));
6779
+ const nameOf = (mutaplasmidId) => names[mutaplasmids.findIndex((t2) => {
6780
+ const { id: other } = t2;
6781
+ return other === mutaplasmidId;
6782
+ })];
6783
+ let t3;
6784
+ let t4;
6785
+ if ($[2] !== open) {
6786
+ t3 = () => {
6787
+ if (!open) return;
6788
+ list.current?.querySelector("[aria-checked=true]")?.focus();
6789
+ const outside = (event) => {
6790
+ if (!(event.target instanceof Node && root.current?.contains(event.target))) setOpen(false);
6791
+ };
6792
+ document.addEventListener("pointerdown", outside);
6793
+ return () => document.removeEventListener("pointerdown", outside);
6794
+ };
6795
+ t4 = [open];
6796
+ $[2] = open;
6797
+ $[3] = t3;
6798
+ $[4] = t4;
6799
+ } else {
6800
+ t3 = $[3];
6801
+ t4 = $[4];
6802
+ }
6803
+ useEffect(t3, t4);
6804
+ let t5;
6805
+ if ($[5] !== roll.mutaplasmid) {
6806
+ t5 = () => {
6807
+ setActive(roll.mutaplasmid);
6808
+ setOpen(true);
6809
+ };
6810
+ $[5] = roll.mutaplasmid;
6811
+ $[6] = t5;
6812
+ } else t5 = $[6];
6813
+ const show = t5;
6814
+ const close = () => {
6815
+ setOpen(false);
6816
+ button.current?.focus();
6817
+ };
6818
+ const choose = (mutaplasmidId_0) => {
6819
+ close();
6820
+ onChoose(mutaplasmidId_0);
6821
+ };
6822
+ const onMenuKey = (event_0) => {
6823
+ const items = [...event_0.currentTarget.querySelectorAll("[role=menuitemradio]")];
6824
+ const index = items.indexOf(document.activeElement);
6825
+ if (event_0.key === "ArrowDown" || event_0.key === "ArrowUp") {
6826
+ event_0.preventDefault();
6827
+ const step = event_0.key === "ArrowDown" ? 1 : -1;
6828
+ items[Math.min(items.length - 1, Math.max(0, index + step))]?.focus();
6829
+ } else if (event_0.key === "Escape" || event_0.key === "Tab") {
6830
+ event_0.preventDefault();
6831
+ event_0.stopPropagation();
6832
+ close();
6833
+ }
6834
+ };
6835
+ const t6 = Mutate_module_default;
6836
+ const t7 = `${id}-menu`;
6837
+ let t8;
6838
+ if ($[7] !== open || $[8] !== show) {
6839
+ t8 = () => open ? setOpen(false) : show();
6840
+ $[7] = open;
6841
+ $[8] = show;
6842
+ $[9] = t8;
6843
+ } else t8 = $[9];
6844
+ let t9;
6845
+ if ($[10] !== show) {
6846
+ t9 = (event_1) => {
6847
+ if (event_1.key !== "ArrowDown" && event_1.key !== "ArrowUp") return;
6848
+ event_1.preventDefault();
6849
+ show();
6850
+ };
6851
+ $[10] = show;
6852
+ $[11] = t9;
6853
+ } else t9 = $[11];
6854
+ const t10 = nameOf(roll.mutaplasmid);
6855
+ let t11;
6856
+ if ($[12] !== t10) {
6857
+ t11 = /* @__PURE__ */ jsx("span", {
6858
+ className: Mutate_module_default.selected,
6859
+ children: t10
6860
+ });
6861
+ $[12] = t10;
6862
+ $[13] = t11;
6863
+ } else t11 = $[13];
6864
+ let t12;
6865
+ if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
6866
+ t12 = /* @__PURE__ */ jsx("span", {
6867
+ className: Mutate_module_default.caret,
6868
+ "aria-hidden": true,
6869
+ children: "▾"
6870
+ });
6871
+ $[14] = t12;
6872
+ } else t12 = $[14];
6873
+ let t13;
6874
+ if ($[15] !== open || $[16] !== t11 || $[17] !== t7 || $[18] !== t8 || $[19] !== t9) {
6875
+ t13 = /* @__PURE__ */ jsxs("button", {
6876
+ ref: button,
6877
+ type: "button",
6878
+ className: Mutate_module_default.select,
6879
+ "aria-haspopup": "menu",
6880
+ "aria-expanded": open,
6881
+ "aria-controls": t7,
6882
+ onClick: t8,
6883
+ onKeyDown: t9,
6884
+ children: [t11, t12]
6885
+ });
6886
+ $[15] = open;
6887
+ $[16] = t11;
6888
+ $[17] = t7;
6889
+ $[18] = t8;
6890
+ $[19] = t9;
6891
+ $[20] = t13;
6892
+ } else t13 = $[20];
6893
+ const t14 = open && /* @__PURE__ */ jsxs("div", {
6894
+ className: Mutate_module_default.menu,
6895
+ children: [/* @__PURE__ */ jsx("div", {
6896
+ ref: list,
6897
+ id: `${id}-menu`,
6898
+ className: Mutate_module_default.options,
6899
+ role: "menu",
6900
+ "aria-label": "Mutaplasmid",
6901
+ tabIndex: -1,
6902
+ onKeyDown: onMenuKey,
6903
+ children: mutaplasmids.map((mutaplasmid_0, index_0) => /* @__PURE__ */ jsx("button", {
6904
+ type: "button",
6905
+ className: Mutate_module_default.option,
6906
+ role: "menuitemradio",
6907
+ "aria-checked": mutaplasmid_0.id === roll.mutaplasmid,
6908
+ tabIndex: -1,
6909
+ "data-active": mutaplasmid_0.id === active || void 0,
6910
+ onFocus: () => setActive(mutaplasmid_0.id),
6911
+ onPointerMove: _temp$11,
6912
+ onClick: () => choose(mutaplasmid_0.id),
6913
+ children: names[index_0]
6914
+ }, mutaplasmid_0.id))
6915
+ }), /* @__PURE__ */ jsx(RangeChart, {
6916
+ mutaplasmids,
6917
+ shown: active,
6918
+ roll,
6919
+ names
6920
+ })]
6921
+ });
6922
+ let t15;
6923
+ if ($[21] !== t13 || $[22] !== t14 || $[23] !== t6.picker) {
6924
+ t15 = /* @__PURE__ */ jsxs("div", {
6925
+ ref: root,
6926
+ className: t6.picker,
6927
+ children: [t13, t14]
6928
+ });
6929
+ $[21] = t13;
6930
+ $[22] = t14;
6931
+ $[23] = t6.picker;
6932
+ $[24] = t15;
6933
+ } else t15 = $[24];
6934
+ return t15;
6935
+ }
6936
+ function _temp$11(event_2) {
6937
+ return event_2.currentTarget.focus();
6938
+ }
6939
+ /** Each stat's range under one mutaplasmid, the widest one's behind it, and the roll. */
6940
+ function RangeChart(t0) {
6941
+ const $ = c(49);
6942
+ const { mutaplasmids, shown, roll, names } = t0;
6943
+ const sde = useSde();
6944
+ let t1;
6945
+ if ($[0] !== roll.base || $[1] !== sde) {
6946
+ t1 = (mutaplasmid) => mutationRanges(sde, roll.base, mutaplasmid);
6947
+ $[0] = roll.base;
6948
+ $[1] = sde;
6949
+ $[2] = t1;
6950
+ } else t1 = $[2];
6951
+ const rangesOf = t1;
6952
+ let low;
6953
+ let t2;
6954
+ if ($[3] !== mutaplasmids || $[4] !== rangesOf) {
6955
+ let t3;
6956
+ if ($[7] !== rangesOf) {
6957
+ t3 = (t4) => {
6958
+ const { id } = t4;
6959
+ return rangesOf(id).flatMap(_temp2$6);
6960
+ };
6961
+ $[7] = rangesOf;
6962
+ $[8] = t3;
6963
+ } else t3 = $[8];
6964
+ const all = mutaplasmids.flatMap(t3);
6965
+ low = Math.min(1, ...all);
6966
+ t2 = Math.max(1, ...all);
6967
+ $[3] = mutaplasmids;
6968
+ $[4] = rangesOf;
6969
+ $[5] = low;
6970
+ $[6] = t2;
6971
+ } else {
6972
+ low = $[5];
6973
+ t2 = $[6];
6974
+ }
6975
+ const high = t2;
6976
+ let t3;
6977
+ if ($[9] !== high || $[10] !== low) {
6978
+ t3 = (value) => `${(value - low) / (high - low || 1) * 100}%`;
6979
+ $[9] = high;
6980
+ $[10] = low;
6981
+ $[11] = t3;
6982
+ } else t3 = $[11];
6983
+ const at = t3;
6984
+ let t4;
6985
+ let t5;
6986
+ let t6;
6987
+ let t7;
6988
+ if ($[12] !== at || $[13] !== mutaplasmids || $[14] !== names || $[15] !== rangesOf || $[16] !== roll.attributes || $[17] !== sde || $[18] !== shown) {
6989
+ const widest = mutaplasmids.at(-1)?.id ?? shown;
6990
+ const behind = new Map(rangesOf(widest).map(_temp3$3));
6991
+ let t8;
6992
+ if ($[23] !== mutaplasmids || $[24] !== names) {
6993
+ t8 = (mutaplasmidId) => names[mutaplasmids.findIndex((t9) => {
6994
+ const { id: id_0 } = t9;
6995
+ return id_0 === mutaplasmidId;
6996
+ })];
6997
+ $[23] = mutaplasmids;
6998
+ $[24] = names;
6999
+ $[25] = t8;
7000
+ } else t8 = $[25];
7001
+ const nameOf = t8;
7002
+ t4 = Mutate_module_default.chart;
7003
+ t5 = true;
7004
+ let t9;
7005
+ if ($[26] !== nameOf || $[27] !== shown) {
7006
+ t9 = nameOf(shown);
7007
+ $[26] = nameOf;
7008
+ $[27] = shown;
7009
+ $[28] = t9;
7010
+ } else t9 = $[28];
7011
+ if ($[29] !== t9) {
7012
+ t6 = /* @__PURE__ */ jsx("span", {
7013
+ className: Mutate_module_default.chartTitle,
7014
+ children: t9
7015
+ });
7016
+ $[29] = t9;
7017
+ $[30] = t6;
7018
+ } else t6 = $[30];
7019
+ t7 = rangesOf(shown).map((range_1) => {
7020
+ const attribute = sde.attribute(range_1.attributeId);
7021
+ const widestRange = behind.get(range_1.attributeId);
7022
+ const [from, to] = ends(range_1);
7023
+ const rolled = roll.attributes[range_1.attributeId];
7024
+ return /* @__PURE__ */ jsxs("div", {
7025
+ className: Mutate_module_default.chartRow,
7026
+ children: [/* @__PURE__ */ jsx("span", {
7027
+ className: Mutate_module_default.chartName,
7028
+ children: attribute?.displayName ?? attribute?.name
7029
+ }), /* @__PURE__ */ jsxs("span", {
7030
+ className: Mutate_module_default.chartBar,
7031
+ children: [
7032
+ shown !== widest && widestRange !== void 0 && /* @__PURE__ */ jsx("span", {
7033
+ className: Mutate_module_default.chartBehind,
7034
+ style: span(at, ...ends(widestRange))
7035
+ }),
7036
+ /* @__PURE__ */ jsx("span", {
7037
+ className: Mutate_module_default.chartRange,
7038
+ style: {
7039
+ ...span(at, from, to),
7040
+ "--neutral": `${(1 - from) / (to - from || 1) * 100}%`
7041
+ },
7042
+ "data-up-is-good": upIsGood(range_1) || void 0
7043
+ }),
7044
+ /* @__PURE__ */ jsx("span", {
7045
+ className: Mutate_module_default.chartBase,
7046
+ style: { left: at(1) }
7047
+ }),
7048
+ rolled !== void 0 && /* @__PURE__ */ jsx("span", {
7049
+ className: Mutate_module_default.chartRoll,
7050
+ style: { left: at(ratio(range_1, rolled)) }
7051
+ })
7052
+ ]
7053
+ })]
7054
+ }, range_1.attributeId);
7055
+ });
7056
+ $[12] = at;
7057
+ $[13] = mutaplasmids;
7058
+ $[14] = names;
7059
+ $[15] = rangesOf;
7060
+ $[16] = roll.attributes;
7061
+ $[17] = sde;
7062
+ $[18] = shown;
7063
+ $[19] = t4;
7064
+ $[20] = t5;
7065
+ $[21] = t6;
7066
+ $[22] = t7;
7067
+ } else {
7068
+ t4 = $[19];
7069
+ t5 = $[20];
7070
+ t6 = $[21];
7071
+ t7 = $[22];
7072
+ }
7073
+ let t8;
7074
+ if ($[31] !== low) {
7075
+ t8 = percent(low);
7076
+ $[31] = low;
7077
+ $[32] = t8;
7078
+ } else t8 = $[32];
7079
+ let t9;
7080
+ if ($[33] !== t8) {
7081
+ t9 = /* @__PURE__ */ jsx("span", { children: t8 });
7082
+ $[33] = t8;
7083
+ $[34] = t9;
7084
+ } else t9 = $[34];
7085
+ let t10;
7086
+ if ($[35] === Symbol.for("react.memo_cache_sentinel")) {
7087
+ t10 = /* @__PURE__ */ jsx("span", { children: "base" });
7088
+ $[35] = t10;
7089
+ } else t10 = $[35];
7090
+ let t11;
7091
+ if ($[36] !== high) {
7092
+ t11 = percent(high);
7093
+ $[36] = high;
7094
+ $[37] = t11;
7095
+ } else t11 = $[37];
7096
+ let t12;
7097
+ if ($[38] !== t11) {
7098
+ t12 = /* @__PURE__ */ jsx("span", { children: t11 });
7099
+ $[38] = t11;
7100
+ $[39] = t12;
7101
+ } else t12 = $[39];
7102
+ let t13;
7103
+ if ($[40] !== t12 || $[41] !== t9) {
7104
+ t13 = /* @__PURE__ */ jsxs("div", {
7105
+ className: Mutate_module_default.chartAxis,
7106
+ children: [
7107
+ t9,
7108
+ t10,
7109
+ t12
7110
+ ]
7111
+ });
7112
+ $[40] = t12;
7113
+ $[41] = t9;
7114
+ $[42] = t13;
7115
+ } else t13 = $[42];
7116
+ let t14;
7117
+ if ($[43] !== t13 || $[44] !== t4 || $[45] !== t5 || $[46] !== t6 || $[47] !== t7) {
7118
+ t14 = /* @__PURE__ */ jsxs("div", {
7119
+ className: t4,
7120
+ "aria-hidden": t5,
7121
+ children: [
7122
+ t6,
7123
+ t7,
7124
+ t13
7125
+ ]
7126
+ });
7127
+ $[43] = t13;
7128
+ $[44] = t4;
7129
+ $[45] = t5;
7130
+ $[46] = t6;
7131
+ $[47] = t7;
7132
+ $[48] = t14;
7133
+ } else t14 = $[48];
7134
+ return t14;
7135
+ }
7136
+ function _temp3$3(range_0) {
7137
+ return [range_0.attributeId, range_0];
7138
+ }
7139
+ function _temp2$6(range) {
7140
+ return [ratio(range, range.min), ratio(range, range.max)];
7141
+ }
7142
+ function percent(value) {
7143
+ return `${value > 1 ? "+" : value < 1 ? "−" : ""}${formatNumber(Math.abs(value - 1) * 100, { decimals: 0 })}%`;
7144
+ }
7145
+ function ratio(range, value) {
7146
+ return range.base === 0 ? 1 : value / range.base;
7147
+ }
7148
+ function ends(range) {
7149
+ const a = ratio(range, range.min);
7150
+ const b = ratio(range, range.max);
7151
+ return [Math.min(a, b), Math.max(a, b)];
7152
+ }
7153
+ function span(at, from, to) {
7154
+ return {
7155
+ left: at(from),
7156
+ right: `calc(100% - ${at(to)})`
7157
+ };
7158
+ }
7159
+ /** Whether a bigger multiplier makes the stat better. */
7160
+ function upIsGood(range) {
7161
+ return range.highIsGood === range.base >= 0;
7162
+ }
7163
+ /** The names without the words they all end in, like "Large Shield Extender Mutaplasmid". */
7164
+ function shortNames(names) {
7165
+ const words = names.map((name) => name.split(" "));
7166
+ let shared = 0;
7167
+ while (words.every((name) => name.length > shared + 1) && words.every((name) => name.at(-1 - shared) === words[0].at(-1 - shared))) shared++;
7168
+ if (names.length === 1) shared = words[0].at(-1) === "Mutaplasmid" ? 1 : 0;
7169
+ return words.map((name) => name.slice(0, name.length - shared).join(" "));
7170
+ }
7171
+ // src/components/Mutate/Mutate.tsx
7172
+ const PREVIEW_TARGET = "mutate";
7173
+ /** The window to roll a fitted module's mutation in, next to what asked for it. */
7174
+ function Mutate() {
7175
+ const $ = c(20);
7176
+ const { shown, close } = useMutate();
7177
+ const fit = useFit();
7178
+ const sde = useSde();
7179
+ let t0;
7180
+ if ($[0] !== fit || $[1] !== shown) {
7181
+ t0 = shown === void 0 ? -1 : refIn(fit, shown.slot);
7182
+ $[0] = fit;
7183
+ $[1] = shown;
7184
+ $[2] = t0;
7185
+ } else t0 = $[2];
7186
+ const ref = t0;
7187
+ const item = fit.items[ref];
7188
+ let t1;
7189
+ if ($[3] !== item || $[4] !== sde) {
7190
+ t1 = item && mutationRollOf(sde, item);
7191
+ $[3] = item;
7192
+ $[4] = sde;
7193
+ $[5] = t1;
7194
+ } else t1 = $[5];
7195
+ const roll = t1;
7196
+ const gone = shown !== void 0 && roll === void 0;
7197
+ const closeWhenGone = useEffectEvent(close);
7198
+ let t2;
7199
+ if ($[6] !== closeWhenGone || $[7] !== gone) {
7200
+ t2 = () => {
7201
+ if (gone) closeWhenGone();
7202
+ };
7203
+ $[6] = closeWhenGone;
7204
+ $[7] = gone;
7205
+ $[8] = t2;
7206
+ } else t2 = $[8];
7207
+ let t3;
7208
+ if ($[9] !== gone) {
7209
+ t3 = [gone];
7210
+ $[9] = gone;
7211
+ $[10] = t3;
7212
+ } else t3 = $[10];
7213
+ useEffect(t2, t3);
7214
+ if (shown === void 0 || item === void 0 || roll === void 0) return null;
7215
+ const t4 = shown.slot.type;
7216
+ let t5;
7217
+ if ($[11] !== shown.slot) {
7218
+ t5 = slotIndex(shown.slot);
7219
+ $[11] = shown.slot;
7220
+ $[12] = t5;
7221
+ } else t5 = $[12];
7222
+ const t6 = `${t4} ${t5}`;
7223
+ let t7;
7224
+ if ($[13] !== close || $[14] !== item.type_id || $[15] !== ref || $[16] !== roll || $[17] !== shown || $[18] !== t6) {
7225
+ t7 = /* @__PURE__ */ jsx(MutateCard, {
7226
+ shown,
7227
+ itemRef: ref,
7228
+ typeId: item.type_id,
7229
+ roll,
7230
+ onClose: close
7231
+ }, t6);
7232
+ $[13] = close;
7233
+ $[14] = item.type_id;
7234
+ $[15] = ref;
7235
+ $[16] = roll;
7236
+ $[17] = shown;
7237
+ $[18] = t6;
7238
+ $[19] = t7;
7239
+ } else t7 = $[19];
7240
+ return t7;
7241
+ }
7242
+ function MutateCard(t0) {
7243
+ const $ = c(42);
7244
+ const { shown: t1, itemRef: ref, typeId, roll: fitted, onClose } = t0;
7245
+ const { slot, anchor } = t1;
7246
+ const sde = useSde();
7247
+ const store = useFitStore();
7248
+ const preview = usePreview();
7249
+ const { card, style } = useAnchoredCard(anchor, onClose);
7250
+ const { open: openMenu, menu } = useContextMenu();
7251
+ const tabId = useId();
7252
+ const [tab, setTab] = useState("attributes");
7253
+ const [chosen, setChosen] = useState();
7254
+ const [dragged, setDragged] = useState();
7255
+ let t2;
7256
+ if ($[0] !== fitted.base || $[1] !== sde) {
7257
+ t2 = mutaplasmidsOf(sde, fitted.base);
7258
+ $[0] = fitted.base;
7259
+ $[1] = sde;
7260
+ $[2] = t2;
7261
+ } else t2 = $[2];
7262
+ const mutaplasmids = t2;
7263
+ let t3;
7264
+ if ($[3] !== chosen || $[4] !== fitted || $[5] !== sde) {
7265
+ t3 = chosen !== void 0 && rollFits(sde, {
7266
+ ...fitted,
7267
+ mutaplasmid: chosen
7268
+ }) ? chosen : fitted.mutaplasmid;
7269
+ $[3] = chosen;
7270
+ $[4] = fitted;
7271
+ $[5] = sde;
7272
+ $[6] = t3;
7273
+ } else t3 = $[6];
7274
+ const mutaplasmid = t3;
7275
+ const roll = dragged ?? {
7276
+ ...fitted,
7277
+ mutaplasmid
7278
+ };
7279
+ const ranges = mutationRanges(sde, roll.base, roll.mutaplasmid);
7280
+ const base = sde.type(roll.base);
7281
+ let t4;
7282
+ if ($[7] !== preview) {
7283
+ t4 = () => preview.clear(PREVIEW_TARGET);
7284
+ $[7] = preview;
7285
+ $[8] = t4;
7286
+ } else t4 = $[8];
7287
+ const clearPreview = useEffectEvent(t4);
7288
+ let t5;
7289
+ if ($[9] !== clearPreview) {
7290
+ t5 = () => () => clearPreview();
7291
+ $[9] = clearPreview;
7292
+ $[10] = t5;
7293
+ } else t5 = $[10];
7294
+ let t6;
7295
+ if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
7296
+ t6 = [];
7297
+ $[11] = t6;
7298
+ } else t6 = $[11];
7299
+ useEffect(t5, t6);
7300
+ let t7;
7301
+ if ($[12] !== preview || $[13] !== ref || $[14] !== store) {
7302
+ t7 = (next) => {
7303
+ preview.clear(PREVIEW_TARGET);
7304
+ setDragged(void 0);
7305
+ setChosen(next.mutaplasmid);
7306
+ store.setMutation(ref, next);
7307
+ };
7308
+ $[12] = preview;
7309
+ $[13] = ref;
7310
+ $[14] = store;
7311
+ $[15] = t7;
7312
+ } else t7 = $[15];
7313
+ const commit = t7;
7314
+ let t8;
7315
+ if ($[16] !== preview || $[17] !== ref) {
7316
+ t8 = (next_0) => {
7317
+ setDragged(next_0);
7318
+ preview.show((draft) => draft.setMutation(ref, next_0), PREVIEW_TARGET);
7319
+ };
7320
+ $[16] = preview;
7321
+ $[17] = ref;
7322
+ $[18] = t8;
7323
+ } else t8 = $[18];
7324
+ const drag = t8;
7325
+ const setValue = (range, value) => drag({
7326
+ ...roll,
7327
+ attributes: {
7328
+ ...roll.attributes,
7329
+ [range.attributeId]: clamp(value, range)
7330
+ }
7331
+ });
7332
+ let t9;
7333
+ if ($[19] !== commit || $[20] !== dragged) {
7334
+ t9 = () => {
7335
+ if (dragged !== void 0) commit(dragged);
7336
+ };
7337
+ $[19] = commit;
7338
+ $[20] = dragged;
7339
+ $[21] = t9;
7340
+ } else t9 = $[21];
7341
+ const finish = t9;
7342
+ const reroll = (kind) => commit(rollMutation(sde, roll.base, roll.mutaplasmid, kind));
7343
+ const choose = (picked) => {
7344
+ const attributes = {};
7345
+ for (const range_0 of mutationRanges(sde, roll.base, picked)) attributes[range_0.attributeId] = clamp(roll.attributes[range_0.attributeId] ?? range_0.base, range_0);
7346
+ commit({
7347
+ base: roll.base,
7348
+ mutaplasmid: picked,
7349
+ attributes
7350
+ });
7351
+ };
7352
+ let t10;
7353
+ if ($[22] !== onClose) {
7354
+ t10 = (event) => {
7355
+ if (event.target === event.currentTarget && event.newState === "closed") onClose();
7356
+ };
7357
+ $[22] = onClose;
7358
+ $[23] = t10;
7359
+ } else t10 = $[23];
7360
+ let t11;
7361
+ if ($[24] === Symbol.for("react.memo_cache_sentinel")) {
7362
+ t11 = /* @__PURE__ */ jsx(Icon, { name: "close" });
7363
+ $[24] = t11;
7364
+ } else t11 = $[24];
7365
+ let t12;
7366
+ if ($[25] !== onClose) {
7367
+ t12 = /* @__PURE__ */ jsx("button", {
7368
+ type: "button",
7369
+ className: ItemInfo_module_default.close,
7370
+ "aria-label": "Close",
7371
+ onClick: onClose,
7372
+ children: t11
7373
+ });
7374
+ $[25] = onClose;
7375
+ $[26] = t12;
7376
+ } else t12 = $[26];
7377
+ let t13;
7378
+ if ($[27] !== typeId) {
7379
+ t13 = /* @__PURE__ */ jsx("span", {
7380
+ className: ItemInfo_module_default.typeIcon,
7381
+ children: /* @__PURE__ */ jsx(TypeIcon, {
7382
+ typeId,
7383
+ size: 64
7384
+ })
7385
+ });
7386
+ $[27] = typeId;
7387
+ $[28] = t13;
7388
+ } else t13 = $[28];
7389
+ let t14;
7390
+ if ($[29] !== slot) {
7391
+ t14 = slotName(slot);
7392
+ $[29] = slot;
7393
+ $[30] = t14;
7394
+ } else t14 = $[30];
7395
+ let t15;
7396
+ if ($[31] !== t14) {
7397
+ t15 = /* @__PURE__ */ jsxs("span", { children: ["Fitted · ", t14] });
7398
+ $[31] = t14;
7399
+ $[32] = t15;
7400
+ } else t15 = $[32];
7401
+ let t16;
7402
+ if ($[33] !== tab || $[34] !== tabId) {
7403
+ t16 = tabs.map((name) => /* @__PURE__ */ jsx("button", {
7404
+ type: "button",
7405
+ id: `${tabId}-${name}`,
7406
+ className: ItemInfo_module_default.tab,
7407
+ role: "tab",
7408
+ "aria-selected": name === tab,
7409
+ onClick: () => setTab(name),
7410
+ children: tabLabels[name]
7411
+ }, name));
7412
+ $[33] = tab;
7413
+ $[34] = tabId;
7414
+ $[35] = t16;
7415
+ } else t16 = $[35];
7416
+ let t17;
7417
+ if ($[36] !== t16) {
7418
+ t17 = /* @__PURE__ */ jsx("div", {
7419
+ className: ItemInfo_module_default.tabs,
7420
+ role: "tablist",
7421
+ children: t16
7422
+ });
7423
+ $[36] = t16;
7424
+ $[37] = t17;
7425
+ } else t17 = $[37];
7426
+ const t18 = Mutate_module_default;
7427
+ const t19 = "tabpanel";
7428
+ const t20 = `${tabId}-${tab}`;
7429
+ const t21 = tab === "attributes" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
7430
+ /* @__PURE__ */ jsxs("div", {
7431
+ className: Mutate_module_default.toolbar,
7432
+ children: [/* @__PURE__ */ jsx(MutaplasmidPicker, {
7433
+ mutaplasmids,
7434
+ roll,
7435
+ onChoose: choose
7436
+ }), /* @__PURE__ */ jsxs("span", {
7437
+ className: Mutate_module_default.roll,
7438
+ children: [/* @__PURE__ */ jsx("button", {
7439
+ type: "button",
7440
+ className: Mutate_module_default.dice,
7441
+ "aria-label": "Roll",
7442
+ title: "Roll",
7443
+ onClick: () => reroll("random"),
7444
+ children: /* @__PURE__ */ jsx(Dice, {})
7445
+ }), /* @__PURE__ */ jsx("button", {
7446
+ type: "button",
7447
+ className: Mutate_module_default.more,
7448
+ "aria-label": "More Rolls",
7449
+ "aria-haspopup": "menu",
7450
+ onClick: (event_0) => openMenu(event_0, [{
7451
+ label: "Best Roll",
7452
+ onSelect: () => reroll("best")
7453
+ }, {
7454
+ label: "Worst Roll",
7455
+ onSelect: () => reroll("worst")
7456
+ }]),
7457
+ children: "▾"
7458
+ })]
7459
+ })]
7460
+ }),
7461
+ menu,
7462
+ /* @__PURE__ */ jsx("div", {
7463
+ className: Mutate_module_default.stats,
7464
+ children: ranges.map((range_1) => /* @__PURE__ */ jsx(Stat$1, {
7465
+ range: range_1,
7466
+ value: roll.attributes[range_1.attributeId] ?? range_1.base,
7467
+ onChange: (value_0) => setValue(range_1, value_0),
7468
+ onFinish: finish
7469
+ }, range_1.attributeId))
7470
+ })
7471
+ ] }) : /* @__PURE__ */ jsx(Import, {
7472
+ slot,
7473
+ current: fitted,
7474
+ onFound: (found) => {
7475
+ setChosen(found.mutaplasmid);
7476
+ setTab("attributes");
7477
+ }
7478
+ });
7479
+ let t22;
7480
+ if ($[38] !== t18.panel || $[39] !== t20 || $[40] !== t21) {
7481
+ t22 = /* @__PURE__ */ jsx("div", {
7482
+ className: t18.panel,
7483
+ role: t19,
7484
+ "aria-labelledby": t20,
7485
+ children: t21
7486
+ });
7487
+ $[38] = t18.panel;
7488
+ $[39] = t20;
7489
+ $[40] = t21;
7490
+ $[41] = t22;
7491
+ } else t22 = $[41];
7492
+ return /* @__PURE__ */ jsxs("section", {
7493
+ ref: card,
7494
+ className: `${ItemInfo_module_default.card} ${Mutate_module_default.card}`,
7495
+ popover: "auto",
7496
+ onToggle: t10,
7497
+ "aria-label": `Mutate ${base?.name ?? ""}`,
7498
+ "data-side": anchor?.side,
7499
+ style,
7500
+ children: [
7501
+ t12,
7502
+ /* @__PURE__ */ jsxs("header", {
7503
+ className: ItemInfo_module_default.header,
7504
+ children: [t13, /* @__PURE__ */ jsxs("div", {
7505
+ className: ItemInfo_module_default.title,
7506
+ children: [
7507
+ /* @__PURE__ */ jsxs("h2", {
7508
+ className: ItemInfo_module_default.name,
7509
+ children: ["Mutate ", base?.name]
7510
+ }),
7511
+ /* @__PURE__ */ jsx("span", {
7512
+ className: ItemInfo_module_default.muted,
7513
+ children: sde.type(roll.mutaplasmid)?.name
7514
+ }),
7515
+ t15
7516
+ ]
7517
+ })]
7518
+ }),
7519
+ t17,
7520
+ t22
7521
+ ]
7522
+ });
7523
+ }
7524
+ const tabs = ["attributes", "import"];
7525
+ const tabLabels = {
7526
+ attributes: "Attributes",
7527
+ import: "Import"
7528
+ };
7529
+ function Stat$1(t0) {
7530
+ const $ = c(49);
7531
+ const { range, value, onChange, onFinish } = t0;
7532
+ const sde = useSde();
7533
+ let t1;
7534
+ if ($[0] !== range.attributeId || $[1] !== sde) {
7535
+ t1 = sde.attribute(range.attributeId);
7536
+ $[0] = range.attributeId;
7537
+ $[1] = sde;
7538
+ $[2] = t1;
7539
+ } else t1 = $[2];
7540
+ const attribute = t1;
7541
+ const name = attribute?.displayName ?? attribute?.name ?? String(range.attributeId);
7542
+ const t2 = useImages();
7543
+ let t3;
7544
+ if ($[3] !== range.attributeId || $[4] !== t2) {
7545
+ t3 = t2.attributeIcon(range.attributeId);
7546
+ $[3] = range.attributeId;
7547
+ $[4] = t2;
7548
+ $[5] = t3;
7549
+ } else t3 = $[5];
7550
+ const icon = t3;
7551
+ const span = range.max - range.min;
7552
+ const base = `${span === 0 ? 50 : (range.base - range.min) / span * 100}%`;
7553
+ const change = range.base === 0 ? 0 : value / range.base - 1;
7554
+ const t4 = Math.abs(change) * 100;
7555
+ let t5;
7556
+ if ($[6] !== t4) {
7557
+ t5 = formatNumber(t4, { decimals: 1 });
7558
+ $[6] = t4;
7559
+ $[7] = t5;
7560
+ } else t5 = $[7];
7561
+ const percent = t5;
7562
+ const unchanged = Number(percent) === 0;
7563
+ const better = value > range.base === range.highIsGood;
7564
+ let t6;
7565
+ if ($[8] !== range.attributeId || $[9] !== sde || $[10] !== value) {
7566
+ t6 = formatAttribute(sde, range.attributeId, value);
7567
+ $[8] = range.attributeId;
7568
+ $[9] = sde;
7569
+ $[10] = value;
7570
+ $[11] = t6;
7571
+ } else t6 = $[11];
7572
+ const text = t6;
7573
+ const slider = useRef(null);
7574
+ const released = useEffectEvent(onFinish);
7575
+ let t7;
7576
+ if ($[12] !== released) {
7577
+ t7 = () => {
7578
+ const input = slider.current;
7579
+ const listener = () => released();
7580
+ input?.addEventListener("change", listener);
7581
+ return () => input?.removeEventListener("change", listener);
7582
+ };
7583
+ $[12] = released;
7584
+ $[13] = t7;
7585
+ } else t7 = $[13];
7586
+ let t8;
7587
+ if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
7588
+ t8 = [];
7589
+ $[14] = t8;
7590
+ } else t8 = $[14];
7591
+ useEffect(t7, t8);
7592
+ let t9;
7593
+ if ($[15] !== icon) {
7594
+ t9 = icon === void 0 ? /* @__PURE__ */ jsx("span", { className: Mutate_module_default.icon }) : /* @__PURE__ */ jsx("img", {
7595
+ className: Mutate_module_default.icon,
7596
+ src: icon,
7597
+ alt: ""
7598
+ });
7599
+ $[15] = icon;
7600
+ $[16] = t9;
7601
+ } else t9 = $[16];
7602
+ let t10;
7603
+ if ($[17] !== name) {
7604
+ t10 = /* @__PURE__ */ jsx("span", {
7605
+ className: Mutate_module_default.label,
7606
+ children: name
7607
+ });
7608
+ $[17] = name;
7609
+ $[18] = t10;
7610
+ } else t10 = $[18];
7611
+ let t11;
7612
+ if ($[19] !== name || $[20] !== t10 || $[21] !== t9) {
7613
+ t11 = /* @__PURE__ */ jsxs("span", {
7614
+ className: Mutate_module_default.name,
7615
+ title: name,
7616
+ children: [t9, t10]
7617
+ });
7618
+ $[19] = name;
7619
+ $[20] = t10;
7620
+ $[21] = t9;
7621
+ $[22] = t11;
7622
+ } else t11 = $[22];
7623
+ let t12;
7624
+ if ($[23] !== base) {
7625
+ t12 = { "--base": base };
7626
+ $[23] = base;
7627
+ $[24] = t12;
7628
+ } else t12 = $[24];
7629
+ const t13 = t12;
7630
+ const t14 = range.highIsGood || void 0;
7631
+ let t15;
7632
+ if ($[25] !== onChange) {
7633
+ t15 = (event) => onChange(Number(event.currentTarget.value));
7634
+ $[25] = onChange;
7635
+ $[26] = t15;
7636
+ } else t15 = $[26];
7637
+ let t16;
7638
+ if ($[27] !== name || $[28] !== onFinish || $[29] !== range.max || $[30] !== range.min || $[31] !== t15 || $[32] !== text || $[33] !== value) {
7639
+ t16 = /* @__PURE__ */ jsx("input", {
7640
+ ref: slider,
7641
+ type: "range",
7642
+ "aria-label": name,
7643
+ min: range.min,
7644
+ max: range.max,
7645
+ step: "any",
7646
+ value,
7647
+ "aria-valuetext": text,
7648
+ onChange: t15,
7649
+ onPointerUp: onFinish,
7650
+ onBlur: onFinish
7651
+ });
7652
+ $[27] = name;
7653
+ $[28] = onFinish;
7654
+ $[29] = range.max;
7655
+ $[30] = range.min;
7656
+ $[31] = t15;
7657
+ $[32] = text;
7658
+ $[33] = value;
7659
+ $[34] = t16;
7660
+ } else t16 = $[34];
7661
+ let t17;
7662
+ if ($[35] !== t13 || $[36] !== t14 || $[37] !== t16) {
7663
+ t17 = /* @__PURE__ */ jsx("span", {
7664
+ className: Mutate_module_default.slider,
7665
+ style: t13,
7666
+ "data-high-is-good": t14,
7667
+ children: t16
7668
+ });
7669
+ $[35] = t13;
7670
+ $[36] = t14;
7671
+ $[37] = t16;
7672
+ $[38] = t17;
7673
+ } else t17 = $[38];
7674
+ let t18;
7675
+ if ($[39] !== text) {
7676
+ t18 = /* @__PURE__ */ jsx("span", {
7677
+ className: Mutate_module_default.value,
7678
+ children: text
7679
+ });
7680
+ $[39] = text;
7681
+ $[40] = t18;
7682
+ } else t18 = $[40];
7683
+ const t19 = unchanged ? void 0 : better ? "better" : "worse";
7684
+ const t20 = unchanged ? "0%" : `${change > 0 ? "+" : "-"}${percent}%`;
7685
+ let t21;
7686
+ if ($[41] !== t19 || $[42] !== t20) {
7687
+ t21 = /* @__PURE__ */ jsx("span", {
7688
+ className: Mutate_module_default.change,
7689
+ "data-change": t19,
7690
+ children: t20
7691
+ });
7692
+ $[41] = t19;
7693
+ $[42] = t20;
7694
+ $[43] = t21;
7695
+ } else t21 = $[43];
7696
+ let t22;
7697
+ if ($[44] !== t11 || $[45] !== t17 || $[46] !== t18 || $[47] !== t21) {
7698
+ t22 = /* @__PURE__ */ jsxs("div", {
7699
+ className: Mutate_module_default.stat,
7700
+ children: [
7701
+ t11,
7702
+ t17,
7703
+ t18,
7704
+ t21
7705
+ ]
7706
+ });
7707
+ $[44] = t11;
7708
+ $[45] = t17;
7709
+ $[46] = t18;
7710
+ $[47] = t21;
7711
+ $[48] = t22;
7712
+ } else t22 = $[48];
7713
+ return t22;
6513
7714
  }
6514
- function Variation(t0) {
6515
- const $ = c(20);
6516
- const { type, current, onHover, onActivate, onInfo } = t0;
7715
+ /** Rolls this module like one pasted from Pyfa, or one in game looked up by its link or IDs. */
7716
+ function Import(t0) {
7717
+ const $ = c(39);
7718
+ const { slot, current, onFound } = t0;
7719
+ const engine = useEngine();
7720
+ const store = useFitStore();
7721
+ const sde = useSde();
7722
+ const fieldId = useId();
7723
+ const [text, setText] = useState("");
7724
+ const [status, setStatus] = useState();
6517
7725
  let t1;
6518
- if ($[0] !== type.id) {
6519
- t1 = /* @__PURE__ */ jsx("span", {
6520
- className: ItemInfo_module_default.variationIcon,
6521
- children: /* @__PURE__ */ jsx(TypeIcon, { typeId: type.id })
6522
- });
6523
- $[0] = type.id;
6524
- $[1] = t1;
6525
- } else t1 = $[1];
7726
+ if ($[0] !== sde || $[1] !== text) {
7727
+ t1 = parseMutationText(sde, text);
7728
+ $[0] = sde;
7729
+ $[1] = text;
7730
+ $[2] = t1;
7731
+ } else t1 = $[2];
7732
+ const pasted = t1;
6526
7733
  let t2;
6527
- if ($[2] !== type.name) {
6528
- t2 = /* @__PURE__ */ jsx("span", { children: type.name });
6529
- $[2] = type.name;
6530
- $[3] = t2;
6531
- } else t2 = $[3];
6532
- let t3;
6533
- if ($[4] !== t1 || $[5] !== t2) {
6534
- t3 = /* @__PURE__ */ jsxs(Fragment$1, { children: [t1, t2] });
6535
- $[4] = t1;
7734
+ if ($[3] !== engine.esi || $[4] !== text) {
7735
+ t2 = engine.esi === void 0 ? void 0 : parseItemLink(text);
7736
+ $[3] = engine.esi;
7737
+ $[4] = text;
6536
7738
  $[5] = t2;
6537
- $[6] = t3;
6538
- } else t3 = $[6];
6539
- const label = t3;
6540
- const t4 = current || void 0;
7739
+ } else t2 = $[5];
7740
+ const ids = t2;
7741
+ let t3;
7742
+ if ($[6] !== onFound || $[7] !== sde || $[8] !== slot || $[9] !== store) {
7743
+ t3 = (roll) => {
7744
+ const { fit } = store.getSnapshot();
7745
+ const ref = refIn(fit, slot);
7746
+ const base = fit.items[ref]?.mutation?.base;
7747
+ if (base !== roll.base) {
7748
+ const name = (typeId) => typeId === void 0 ? "module" : sde.type(typeId)?.name;
7749
+ setStatus({ error: `That is a ${name(roll.base)}, not a ${name(base)}` });
7750
+ return;
7751
+ }
7752
+ store.setMutation(ref, roll);
7753
+ setStatus(void 0);
7754
+ onFound(roll);
7755
+ };
7756
+ $[6] = onFound;
7757
+ $[7] = sde;
7758
+ $[8] = slot;
7759
+ $[9] = store;
7760
+ $[10] = t3;
7761
+ } else t3 = $[10];
7762
+ const apply = t3;
7763
+ let t4;
7764
+ if ($[11] !== apply || $[12] !== engine || $[13] !== ids || $[14] !== pasted) {
7765
+ t4 = async () => {
7766
+ if (pasted !== void 0) {
7767
+ apply(pasted);
7768
+ return;
7769
+ }
7770
+ if (ids === void 0) return;
7771
+ setStatus({ busy: true });
7772
+ try {
7773
+ apply(await engine.loadMutation(ids.typeId, ids.itemId));
7774
+ } catch (t5) {
7775
+ const failure = t5;
7776
+ setStatus({ error: failure instanceof Error ? failure.message : String(failure) });
7777
+ }
7778
+ };
7779
+ $[11] = apply;
7780
+ $[12] = engine;
7781
+ $[13] = ids;
7782
+ $[14] = pasted;
7783
+ $[15] = t4;
7784
+ } else t4 = $[15];
7785
+ const lookUp = t4;
6541
7786
  let t5;
6542
- if ($[7] !== current || $[8] !== label || $[9] !== onActivate || $[10] !== onHover) {
6543
- t5 = current || onActivate === void 0 ? /* @__PURE__ */ jsx("div", {
6544
- className: ItemInfo_module_default.variation,
6545
- children: label
6546
- }) : /* @__PURE__ */ jsx("button", {
6547
- type: "button",
6548
- className: ItemInfo_module_default.variation,
6549
- title: "Double click to fit this instead",
6550
- onDoubleClick: onActivate,
6551
- onKeyDown: (event) => {
6552
- if (event.key !== "Enter") return;
6553
- event.preventDefault();
6554
- onActivate();
6555
- },
6556
- onMouseEnter: () => onHover?.(true),
6557
- onMouseLeave: () => onHover?.(false),
6558
- onFocus: () => onHover?.(true),
6559
- onBlur: () => onHover?.(false),
6560
- children: label
6561
- });
6562
- $[7] = current;
6563
- $[8] = label;
6564
- $[9] = onActivate;
6565
- $[10] = onHover;
6566
- $[11] = t5;
6567
- } else t5 = $[11];
6568
- const t6 = `Show Info on ${type.name}`;
7787
+ if ($[16] !== lookUp) {
7788
+ t5 = (event) => {
7789
+ event.preventDefault();
7790
+ lookUp();
7791
+ };
7792
+ $[16] = lookUp;
7793
+ $[17] = t5;
7794
+ } else t5 = $[17];
7795
+ const t6 = engine.esi === void 0 ? "Paste the module from Pyfa." : "Paste the module from Pyfa or its item link from EVE, or type its type ID and item ID.";
6569
7796
  let t7;
6570
- if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
6571
- t7 = /* @__PURE__ */ jsx(Icon, { name: "module-info" });
6572
- $[12] = t7;
6573
- } else t7 = $[12];
6574
- let t8;
6575
- if ($[13] !== onInfo || $[14] !== t6) {
6576
- t8 = /* @__PURE__ */ jsx("button", {
6577
- type: "button",
6578
- className: ItemInfo_module_default.info,
6579
- "aria-label": t6,
6580
- onClick: onInfo,
6581
- children: t7
7797
+ if ($[18] !== fieldId || $[19] !== t6) {
7798
+ t7 = /* @__PURE__ */ jsx("label", {
7799
+ htmlFor: fieldId,
7800
+ children: t6
6582
7801
  });
6583
- $[13] = onInfo;
6584
- $[14] = t6;
6585
- $[15] = t8;
6586
- } else t8 = $[15];
7802
+ $[18] = fieldId;
7803
+ $[19] = t6;
7804
+ $[20] = t7;
7805
+ } else t7 = $[20];
7806
+ let t8;
7807
+ if ($[21] !== current || $[22] !== sde) {
7808
+ t8 = pyfaText(sde, current);
7809
+ $[21] = current;
7810
+ $[22] = sde;
7811
+ $[23] = t8;
7812
+ } else t8 = $[23];
6587
7813
  let t9;
6588
- if ($[16] !== t4 || $[17] !== t5 || $[18] !== t8) {
6589
- t9 = /* @__PURE__ */ jsxs("li", {
6590
- className: ItemInfo_module_default.row,
6591
- "aria-current": t4,
6592
- children: [t5, t8]
7814
+ if ($[24] === Symbol.for("react.memo_cache_sentinel")) {
7815
+ t9 = (event_0) => {
7816
+ setText(event_0.currentTarget.value);
7817
+ setStatus(void 0);
7818
+ };
7819
+ $[24] = t9;
7820
+ } else t9 = $[24];
7821
+ let t10;
7822
+ if ($[25] !== fieldId || $[26] !== t8 || $[27] !== text) {
7823
+ t10 = /* @__PURE__ */ jsx("textarea", {
7824
+ id: fieldId,
7825
+ className: Mutate_module_default.field,
7826
+ rows: 5,
7827
+ placeholder: t8,
7828
+ value: text,
7829
+ onChange: t9
6593
7830
  });
6594
- $[16] = t4;
6595
- $[17] = t5;
6596
- $[18] = t8;
6597
- $[19] = t9;
6598
- } else t9 = $[19];
6599
- return t9;
7831
+ $[25] = fieldId;
7832
+ $[26] = t8;
7833
+ $[27] = text;
7834
+ $[28] = t10;
7835
+ } else t10 = $[28];
7836
+ const t11 = pasted === void 0 && ids === void 0 || status !== void 0 && "busy" in status;
7837
+ let t12;
7838
+ if ($[29] !== t11) {
7839
+ t12 = /* @__PURE__ */ jsx("button", {
7840
+ type: "submit",
7841
+ className: Mutate_module_default.button,
7842
+ disabled: t11,
7843
+ children: "Apply"
7844
+ });
7845
+ $[29] = t11;
7846
+ $[30] = t12;
7847
+ } else t12 = $[30];
7848
+ let t13;
7849
+ if ($[31] !== status) {
7850
+ t13 = status !== void 0 && "error" in status && /* @__PURE__ */ jsx("p", {
7851
+ className: Mutate_module_default.error,
7852
+ role: "alert",
7853
+ children: status.error
7854
+ });
7855
+ $[31] = status;
7856
+ $[32] = t13;
7857
+ } else t13 = $[32];
7858
+ let t14;
7859
+ if ($[33] !== t10 || $[34] !== t12 || $[35] !== t13 || $[36] !== t5 || $[37] !== t7) {
7860
+ t14 = /* @__PURE__ */ jsxs("form", {
7861
+ className: Mutate_module_default.import,
7862
+ onSubmit: t5,
7863
+ children: [
7864
+ t7,
7865
+ t10,
7866
+ t12,
7867
+ t13
7868
+ ]
7869
+ });
7870
+ $[33] = t10;
7871
+ $[34] = t12;
7872
+ $[35] = t13;
7873
+ $[36] = t5;
7874
+ $[37] = t7;
7875
+ $[38] = t14;
7876
+ } else t14 = $[38];
7877
+ return t14;
6600
7878
  }
6601
- function slotName(slot) {
6602
- const name = slotNames$1[slot.type] ?? slot.type;
6603
- if (!("index" in slot)) return name;
6604
- return `${name} ${slot.type === "implant" || slot.type === "booster" ? slot.index : slot.index + 1}`;
7879
+ /** A roll as Pyfa copies a mutated module. */
7880
+ function pyfaText(sde, roll) {
7881
+ const values = Object.entries(roll.attributes).map(([id, value]) => `${sde.attribute(Number(id))?.name ?? id} ${Number(value.toFixed(4))}`).join(", ");
7882
+ return `${sde.type(roll.base)?.name ?? roll.base}\n${sde.type(roll.mutaplasmid)?.name ?? roll.mutaplasmid}\n${values}`;
7883
+ }
7884
+ function refIn(fit, slot) {
7885
+ return fit.items.findIndex((item) => item.slot.type === slot.type && slotIndex(item.slot) === slotIndex(slot));
7886
+ }
7887
+ function slotIndex(slot) {
7888
+ return "index" in slot ? slot.index : void 0;
7889
+ }
7890
+ function clamp(value, range) {
7891
+ return Math.min(range.max, Math.max(range.min, value));
7892
+ }
7893
+ function Dice() {
7894
+ const $ = c(1);
7895
+ let t0;
7896
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
7897
+ t0 = /* @__PURE__ */ jsxs("svg", {
7898
+ viewBox: "0 0 16 16",
7899
+ width: "16",
7900
+ height: "16",
7901
+ "aria-hidden": true,
7902
+ children: [
7903
+ /* @__PURE__ */ jsx("rect", {
7904
+ x: "1.5",
7905
+ y: "1.5",
7906
+ width: "13",
7907
+ height: "13",
7908
+ rx: "2.5",
7909
+ fill: "none",
7910
+ stroke: "currentColor"
7911
+ }),
7912
+ /* @__PURE__ */ jsx("circle", {
7913
+ cx: "5",
7914
+ cy: "5",
7915
+ r: "1.3",
7916
+ fill: "currentColor"
7917
+ }),
7918
+ /* @__PURE__ */ jsx("circle", {
7919
+ cx: "8",
7920
+ cy: "8",
7921
+ r: "1.3",
7922
+ fill: "currentColor"
7923
+ }),
7924
+ /* @__PURE__ */ jsx("circle", {
7925
+ cx: "11",
7926
+ cy: "11",
7927
+ r: "1.3",
7928
+ fill: "currentColor"
7929
+ })
7930
+ ]
7931
+ });
7932
+ $[0] = t0;
7933
+ } else t0 = $[0];
7934
+ return t0;
6605
7935
  }
6606
7936
  // src/components/ShipBonuses/ShipBonuses.module.css
6607
7937
  var ShipBonuses_module_default = {
@@ -8185,6 +9515,7 @@ function FittingWindow({ label = "Fitting Window", browser, statistics: givenSta
8185
9515
  "data-statistics": statisticsShown || void 0,
8186
9516
  children: [
8187
9517
  !preview && /* @__PURE__ */ jsx(ItemInfo, {}),
9518
+ !preview && /* @__PURE__ */ jsx(Mutate, {}),
8188
9519
  browser !== void 0 && /* @__PURE__ */ jsx("div", {
8189
9520
  id: browserId,
8190
9521
  className: FittingWindow_module_default.browser,
@@ -9240,7 +10571,7 @@ const folders = {
9240
10571
  };
9241
10572
  /** Previews a type on hover, fits it on double click, drags it to the wheel, shows its info and its menu; render `overlays` once. */
9242
10573
  function useTypeActions(noHullSelected) {
9243
- const $ = c(55);
10574
+ const $ = c(57);
9244
10575
  const store = useFitStore();
9245
10576
  const sde = useSde();
9246
10577
  const refuses = useHullRefuses();
@@ -9249,6 +10580,7 @@ function useTypeActions(noHullSelected) {
9249
10580
  const { show, clear } = usePreview();
9250
10581
  const { start, end } = useDrag();
9251
10582
  const { show: showInfo } = useShowInfo();
10583
+ const { show: showMutate } = useMutate();
9252
10584
  const { open, menu } = useContextMenu();
9253
10585
  const [hovered, setHovered] = useState();
9254
10586
  const dragImage = useRef(null);
@@ -9265,22 +10597,22 @@ function useTypeActions(noHullSelected) {
9265
10597
  } else t0 = $[3];
9266
10598
  const refused = t0;
9267
10599
  let actions;
9268
- if ($[4] !== clear || $[5] !== end || $[6] !== hold || $[7] !== noHullSelected || $[8] !== open || $[9] !== refuse || $[10] !== refused || $[11] !== release || $[12] !== show || $[13] !== showInfo || $[14] !== start || $[15] !== store) {
10600
+ if ($[4] !== clear || $[5] !== end || $[6] !== hold || $[7] !== noHullSelected || $[8] !== open || $[9] !== refuse || $[10] !== refused || $[11] !== release || $[12] !== sde || $[13] !== show || $[14] !== showInfo || $[15] !== showMutate || $[16] !== start || $[17] !== store) {
9269
10601
  let t1;
9270
- if ($[17] !== noHullSelected || $[18] !== refuse || $[19] !== refused || $[20] !== store) {
10602
+ if ($[19] !== noHullSelected || $[20] !== refuse || $[21] !== refused || $[22] !== store) {
9271
10603
  t1 = (typeId_0) => {
9272
10604
  if (noHullSelected) return;
9273
10605
  if (refused(typeId_0)) refuse(typeId_0);
9274
10606
  else store.fit(typeId_0);
9275
10607
  };
9276
- $[17] = noHullSelected;
9277
- $[18] = refuse;
9278
- $[19] = refused;
9279
- $[20] = store;
9280
- $[21] = t1;
9281
- } else t1 = $[21];
10608
+ $[19] = noHullSelected;
10609
+ $[20] = refuse;
10610
+ $[21] = refused;
10611
+ $[22] = store;
10612
+ $[23] = t1;
10613
+ } else t1 = $[23];
9282
10614
  let t2;
9283
- if ($[22] !== clear || $[23] !== hold || $[24] !== noHullSelected || $[25] !== refused || $[26] !== release || $[27] !== show) {
10615
+ if ($[24] !== clear || $[25] !== hold || $[26] !== noHullSelected || $[27] !== refused || $[28] !== release || $[29] !== show) {
9284
10616
  t2 = (typeId_1, hovering) => {
9285
10617
  if (noHullSelected) return;
9286
10618
  if (hovering) {
@@ -9292,25 +10624,25 @@ function useTypeActions(noHullSelected) {
9292
10624
  release();
9293
10625
  }
9294
10626
  };
9295
- $[22] = clear;
9296
- $[23] = hold;
9297
- $[24] = noHullSelected;
9298
- $[25] = refused;
9299
- $[26] = release;
9300
- $[27] = show;
9301
- $[28] = t2;
9302
- } else t2 = $[28];
10627
+ $[24] = clear;
10628
+ $[25] = hold;
10629
+ $[26] = noHullSelected;
10630
+ $[27] = refused;
10631
+ $[28] = release;
10632
+ $[29] = show;
10633
+ $[30] = t2;
10634
+ } else t2 = $[30];
9303
10635
  let t3;
9304
- if ($[29] !== showInfo) {
10636
+ if ($[31] !== showInfo) {
9305
10637
  t3 = (typeId_2, element) => showInfo({ typeId: typeId_2 }, {
9306
10638
  element,
9307
10639
  side: "right"
9308
10640
  });
9309
- $[29] = showInfo;
9310
- $[30] = t3;
9311
- } else t3 = $[30];
10641
+ $[31] = showInfo;
10642
+ $[32] = t3;
10643
+ } else t3 = $[32];
9312
10644
  let t4;
9313
- if ($[31] !== clear || $[32] !== noHullSelected || $[33] !== release || $[34] !== start) {
10645
+ if ($[33] !== clear || $[34] !== noHullSelected || $[35] !== release || $[36] !== start) {
9314
10646
  t4 = (event, type_0) => {
9315
10647
  if (noHullSelected) {
9316
10648
  event.preventDefault();
@@ -9327,24 +10659,24 @@ function useTypeActions(noHullSelected) {
9327
10659
  typeId: type_0.id
9328
10660
  });
9329
10661
  };
9330
- $[31] = clear;
9331
- $[32] = noHullSelected;
9332
- $[33] = release;
9333
- $[34] = start;
9334
- $[35] = t4;
9335
- } else t4 = $[35];
10662
+ $[33] = clear;
10663
+ $[34] = noHullSelected;
10664
+ $[35] = release;
10665
+ $[36] = start;
10666
+ $[37] = t4;
10667
+ } else t4 = $[37];
9336
10668
  let t5;
9337
- if ($[36] !== clear || $[37] !== end || $[38] !== release) {
10669
+ if ($[38] !== clear || $[39] !== end || $[40] !== release) {
9338
10670
  t5 = () => {
9339
10671
  end();
9340
10672
  clear();
9341
10673
  release();
9342
10674
  };
9343
- $[36] = clear;
9344
- $[37] = end;
9345
- $[38] = release;
9346
- $[39] = t5;
9347
- } else t5 = $[39];
10675
+ $[38] = clear;
10676
+ $[39] = end;
10677
+ $[40] = release;
10678
+ $[41] = t5;
10679
+ } else t5 = $[41];
9348
10680
  actions = {
9349
10681
  fit: t1,
9350
10682
  hover: t2,
@@ -9363,6 +10695,21 @@ function useTypeActions(noHullSelected) {
9363
10695
  !noHullSelected && {
9364
10696
  label: "Fit to Ship",
9365
10697
  onSelect: () => actions.fit(type_1.id)
10698
+ },
10699
+ !noHullSelected && canMutate(sde, type_1) && {
10700
+ label: "Fit Mutated",
10701
+ onSelect: () => {
10702
+ if (refused(type_1.id)) {
10703
+ refuse(type_1.id);
10704
+ return;
10705
+ }
10706
+ const ref = store.fitMutated(rollMutation(sde, type_1.id, mutaplasmidsOf(sde, type_1.id)[0].id, "base"));
10707
+ const slot = ref === void 0 ? void 0 : store.getSnapshot().fit.items[ref]?.slot;
10708
+ if (slot !== void 0) showMutate(slot, {
10709
+ element: anchor,
10710
+ side: "right"
10711
+ });
10712
+ }
9366
10713
  }
9367
10714
  ]);
9368
10715
  }
@@ -9375,37 +10722,39 @@ function useTypeActions(noHullSelected) {
9375
10722
  $[9] = refuse;
9376
10723
  $[10] = refused;
9377
10724
  $[11] = release;
9378
- $[12] = show;
9379
- $[13] = showInfo;
9380
- $[14] = start;
9381
- $[15] = store;
9382
- $[16] = actions;
9383
- } else actions = $[16];
10725
+ $[12] = sde;
10726
+ $[13] = show;
10727
+ $[14] = showInfo;
10728
+ $[15] = showMutate;
10729
+ $[16] = start;
10730
+ $[17] = store;
10731
+ $[18] = actions;
10732
+ } else actions = $[18];
9384
10733
  const releaseOnUnmount = useEffectEvent(release);
9385
10734
  let t1;
9386
- if ($[40] !== releaseOnUnmount) {
10735
+ if ($[42] !== releaseOnUnmount) {
9387
10736
  t1 = () => () => releaseOnUnmount();
9388
- $[40] = releaseOnUnmount;
9389
- $[41] = t1;
9390
- } else t1 = $[41];
10737
+ $[42] = releaseOnUnmount;
10738
+ $[43] = t1;
10739
+ } else t1 = $[43];
9391
10740
  let t2;
9392
- if ($[42] === Symbol.for("react.memo_cache_sentinel")) {
10741
+ if ($[44] === Symbol.for("react.memo_cache_sentinel")) {
9393
10742
  t2 = [];
9394
- $[42] = t2;
9395
- } else t2 = $[42];
10743
+ $[44] = t2;
10744
+ } else t2 = $[44];
9396
10745
  useEffect(t1, t2);
9397
10746
  let t3;
9398
- if ($[43] !== clear || $[44] !== release) {
10747
+ if ($[45] !== clear || $[46] !== release) {
9399
10748
  t3 = () => {
9400
10749
  clear();
9401
10750
  release();
9402
10751
  };
9403
- $[43] = clear;
9404
- $[44] = release;
9405
- $[45] = t3;
9406
- } else t3 = $[45];
10752
+ $[45] = clear;
10753
+ $[46] = release;
10754
+ $[47] = t3;
10755
+ } else t3 = $[47];
9407
10756
  let t4;
9408
- if ($[46] !== hovered) {
10757
+ if ($[48] !== hovered) {
9409
10758
  t4 = hovered !== void 0 && /* @__PURE__ */ jsx("span", {
9410
10759
  ref: dragImage,
9411
10760
  className: ItemBrowser_module_default.dragImage,
@@ -9417,28 +10766,28 @@ function useTypeActions(noHullSelected) {
9417
10766
  loading: "eager"
9418
10767
  })
9419
10768
  });
9420
- $[46] = hovered;
9421
- $[47] = t4;
9422
- } else t4 = $[47];
10769
+ $[48] = hovered;
10770
+ $[49] = t4;
10771
+ } else t4 = $[49];
9423
10772
  let t5;
9424
- if ($[48] !== menu || $[49] !== t4) {
10773
+ if ($[50] !== menu || $[51] !== t4) {
9425
10774
  t5 = /* @__PURE__ */ jsxs(Fragment$1, { children: [t4, menu] });
9426
- $[48] = menu;
9427
- $[49] = t4;
9428
- $[50] = t5;
9429
- } else t5 = $[50];
10775
+ $[50] = menu;
10776
+ $[51] = t4;
10777
+ $[52] = t5;
10778
+ } else t5 = $[52];
9430
10779
  let t6;
9431
- if ($[51] !== actions || $[52] !== t3 || $[53] !== t5) {
10780
+ if ($[53] !== actions || $[54] !== t3 || $[55] !== t5) {
9432
10781
  t6 = {
9433
10782
  actions,
9434
10783
  clear: t3,
9435
10784
  overlays: t5
9436
10785
  };
9437
- $[51] = actions;
9438
- $[52] = t3;
9439
- $[53] = t5;
9440
- $[54] = t6;
9441
- } else t6 = $[54];
10786
+ $[53] = actions;
10787
+ $[54] = t3;
10788
+ $[55] = t5;
10789
+ $[56] = t6;
10790
+ } else t6 = $[56];
9442
10791
  return t6;
9443
10792
  }
9444
10793
  function TypeLeaf({ type, actions, icon = false }) {
@@ -9951,7 +11300,7 @@ function _temp$6(event) {
9951
11300
  const FLASH_MS = 2e3;
9952
11301
  /** The buttons under the `ItemBrowser`: save the fit in the browser, import one, or copy it out. */
9953
11302
  function FitActions(t0) {
9954
- const $ = c(79);
11303
+ const $ = c(80);
9955
11304
  const { noHullSelected, pasteToOpen } = t0;
9956
11305
  const engine = useEngine();
9957
11306
  const fit = useFit();
@@ -9992,7 +11341,7 @@ function FitActions(t0) {
9992
11341
  const trySave = t2;
9993
11342
  let t3;
9994
11343
  let t4;
9995
- if ($[7] !== engine || $[8] !== pasteToOpen || $[9] !== store) {
11344
+ if ($[7] !== engine || $[8] !== noHullSelected || $[9] !== pasteToOpen || $[10] !== store) {
9996
11345
  t3 = () => {
9997
11346
  if (!pasteToOpen) return;
9998
11347
  const onPaste = (event) => {
@@ -10003,13 +11352,29 @@ function FitActions(t0) {
10003
11352
  const text = event.clipboardData?.getData("text/plain").trim() ?? "";
10004
11353
  if (text === "") return;
10005
11354
  event.preventDefault();
11355
+ const pasted = noHullSelected ? void 0 : parseMutationText(engine.sde, text);
11356
+ if (pasted !== void 0) {
11357
+ if (store.fitMutated(pasted) === void 0) setImporting({
11358
+ text,
11359
+ error: "This module does not fit on the ship"
11360
+ });
11361
+ return;
11362
+ }
11363
+ const item = engine.esi === void 0 || noHullSelected ? void 0 : parseItemLink(text);
11364
+ if (item !== void 0) {
11365
+ fitMutated(engine, store, item.typeId, item.itemId).catch((failure) => setImporting({
11366
+ text,
11367
+ error: failure instanceof Error ? failure.message : String(failure)
11368
+ }));
11369
+ return;
11370
+ }
10006
11371
  try {
10007
11372
  store.replace(engine.loadText(text, store.character));
10008
11373
  } catch (t5) {
10009
- const failure = t5;
11374
+ const failure_0 = t5;
10010
11375
  setImporting({
10011
11376
  text,
10012
- error: failure instanceof Error ? failure.message : String(failure)
11377
+ error: failure_0 instanceof Error ? failure_0.message : String(failure_0)
10013
11378
  });
10014
11379
  }
10015
11380
  };
@@ -10019,41 +11384,43 @@ function FitActions(t0) {
10019
11384
  t4 = [
10020
11385
  engine,
10021
11386
  store,
10022
- pasteToOpen
11387
+ pasteToOpen,
11388
+ noHullSelected
10023
11389
  ];
10024
11390
  $[7] = engine;
10025
- $[8] = pasteToOpen;
10026
- $[9] = store;
10027
- $[10] = t3;
10028
- $[11] = t4;
11391
+ $[8] = noHullSelected;
11392
+ $[9] = pasteToOpen;
11393
+ $[10] = store;
11394
+ $[11] = t3;
11395
+ $[12] = t4;
10029
11396
  } else {
10030
- t3 = $[10];
10031
- t4 = $[11];
11397
+ t3 = $[11];
11398
+ t4 = $[12];
10032
11399
  }
10033
11400
  useEffect(t3, t4);
10034
11401
  let t5;
10035
- if ($[12] !== copyFit || $[13] !== fit || $[14] !== flashCopied || $[15] !== menu) {
11402
+ if ($[13] !== copyFit || $[14] !== fit || $[15] !== flashCopied || $[16] !== menu) {
10036
11403
  t5 = (format) => {
10037
11404
  document.getElementById(menu)?.hidePopover();
10038
11405
  copyFit(fit, format, flashCopied);
10039
11406
  };
10040
- $[12] = copyFit;
10041
- $[13] = fit;
10042
- $[14] = flashCopied;
10043
- $[15] = menu;
10044
- $[16] = t5;
10045
- } else t5 = $[16];
11407
+ $[13] = copyFit;
11408
+ $[14] = fit;
11409
+ $[15] = flashCopied;
11410
+ $[16] = menu;
11411
+ $[17] = t5;
11412
+ } else t5 = $[17];
10046
11413
  const copy = t5;
10047
11414
  let t6;
10048
- if ($[17] !== fit || $[18] !== trySave) {
11415
+ if ($[18] !== fit || $[19] !== trySave) {
10049
11416
  t6 = () => fit.name ? trySave(fit) : setNaming(true);
10050
- $[17] = fit;
10051
- $[18] = trySave;
10052
- $[19] = t6;
10053
- } else t6 = $[19];
11417
+ $[18] = fit;
11418
+ $[19] = trySave;
11419
+ $[20] = t6;
11420
+ } else t6 = $[20];
10054
11421
  const t7 = saved ? "Saved" : "Save";
10055
11422
  let t8;
10056
- if ($[20] !== noHullSelected || $[21] !== t6 || $[22] !== t7) {
11423
+ if ($[21] !== noHullSelected || $[22] !== t6 || $[23] !== t7) {
10057
11424
  t8 = /* @__PURE__ */ jsx("button", {
10058
11425
  type: "button",
10059
11426
  className: ItemBrowser_module_default.action,
@@ -10061,31 +11428,31 @@ function FitActions(t0) {
10061
11428
  onClick: t6,
10062
11429
  children: t7
10063
11430
  });
10064
- $[20] = noHullSelected;
10065
- $[21] = t6;
10066
- $[22] = t7;
10067
- $[23] = t8;
10068
- } else t8 = $[23];
11431
+ $[21] = noHullSelected;
11432
+ $[22] = t6;
11433
+ $[23] = t7;
11434
+ $[24] = t8;
11435
+ } else t8 = $[24];
10069
11436
  let t9;
10070
- if ($[24] === Symbol.for("react.memo_cache_sentinel")) {
11437
+ if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
10071
11438
  t9 = /* @__PURE__ */ jsx("button", {
10072
11439
  type: "button",
10073
11440
  className: ItemBrowser_module_default.action,
10074
11441
  onClick: () => setImporting({ text: "" }),
10075
11442
  children: "Import…"
10076
11443
  });
10077
- $[24] = t9;
10078
- } else t9 = $[24];
11444
+ $[25] = t9;
11445
+ } else t9 = $[25];
10079
11446
  const t10 = copied ? "Copied" : "Copy";
10080
11447
  const t11 = copied ? "checkmark" : "export";
10081
11448
  let t12;
10082
- if ($[25] !== t11) {
11449
+ if ($[26] !== t11) {
10083
11450
  t12 = /* @__PURE__ */ jsx(Icon, { name: t11 });
10084
- $[25] = t11;
10085
- $[26] = t12;
10086
- } else t12 = $[26];
11451
+ $[26] = t11;
11452
+ $[27] = t12;
11453
+ } else t12 = $[27];
10087
11454
  let t13;
10088
- if ($[27] !== menu || $[28] !== noHullSelected || $[29] !== t12) {
11455
+ if ($[28] !== menu || $[29] !== noHullSelected || $[30] !== t12) {
10089
11456
  t13 = /* @__PURE__ */ jsx("button", {
10090
11457
  type: "button",
10091
11458
  className: `${ItemBrowser_module_default.action} ${ItemBrowser_module_default.copy}`,
@@ -10094,13 +11461,13 @@ function FitActions(t0) {
10094
11461
  disabled: noHullSelected,
10095
11462
  children: t12
10096
11463
  });
10097
- $[27] = menu;
10098
- $[28] = noHullSelected;
10099
- $[29] = t12;
10100
- $[30] = t13;
10101
- } else t13 = $[30];
11464
+ $[28] = menu;
11465
+ $[29] = noHullSelected;
11466
+ $[30] = t12;
11467
+ $[31] = t13;
11468
+ } else t13 = $[31];
10102
11469
  let t14;
10103
- if ($[31] !== t10 || $[32] !== t13) {
11470
+ if ($[32] !== t10 || $[33] !== t13) {
10104
11471
  t14 = /* @__PURE__ */ jsx("span", {
10105
11472
  className: ItemBrowser_module_default.copyAnchor,
10106
11473
  children: /* @__PURE__ */ jsx(Tooltip, {
@@ -10108,34 +11475,34 @@ function FitActions(t0) {
10108
11475
  children: t13
10109
11476
  })
10110
11477
  });
10111
- $[31] = t10;
10112
- $[32] = t13;
10113
- $[33] = t14;
10114
- } else t14 = $[33];
11478
+ $[32] = t10;
11479
+ $[33] = t13;
11480
+ $[34] = t14;
11481
+ } else t14 = $[34];
10115
11482
  let t15;
10116
- if ($[34] !== copy) {
11483
+ if ($[35] !== copy) {
10117
11484
  t15 = /* @__PURE__ */ jsx("button", {
10118
11485
  type: "button",
10119
11486
  role: "menuitem",
10120
11487
  onClick: () => copy("eft"),
10121
11488
  children: "Copy as EFT"
10122
11489
  });
10123
- $[34] = copy;
10124
- $[35] = t15;
10125
- } else t15 = $[35];
11490
+ $[35] = copy;
11491
+ $[36] = t15;
11492
+ } else t15 = $[36];
10126
11493
  let t16;
10127
- if ($[36] !== copy) {
11494
+ if ($[37] !== copy) {
10128
11495
  t16 = /* @__PURE__ */ jsx("button", {
10129
11496
  type: "button",
10130
11497
  role: "menuitem",
10131
11498
  onClick: () => copy("esf"),
10132
11499
  children: "Copy as esf/1"
10133
11500
  });
10134
- $[36] = copy;
10135
- $[37] = t16;
10136
- } else t16 = $[37];
11501
+ $[37] = copy;
11502
+ $[38] = t16;
11503
+ } else t16 = $[38];
10137
11504
  let t17;
10138
- if ($[38] !== menu || $[39] !== t15 || $[40] !== t16) {
11505
+ if ($[39] !== menu || $[40] !== t15 || $[41] !== t16) {
10139
11506
  t17 = /* @__PURE__ */ jsxs("div", {
10140
11507
  id: menu,
10141
11508
  className: ItemBrowser_module_default.menu,
@@ -10143,23 +11510,23 @@ function FitActions(t0) {
10143
11510
  role: "menu",
10144
11511
  children: [t15, t16]
10145
11512
  });
10146
- $[38] = menu;
10147
- $[39] = t15;
10148
- $[40] = t16;
10149
- $[41] = t17;
10150
- } else t17 = $[41];
11513
+ $[39] = menu;
11514
+ $[40] = t15;
11515
+ $[41] = t16;
11516
+ $[42] = t17;
11517
+ } else t17 = $[42];
10151
11518
  let t18;
10152
- if ($[42] === Symbol.for("react.memo_cache_sentinel")) {
11519
+ if ($[43] === Symbol.for("react.memo_cache_sentinel")) {
10153
11520
  t18 = () => setNaming(false);
10154
- $[42] = t18;
10155
- } else t18 = $[42];
11521
+ $[43] = t18;
11522
+ } else t18 = $[43];
10156
11523
  let t19;
10157
- if ($[43] === Symbol.for("react.memo_cache_sentinel")) {
11524
+ if ($[44] === Symbol.for("react.memo_cache_sentinel")) {
10158
11525
  t19 = () => setNaming(false);
10159
- $[43] = t19;
10160
- } else t19 = $[43];
11526
+ $[44] = t19;
11527
+ } else t19 = $[44];
10161
11528
  let t20;
10162
- if ($[44] !== trySave) {
11529
+ if ($[45] !== trySave) {
10163
11530
  t20 = /* @__PURE__ */ jsx(NameForm, {
10164
11531
  onCancel: t19,
10165
11532
  onSave: (named_1) => {
@@ -10167,50 +11534,50 @@ function FitActions(t0) {
10167
11534
  trySave(named_1);
10168
11535
  }
10169
11536
  });
10170
- $[44] = trySave;
10171
- $[45] = t20;
10172
- } else t20 = $[45];
11537
+ $[45] = trySave;
11538
+ $[46] = t20;
11539
+ } else t20 = $[46];
10173
11540
  let t21;
10174
- if ($[46] !== naming || $[47] !== t20) {
11541
+ if ($[47] !== naming || $[48] !== t20) {
10175
11542
  t21 = /* @__PURE__ */ jsx(Dialog, {
10176
11543
  open: naming,
10177
11544
  title: "Save Fit",
10178
11545
  onClose: t18,
10179
11546
  children: t20
10180
11547
  });
10181
- $[46] = naming;
10182
- $[47] = t20;
10183
- $[48] = t21;
10184
- } else t21 = $[48];
11548
+ $[47] = naming;
11549
+ $[48] = t20;
11550
+ $[49] = t21;
11551
+ } else t21 = $[49];
10185
11552
  const t22 = overwriting !== void 0;
10186
11553
  let t23;
10187
- if ($[49] === Symbol.for("react.memo_cache_sentinel")) {
11554
+ if ($[50] === Symbol.for("react.memo_cache_sentinel")) {
10188
11555
  t23 = () => setOverwriting(void 0);
10189
- $[49] = t23;
10190
- } else t23 = $[49];
11556
+ $[50] = t23;
11557
+ } else t23 = $[50];
10191
11558
  const t24 = overwriting?.name;
10192
11559
  let t25;
10193
- if ($[50] !== t24) {
11560
+ if ($[51] !== t24) {
10194
11561
  t25 = /* @__PURE__ */ jsxs("p", { children: [
10195
11562
  "A fit named \"",
10196
11563
  t24,
10197
11564
  "\" is already saved for this hull. Overwrite it?"
10198
11565
  ] });
10199
- $[50] = t24;
10200
- $[51] = t25;
10201
- } else t25 = $[51];
11566
+ $[51] = t24;
11567
+ $[52] = t25;
11568
+ } else t25 = $[52];
10202
11569
  let t26;
10203
- if ($[52] === Symbol.for("react.memo_cache_sentinel")) {
11570
+ if ($[53] === Symbol.for("react.memo_cache_sentinel")) {
10204
11571
  t26 = /* @__PURE__ */ jsx("button", {
10205
11572
  type: "button",
10206
11573
  className: ItemBrowser_module_default.action,
10207
11574
  onClick: () => setOverwriting(void 0),
10208
11575
  children: "Cancel"
10209
11576
  });
10210
- $[52] = t26;
10211
- } else t26 = $[52];
11577
+ $[53] = t26;
11578
+ } else t26 = $[53];
10212
11579
  let t27;
10213
- if ($[53] !== overwriting || $[54] !== saveNow) {
11580
+ if ($[54] !== overwriting || $[55] !== saveNow) {
10214
11581
  t27 = /* @__PURE__ */ jsxs("div", {
10215
11582
  className: ItemBrowser_module_default.dialogButtons,
10216
11583
  children: [t26, /* @__PURE__ */ jsx("button", {
@@ -10220,72 +11587,72 @@ function FitActions(t0) {
10220
11587
  children: "Overwrite"
10221
11588
  })]
10222
11589
  });
10223
- $[53] = overwriting;
10224
- $[54] = saveNow;
10225
- $[55] = t27;
10226
- } else t27 = $[55];
11590
+ $[54] = overwriting;
11591
+ $[55] = saveNow;
11592
+ $[56] = t27;
11593
+ } else t27 = $[56];
10227
11594
  let t28;
10228
- if ($[56] !== t25 || $[57] !== t27) {
11595
+ if ($[57] !== t25 || $[58] !== t27) {
10229
11596
  t28 = /* @__PURE__ */ jsxs("div", {
10230
11597
  className: ItemBrowser_module_default.confirm,
10231
11598
  children: [t25, t27]
10232
11599
  });
10233
- $[56] = t25;
10234
- $[57] = t27;
10235
- $[58] = t28;
10236
- } else t28 = $[58];
11600
+ $[57] = t25;
11601
+ $[58] = t27;
11602
+ $[59] = t28;
11603
+ } else t28 = $[59];
10237
11604
  let t29;
10238
- if ($[59] !== t22 || $[60] !== t28) {
11605
+ if ($[60] !== t22 || $[61] !== t28) {
10239
11606
  t29 = /* @__PURE__ */ jsx(Dialog, {
10240
11607
  open: t22,
10241
11608
  title: "Overwrite Fit?",
10242
11609
  onClose: t23,
10243
11610
  children: t28
10244
11611
  });
10245
- $[59] = t22;
10246
- $[60] = t28;
10247
- $[61] = t29;
10248
- } else t29 = $[61];
11612
+ $[60] = t22;
11613
+ $[61] = t28;
11614
+ $[62] = t29;
11615
+ } else t29 = $[62];
10249
11616
  const t30 = importing !== void 0;
10250
11617
  let t31;
10251
- if ($[62] === Symbol.for("react.memo_cache_sentinel")) {
11618
+ if ($[63] === Symbol.for("react.memo_cache_sentinel")) {
10252
11619
  t31 = () => setImporting(void 0);
10253
- $[62] = t31;
10254
- } else t31 = $[62];
11620
+ $[63] = t31;
11621
+ } else t31 = $[63];
10255
11622
  let t32;
10256
- if ($[63] !== importing) {
11623
+ if ($[64] !== importing) {
10257
11624
  t32 = importing ?? { text: "" };
10258
- $[63] = importing;
10259
- $[64] = t32;
10260
- } else t32 = $[64];
11625
+ $[64] = importing;
11626
+ $[65] = t32;
11627
+ } else t32 = $[65];
10261
11628
  let t33;
10262
- if ($[65] === Symbol.for("react.memo_cache_sentinel")) {
11629
+ if ($[66] === Symbol.for("react.memo_cache_sentinel")) {
10263
11630
  t33 = () => setImporting(void 0);
10264
- $[65] = t33;
10265
- } else t33 = $[65];
11631
+ $[66] = t33;
11632
+ } else t33 = $[66];
10266
11633
  let t34;
10267
- if ($[66] !== t32) {
11634
+ if ($[67] !== t32) {
10268
11635
  t34 = /* @__PURE__ */ jsx(ImportForm, {
10269
11636
  draft: t32,
10270
11637
  onDone: t33
10271
11638
  });
10272
- $[66] = t32;
10273
- $[67] = t34;
10274
- } else t34 = $[67];
11639
+ $[67] = t32;
11640
+ $[68] = t34;
11641
+ } else t34 = $[68];
10275
11642
  let t35;
10276
- if ($[68] !== t30 || $[69] !== t34) {
11643
+ if ($[69] !== t30 || $[70] !== t34) {
10277
11644
  t35 = /* @__PURE__ */ jsx(Dialog, {
10278
11645
  open: t30,
10279
11646
  title: "Import Fit",
10280
11647
  onClose: t31,
10281
11648
  children: t34
10282
11649
  });
10283
- $[68] = t30;
10284
- $[69] = t34;
10285
- $[70] = t35;
10286
- } else t35 = $[70];
11650
+ $[69] = t30;
11651
+ $[70] = t34;
11652
+ $[71] = t35;
11653
+ } else t35 = $[71];
10287
11654
  let t36;
10288
- if ($[71] !== copyDialog || $[72] !== t14 || $[73] !== t17 || $[74] !== t21 || $[75] !== t29 || $[76] !== t35 || $[77] !== t8) {
11655
+ if ($[72] !== copyDialog || $[73] !== t14 || $[74] !== t17 || $[75] !== t21 || $[76] !== t29 || $[77] !== t35 || $[78] !== t8) {
10289
11656
  t36 = /* @__PURE__ */ jsxs("div", {
10290
11657
  className: ItemBrowser_module_default.actions,
10291
11658
  children: [
@@ -10299,15 +11666,15 @@ function FitActions(t0) {
10299
11666
  copyDialog
10300
11667
  ]
10301
11668
  });
10302
- $[71] = copyDialog;
10303
- $[72] = t14;
10304
- $[73] = t17;
10305
- $[74] = t21;
10306
- $[75] = t29;
10307
- $[76] = t35;
10308
- $[77] = t8;
10309
- $[78] = t36;
10310
- } else t36 = $[78];
11669
+ $[72] = copyDialog;
11670
+ $[73] = t14;
11671
+ $[74] = t17;
11672
+ $[75] = t21;
11673
+ $[76] = t29;
11674
+ $[77] = t35;
11675
+ $[78] = t8;
11676
+ $[79] = t36;
11677
+ } else t36 = $[79];
10311
11678
  return t36;
10312
11679
  }
10313
11680
  function NameForm(t0) {
@@ -10614,6 +11981,11 @@ function useFlash() {
10614
11981
  } else t4 = $[5];
10615
11982
  return t4;
10616
11983
  }
11984
+ /** Fits a mutated item from the game in the first free slot of its rack, rolled as it is. */
11985
+ async function fitMutated(engine, store, typeId, itemId) {
11986
+ const roll = await engine.loadMutation(typeId, itemId);
11987
+ if (store.fitMutated(roll) === void 0) throw new Error("This item does not fit on the ship");
11988
+ }
10617
11989
  // src/components/ItemBrowser/HullsAndFits.tsx
10618
11990
  const noFits = [];
10619
11991
  const SHIPS_MARKET_GROUP_ID = 4;