dirk-cfx-react 1.1.87 → 1.1.89
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/components/index.cjs +872 -32
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +192 -2
- package/dist/components/index.d.ts +192 -2
- package/dist/components/index.js +863 -37
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.cjs +159 -26
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +16 -1
- package/dist/hooks/index.d.ts +16 -1
- package/dist/hooks/index.js +157 -28
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +1439 -451
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +1342 -374
- package/dist/index.js.map +1 -1
- package/dist/providers/index.cjs +133 -1
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.d.cts +3 -1
- package/dist/providers/index.d.ts +3 -1
- package/dist/providers/index.js +134 -3
- package/dist/providers/index.js.map +1 -1
- package/dist/usePlayers-BlGBBevs.d.cts +37 -0
- package/dist/usePlayers-BlGBBevs.d.ts +37 -0
- package/dist/utils/index.cjs +16 -8
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +2 -1
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +16 -9
- package/dist/utils/index.js.map +1 -1
- package/package.json +123 -117
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var core = require('@mantine/core');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
var
|
|
5
|
+
var React4 = require('react');
|
|
6
6
|
var zustand = require('zustand');
|
|
7
7
|
var axios = require('axios');
|
|
8
8
|
var reactFontawesome = require('@fortawesome/react-fontawesome');
|
|
@@ -12,7 +12,6 @@ var clickSoundUrl = require('./click_sound-PNCRRTM4.mp3');
|
|
|
12
12
|
var hoverSoundUrl = require('./hover_sound-NBUA222C.mp3');
|
|
13
13
|
var notifications = require('@mantine/notifications');
|
|
14
14
|
var reactQuery = require('@tanstack/react-query');
|
|
15
|
-
var colorsGenerator = require('@mantine/colors-generator');
|
|
16
15
|
require('@mantine/core/styles.css');
|
|
17
16
|
require('@mantine/notifications/styles.css');
|
|
18
17
|
require('./styles/fonts.css');
|
|
@@ -23,11 +22,17 @@ var fontawesomeSvgCore = require('@fortawesome/fontawesome-svg-core');
|
|
|
23
22
|
var freeBrandsSvgIcons = require('@fortawesome/free-brands-svg-icons');
|
|
24
23
|
var freeRegularSvgIcons = require('@fortawesome/free-regular-svg-icons');
|
|
25
24
|
var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
|
|
25
|
+
var colorsGenerator = require('@mantine/colors-generator');
|
|
26
|
+
var reactDom = require('react-dom');
|
|
27
|
+
var leaflet = require('leaflet');
|
|
28
|
+
require('leaflet/dist/leaflet.css');
|
|
29
|
+
var reactLeaflet = require('react-leaflet');
|
|
30
|
+
var reactLeafletComponentMarker = require('@adamscybot/react-leaflet-component-marker');
|
|
26
31
|
var zod = require('zod');
|
|
27
32
|
|
|
28
33
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
29
34
|
|
|
30
|
-
var
|
|
35
|
+
var React4__default = /*#__PURE__*/_interopDefault(React4);
|
|
31
36
|
var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
32
37
|
var clickSoundUrl__default = /*#__PURE__*/_interopDefault(clickSoundUrl);
|
|
33
38
|
var hoverSoundUrl__default = /*#__PURE__*/_interopDefault(hoverSoundUrl);
|
|
@@ -976,6 +981,18 @@ var BLIP_COLOR_DATA = BLIP_COLORS.map(([id, label2]) => ({
|
|
|
976
981
|
}));
|
|
977
982
|
var blipEntryMap = new Map(BLIP_ENTRIES.map(([id, name, ext]) => [String(id), { id, name, ext }]));
|
|
978
983
|
var blipColorMap = new Map(BLIP_COLORS.map(([id, label2, hex]) => [String(id), { id, label: label2, hex }]));
|
|
984
|
+
function getBlipEntry(spriteId) {
|
|
985
|
+
if (spriteId == null) return void 0;
|
|
986
|
+
return blipEntryMap.get(String(spriteId));
|
|
987
|
+
}
|
|
988
|
+
function getBlipColor(colorId) {
|
|
989
|
+
if (colorId == null) return void 0;
|
|
990
|
+
return blipColorMap.get(String(colorId));
|
|
991
|
+
}
|
|
992
|
+
function blipUrlForSprite(spriteId) {
|
|
993
|
+
const entry = getBlipEntry(spriteId);
|
|
994
|
+
return entry ? blipUrl(entry.name, entry.ext) : null;
|
|
995
|
+
}
|
|
979
996
|
var renderBlipOption = ({ option }) => {
|
|
980
997
|
const entry = blipEntryMap.get(option.value);
|
|
981
998
|
if (!entry) return option.label;
|
|
@@ -1253,11 +1270,11 @@ var colorNames = {
|
|
|
1253
1270
|
Yellow: { r: 255, g: 255, b: 0 },
|
|
1254
1271
|
YellowGreen: { r: 154, g: 205, b: 50 }
|
|
1255
1272
|
};
|
|
1256
|
-
function colorWithAlpha(color,
|
|
1273
|
+
function colorWithAlpha(color, alpha18) {
|
|
1257
1274
|
const lowerCasedColor = color.toLowerCase();
|
|
1258
1275
|
if (colorNames[lowerCasedColor]) {
|
|
1259
1276
|
const rgb = colorNames[lowerCasedColor];
|
|
1260
|
-
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${
|
|
1277
|
+
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha18})`;
|
|
1261
1278
|
}
|
|
1262
1279
|
if (/^#([A-Fa-f0-9]{6})$/.test(color)) {
|
|
1263
1280
|
const hex = color.slice(1);
|
|
@@ -1265,12 +1282,12 @@ function colorWithAlpha(color, alpha12) {
|
|
|
1265
1282
|
const r = bigint >> 16 & 255;
|
|
1266
1283
|
const g = bigint >> 8 & 255;
|
|
1267
1284
|
const b = bigint & 255;
|
|
1268
|
-
return `rgba(${r}, ${g}, ${b}, ${
|
|
1285
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha18})`;
|
|
1269
1286
|
}
|
|
1270
1287
|
if (/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/.test(color)) {
|
|
1271
1288
|
const result = color.match(/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/);
|
|
1272
1289
|
if (result) {
|
|
1273
|
-
return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${
|
|
1290
|
+
return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${alpha18})`;
|
|
1274
1291
|
}
|
|
1275
1292
|
}
|
|
1276
1293
|
return color;
|
|
@@ -1369,7 +1386,7 @@ async function runFetches() {
|
|
|
1369
1386
|
);
|
|
1370
1387
|
}
|
|
1371
1388
|
var useAutoFetcher = () => {
|
|
1372
|
-
|
|
1389
|
+
React4.useEffect(() => {
|
|
1373
1390
|
if (isEnvBrowser()) return;
|
|
1374
1391
|
runFetches().catch(() => {
|
|
1375
1392
|
});
|
|
@@ -1432,6 +1449,7 @@ if (typeof window !== "undefined") {
|
|
|
1432
1449
|
const msg = event.data;
|
|
1433
1450
|
if (!msg || msg.action !== "UPDATE_DIRK_LIB_LOCALES") return;
|
|
1434
1451
|
if (!msg.data || typeof msg.data !== "object") return;
|
|
1452
|
+
if (Object.keys(msg.data).length === 0) return;
|
|
1435
1453
|
localeStore.setState({ locales: msg.data });
|
|
1436
1454
|
});
|
|
1437
1455
|
}
|
|
@@ -1865,7 +1883,7 @@ function createSkill(defaultSettings) {
|
|
|
1865
1883
|
}));
|
|
1866
1884
|
const useSkill = (xp) => {
|
|
1867
1885
|
const { settings, levelMap } = useStore4();
|
|
1868
|
-
return
|
|
1886
|
+
return React4.useMemo(() => {
|
|
1869
1887
|
const currentLevel = getLevelFromXP(xp, levelMap, settings);
|
|
1870
1888
|
const nextLevel = Math.min(currentLevel + 1, settings.maxLevel);
|
|
1871
1889
|
const currentLevelXP = levelMap[currentLevel.toString()] || 0;
|
|
@@ -1958,15 +1976,21 @@ var useFrameworkGroups = zustand.create(() => ({
|
|
|
1958
1976
|
gangs: [],
|
|
1959
1977
|
loaded: false
|
|
1960
1978
|
}));
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1979
|
+
var frameworkGroupsRequested = false;
|
|
1980
|
+
function ensureFrameworkGroups() {
|
|
1981
|
+
if (frameworkGroupsRequested) return;
|
|
1982
|
+
frameworkGroupsRequested = true;
|
|
1983
|
+
fetchNui("GET_FRAMEWORK_GROUPS", void 0).then((data) => {
|
|
1984
|
+
useFrameworkGroups.setState({
|
|
1985
|
+
jobs: Array.isArray(data?.jobs) ? data.jobs : [],
|
|
1986
|
+
gangs: Array.isArray(data?.gangs) ? data.gangs : [],
|
|
1987
|
+
loaded: true
|
|
1988
|
+
});
|
|
1989
|
+
}).catch(() => {
|
|
1990
|
+
frameworkGroupsRequested = false;
|
|
1991
|
+
useFrameworkGroups.setState({ loaded: true });
|
|
1966
1992
|
});
|
|
1967
|
-
}
|
|
1968
|
-
useFrameworkGroups.setState({ loaded: true });
|
|
1969
|
-
});
|
|
1993
|
+
}
|
|
1970
1994
|
function selectAllGroups(state) {
|
|
1971
1995
|
return [...state.jobs, ...state.gangs];
|
|
1972
1996
|
}
|
|
@@ -2455,8 +2479,8 @@ var FloatingParticles = ({
|
|
|
2455
2479
|
mouseRepelStrength = 50,
|
|
2456
2480
|
backgroundColor = "transparent"
|
|
2457
2481
|
}) => {
|
|
2458
|
-
const containerRef =
|
|
2459
|
-
const [particles, setParticles] =
|
|
2482
|
+
const containerRef = React4.useRef(null);
|
|
2483
|
+
const [particles, setParticles] = React4.useState([]);
|
|
2460
2484
|
const mouseX = framerMotion.useMotionValue(0);
|
|
2461
2485
|
const mouseY = framerMotion.useMotionValue(0);
|
|
2462
2486
|
const durationMap = {
|
|
@@ -2469,7 +2493,7 @@ var FloatingParticles = ({
|
|
|
2469
2493
|
const x = Math.sin(seed) * 1e4;
|
|
2470
2494
|
return x - Math.floor(x);
|
|
2471
2495
|
};
|
|
2472
|
-
|
|
2496
|
+
React4.useEffect(() => {
|
|
2473
2497
|
if (!containerRef.current) return;
|
|
2474
2498
|
const bounds = containerRef.current.getBoundingClientRect();
|
|
2475
2499
|
const newParticles = [...Array(particleCount)].map((_, i) => {
|
|
@@ -2490,7 +2514,7 @@ var FloatingParticles = ({
|
|
|
2490
2514
|
});
|
|
2491
2515
|
setParticles(newParticles);
|
|
2492
2516
|
}, [particleCount, icons.length, duration.base, duration.variance]);
|
|
2493
|
-
|
|
2517
|
+
React4.useEffect(() => {
|
|
2494
2518
|
if (!containerRef.current) return;
|
|
2495
2519
|
const handleMouseMove = (e) => {
|
|
2496
2520
|
const bounds = containerRef.current.getBoundingClientRect();
|
|
@@ -2539,7 +2563,7 @@ var FloatingParticles = ({
|
|
|
2539
2563
|
container.removeEventListener("mouseleave", handleMouseLeave);
|
|
2540
2564
|
};
|
|
2541
2565
|
}, [mouseX, mouseY, mouseRepelDistance, mouseRepelStrength]);
|
|
2542
|
-
|
|
2566
|
+
React4.useEffect(() => {
|
|
2543
2567
|
const handleResize = () => {
|
|
2544
2568
|
if (!containerRef.current) return;
|
|
2545
2569
|
const bounds = containerRef.current.getBoundingClientRect();
|
|
@@ -2975,23 +2999,23 @@ function Segment(props) {
|
|
|
2975
2999
|
}
|
|
2976
3000
|
);
|
|
2977
3001
|
}
|
|
2978
|
-
var NavigationContext =
|
|
3002
|
+
var NavigationContext = React4.createContext(null);
|
|
2979
3003
|
function useNavigation(selector) {
|
|
2980
|
-
const navigation =
|
|
3004
|
+
const navigation = React4.useContext(NavigationContext);
|
|
2981
3005
|
if (!navigation) {
|
|
2982
3006
|
throw new Error("useNavigation must be used within a NavigationProvider");
|
|
2983
3007
|
}
|
|
2984
3008
|
return zustand.useStore(navigation, selector);
|
|
2985
3009
|
}
|
|
2986
3010
|
function useNavigationStore() {
|
|
2987
|
-
const navigation =
|
|
3011
|
+
const navigation = React4.useContext(NavigationContext);
|
|
2988
3012
|
if (!navigation) {
|
|
2989
3013
|
throw new Error("useNavigationStore must be used within a NavigationProvider");
|
|
2990
3014
|
}
|
|
2991
3015
|
return navigation;
|
|
2992
3016
|
}
|
|
2993
3017
|
function NavigationProvider({ children, defaultPage }) {
|
|
2994
|
-
const storeRef =
|
|
3018
|
+
const storeRef = React4.useRef(
|
|
2995
3019
|
zustand.create(() => ({
|
|
2996
3020
|
pageId: defaultPage || "home"
|
|
2997
3021
|
}))
|
|
@@ -3000,7 +3024,7 @@ function NavigationProvider({ children, defaultPage }) {
|
|
|
3000
3024
|
}
|
|
3001
3025
|
function NavBar(props) {
|
|
3002
3026
|
const pageId = useNavigation((state) => state.pageId);
|
|
3003
|
-
const
|
|
3027
|
+
const store2 = useNavigationStore();
|
|
3004
3028
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3005
3029
|
SegmentedControl,
|
|
3006
3030
|
{
|
|
@@ -3009,7 +3033,7 @@ function NavBar(props) {
|
|
|
3009
3033
|
value: pageId,
|
|
3010
3034
|
items: props.items,
|
|
3011
3035
|
onChange: (value) => {
|
|
3012
|
-
|
|
3036
|
+
store2.setState({ pageId: value });
|
|
3013
3037
|
}
|
|
3014
3038
|
}
|
|
3015
3039
|
);
|
|
@@ -3343,7 +3367,7 @@ function Modal({
|
|
|
3343
3367
|
children
|
|
3344
3368
|
}) {
|
|
3345
3369
|
const theme2 = core.useMantineTheme();
|
|
3346
|
-
const pointerDownOnOverlay =
|
|
3370
|
+
const pointerDownOnOverlay = React4.useRef(false);
|
|
3347
3371
|
return /* @__PURE__ */ jsxRuntime.jsx(core.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3348
3372
|
framerMotion.motion.div,
|
|
3349
3373
|
{
|
|
@@ -3524,9 +3548,9 @@ function PromptModal(props) {
|
|
|
3524
3548
|
}
|
|
3525
3549
|
);
|
|
3526
3550
|
}
|
|
3527
|
-
var ModalContext =
|
|
3551
|
+
var ModalContext = React4.createContext(null);
|
|
3528
3552
|
function useModal(selector) {
|
|
3529
|
-
const modal =
|
|
3553
|
+
const modal = React4.useContext(ModalContext);
|
|
3530
3554
|
if (!modal) {
|
|
3531
3555
|
throw new Error("useModal must be used within a ModalProvider");
|
|
3532
3556
|
}
|
|
@@ -3554,7 +3578,7 @@ function StoreModal() {
|
|
|
3554
3578
|
) });
|
|
3555
3579
|
}
|
|
3556
3580
|
function ModalProvider({ children }) {
|
|
3557
|
-
const storeRef =
|
|
3581
|
+
const storeRef = React4.useRef(
|
|
3558
3582
|
zustand.create(() => ({
|
|
3559
3583
|
active: null
|
|
3560
3584
|
}))
|
|
@@ -3565,7 +3589,7 @@ function ModalProvider({ children }) {
|
|
|
3565
3589
|
] });
|
|
3566
3590
|
}
|
|
3567
3591
|
function useModalActions() {
|
|
3568
|
-
const modal =
|
|
3592
|
+
const modal = React4.useContext(ModalContext);
|
|
3569
3593
|
if (!modal) throw new Error("useModalActions must be used within a ModalProvider");
|
|
3570
3594
|
const showModal = (openModal) => {
|
|
3571
3595
|
modal.setState({ active: openModal });
|
|
@@ -3585,7 +3609,7 @@ function ConfirmModal({
|
|
|
3585
3609
|
zIndex = 200
|
|
3586
3610
|
}) {
|
|
3587
3611
|
const theme2 = core.useMantineTheme();
|
|
3588
|
-
const [typed, setTyped] =
|
|
3612
|
+
const [typed, setTyped] = React4.useState("");
|
|
3589
3613
|
const canConfirm = !confirmText || typed === confirmText;
|
|
3590
3614
|
return /* @__PURE__ */ jsxRuntime.jsx(core.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3591
3615
|
framerMotion.motion.div,
|
|
@@ -3852,14 +3876,14 @@ function MissingItemsBanner() {
|
|
|
3852
3876
|
const loaded = useMissingItemsAudit((s) => s.loaded);
|
|
3853
3877
|
const inFlight = useMissingItemsAudit((s) => s.inFlight);
|
|
3854
3878
|
const refresh = useMissingItemsAudit((s) => s.refresh);
|
|
3855
|
-
const [expanded, setExpanded] =
|
|
3856
|
-
const [activeTab, setActiveTab] =
|
|
3857
|
-
const [hoveredTab, setHoveredTab] =
|
|
3858
|
-
const [copied, setCopied] =
|
|
3859
|
-
|
|
3879
|
+
const [expanded, setExpanded] = React4.useState(false);
|
|
3880
|
+
const [activeTab, setActiveTab] = React4.useState("ox");
|
|
3881
|
+
const [hoveredTab, setHoveredTab] = React4.useState(null);
|
|
3882
|
+
const [copied, setCopied] = React4.useState(null);
|
|
3883
|
+
React4.useEffect(() => {
|
|
3860
3884
|
if (!loaded) refresh();
|
|
3861
3885
|
}, [loaded, refresh]);
|
|
3862
|
-
const handleCopy =
|
|
3886
|
+
const handleCopy = React4.useCallback((tab) => {
|
|
3863
3887
|
if (!audit) return;
|
|
3864
3888
|
const text = audit.snippets[tab] ?? "";
|
|
3865
3889
|
navigator.clipboard.writeText(text).then(() => {
|
|
@@ -3868,7 +3892,7 @@ function MissingItemsBanner() {
|
|
|
3868
3892
|
}).catch(() => {
|
|
3869
3893
|
});
|
|
3870
3894
|
}, [audit]);
|
|
3871
|
-
const handleRefresh =
|
|
3895
|
+
const handleRefresh = React4.useCallback((e) => {
|
|
3872
3896
|
e.stopPropagation();
|
|
3873
3897
|
refresh();
|
|
3874
3898
|
}, [refresh]);
|
|
@@ -4000,7 +4024,7 @@ function CodeView({
|
|
|
4000
4024
|
warnColor
|
|
4001
4025
|
}) {
|
|
4002
4026
|
const theme2 = core.useMantineTheme();
|
|
4003
|
-
const [hovered, setHovered] =
|
|
4027
|
+
const [hovered, setHovered] = React4.useState(false);
|
|
4004
4028
|
const lines = code === "" ? [""] : code.split("\n");
|
|
4005
4029
|
const lineNumWidth = String(lines.length).length;
|
|
4006
4030
|
const copyBg = copied ? core.alpha("#22c55e", 0.15) : hovered ? core.alpha(warnColor, 0.18) : core.alpha(warnColor, 0.1);
|
|
@@ -4303,42 +4327,42 @@ function createFormStore(initialValues, validationRules, onSubmit) {
|
|
|
4303
4327
|
}
|
|
4304
4328
|
}));
|
|
4305
4329
|
}
|
|
4306
|
-
var FormContext =
|
|
4330
|
+
var FormContext = React4.createContext(null);
|
|
4307
4331
|
function FormProvider({
|
|
4308
4332
|
initialValues,
|
|
4309
4333
|
validate,
|
|
4310
4334
|
onSubmit,
|
|
4311
4335
|
children
|
|
4312
4336
|
}) {
|
|
4313
|
-
const storeRef =
|
|
4337
|
+
const storeRef = React4.useRef(
|
|
4314
4338
|
createFormStore(initialValues, validate, onSubmit)
|
|
4315
4339
|
);
|
|
4316
4340
|
return /* @__PURE__ */ jsxRuntime.jsx(FormContext.Provider, { value: storeRef.current, children });
|
|
4317
4341
|
}
|
|
4318
4342
|
function useForm() {
|
|
4319
|
-
const
|
|
4320
|
-
if (!
|
|
4343
|
+
const store2 = React4.useContext(FormContext);
|
|
4344
|
+
if (!store2) {
|
|
4321
4345
|
throw new Error("useForm must be used inside <FormProvider>");
|
|
4322
4346
|
}
|
|
4323
|
-
const state = zustand.useStore(
|
|
4324
|
-
const changedFields =
|
|
4347
|
+
const state = zustand.useStore(store2);
|
|
4348
|
+
const changedFields = React4.useMemo(() => {
|
|
4325
4349
|
return collectChangedPaths(state.values, state.initialValues);
|
|
4326
4350
|
}, [state.values, state.initialValues]);
|
|
4327
4351
|
return { ...state, changedFields, changedCount: changedFields.length };
|
|
4328
4352
|
}
|
|
4329
4353
|
function useFormField(path) {
|
|
4330
|
-
const
|
|
4331
|
-
if (!
|
|
4354
|
+
const store2 = React4.useContext(FormContext);
|
|
4355
|
+
if (!store2) {
|
|
4332
4356
|
throw new Error("useFormField must be used inside <FormProvider>");
|
|
4333
4357
|
}
|
|
4334
|
-
return zustand.useStore(
|
|
4358
|
+
return zustand.useStore(store2, (s) => getNested(s.values, path));
|
|
4335
4359
|
}
|
|
4336
4360
|
function useFormFields(...paths) {
|
|
4337
|
-
const
|
|
4338
|
-
if (!
|
|
4361
|
+
const store2 = React4.useContext(FormContext);
|
|
4362
|
+
if (!store2) {
|
|
4339
4363
|
throw new Error("useFormFields must be used inside <FormProvider>");
|
|
4340
4364
|
}
|
|
4341
|
-
return zustand.useStore(
|
|
4365
|
+
return zustand.useStore(store2, (s) => {
|
|
4342
4366
|
const result = {};
|
|
4343
4367
|
for (const path of paths) {
|
|
4344
4368
|
result[path] = getNested(s.values, path);
|
|
@@ -4347,18 +4371,18 @@ function useFormFields(...paths) {
|
|
|
4347
4371
|
});
|
|
4348
4372
|
}
|
|
4349
4373
|
function useFormError(path) {
|
|
4350
|
-
const
|
|
4351
|
-
if (!
|
|
4374
|
+
const store2 = React4.useContext(FormContext);
|
|
4375
|
+
if (!store2) {
|
|
4352
4376
|
throw new Error("useFormError must be used inside <FormProvider>");
|
|
4353
4377
|
}
|
|
4354
|
-
return zustand.useStore(
|
|
4378
|
+
return zustand.useStore(store2, (s) => s.errors[path]);
|
|
4355
4379
|
}
|
|
4356
4380
|
function useFormErrors(...paths) {
|
|
4357
|
-
const
|
|
4358
|
-
if (!
|
|
4381
|
+
const store2 = React4.useContext(FormContext);
|
|
4382
|
+
if (!store2) {
|
|
4359
4383
|
throw new Error("useFormErrors must be used inside <FormProvider>");
|
|
4360
4384
|
}
|
|
4361
|
-
return zustand.useStore(
|
|
4385
|
+
return zustand.useStore(store2, (s) => {
|
|
4362
4386
|
const result = {};
|
|
4363
4387
|
for (const path of paths) {
|
|
4364
4388
|
result[path] = s.errors[path];
|
|
@@ -4367,18 +4391,229 @@ function useFormErrors(...paths) {
|
|
|
4367
4391
|
});
|
|
4368
4392
|
}
|
|
4369
4393
|
function useFormActions() {
|
|
4370
|
-
const
|
|
4371
|
-
if (!
|
|
4394
|
+
const store2 = React4.useContext(FormContext);
|
|
4395
|
+
if (!store2) {
|
|
4372
4396
|
throw new Error("useFormActions must be used inside <FormProvider>");
|
|
4373
4397
|
}
|
|
4374
|
-
return
|
|
4398
|
+
return store2.getState();
|
|
4399
|
+
}
|
|
4400
|
+
var store = /* @__PURE__ */ new Map();
|
|
4401
|
+
var listeners = /* @__PURE__ */ new Map();
|
|
4402
|
+
function notify(key) {
|
|
4403
|
+
const ls = listeners.get(key);
|
|
4404
|
+
if (!ls) return;
|
|
4405
|
+
ls.forEach((fn) => fn());
|
|
4406
|
+
}
|
|
4407
|
+
function useAdminState(key, initial) {
|
|
4408
|
+
const [, setTick] = React4.useState(0);
|
|
4409
|
+
React4.useEffect(() => {
|
|
4410
|
+
const set = listeners.get(key) ?? /* @__PURE__ */ new Set();
|
|
4411
|
+
listeners.set(key, set);
|
|
4412
|
+
const handler = () => setTick((t3) => t3 + 1);
|
|
4413
|
+
set.add(handler);
|
|
4414
|
+
return () => {
|
|
4415
|
+
set.delete(handler);
|
|
4416
|
+
if (set.size === 0) listeners.delete(key);
|
|
4417
|
+
};
|
|
4418
|
+
}, [key]);
|
|
4419
|
+
const value = store.has(key) ? store.get(key) : initial;
|
|
4420
|
+
const setValue = (v) => {
|
|
4421
|
+
const next = typeof v === "function" ? v(value) : v;
|
|
4422
|
+
store.set(key, next);
|
|
4423
|
+
notify(key);
|
|
4424
|
+
};
|
|
4425
|
+
return [value, setValue];
|
|
4426
|
+
}
|
|
4427
|
+
function clearAdminState(key) {
|
|
4428
|
+
if (key) {
|
|
4429
|
+
store.delete(key);
|
|
4430
|
+
notify(key);
|
|
4431
|
+
} else {
|
|
4432
|
+
const keys = Array.from(store.keys());
|
|
4433
|
+
store.clear();
|
|
4434
|
+
keys.forEach(notify);
|
|
4435
|
+
}
|
|
4375
4436
|
}
|
|
4437
|
+
var label = {
|
|
4438
|
+
fontSize: "var(--mantine-font-size-xs)",
|
|
4439
|
+
fontFamily: "Akrobat Bold",
|
|
4440
|
+
letterSpacing: "0.05em",
|
|
4441
|
+
textTransform: "uppercase"
|
|
4442
|
+
};
|
|
4443
|
+
var error = {
|
|
4444
|
+
fontSize: "var(--mantine-font-size-xs)",
|
|
4445
|
+
fontFamily: "Akrobat Regular"
|
|
4446
|
+
};
|
|
4447
|
+
var description = {
|
|
4448
|
+
fontSize: "var(--mantine-font-size-xs)"
|
|
4449
|
+
};
|
|
4450
|
+
var genericInputStyles = {
|
|
4451
|
+
styles: {
|
|
4452
|
+
label,
|
|
4453
|
+
error,
|
|
4454
|
+
description,
|
|
4455
|
+
input: {
|
|
4456
|
+
background: "rgba(255,255,255,0.04)",
|
|
4457
|
+
border: "0.1vh solid rgba(255,255,255,0.08)",
|
|
4458
|
+
color: "rgba(255,255,255,0.85)",
|
|
4459
|
+
minHeight: "4vh"
|
|
4460
|
+
}
|
|
4461
|
+
}
|
|
4462
|
+
};
|
|
4463
|
+
var theme = core.createTheme({
|
|
4464
|
+
primaryColor: "dirk",
|
|
4465
|
+
primaryShade: 9,
|
|
4466
|
+
defaultRadius: "xs",
|
|
4467
|
+
fontFamily: "Akrobat Regular, sans-serif",
|
|
4468
|
+
radius: {
|
|
4469
|
+
xxs: "0.3vh",
|
|
4470
|
+
xs: "0.5vh",
|
|
4471
|
+
sm: "0.75vh",
|
|
4472
|
+
md: "1vh",
|
|
4473
|
+
lg: "1.5vh",
|
|
4474
|
+
xl: "2vh",
|
|
4475
|
+
xxl: "3vh"
|
|
4476
|
+
},
|
|
4477
|
+
fontSizes: {
|
|
4478
|
+
xxs: "1.2vh",
|
|
4479
|
+
xs: "1.5vh",
|
|
4480
|
+
sm: "1.8vh",
|
|
4481
|
+
md: "2.2vh",
|
|
4482
|
+
lg: "2.8vh",
|
|
4483
|
+
xl: "3.3vh",
|
|
4484
|
+
xxl: "3.8vh"
|
|
4485
|
+
},
|
|
4486
|
+
lineHeights: {
|
|
4487
|
+
xxs: "1.4vh",
|
|
4488
|
+
xs: "1.8vh",
|
|
4489
|
+
sm: "2.2vh",
|
|
4490
|
+
md: "2.8vh",
|
|
4491
|
+
lg: "3.3vh",
|
|
4492
|
+
xl: "3.8vh"
|
|
4493
|
+
},
|
|
4494
|
+
spacing: {
|
|
4495
|
+
xxs: "0.5vh",
|
|
4496
|
+
xs: "0.75vh",
|
|
4497
|
+
sm: "1.5vh",
|
|
4498
|
+
md: "2vh",
|
|
4499
|
+
lg: "3vh",
|
|
4500
|
+
xl: "4vh",
|
|
4501
|
+
xxl: "5vh"
|
|
4502
|
+
},
|
|
4503
|
+
components: {
|
|
4504
|
+
Progress: {
|
|
4505
|
+
styles: {
|
|
4506
|
+
label: {
|
|
4507
|
+
fontFamily: "Akrobat Bold",
|
|
4508
|
+
letterSpacing: "0.05em",
|
|
4509
|
+
textTransform: "uppercase"
|
|
4510
|
+
},
|
|
4511
|
+
root: {
|
|
4512
|
+
backgroundColor: "rgba(77, 77, 77, 0.4)"
|
|
4513
|
+
}
|
|
4514
|
+
}
|
|
4515
|
+
},
|
|
4516
|
+
Input: genericInputStyles,
|
|
4517
|
+
TextInput: genericInputStyles,
|
|
4518
|
+
NumberInput: genericInputStyles,
|
|
4519
|
+
Select: genericInputStyles,
|
|
4520
|
+
MultiSelect: genericInputStyles,
|
|
4521
|
+
Textarea: genericInputStyles,
|
|
4522
|
+
ColorInput: genericInputStyles,
|
|
4523
|
+
DateInput: genericInputStyles,
|
|
4524
|
+
// Mantine's <Button> defaults to rem-based heights (xs ≈ 1.875rem)
|
|
4525
|
+
// which doesn't match this theme's vh-based input min-heights, so
|
|
4526
|
+
// `<Button size="xs">` rendered next to `<TextInput size="xs">` ends
|
|
4527
|
+
// up visibly shorter. Pin the button heights to the same vh values
|
|
4528
|
+
// the inputs use so xs-everything lines up out of the box.
|
|
4529
|
+
Button: {
|
|
4530
|
+
styles: {
|
|
4531
|
+
label: {
|
|
4532
|
+
fontFamily: "Akrobat Bold",
|
|
4533
|
+
letterSpacing: "0.05em",
|
|
4534
|
+
textTransform: "uppercase"
|
|
4535
|
+
},
|
|
4536
|
+
root: {
|
|
4537
|
+
// Mantine maps these to --button-height per size; setting them
|
|
4538
|
+
// directly here keeps native Button sizing logic intact.
|
|
4539
|
+
}
|
|
4540
|
+
},
|
|
4541
|
+
vars: (_theme, props) => {
|
|
4542
|
+
const heights = {
|
|
4543
|
+
xs: "4vh",
|
|
4544
|
+
sm: "4.5vh",
|
|
4545
|
+
md: "5vh",
|
|
4546
|
+
lg: "5.5vh",
|
|
4547
|
+
xl: "6vh"
|
|
4548
|
+
};
|
|
4549
|
+
const h = heights[props.size ?? "sm"] ?? "4.5vh";
|
|
4550
|
+
return {
|
|
4551
|
+
root: {
|
|
4552
|
+
"--button-height": h
|
|
4553
|
+
}
|
|
4554
|
+
};
|
|
4555
|
+
}
|
|
4556
|
+
},
|
|
4557
|
+
Pill: {
|
|
4558
|
+
styles: (theme2) => ({
|
|
4559
|
+
root: {
|
|
4560
|
+
display: "inline-flex",
|
|
4561
|
+
alignItems: "center",
|
|
4562
|
+
justifyContent: "space-between",
|
|
4563
|
+
backgroundColor: "rgba(76, 76, 76, 0.3)",
|
|
4564
|
+
height: "fit-content",
|
|
4565
|
+
textTransform: "uppercase",
|
|
4566
|
+
letterSpacing: "0.05em",
|
|
4567
|
+
fontFamily: "Akrobat Bold",
|
|
4568
|
+
fontSize: "1.25vh",
|
|
4569
|
+
borderRadius: theme2.defaultRadius,
|
|
4570
|
+
paddingBottom: "0.5vh",
|
|
4571
|
+
paddingTop: "0.5vh"
|
|
4572
|
+
}
|
|
4573
|
+
})
|
|
4574
|
+
},
|
|
4575
|
+
// Mantine's <Tooltip> defaults to a white card with black text — looks
|
|
4576
|
+
// jarring against every dirk consumer's dark configurator. Every script
|
|
4577
|
+
// used to hand-paste this dark style block per Tooltip; centralised here
|
|
4578
|
+
// so consumers get the right look automatically and never need to think
|
|
4579
|
+
// about it again.
|
|
4580
|
+
Tooltip: {
|
|
4581
|
+
styles: (theme2) => ({
|
|
4582
|
+
tooltip: {
|
|
4583
|
+
background: core.alpha(theme2.colors.dark[7], 0.95),
|
|
4584
|
+
border: "0.1vh solid rgba(255,255,255,0.1)",
|
|
4585
|
+
color: "rgba(255,255,255,0.75)",
|
|
4586
|
+
fontFamily: "Akrobat Bold",
|
|
4587
|
+
fontSize: "1.3vh",
|
|
4588
|
+
lineHeight: 1.3,
|
|
4589
|
+
padding: "0.6vh 0.8vh",
|
|
4590
|
+
letterSpacing: "0.03em"
|
|
4591
|
+
}
|
|
4592
|
+
})
|
|
4593
|
+
}
|
|
4594
|
+
},
|
|
4595
|
+
colors: {
|
|
4596
|
+
dirk: [
|
|
4597
|
+
"#ffffff",
|
|
4598
|
+
"#f3fce9",
|
|
4599
|
+
"#dbf5bd",
|
|
4600
|
+
"#c3ee91",
|
|
4601
|
+
"#ace765",
|
|
4602
|
+
"#94e039",
|
|
4603
|
+
"#7ac61f",
|
|
4604
|
+
"#5f9a18",
|
|
4605
|
+
"#29420a",
|
|
4606
|
+
"#446e11"
|
|
4607
|
+
]
|
|
4608
|
+
}
|
|
4609
|
+
});
|
|
4610
|
+
var theme_default = theme;
|
|
4376
4611
|
var useNuiEvent = (action, handler) => {
|
|
4377
|
-
const savedHandler =
|
|
4378
|
-
|
|
4612
|
+
const savedHandler = React4.useRef(noop);
|
|
4613
|
+
React4.useEffect(() => {
|
|
4379
4614
|
savedHandler.current = handler;
|
|
4380
4615
|
}, [handler]);
|
|
4381
|
-
|
|
4616
|
+
React4.useEffect(() => {
|
|
4382
4617
|
const eventListener = (event) => {
|
|
4383
4618
|
const { action: eventAction, data } = event.data;
|
|
4384
4619
|
if (savedHandler.current) {
|
|
@@ -4391,13 +4626,35 @@ var useNuiEvent = (action, handler) => {
|
|
|
4391
4626
|
return () => window.removeEventListener("message", eventListener);
|
|
4392
4627
|
}, [action]);
|
|
4393
4628
|
};
|
|
4629
|
+
|
|
4630
|
+
// src/utils/mergeMantineTheme.ts
|
|
4631
|
+
var isValidColorScale = (v) => Array.isArray(v) && v.length === 10 && v.every((shade) => typeof shade === "string");
|
|
4632
|
+
function mergeMantineThemeSafe(base, custom, override) {
|
|
4633
|
+
const colors = { ...base.colors };
|
|
4634
|
+
if (custom && isValidColorScale(custom)) {
|
|
4635
|
+
colors["custom"] = custom;
|
|
4636
|
+
} else if (!colors["custom"]) {
|
|
4637
|
+
const fallback = base.colors && base.colors.dirk;
|
|
4638
|
+
if (fallback && isValidColorScale(fallback)) {
|
|
4639
|
+
colors["custom"] = fallback;
|
|
4640
|
+
}
|
|
4641
|
+
}
|
|
4642
|
+
return {
|
|
4643
|
+
...base,
|
|
4644
|
+
...override,
|
|
4645
|
+
colors: {
|
|
4646
|
+
...colors,
|
|
4647
|
+
...override?.colors ?? {}
|
|
4648
|
+
}
|
|
4649
|
+
};
|
|
4650
|
+
}
|
|
4394
4651
|
var _instance = null;
|
|
4395
4652
|
function getScriptConfigInstance() {
|
|
4396
4653
|
if (!_instance) throw new Error("[dirk-cfx-react] createScriptConfig must be called before using ConfigPanel");
|
|
4397
4654
|
return _instance;
|
|
4398
4655
|
}
|
|
4399
4656
|
function createScriptConfig(defaultValue) {
|
|
4400
|
-
const
|
|
4657
|
+
const store2 = zustand.create(() => defaultValue);
|
|
4401
4658
|
let clientVersion = 0;
|
|
4402
4659
|
const useScriptConfigHooks = () => {
|
|
4403
4660
|
useNuiEvent("UPDATE_SCRIPT_CONFIG", (data) => {
|
|
@@ -4406,7 +4663,7 @@ function createScriptConfig(defaultValue) {
|
|
|
4406
4663
|
clientVersion = data.clientVersion;
|
|
4407
4664
|
}
|
|
4408
4665
|
if (data.config && typeof data.config === "object") {
|
|
4409
|
-
|
|
4666
|
+
store2.setState((prev) => ({ ...prev, ...data.config }));
|
|
4410
4667
|
}
|
|
4411
4668
|
});
|
|
4412
4669
|
};
|
|
@@ -4414,7 +4671,7 @@ function createScriptConfig(defaultValue) {
|
|
|
4414
4671
|
try {
|
|
4415
4672
|
const response = await fetchNui("GET_FULL_SCRIPT_CONFIG");
|
|
4416
4673
|
if (response?.success && response.data?.config) {
|
|
4417
|
-
|
|
4674
|
+
store2.setState(() => response.data.config);
|
|
4418
4675
|
if (typeof response.data.clientVersion === "number") {
|
|
4419
4676
|
clientVersion = response.data.clientVersion;
|
|
4420
4677
|
}
|
|
@@ -4425,7 +4682,7 @@ function createScriptConfig(defaultValue) {
|
|
|
4425
4682
|
return null;
|
|
4426
4683
|
};
|
|
4427
4684
|
const updateScriptConfig = async (newConfig) => {
|
|
4428
|
-
|
|
4685
|
+
store2.setState((prev) => ({ ...prev, ...newConfig }));
|
|
4429
4686
|
const response = await fetchNui("UPDATE_SCRIPT_CONFIG", {
|
|
4430
4687
|
data: newConfig,
|
|
4431
4688
|
expectedVersion: clientVersion
|
|
@@ -4434,7 +4691,7 @@ function createScriptConfig(defaultValue) {
|
|
|
4434
4691
|
clientVersion = response.meta.client_version;
|
|
4435
4692
|
}
|
|
4436
4693
|
if (response?.success === false && response?.meta?.latestData) {
|
|
4437
|
-
|
|
4694
|
+
store2.setState((prev) => ({ ...prev, ...response.meta.latestData }));
|
|
4438
4695
|
}
|
|
4439
4696
|
return response;
|
|
4440
4697
|
};
|
|
@@ -4446,30 +4703,253 @@ function createScriptConfig(defaultValue) {
|
|
|
4446
4703
|
if (response?.success) {
|
|
4447
4704
|
const fresh = await fetchScriptConfig();
|
|
4448
4705
|
if (fresh) {
|
|
4449
|
-
|
|
4706
|
+
store2.setState(() => fresh);
|
|
4450
4707
|
}
|
|
4451
4708
|
}
|
|
4452
4709
|
return response;
|
|
4453
4710
|
};
|
|
4454
4711
|
_instance = {
|
|
4455
|
-
store,
|
|
4712
|
+
store: store2,
|
|
4456
4713
|
updateConfig: updateScriptConfig,
|
|
4457
4714
|
resetConfig,
|
|
4458
4715
|
getHistory: getScriptConfigHistory,
|
|
4459
4716
|
fetchConfig: fetchScriptConfig
|
|
4460
4717
|
};
|
|
4461
|
-
return { store, updateScriptConfig, resetConfig, getScriptConfigHistory, useScriptConfigHooks, fetchScriptConfig };
|
|
4718
|
+
return { store: store2, updateScriptConfig, resetConfig, getScriptConfigHistory, useScriptConfigHooks, fetchScriptConfig };
|
|
4719
|
+
}
|
|
4720
|
+
var DirkErrorBoundary = class extends React4__default.default.Component {
|
|
4721
|
+
constructor() {
|
|
4722
|
+
super(...arguments);
|
|
4723
|
+
__publicField(this, "state", { error: null, stack: void 0 });
|
|
4724
|
+
}
|
|
4725
|
+
static getDerivedStateFromError(error2) {
|
|
4726
|
+
return { error: error2 };
|
|
4727
|
+
}
|
|
4728
|
+
componentDidCatch(error2, info) {
|
|
4729
|
+
console.group("\u{1F525} Dirk UI Crash");
|
|
4730
|
+
console.error("Error:", error2);
|
|
4731
|
+
console.error("Component Stack:", info.componentStack);
|
|
4732
|
+
console.groupEnd();
|
|
4733
|
+
}
|
|
4734
|
+
render() {
|
|
4735
|
+
if (!this.state.error) return this.props.children;
|
|
4736
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4737
|
+
core.Box,
|
|
4738
|
+
{
|
|
4739
|
+
style: {
|
|
4740
|
+
position: "fixed",
|
|
4741
|
+
inset: 0,
|
|
4742
|
+
width: "100vw",
|
|
4743
|
+
height: "100vh",
|
|
4744
|
+
background: "rgba(10, 10, 12, 0.92)",
|
|
4745
|
+
display: "flex",
|
|
4746
|
+
alignItems: "center",
|
|
4747
|
+
justifyContent: "center",
|
|
4748
|
+
padding: "2rem",
|
|
4749
|
+
zIndex: 999999
|
|
4750
|
+
},
|
|
4751
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4752
|
+
core.Box,
|
|
4753
|
+
{
|
|
4754
|
+
maw: 900,
|
|
4755
|
+
w: "100%",
|
|
4756
|
+
p: "lg",
|
|
4757
|
+
style: {
|
|
4758
|
+
background: "rgba(20,20,24,0.75)",
|
|
4759
|
+
border: "1px solid rgba(255,255,255,0.08)",
|
|
4760
|
+
borderRadius: "10px",
|
|
4761
|
+
boxShadow: "0 10px 40px rgba(0,0,0,0.6)"
|
|
4762
|
+
},
|
|
4763
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(core.Stack, { gap: "sm", children: [
|
|
4764
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Title, { order: 2, c: "red.5", children: "Dirk UI Crash" }),
|
|
4765
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { c: "dimmed", size: "sm", children: "The interface encountered a fatal error and stopped rendering." }),
|
|
4766
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Code, { block: true, style: { maxHeight: 150, overflow: "auto" }, children: this.state.error?.message }),
|
|
4767
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xs", c: "dimmed", children: "Check console for full stack trace" })
|
|
4768
|
+
] })
|
|
4769
|
+
}
|
|
4770
|
+
)
|
|
4771
|
+
}
|
|
4772
|
+
);
|
|
4773
|
+
}
|
|
4774
|
+
};
|
|
4775
|
+
var useAdminToolStore = zustand.create((set, get) => ({
|
|
4776
|
+
active: null,
|
|
4777
|
+
begin: (spec) => new Promise((resolve) => {
|
|
4778
|
+
const prev = get().active;
|
|
4779
|
+
if (prev) prev.resolve(null);
|
|
4780
|
+
set({ active: { ...spec, resolve } });
|
|
4781
|
+
}),
|
|
4782
|
+
resolveActive: (value) => {
|
|
4783
|
+
const cur = get().active;
|
|
4784
|
+
if (!cur) return;
|
|
4785
|
+
cur.resolve(value);
|
|
4786
|
+
set({ active: null });
|
|
4787
|
+
},
|
|
4788
|
+
cancelActive: () => {
|
|
4789
|
+
const cur = get().active;
|
|
4790
|
+
if (!cur) return;
|
|
4791
|
+
cur.resolve(null);
|
|
4792
|
+
set({ active: null });
|
|
4793
|
+
}
|
|
4794
|
+
}));
|
|
4795
|
+
|
|
4796
|
+
// src/components/AdminTools/AdminOverlays.tsx
|
|
4797
|
+
var listenerInstalled = false;
|
|
4798
|
+
function installNuiListener() {
|
|
4799
|
+
if (listenerInstalled || typeof window === "undefined") return;
|
|
4800
|
+
listenerInstalled = true;
|
|
4801
|
+
window.addEventListener("message", (e) => {
|
|
4802
|
+
const msg = e?.data;
|
|
4803
|
+
if (!msg || typeof msg !== "object" || typeof msg.action !== "string") return;
|
|
4804
|
+
const action = msg.action;
|
|
4805
|
+
const cur = useAdminToolStore.getState().active;
|
|
4806
|
+
if (!cur) return;
|
|
4807
|
+
if (action === `${cur.id}_RESULT`) {
|
|
4808
|
+
useAdminToolStore.getState().resolveActive(msg.data ?? null);
|
|
4809
|
+
} else if (action === `${cur.id}_CANCELLED`) {
|
|
4810
|
+
useAdminToolStore.getState().cancelActive();
|
|
4811
|
+
}
|
|
4812
|
+
});
|
|
4813
|
+
}
|
|
4814
|
+
var BODY_HIDE_STYLE_ID = "dirk-instruction-panel-style";
|
|
4815
|
+
var BODY_HIDE_ATTR = "data-dirk-instruction-active";
|
|
4816
|
+
var OVERLAY_ATTR = "data-dirk-instruction-overlay";
|
|
4817
|
+
function ensureBodyHideStyle() {
|
|
4818
|
+
if (typeof document === "undefined") return;
|
|
4819
|
+
if (document.getElementById(BODY_HIDE_STYLE_ID)) return;
|
|
4820
|
+
const el = document.createElement("style");
|
|
4821
|
+
el.id = BODY_HIDE_STYLE_ID;
|
|
4822
|
+
el.textContent = `
|
|
4823
|
+
body[${BODY_HIDE_ATTR}] > *:not([${OVERLAY_ATTR}]) {
|
|
4824
|
+
visibility: hidden !important;
|
|
4825
|
+
opacity: 0 !important;
|
|
4826
|
+
pointer-events: none !important;
|
|
4827
|
+
}
|
|
4828
|
+
`;
|
|
4829
|
+
document.head.appendChild(el);
|
|
4830
|
+
}
|
|
4831
|
+
function AdminOverlays() {
|
|
4832
|
+
const active = useAdminToolStore((s) => s.active);
|
|
4833
|
+
React4.useEffect(() => {
|
|
4834
|
+
installNuiListener();
|
|
4835
|
+
}, []);
|
|
4836
|
+
React4.useEffect(() => {
|
|
4837
|
+
if (!active || typeof document === "undefined") return;
|
|
4838
|
+
ensureBodyHideStyle();
|
|
4839
|
+
document.body.setAttribute(BODY_HIDE_ATTR, "");
|
|
4840
|
+
return () => {
|
|
4841
|
+
document.body.removeAttribute(BODY_HIDE_ATTR);
|
|
4842
|
+
};
|
|
4843
|
+
}, [active]);
|
|
4844
|
+
return null;
|
|
4462
4845
|
}
|
|
4463
|
-
|
|
4846
|
+
fontawesomeSvgCore.library.add(freeSolidSvgIcons.fas, freeRegularSvgIcons.far, freeBrandsSvgIcons.fab);
|
|
4847
|
+
var dirkQueryClient = new reactQuery.QueryClient({
|
|
4464
4848
|
defaultOptions: { queries: { staleTime: 3e4, gcTime: 5 * 6e4 } }
|
|
4465
4849
|
});
|
|
4466
|
-
function
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4850
|
+
function DirkProvider({ children, overideResourceName, themeOverride }) {
|
|
4851
|
+
const {
|
|
4852
|
+
primaryColor,
|
|
4853
|
+
primaryShade,
|
|
4854
|
+
customTheme,
|
|
4855
|
+
game
|
|
4856
|
+
} = useSettings();
|
|
4857
|
+
localeStore((s) => s.locales);
|
|
4858
|
+
const [scTheme, setScTheme] = React4.useState(null);
|
|
4859
|
+
React4.useLayoutEffect(() => {
|
|
4860
|
+
useSettings.setState({
|
|
4861
|
+
overideResourceName
|
|
4862
|
+
});
|
|
4863
|
+
}, [overideResourceName]);
|
|
4864
|
+
React4.useEffect(() => {
|
|
4865
|
+
fetchNui("NUI_READY").catch(() => {
|
|
4866
|
+
});
|
|
4867
|
+
Promise.all([
|
|
4868
|
+
fetchNui("GET_SETTINGS"),
|
|
4869
|
+
fetchNui("GET_RESOURCE_VERSION", void 0, { version: "dev" })
|
|
4870
|
+
]).then(([data, resourceInfo]) => {
|
|
4871
|
+
useSettings.setState({
|
|
4872
|
+
...data,
|
|
4873
|
+
resourceVersion: resourceInfo?.version || "dev"
|
|
4874
|
+
});
|
|
4875
|
+
}).catch((err) => {
|
|
4876
|
+
console.error("Failed to fetch initial settings within dirk-cfx-react:", err);
|
|
4877
|
+
});
|
|
4878
|
+
}, []);
|
|
4879
|
+
useNuiEvent("UPDATE_DIRK_LIB_SETTINGS", (data) => {
|
|
4880
|
+
if (!data || typeof data !== "object") return;
|
|
4881
|
+
useSettings.setState(data);
|
|
4882
|
+
});
|
|
4883
|
+
useNuiEvent(
|
|
4884
|
+
"UPDATE_SCRIPT_CONFIG",
|
|
4885
|
+
(data) => {
|
|
4886
|
+
if (!data || !data.config || typeof data.config !== "object") return;
|
|
4887
|
+
try {
|
|
4888
|
+
const inst = getScriptConfigInstance();
|
|
4889
|
+
inst.store.setState((prev) => ({ ...prev, ...data.config }));
|
|
4890
|
+
} catch {
|
|
4891
|
+
}
|
|
4892
|
+
}
|
|
4893
|
+
);
|
|
4894
|
+
React4.useEffect(() => {
|
|
4895
|
+
let unsubscribe;
|
|
4896
|
+
try {
|
|
4897
|
+
const inst = getScriptConfigInstance();
|
|
4898
|
+
setScTheme(inst.store.getState()?.theme ?? null);
|
|
4899
|
+
const subscribable = inst.store;
|
|
4900
|
+
if (typeof subscribable.subscribe === "function") {
|
|
4901
|
+
unsubscribe = subscribable.subscribe((s) => {
|
|
4902
|
+
setScTheme(s?.theme ?? null);
|
|
4903
|
+
});
|
|
4904
|
+
}
|
|
4905
|
+
inst.fetchConfig?.().then((full) => {
|
|
4906
|
+
if (full && typeof full === "object") {
|
|
4907
|
+
setScTheme(full.theme ?? null);
|
|
4908
|
+
}
|
|
4909
|
+
}).catch(() => {
|
|
4910
|
+
});
|
|
4911
|
+
} catch {
|
|
4912
|
+
}
|
|
4913
|
+
return () => {
|
|
4914
|
+
unsubscribe?.();
|
|
4915
|
+
};
|
|
4916
|
+
}, []);
|
|
4917
|
+
const overrideActive = scTheme?.useOverride === true;
|
|
4918
|
+
const effectivePrimaryColor = overrideActive ? scTheme.primaryColor ?? primaryColor : primaryColor;
|
|
4919
|
+
const effectivePrimaryShade = overrideActive ? scTheme.primaryShade ?? primaryShade : primaryShade;
|
|
4920
|
+
const effectiveCustomTheme = overrideActive ? scTheme.customTheme ?? customTheme : customTheme;
|
|
4921
|
+
const mergedTheme = React4.useMemo(
|
|
4922
|
+
() => mergeMantineThemeSafe(
|
|
4923
|
+
{ ...theme_default, primaryColor: effectivePrimaryColor, primaryShade: effectivePrimaryShade },
|
|
4924
|
+
effectiveCustomTheme,
|
|
4925
|
+
themeOverride
|
|
4926
|
+
),
|
|
4927
|
+
[effectivePrimaryColor, effectivePrimaryShade, effectiveCustomTheme, themeOverride]
|
|
4928
|
+
);
|
|
4929
|
+
React4.useEffect(() => {
|
|
4930
|
+
document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : '"Akrobat Regular", sans-serif';
|
|
4931
|
+
}, [game]);
|
|
4932
|
+
const content = isEnvBrowser() ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4933
|
+
core.BackgroundImage,
|
|
4934
|
+
{
|
|
4935
|
+
w: "100vw",
|
|
4936
|
+
h: "100vh",
|
|
4937
|
+
src: game === "fivem" ? "https://i.ytimg.com/vi/TOxuNbXrO28/maxresdefault.jpg" : "https://raw.githubusercontent.com/Jump-On-Studios/RedM-jo_libs/refs/heads/main/source-repositories/Menu/public/assets/images/background_dev.jpg",
|
|
4938
|
+
children
|
|
4939
|
+
}
|
|
4940
|
+
) : children;
|
|
4941
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: dirkQueryClient, children: /* @__PURE__ */ jsxRuntime.jsx(core.MantineProvider, { theme: mergedTheme, defaultColorScheme: "dark", children: /* @__PURE__ */ jsxRuntime.jsxs(DirkErrorBoundary, { children: [
|
|
4942
|
+
content,
|
|
4943
|
+
/* @__PURE__ */ jsxRuntime.jsx(AdminOverlays, {})
|
|
4944
|
+
] }) }) });
|
|
4945
|
+
}
|
|
4946
|
+
function NavItemButton({
|
|
4947
|
+
icon: Icon,
|
|
4948
|
+
label: label2,
|
|
4949
|
+
active,
|
|
4950
|
+
onClick
|
|
4951
|
+
}) {
|
|
4952
|
+
const theme2 = core.useMantineTheme();
|
|
4473
4953
|
const color = theme2.colors[theme2.primaryColor][5];
|
|
4474
4954
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4475
4955
|
framerMotion.motion.button,
|
|
@@ -4511,8 +4991,8 @@ function ConfigJsonModal({
|
|
|
4511
4991
|
const theme2 = core.useMantineTheme();
|
|
4512
4992
|
const color = theme2.colors[theme2.primaryColor][5];
|
|
4513
4993
|
const form = useForm();
|
|
4514
|
-
const [json, setJson] =
|
|
4515
|
-
const [error2, setError] =
|
|
4994
|
+
const [json, setJson] = React4.useState(() => JSON.stringify(form.values, null, 2));
|
|
4995
|
+
const [error2, setError] = React4.useState(null);
|
|
4516
4996
|
const handleSave = () => {
|
|
4517
4997
|
try {
|
|
4518
4998
|
const parsed = JSON.parse(json);
|
|
@@ -4689,14 +5169,14 @@ function ConfigHistoryModal({
|
|
|
4689
5169
|
const { getHistory } = getScriptConfigInstance();
|
|
4690
5170
|
const theme2 = core.useMantineTheme();
|
|
4691
5171
|
const color = theme2.colors[theme2.primaryColor][5];
|
|
4692
|
-
const [queryInput, setQueryInput] =
|
|
4693
|
-
const [pathInput, setPathInput] =
|
|
4694
|
-
const [adminInput, setAdminInput] =
|
|
4695
|
-
const [query, setQuery] =
|
|
4696
|
-
const [path, setPath] =
|
|
4697
|
-
const [admin, setAdmin] =
|
|
4698
|
-
const [expandedKey, setExpandedKey] =
|
|
4699
|
-
const filters =
|
|
5172
|
+
const [queryInput, setQueryInput] = React4.useState("");
|
|
5173
|
+
const [pathInput, setPathInput] = React4.useState("");
|
|
5174
|
+
const [adminInput, setAdminInput] = React4.useState("");
|
|
5175
|
+
const [query, setQuery] = React4.useState("");
|
|
5176
|
+
const [path, setPath] = React4.useState("");
|
|
5177
|
+
const [admin, setAdmin] = React4.useState("");
|
|
5178
|
+
const [expandedKey, setExpandedKey] = React4.useState(null);
|
|
5179
|
+
const filters = React4.useMemo(() => ({ query, path, admin }), [query, path, admin]);
|
|
4700
5180
|
const historyQuery = reactQuery.useInfiniteQuery({
|
|
4701
5181
|
queryKey: ["scriptConfigHistory", filters],
|
|
4702
5182
|
initialPageParam: 0,
|
|
@@ -4791,12 +5271,12 @@ function ConfigPanelInner({
|
|
|
4791
5271
|
const theme2 = core.useMantineTheme();
|
|
4792
5272
|
const color = theme2.colors[theme2.primaryColor][5];
|
|
4793
5273
|
const version = useSettings((s) => s.resourceVersion);
|
|
4794
|
-
const [activeTab, setActiveTab] =
|
|
4795
|
-
const firstMountRef =
|
|
4796
|
-
const [jsonOpen, setJsonOpen] =
|
|
4797
|
-
const [historyOpen, setHistoryOpen] =
|
|
4798
|
-
const [resetOpen, setResetOpen] =
|
|
4799
|
-
const [pendingAction, setPendingAction] =
|
|
5274
|
+
const [activeTab, setActiveTab] = useAdminState("__dirkConfigPanel:activeTab", navItems[0]?.id ?? "");
|
|
5275
|
+
const firstMountRef = React4.useRef(true);
|
|
5276
|
+
const [jsonOpen, setJsonOpen] = React4.useState(false);
|
|
5277
|
+
const [historyOpen, setHistoryOpen] = React4.useState(false);
|
|
5278
|
+
const [resetOpen, setResetOpen] = React4.useState(false);
|
|
5279
|
+
const [pendingAction, setPendingAction] = React4.useState(null);
|
|
4800
5280
|
const changedCount = form.changedCount ?? 0;
|
|
4801
5281
|
const isDirty = changedCount > 0;
|
|
4802
5282
|
const goBack = () => fetchNui("CONFIG_PANEL_BACK");
|
|
@@ -4807,7 +5287,7 @@ function ConfigPanelInner({
|
|
|
4807
5287
|
}
|
|
4808
5288
|
goBack();
|
|
4809
5289
|
};
|
|
4810
|
-
|
|
5290
|
+
React4.useEffect(() => {
|
|
4811
5291
|
function handleKeyDown(e) {
|
|
4812
5292
|
if (e.key !== "Escape") return;
|
|
4813
5293
|
if (isDirty) {
|
|
@@ -4834,8 +5314,8 @@ function ConfigPanelInner({
|
|
|
4834
5314
|
setResetOpen(false);
|
|
4835
5315
|
const result = await resetConfig();
|
|
4836
5316
|
if (result?.success) {
|
|
4837
|
-
const { store } = getScriptConfigInstance();
|
|
4838
|
-
form.reinitialize(cloneConfig(
|
|
5317
|
+
const { store: store2 } = getScriptConfigInstance();
|
|
5318
|
+
form.reinitialize(cloneConfig(store2.getState()));
|
|
4839
5319
|
notifications.notifications.show({
|
|
4840
5320
|
color: "green",
|
|
4841
5321
|
title: locale("ConfigResetSuccessTitle"),
|
|
@@ -5048,7 +5528,7 @@ function cloneConfig(value) {
|
|
|
5048
5528
|
function ServerOnlyFetcher() {
|
|
5049
5529
|
const { fetchConfig } = getScriptConfigInstance();
|
|
5050
5530
|
const { reinitialize } = useFormActions();
|
|
5051
|
-
|
|
5531
|
+
React4.useEffect(() => {
|
|
5052
5532
|
let cancelled = false;
|
|
5053
5533
|
fetchConfig().then((full) => {
|
|
5054
5534
|
if (!cancelled && full) reinitialize(full);
|
|
@@ -5063,13 +5543,13 @@ function ServerOnlyFetcher() {
|
|
|
5063
5543
|
var defaultOnClose = () => fetchNui("CLOSE_ADMIN_SECTION");
|
|
5064
5544
|
function ConfigPanel(props) {
|
|
5065
5545
|
const { open, onClose = defaultOnClose } = props;
|
|
5066
|
-
const { store, updateConfig } = getScriptConfigInstance();
|
|
5067
|
-
const [isSaving, setIsSaving] =
|
|
5546
|
+
const { store: store2, updateConfig } = getScriptConfigInstance();
|
|
5547
|
+
const [isSaving, setIsSaving] = React4.useState(false);
|
|
5068
5548
|
if (!open) return null;
|
|
5069
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5549
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5070
5550
|
FormProvider,
|
|
5071
5551
|
{
|
|
5072
|
-
initialValues: cloneConfig(
|
|
5552
|
+
initialValues: cloneConfig(store2.getState()),
|
|
5073
5553
|
onSubmit: async (form) => {
|
|
5074
5554
|
if (isSaving) return;
|
|
5075
5555
|
setIsSaving(true);
|
|
@@ -5077,7 +5557,7 @@ function ConfigPanel(props) {
|
|
|
5077
5557
|
const result = await updateConfig(form.values);
|
|
5078
5558
|
if (result?.success) {
|
|
5079
5559
|
form.reinitialize(cloneConfig(form.values));
|
|
5080
|
-
|
|
5560
|
+
dirkQueryClient.invalidateQueries({ queryKey: ["scriptConfigHistory"] });
|
|
5081
5561
|
useMissingItemsAudit.getState().refresh();
|
|
5082
5562
|
notifications.notifications.show({
|
|
5083
5563
|
color: "green",
|
|
@@ -5087,7 +5567,7 @@ function ConfigPanel(props) {
|
|
|
5087
5567
|
});
|
|
5088
5568
|
return;
|
|
5089
5569
|
}
|
|
5090
|
-
form.reinitialize(cloneConfig(
|
|
5570
|
+
form.reinitialize(cloneConfig(store2.getState()));
|
|
5091
5571
|
const err = result?._error || "Unknown";
|
|
5092
5572
|
console.warn(`[ConfigPanel] config save failed: ${err}`);
|
|
5093
5573
|
const titleKey = err === "NoPermission" ? "ConfigSaveNoPermissionTitle" : err === "VersionConflict" ? "ConfigSaveVersionConflictTitle" : err === "NotReady" ? "ConfigSaveNotReadyTitle" : "ConfigSaveFailedTitle";
|
|
@@ -5118,9 +5598,9 @@ function ConfigPanel(props) {
|
|
|
5118
5598
|
}
|
|
5119
5599
|
var MISSING_COLOR = "#f59e0b";
|
|
5120
5600
|
function LazyImage({ src, style }) {
|
|
5121
|
-
const [visible, setVisible] =
|
|
5122
|
-
const ref =
|
|
5123
|
-
|
|
5601
|
+
const [visible, setVisible] = React4.useState(false);
|
|
5602
|
+
const ref = React4.useRef(null);
|
|
5603
|
+
React4.useEffect(() => {
|
|
5124
5604
|
const observer = new IntersectionObserver(([entry]) => {
|
|
5125
5605
|
if (entry.isIntersecting) {
|
|
5126
5606
|
setVisible(true);
|
|
@@ -5135,7 +5615,7 @@ function LazyImage({ src, style }) {
|
|
|
5135
5615
|
function SelectItem(props) {
|
|
5136
5616
|
const invItems = useItems();
|
|
5137
5617
|
const isMissing = !!props.value && !invItems[props.value];
|
|
5138
|
-
const formattedItems =
|
|
5618
|
+
const formattedItems = React4.useMemo(() => {
|
|
5139
5619
|
const seen = /* @__PURE__ */ new Set();
|
|
5140
5620
|
const list = useItemsList(props.excludeItemNames ?? []).filter((item) => {
|
|
5141
5621
|
if (seen.has(item.name)) return false;
|
|
@@ -5225,9 +5705,9 @@ function PositionPicker(props) {
|
|
|
5225
5705
|
} = props;
|
|
5226
5706
|
const theme2 = core.useMantineTheme();
|
|
5227
5707
|
const color = theme2.colors[theme2.primaryColor][5];
|
|
5228
|
-
const [previewing, setPreviewing] =
|
|
5229
|
-
const previewingRef =
|
|
5230
|
-
|
|
5708
|
+
const [previewing, setPreviewing] = React4.useState(false);
|
|
5709
|
+
const previewingRef = React4.useRef(false);
|
|
5710
|
+
React4.useEffect(() => {
|
|
5231
5711
|
return () => {
|
|
5232
5712
|
if (previewingRef.current) {
|
|
5233
5713
|
fetchNui(stopPreviewEvent, { relativeTo }).catch(() => {
|
|
@@ -5565,7 +6045,7 @@ function Vector4DeleteButton({
|
|
|
5565
6045
|
}
|
|
5566
6046
|
);
|
|
5567
6047
|
}
|
|
5568
|
-
var GroupSelectContext =
|
|
6048
|
+
var GroupSelectContext = React4.createContext(null);
|
|
5569
6049
|
function GroupSelect({
|
|
5570
6050
|
value,
|
|
5571
6051
|
onChange,
|
|
@@ -5581,9 +6061,12 @@ function filterByType(jobs, gangs, type) {
|
|
|
5581
6061
|
return [...jobs, ...gangs];
|
|
5582
6062
|
}
|
|
5583
6063
|
function GroupName(props) {
|
|
5584
|
-
const ctx =
|
|
6064
|
+
const ctx = React4.useContext(GroupSelectContext);
|
|
5585
6065
|
const jobs = useFrameworkGroups((s) => s.jobs);
|
|
5586
6066
|
const gangs = useFrameworkGroups((s) => s.gangs);
|
|
6067
|
+
React4.useEffect(() => {
|
|
6068
|
+
ensureFrameworkGroups();
|
|
6069
|
+
}, []);
|
|
5587
6070
|
const inCompound = ctx !== null;
|
|
5588
6071
|
const currentValue = inCompound ? ctx.value.name : props.value;
|
|
5589
6072
|
const filterType = inCompound ? ctx.type : props.type;
|
|
@@ -5617,12 +6100,15 @@ function GroupName(props) {
|
|
|
5617
6100
|
);
|
|
5618
6101
|
}
|
|
5619
6102
|
function GroupRank(props) {
|
|
5620
|
-
const ctx =
|
|
6103
|
+
const ctx = React4.useContext(GroupSelectContext);
|
|
5621
6104
|
if (ctx === null) {
|
|
5622
6105
|
throw new Error("<GroupRank> must be a child of <GroupSelect>");
|
|
5623
6106
|
}
|
|
5624
6107
|
const jobs = useFrameworkGroups((s) => s.jobs);
|
|
5625
6108
|
const gangs = useFrameworkGroups((s) => s.gangs);
|
|
6109
|
+
React4.useEffect(() => {
|
|
6110
|
+
ensureFrameworkGroups();
|
|
6111
|
+
}, []);
|
|
5626
6112
|
const all = [...jobs, ...gangs];
|
|
5627
6113
|
const selectedGroup = all.find((g) => g.name === ctx.value.name) ?? null;
|
|
5628
6114
|
const grades = selectedGroup?.grades ?? [];
|
|
@@ -5653,9 +6139,9 @@ function GroupRank(props) {
|
|
|
5653
6139
|
}
|
|
5654
6140
|
GroupSelect.Name = GroupName;
|
|
5655
6141
|
GroupSelect.Rank = GroupRank;
|
|
5656
|
-
var KeyBindContext =
|
|
6142
|
+
var KeyBindContext = React4.createContext(null);
|
|
5657
6143
|
function useKeyBindContext() {
|
|
5658
|
-
const ctx =
|
|
6144
|
+
const ctx = React4.useContext(KeyBindContext);
|
|
5659
6145
|
if (!ctx) {
|
|
5660
6146
|
throw new Error("FiveMKeyBindInput.* must be used inside <FiveMKeyBindInput>");
|
|
5661
6147
|
}
|
|
@@ -5814,7 +6300,7 @@ function AsyncSaveButton({
|
|
|
5814
6300
|
style
|
|
5815
6301
|
}) {
|
|
5816
6302
|
const theme2 = core.useMantineTheme();
|
|
5817
|
-
const [state, setState] =
|
|
6303
|
+
const [state, setState] = React4.useState("idle");
|
|
5818
6304
|
const handleClick = async () => {
|
|
5819
6305
|
if (state === "pending") return;
|
|
5820
6306
|
setState("pending");
|
|
@@ -5954,10 +6440,10 @@ function TestBed({
|
|
|
5954
6440
|
title = "TestBed",
|
|
5955
6441
|
placement = "top-left"
|
|
5956
6442
|
}) {
|
|
5957
|
-
const [open, setOpen] =
|
|
5958
|
-
const itemsRef =
|
|
6443
|
+
const [open, setOpen] = React4.useState(false);
|
|
6444
|
+
const itemsRef = React4.useRef(items);
|
|
5959
6445
|
itemsRef.current = items;
|
|
5960
|
-
|
|
6446
|
+
React4.useEffect(() => {
|
|
5961
6447
|
if (!isEnvBrowser() || disablePersistence) return;
|
|
5962
6448
|
const persisted = loadPersistedState(storageKey);
|
|
5963
6449
|
itemsRef.current.forEach((item) => {
|
|
@@ -6294,7 +6780,7 @@ function SwatchTile({
|
|
|
6294
6780
|
isPrimary,
|
|
6295
6781
|
onChange
|
|
6296
6782
|
}) {
|
|
6297
|
-
const [opened, setOpened] =
|
|
6783
|
+
const [opened, setOpened] = React4.useState(false);
|
|
6298
6784
|
return /* @__PURE__ */ jsxRuntime.jsxs(core.Popover, { opened, onChange: setOpened, position: "bottom", withArrow: true, zIndex: 1e4, children: [
|
|
6299
6785
|
/* @__PURE__ */ jsxRuntime.jsx(core.Popover.Target, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6300
6786
|
"button",
|
|
@@ -6964,9 +7450,9 @@ var NOT_CONFIGURED_TINT = "rgba(255,184,0,0.35)";
|
|
|
6964
7450
|
var NOT_CONFIGURED_FILL = "rgba(255,184,0,0.05)";
|
|
6965
7451
|
function DiscordRoleSelect(props) {
|
|
6966
7452
|
const { endpoint, label: label2, size = "xs", placeholder, disabled, style, styles } = props;
|
|
6967
|
-
const [roles, setRoles] =
|
|
6968
|
-
const [loading, setLoading] =
|
|
6969
|
-
const [errorCode, setErrorCode] =
|
|
7453
|
+
const [roles, setRoles] = React4.useState(null);
|
|
7454
|
+
const [loading, setLoading] = React4.useState(false);
|
|
7455
|
+
const [errorCode, setErrorCode] = React4.useState(null);
|
|
6970
7456
|
const refresh = async () => {
|
|
6971
7457
|
setLoading(true);
|
|
6972
7458
|
try {
|
|
@@ -6992,10 +7478,10 @@ function DiscordRoleSelect(props) {
|
|
|
6992
7478
|
setLoading(false);
|
|
6993
7479
|
}
|
|
6994
7480
|
};
|
|
6995
|
-
|
|
7481
|
+
React4.useEffect(() => {
|
|
6996
7482
|
refresh();
|
|
6997
7483
|
}, [endpoint]);
|
|
6998
|
-
const rolesById =
|
|
7484
|
+
const rolesById = React4.useMemo(() => {
|
|
6999
7485
|
const map = {};
|
|
7000
7486
|
for (const r of roles ?? []) map[r.id] = r;
|
|
7001
7487
|
return map;
|
|
@@ -7161,9 +7647,9 @@ function FrameworkHint({ framework }) {
|
|
|
7161
7647
|
}
|
|
7162
7648
|
function AccountSelect(props) {
|
|
7163
7649
|
const { endpoint, label: label2, size = "xs", placeholder, disabled, style, styles, hideFrameworkHint } = props;
|
|
7164
|
-
const [accounts, setAccounts] =
|
|
7165
|
-
const [framework, setFramework] =
|
|
7166
|
-
const [loading, setLoading] =
|
|
7650
|
+
const [accounts, setAccounts] = React4.useState(null);
|
|
7651
|
+
const [framework, setFramework] = React4.useState(void 0);
|
|
7652
|
+
const [loading, setLoading] = React4.useState(false);
|
|
7167
7653
|
const refresh = async () => {
|
|
7168
7654
|
setLoading(true);
|
|
7169
7655
|
try {
|
|
@@ -7188,10 +7674,10 @@ function AccountSelect(props) {
|
|
|
7188
7674
|
setLoading(false);
|
|
7189
7675
|
}
|
|
7190
7676
|
};
|
|
7191
|
-
|
|
7677
|
+
React4.useEffect(() => {
|
|
7192
7678
|
refresh();
|
|
7193
7679
|
}, [endpoint]);
|
|
7194
|
-
const accountsByName =
|
|
7680
|
+
const accountsByName = React4.useMemo(() => {
|
|
7195
7681
|
const map = {};
|
|
7196
7682
|
for (const a of accounts ?? []) map[a.name] = a;
|
|
7197
7683
|
if (props.multi) {
|
|
@@ -7268,349 +7754,831 @@ function AccountSelect(props) {
|
|
|
7268
7754
|
!hideFrameworkHint && /* @__PURE__ */ jsxRuntime.jsx(FrameworkHint, { framework })
|
|
7269
7755
|
] });
|
|
7270
7756
|
}
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7757
|
+
var BODY_HIDE_STYLE_ID2 = "dirk-instruction-panel-style";
|
|
7758
|
+
var BODY_HIDE_ATTR2 = "data-dirk-instruction-active";
|
|
7759
|
+
var OVERLAY_ATTR2 = "data-dirk-instruction-overlay";
|
|
7760
|
+
function ensureBodyHideStyle2() {
|
|
7761
|
+
if (document.getElementById(BODY_HIDE_STYLE_ID2)) return;
|
|
7762
|
+
const el = document.createElement("style");
|
|
7763
|
+
el.id = BODY_HIDE_STYLE_ID2;
|
|
7764
|
+
el.textContent = `
|
|
7765
|
+
body[${BODY_HIDE_ATTR2}] > *:not([${OVERLAY_ATTR2}]) {
|
|
7766
|
+
visibility: hidden !important;
|
|
7767
|
+
opacity: 0 !important;
|
|
7768
|
+
pointer-events: none !important;
|
|
7769
|
+
}
|
|
7770
|
+
`;
|
|
7771
|
+
document.head.appendChild(el);
|
|
7274
7772
|
}
|
|
7275
|
-
function
|
|
7773
|
+
function InstructionPanel({
|
|
7774
|
+
visible,
|
|
7775
|
+
title,
|
|
7776
|
+
hint,
|
|
7777
|
+
keys,
|
|
7778
|
+
icon: Icon = lucideReact.MapPin,
|
|
7779
|
+
hideRestOfAdmin = true
|
|
7780
|
+
}) {
|
|
7781
|
+
const theme2 = core.useMantineTheme();
|
|
7782
|
+
const pc = theme2.colors[theme2.primaryColor];
|
|
7783
|
+
React4.useEffect(() => {
|
|
7784
|
+
if (!visible || !hideRestOfAdmin) return;
|
|
7785
|
+
ensureBodyHideStyle2();
|
|
7786
|
+
document.body.setAttribute(BODY_HIDE_ATTR2, "");
|
|
7787
|
+
return () => {
|
|
7788
|
+
document.body.removeAttribute(BODY_HIDE_ATTR2);
|
|
7789
|
+
};
|
|
7790
|
+
}, [visible, hideRestOfAdmin]);
|
|
7791
|
+
if (!visible) return null;
|
|
7792
|
+
return reactDom.createPortal(
|
|
7793
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7794
|
+
"div",
|
|
7795
|
+
{
|
|
7796
|
+
...{ [OVERLAY_ATTR2]: "" },
|
|
7797
|
+
style: { position: "fixed", inset: 0, pointerEvents: "none", zIndex: 1e4 },
|
|
7798
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7799
|
+
framerMotion.motion.div,
|
|
7800
|
+
{
|
|
7801
|
+
initial: { opacity: 0, y: 12, scale: 0.92 },
|
|
7802
|
+
animate: { opacity: 1, y: 0, scale: 1 },
|
|
7803
|
+
exit: { opacity: 0, y: 12, scale: 0.92 },
|
|
7804
|
+
transition: { duration: 0.25, ease: "easeInOut" },
|
|
7805
|
+
style: { position: "absolute", bottom: "3vh", right: "3vh", userSelect: "none" },
|
|
7806
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7807
|
+
core.Flex,
|
|
7808
|
+
{
|
|
7809
|
+
direction: "column",
|
|
7810
|
+
gap: "0.8vh",
|
|
7811
|
+
style: {
|
|
7812
|
+
background: core.alpha(theme2.colors.dark[9], 0.55),
|
|
7813
|
+
border: "0.1vh solid rgba(255,255,255,0.07)",
|
|
7814
|
+
borderRadius: theme2.radius.sm,
|
|
7815
|
+
boxShadow: "0 0.74vh 2.96vh rgba(0,0,0,0.5)",
|
|
7816
|
+
padding: "1.4vh 1.6vh",
|
|
7817
|
+
minWidth: "22vh",
|
|
7818
|
+
maxWidth: "28vh"
|
|
7819
|
+
},
|
|
7820
|
+
children: [
|
|
7821
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "0.6vh", children: [
|
|
7822
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "1.6vh", color: pc[6], strokeWidth: 2.5 }),
|
|
7823
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7824
|
+
core.Text,
|
|
7825
|
+
{
|
|
7826
|
+
style: {
|
|
7827
|
+
fontFamily: "Akrobat Bold, sans-serif",
|
|
7828
|
+
fontSize: "1.7vh",
|
|
7829
|
+
fontWeight: 700,
|
|
7830
|
+
letterSpacing: "0.14em",
|
|
7831
|
+
textTransform: "uppercase",
|
|
7832
|
+
color: pc[6],
|
|
7833
|
+
textShadow: `0 0 0.8vh ${core.alpha(pc[7], 0.5)}, 0 0 1.6vh ${core.alpha(pc[9], 0.3)}`
|
|
7834
|
+
},
|
|
7835
|
+
children: title
|
|
7836
|
+
}
|
|
7837
|
+
)
|
|
7838
|
+
] }),
|
|
7839
|
+
(hint || keys && keys.length > 0) && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "0.1vh", background: "rgba(255,255,255,0.06)", margin: "0.1vh 0" } }),
|
|
7840
|
+
hint && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7841
|
+
core.Text,
|
|
7842
|
+
{
|
|
7843
|
+
style: {
|
|
7844
|
+
fontFamily: "Akrobat Bold, sans-serif",
|
|
7845
|
+
fontSize: "1.05vh",
|
|
7846
|
+
color: "rgba(255,255,255,0.45)",
|
|
7847
|
+
letterSpacing: "0.06em",
|
|
7848
|
+
textTransform: "uppercase",
|
|
7849
|
+
lineHeight: 1.4
|
|
7850
|
+
},
|
|
7851
|
+
children: hint
|
|
7852
|
+
}
|
|
7853
|
+
),
|
|
7854
|
+
keys && keys.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7855
|
+
hint && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "0.1vh", background: "rgba(255,255,255,0.06)", margin: "0.1vh 0" } }),
|
|
7856
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Flex, { direction: "column", gap: "0.5vh", children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsx(InstructionKeyRow, { keyLabel: k.key, action: k.action }, i)) })
|
|
7857
|
+
] })
|
|
7858
|
+
]
|
|
7859
|
+
}
|
|
7860
|
+
)
|
|
7861
|
+
},
|
|
7862
|
+
"instruction-card"
|
|
7863
|
+
) })
|
|
7864
|
+
}
|
|
7865
|
+
),
|
|
7866
|
+
document.body
|
|
7867
|
+
);
|
|
7868
|
+
}
|
|
7869
|
+
function renderKeyContent(keyLabel) {
|
|
7870
|
+
const normalized = keyLabel.trim().toUpperCase();
|
|
7871
|
+
if (normalized === "LMB") return /* @__PURE__ */ jsxRuntime.jsx(MouseIcon, { side: "left" });
|
|
7872
|
+
if (normalized === "RMB") return /* @__PURE__ */ jsxRuntime.jsx(MouseIcon, { side: "right" });
|
|
7873
|
+
if (normalized === "BACKSPACE" || keyLabel === "\u232B") return /* @__PURE__ */ jsxRuntime.jsx(BackspaceIcon, {});
|
|
7276
7874
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7277
|
-
|
|
7875
|
+
core.Text,
|
|
7278
7876
|
{
|
|
7279
|
-
style: {
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
numOctaves: "5",
|
|
7288
|
-
seed: "9",
|
|
7289
|
-
result: "noise1"
|
|
7290
|
-
}
|
|
7291
|
-
),
|
|
7292
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7293
|
-
"feTurbulence",
|
|
7294
|
-
{
|
|
7295
|
-
type: "fractalNoise",
|
|
7296
|
-
baseFrequency: "0.08 0.12",
|
|
7297
|
-
numOctaves: "2",
|
|
7298
|
-
seed: "3",
|
|
7299
|
-
result: "noise2"
|
|
7300
|
-
}
|
|
7301
|
-
),
|
|
7302
|
-
/* @__PURE__ */ jsxRuntime.jsx("feBlend", { in: "noise1", in2: "noise2", mode: "multiply", result: "combinedNoise" }),
|
|
7303
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7304
|
-
"feDisplacementMap",
|
|
7305
|
-
{
|
|
7306
|
-
in: "SourceGraphic",
|
|
7307
|
-
in2: "combinedNoise",
|
|
7308
|
-
scale: "52",
|
|
7309
|
-
xChannelSelector: "R",
|
|
7310
|
-
yChannelSelector: "G",
|
|
7311
|
-
result: "displaced"
|
|
7312
|
-
}
|
|
7313
|
-
),
|
|
7314
|
-
/* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "0.8", in: "displaced", result: "blurred" }),
|
|
7315
|
-
/* @__PURE__ */ jsxRuntime.jsx("feComponentTransfer", { in: "blurred", result: "alphaFade", children: /* @__PURE__ */ jsxRuntime.jsx("feFuncA", { type: "gamma", amplitude: "1", exponent: "1.3", offset: "-0.05" }) }),
|
|
7316
|
-
/* @__PURE__ */ jsxRuntime.jsx("feMorphology", { operator: "erode", radius: "0.4", in: "alphaFade", result: "eroded" }),
|
|
7317
|
-
/* @__PURE__ */ jsxRuntime.jsx("feMerge", { children: /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "eroded" }) })
|
|
7318
|
-
] }) })
|
|
7877
|
+
style: {
|
|
7878
|
+
fontFamily: "Akrobat Bold, sans-serif",
|
|
7879
|
+
fontSize: "1.2vh",
|
|
7880
|
+
color: "rgba(255,255,255,0.85)",
|
|
7881
|
+
lineHeight: 1,
|
|
7882
|
+
padding: "0 0.3vh"
|
|
7883
|
+
},
|
|
7884
|
+
children: keyLabel
|
|
7319
7885
|
}
|
|
7320
7886
|
);
|
|
7321
7887
|
}
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
sm: "0.75vh",
|
|
7357
|
-
md: "1vh",
|
|
7358
|
-
lg: "1.5vh",
|
|
7359
|
-
xl: "2vh",
|
|
7360
|
-
xxl: "3vh"
|
|
7361
|
-
},
|
|
7362
|
-
fontSizes: {
|
|
7363
|
-
xxs: "1.2vh",
|
|
7364
|
-
xs: "1.5vh",
|
|
7365
|
-
sm: "1.8vh",
|
|
7366
|
-
md: "2.2vh",
|
|
7367
|
-
lg: "2.8vh",
|
|
7368
|
-
xl: "3.3vh",
|
|
7369
|
-
xxl: "3.8vh"
|
|
7370
|
-
},
|
|
7371
|
-
lineHeights: {
|
|
7372
|
-
xxs: "1.4vh",
|
|
7373
|
-
xs: "1.8vh",
|
|
7374
|
-
sm: "2.2vh",
|
|
7375
|
-
md: "2.8vh",
|
|
7376
|
-
lg: "3.3vh",
|
|
7377
|
-
xl: "3.8vh"
|
|
7378
|
-
},
|
|
7379
|
-
spacing: {
|
|
7380
|
-
xxs: "0.5vh",
|
|
7381
|
-
xs: "0.75vh",
|
|
7382
|
-
sm: "1.5vh",
|
|
7383
|
-
md: "2vh",
|
|
7384
|
-
lg: "3vh",
|
|
7385
|
-
xl: "4vh",
|
|
7386
|
-
xxl: "5vh"
|
|
7387
|
-
},
|
|
7388
|
-
components: {
|
|
7389
|
-
Progress: {
|
|
7390
|
-
styles: {
|
|
7391
|
-
label: {
|
|
7392
|
-
fontFamily: "Akrobat Bold",
|
|
7393
|
-
letterSpacing: "0.05em",
|
|
7888
|
+
function InstructionKeyRow({ keyLabel, action }) {
|
|
7889
|
+
const normalized = keyLabel.trim().toUpperCase();
|
|
7890
|
+
const isIconKey = normalized === "LMB" || normalized === "RMB" || normalized === "BACKSPACE" || keyLabel === "\u232B";
|
|
7891
|
+
const minWidth = isIconKey ? "2.6vh" : "2.4vh";
|
|
7892
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "0.6vh", children: [
|
|
7893
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7894
|
+
"div",
|
|
7895
|
+
{
|
|
7896
|
+
style: {
|
|
7897
|
+
minWidth,
|
|
7898
|
+
height: "2.4vh",
|
|
7899
|
+
padding: "0 0.4vh",
|
|
7900
|
+
borderRadius: "0.3vh",
|
|
7901
|
+
border: "0.15vh solid rgba(255,255,255,0.35)",
|
|
7902
|
+
background: "rgba(255,255,255,0.06)",
|
|
7903
|
+
display: "flex",
|
|
7904
|
+
alignItems: "center",
|
|
7905
|
+
justifyContent: "center",
|
|
7906
|
+
opacity: 0.85,
|
|
7907
|
+
filter: "drop-shadow(0 0 0.3vh rgba(0,0,0,0.5))",
|
|
7908
|
+
flexShrink: 0,
|
|
7909
|
+
boxSizing: "border-box"
|
|
7910
|
+
},
|
|
7911
|
+
children: renderKeyContent(keyLabel)
|
|
7912
|
+
}
|
|
7913
|
+
),
|
|
7914
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7915
|
+
core.Text,
|
|
7916
|
+
{
|
|
7917
|
+
style: {
|
|
7918
|
+
fontFamily: "Akrobat Bold, sans-serif",
|
|
7919
|
+
fontSize: "1.05vh",
|
|
7920
|
+
color: "rgba(255,255,255,0.45)",
|
|
7921
|
+
letterSpacing: "0.06em",
|
|
7394
7922
|
textTransform: "uppercase"
|
|
7395
7923
|
},
|
|
7396
|
-
|
|
7397
|
-
backgroundColor: "rgba(77, 77, 77, 0.4)"
|
|
7398
|
-
}
|
|
7924
|
+
children: action
|
|
7399
7925
|
}
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7926
|
+
)
|
|
7927
|
+
] });
|
|
7928
|
+
}
|
|
7929
|
+
function MouseIcon({ side }) {
|
|
7930
|
+
const stroke = "rgba(255,255,255,0.85)";
|
|
7931
|
+
const fillActive = "rgba(255,255,255,0.85)";
|
|
7932
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 16 22", width: "1.4vh", height: "1.9vh", fill: "none", stroke, strokeWidth: "1.4", strokeLinejoin: "round", children: [
|
|
7933
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "1", y: "1", width: "14", height: "20", rx: "6" }),
|
|
7934
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "8", y1: "1", x2: "8", y2: "9" }),
|
|
7935
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7936
|
+
"path",
|
|
7937
|
+
{
|
|
7938
|
+
d: side === "left" ? "M 7.4 1.6 L 2 1.6 A 5 5 0 0 0 1 6 L 1 9 L 7.4 9 Z" : "M 8.6 1.6 L 14 1.6 A 5 5 0 0 1 15 6 L 15 9 L 8.6 9 Z",
|
|
7939
|
+
fill: fillActive,
|
|
7940
|
+
stroke: "none"
|
|
7941
|
+
}
|
|
7942
|
+
)
|
|
7943
|
+
] });
|
|
7944
|
+
}
|
|
7945
|
+
function BackspaceIcon() {
|
|
7946
|
+
const stroke = "rgba(255,255,255,0.85)";
|
|
7947
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 22 16", width: "1.7vh", height: "1.3vh", fill: "none", stroke, strokeWidth: "1.4", strokeLinejoin: "round", strokeLinecap: "round", children: [
|
|
7948
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M 21 2 L 8 2 L 2 8 L 8 14 L 21 14 Z" }),
|
|
7949
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "11", y1: "6", x2: "16", y2: "11" }),
|
|
7950
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "6", x2: "11", y2: "11" })
|
|
7951
|
+
] });
|
|
7952
|
+
}
|
|
7953
|
+
function WorldPositionPicker({ value, onChange, compact, setOnly, gotoOnly }) {
|
|
7954
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7955
|
+
!gotoOnly && /* @__PURE__ */ jsxRuntime.jsx(WorldPositionSetButton2, { value, onChange, compact }),
|
|
7956
|
+
!setOnly && /* @__PURE__ */ jsxRuntime.jsx(WorldPositionGotoButton2, { value, compact })
|
|
7957
|
+
] });
|
|
7958
|
+
}
|
|
7959
|
+
function WorldPositionSetButton2({
|
|
7960
|
+
value,
|
|
7961
|
+
onChange,
|
|
7962
|
+
compact
|
|
7963
|
+
}) {
|
|
7964
|
+
const theme2 = core.useMantineTheme();
|
|
7965
|
+
const color = theme2.colors[theme2.primaryColor][5];
|
|
7966
|
+
const begin = useAdminToolStore((s) => s.begin);
|
|
7967
|
+
const onClick = async () => {
|
|
7968
|
+
const instructions = {
|
|
7969
|
+
title: locale("PickPositionTitle") || "Pick Position",
|
|
7970
|
+
hint: locale("PickPositionHint") || "Walk to where you want this set",
|
|
7971
|
+
keys: [
|
|
7972
|
+
{ key: "E", action: locale("Set") || "Set" },
|
|
7973
|
+
{ key: "\u232B", action: locale("Cancel") || "Cancel" }
|
|
7974
|
+
]
|
|
7975
|
+
};
|
|
7976
|
+
const pendingResult = begin({ id: "capturePosition", ...instructions });
|
|
7977
|
+
fetchNui("ADMIN_TOOL_BEGIN", { id: "capturePosition", instructions }).catch(() => {
|
|
7978
|
+
useAdminToolStore.getState().cancelActive();
|
|
7979
|
+
});
|
|
7980
|
+
const result = await pendingResult;
|
|
7981
|
+
if (result) onChange(result);
|
|
7982
|
+
};
|
|
7983
|
+
return /* @__PURE__ */ jsxRuntime.jsx(core.Tooltip, { label: locale("SetWorldTooltip"), position: "top", withArrow: true, withinPortal: true, zIndex: 2e3, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7984
|
+
framerMotion.motion.button,
|
|
7985
|
+
{
|
|
7986
|
+
onClick,
|
|
7987
|
+
whileHover: { background: core.alpha(color, 0.18) },
|
|
7988
|
+
whileTap: { scale: 0.95 },
|
|
7989
|
+
style: {
|
|
7990
|
+
background: core.alpha(color, 0.1),
|
|
7991
|
+
border: `0.1vh solid ${core.alpha(color, 0.35)}`,
|
|
7992
|
+
borderRadius: theme2.radius.xs,
|
|
7993
|
+
padding: compact ? "0.25vh 0.6vh" : "0.5vh 0.8vh",
|
|
7994
|
+
cursor: "pointer",
|
|
7995
|
+
display: "flex",
|
|
7996
|
+
alignItems: "center",
|
|
7997
|
+
gap: compact ? "0.3vh" : "0.4vh"
|
|
7998
|
+
},
|
|
7999
|
+
children: [
|
|
8000
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Crosshair, { size: compact ? "1.1vh" : "1.3vh", color }),
|
|
8001
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: locale("Set") })
|
|
8002
|
+
]
|
|
7426
8003
|
}
|
|
7427
|
-
}
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
8004
|
+
) });
|
|
8005
|
+
}
|
|
8006
|
+
function WorldPositionGotoButton2({
|
|
8007
|
+
value,
|
|
8008
|
+
compact
|
|
8009
|
+
}) {
|
|
8010
|
+
const theme2 = core.useMantineTheme();
|
|
8011
|
+
const color = theme2.colors[theme2.primaryColor][5];
|
|
8012
|
+
const onClick = () => {
|
|
8013
|
+
fetchNui("ADMIN_TOOL_INVOKE", { id: "gotoCoord", value }).catch(() => {
|
|
8014
|
+
});
|
|
8015
|
+
};
|
|
8016
|
+
return /* @__PURE__ */ jsxRuntime.jsx(core.Tooltip, { label: locale("GotoWorldTooltip"), position: "top", withArrow: true, withinPortal: true, zIndex: 2e3, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8017
|
+
framerMotion.motion.button,
|
|
8018
|
+
{
|
|
8019
|
+
onClick,
|
|
8020
|
+
whileHover: { background: core.alpha(color, 0.18) },
|
|
8021
|
+
whileTap: { scale: 0.95 },
|
|
8022
|
+
style: {
|
|
8023
|
+
background: core.alpha(color, 0.1),
|
|
8024
|
+
border: `0.1vh solid ${core.alpha(color, 0.35)}`,
|
|
8025
|
+
borderRadius: theme2.radius.xs,
|
|
8026
|
+
padding: compact ? "0.25vh 0.6vh" : "0.5vh 0.8vh",
|
|
8027
|
+
cursor: "pointer",
|
|
8028
|
+
display: "flex",
|
|
8029
|
+
alignItems: "center",
|
|
8030
|
+
gap: compact ? "0.3vh" : "0.4vh"
|
|
8031
|
+
},
|
|
8032
|
+
children: [
|
|
8033
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPin, { size: compact ? "1.1vh" : "1.3vh", color }),
|
|
8034
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: locale("Goto") })
|
|
8035
|
+
]
|
|
7455
8036
|
}
|
|
7456
|
-
}
|
|
8037
|
+
) });
|
|
8038
|
+
}
|
|
8039
|
+
function usePlayers(opts = {}) {
|
|
8040
|
+
const {
|
|
8041
|
+
includeOffline = false,
|
|
8042
|
+
search = "",
|
|
8043
|
+
limit = 50,
|
|
8044
|
+
staleTimeMs,
|
|
8045
|
+
refetchIntervalMs
|
|
8046
|
+
} = opts;
|
|
8047
|
+
const query = reactQuery.useQuery({
|
|
8048
|
+
queryKey: includeOffline ? ["dirk:players", "search", search.trim().toLowerCase(), limit] : ["dirk:players", "online"],
|
|
8049
|
+
queryFn: async () => {
|
|
8050
|
+
const toolId = includeOffline ? "searchPlayers" : "getOnlinePlayers";
|
|
8051
|
+
const payload = includeOffline ? { id: toolId, value: { search: search.trim(), limit } } : { id: toolId };
|
|
8052
|
+
const result = await fetchNui(
|
|
8053
|
+
"ADMIN_TOOL_QUERY",
|
|
8054
|
+
payload,
|
|
8055
|
+
// Browser-dev fallback. Returns a couple of mock players so the
|
|
8056
|
+
// dev shell isn't blank.
|
|
8057
|
+
includeOffline ? [
|
|
8058
|
+
{ id: 1, citizenId: "ABC12345", name: "Dev User", charName: "John Doe", online: true },
|
|
8059
|
+
{ id: null, citizenId: "DEF67890", name: "", charName: "Jane Offline", online: false }
|
|
8060
|
+
] : [
|
|
8061
|
+
{ id: 1, citizenId: "ABC12345", name: "Dev User", charName: "John Doe", online: true }
|
|
8062
|
+
]
|
|
8063
|
+
);
|
|
8064
|
+
return Array.isArray(result) ? result : [];
|
|
8065
|
+
},
|
|
8066
|
+
staleTime: staleTimeMs ?? (includeOffline ? 3e4 : 5e3),
|
|
8067
|
+
gcTime: 5 * 6e4,
|
|
8068
|
+
refetchInterval: refetchIntervalMs ?? false,
|
|
8069
|
+
refetchOnWindowFocus: false,
|
|
8070
|
+
placeholderData: includeOffline ? reactQuery.keepPreviousData : void 0
|
|
8071
|
+
});
|
|
7457
8072
|
return {
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
8073
|
+
players: query.data ?? [],
|
|
8074
|
+
isLoading: query.isLoading,
|
|
8075
|
+
isFetching: query.isFetching,
|
|
8076
|
+
error: query.error ?? null,
|
|
8077
|
+
refresh: () => query.refetch()
|
|
8078
|
+
};
|
|
8079
|
+
}
|
|
8080
|
+
var DEBOUNCE_MS = 300;
|
|
8081
|
+
var ONLINE_COLOR = "#3FA83F";
|
|
8082
|
+
var OFFLINE_COLOR = "#E54141";
|
|
8083
|
+
function PlayerSelect({
|
|
8084
|
+
value,
|
|
8085
|
+
onChange,
|
|
8086
|
+
includeOffline = false,
|
|
8087
|
+
limit = 50,
|
|
8088
|
+
searchable: searchableProp,
|
|
8089
|
+
placeholder,
|
|
8090
|
+
nothingFoundMessage: nothingFoundMessageProp,
|
|
8091
|
+
loadingLabel = "Loading\u2026",
|
|
8092
|
+
onlineLabel = "Online",
|
|
8093
|
+
offlineLabel = "Offline",
|
|
8094
|
+
refreshLabel = "Refresh player list",
|
|
8095
|
+
...rest
|
|
8096
|
+
}) {
|
|
8097
|
+
const theme2 = core.useMantineTheme();
|
|
8098
|
+
const color = theme2.colors[theme2.primaryColor][5];
|
|
8099
|
+
const [searchInput, setSearchInput] = React4.useState("");
|
|
8100
|
+
const [debouncedSearch, setDebouncedSearch] = React4.useState("");
|
|
8101
|
+
const { players, isFetching, refresh } = usePlayers({
|
|
8102
|
+
includeOffline,
|
|
8103
|
+
search: includeOffline ? debouncedSearch : void 0,
|
|
8104
|
+
limit
|
|
8105
|
+
});
|
|
8106
|
+
const sortedPlayers = React4.useMemo(
|
|
8107
|
+
() => [...players].sort((a, b) => {
|
|
8108
|
+
if (a.online !== b.online) return a.online ? -1 : 1;
|
|
8109
|
+
return a.charName.localeCompare(b.charName);
|
|
8110
|
+
}),
|
|
8111
|
+
[players]
|
|
8112
|
+
);
|
|
8113
|
+
const playerByCitizen = React4.useMemo(() => {
|
|
8114
|
+
const m = /* @__PURE__ */ new Map();
|
|
8115
|
+
for (const p of sortedPlayers) m.set(p.citizenId, p);
|
|
8116
|
+
return m;
|
|
8117
|
+
}, [sortedPlayers]);
|
|
8118
|
+
const data = React4.useMemo(() => {
|
|
8119
|
+
const items = sortedPlayers.map((p) => ({
|
|
8120
|
+
value: p.citizenId,
|
|
8121
|
+
label: formatLabel(p)
|
|
8122
|
+
}));
|
|
8123
|
+
if (value && !items.some((i) => i.value === value)) {
|
|
8124
|
+
items.unshift({ value, label: value });
|
|
7463
8125
|
}
|
|
8126
|
+
return items;
|
|
8127
|
+
}, [sortedPlayers, value]);
|
|
8128
|
+
const selectedPlayer = value ? playerByCitizen.get(value) ?? null : null;
|
|
8129
|
+
const selectedLabel = selectedPlayer ? formatLabel(selectedPlayer) : null;
|
|
8130
|
+
React4.useEffect(() => {
|
|
8131
|
+
if (!includeOffline) return;
|
|
8132
|
+
if (selectedLabel && searchInput === selectedLabel) return;
|
|
8133
|
+
const t3 = setTimeout(() => setDebouncedSearch(searchInput), DEBOUNCE_MS);
|
|
8134
|
+
return () => clearTimeout(t3);
|
|
8135
|
+
}, [searchInput, includeOffline, selectedLabel]);
|
|
8136
|
+
const renderOption = ({ option }) => {
|
|
8137
|
+
const p = playerByCitizen.get(option.value);
|
|
8138
|
+
if (!p) return option.label;
|
|
8139
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(core.Group, { justify: "space-between", wrap: "nowrap", gap: "xs", style: { width: "100%" }, children: [
|
|
8140
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xs", truncate: true, style: { flex: 1 }, children: formatLabel(p) }),
|
|
8141
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusDot, { online: p.online, onlineLabel, offlineLabel })
|
|
8142
|
+
] });
|
|
7464
8143
|
};
|
|
8144
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8145
|
+
core.Select,
|
|
8146
|
+
{
|
|
8147
|
+
...rest,
|
|
8148
|
+
data,
|
|
8149
|
+
value: value ?? null,
|
|
8150
|
+
onChange: (v) => {
|
|
8151
|
+
if (!v) return onChange(null);
|
|
8152
|
+
const player = playerByCitizen.get(v) ?? null;
|
|
8153
|
+
onChange(player);
|
|
8154
|
+
},
|
|
8155
|
+
searchable: searchableProp ?? true,
|
|
8156
|
+
searchValue: includeOffline ? searchInput : void 0,
|
|
8157
|
+
onSearchChange: includeOffline ? setSearchInput : void 0,
|
|
8158
|
+
placeholder,
|
|
8159
|
+
nothingFoundMessage: isFetching ? loadingLabel : nothingFoundMessageProp ?? "No players found",
|
|
8160
|
+
maxDropdownHeight: 300,
|
|
8161
|
+
renderOption,
|
|
8162
|
+
leftSection: selectedPlayer ? /* @__PURE__ */ jsxRuntime.jsx(StatusDot, { online: selectedPlayer.online, onlineLabel, offlineLabel }) : void 0,
|
|
8163
|
+
rightSectionWidth: "3.5vh",
|
|
8164
|
+
rightSectionPointerEvents: "all",
|
|
8165
|
+
rightSection: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8166
|
+
core.ActionIcon,
|
|
8167
|
+
{
|
|
8168
|
+
variant: "subtle",
|
|
8169
|
+
size: "sm",
|
|
8170
|
+
onClick: (e) => {
|
|
8171
|
+
e.stopPropagation();
|
|
8172
|
+
refresh();
|
|
8173
|
+
},
|
|
8174
|
+
"aria-label": refreshLabel,
|
|
8175
|
+
title: refreshLabel,
|
|
8176
|
+
style: { marginRight: "0.6vh" },
|
|
8177
|
+
children: isFetching ? /* @__PURE__ */ jsxRuntime.jsx(core.Loader, { size: "1.2vh", color }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { size: "1.4vh", color })
|
|
8178
|
+
}
|
|
8179
|
+
)
|
|
8180
|
+
}
|
|
8181
|
+
);
|
|
7465
8182
|
}
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
}
|
|
7480
|
-
render() {
|
|
7481
|
-
if (!this.state.error) return this.props.children;
|
|
7482
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7483
|
-
core.Box,
|
|
7484
|
-
{
|
|
7485
|
-
style: {
|
|
7486
|
-
position: "fixed",
|
|
7487
|
-
inset: 0,
|
|
7488
|
-
width: "100vw",
|
|
7489
|
-
height: "100vh",
|
|
7490
|
-
background: "rgba(10, 10, 12, 0.92)",
|
|
7491
|
-
display: "flex",
|
|
7492
|
-
alignItems: "center",
|
|
7493
|
-
justifyContent: "center",
|
|
7494
|
-
padding: "2rem",
|
|
7495
|
-
zIndex: 999999
|
|
7496
|
-
},
|
|
7497
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7498
|
-
core.Box,
|
|
7499
|
-
{
|
|
7500
|
-
maw: 900,
|
|
7501
|
-
w: "100%",
|
|
7502
|
-
p: "lg",
|
|
7503
|
-
style: {
|
|
7504
|
-
background: "rgba(20,20,24,0.75)",
|
|
7505
|
-
border: "1px solid rgba(255,255,255,0.08)",
|
|
7506
|
-
borderRadius: "10px",
|
|
7507
|
-
boxShadow: "0 10px 40px rgba(0,0,0,0.6)"
|
|
7508
|
-
},
|
|
7509
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(core.Stack, { gap: "sm", children: [
|
|
7510
|
-
/* @__PURE__ */ jsxRuntime.jsx(core.Title, { order: 2, c: "red.5", children: "Dirk UI Crash" }),
|
|
7511
|
-
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { c: "dimmed", size: "sm", children: "The interface encountered a fatal error and stopped rendering." }),
|
|
7512
|
-
/* @__PURE__ */ jsxRuntime.jsx(core.Code, { block: true, style: { maxHeight: 150, overflow: "auto" }, children: this.state.error?.message }),
|
|
7513
|
-
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xs", c: "dimmed", children: "Check console for full stack trace" })
|
|
7514
|
-
] })
|
|
7515
|
-
}
|
|
7516
|
-
)
|
|
8183
|
+
function StatusDot({ online, onlineLabel, offlineLabel }) {
|
|
8184
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8185
|
+
"span",
|
|
8186
|
+
{
|
|
8187
|
+
title: online ? onlineLabel : offlineLabel,
|
|
8188
|
+
style: {
|
|
8189
|
+
display: "inline-block",
|
|
8190
|
+
width: "0.9vh",
|
|
8191
|
+
height: "0.9vh",
|
|
8192
|
+
borderRadius: "50%",
|
|
8193
|
+
backgroundColor: online ? ONLINE_COLOR : OFFLINE_COLOR,
|
|
8194
|
+
boxShadow: `0 0 0.4vh ${online ? ONLINE_COLOR : OFFLINE_COLOR}`,
|
|
8195
|
+
flexShrink: 0
|
|
7517
8196
|
}
|
|
7518
|
-
|
|
8197
|
+
}
|
|
8198
|
+
);
|
|
8199
|
+
}
|
|
8200
|
+
function formatLabel(p) {
|
|
8201
|
+
const parts = [p.charName || p.citizenId];
|
|
8202
|
+
if (p.online) {
|
|
8203
|
+
if (p.name) parts.push(p.name);
|
|
8204
|
+
if (p.id != null) parts.push(`#${p.id}`);
|
|
7519
8205
|
}
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
function
|
|
7523
|
-
const
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
8206
|
+
return parts.join(" \xB7 ");
|
|
8207
|
+
}
|
|
8208
|
+
function usePickDoor() {
|
|
8209
|
+
const begin = useAdminToolStore((s) => s.begin);
|
|
8210
|
+
return async () => {
|
|
8211
|
+
const pending = begin({
|
|
8212
|
+
id: "pickDoor",
|
|
8213
|
+
title: locale("PickDoorTitle"),
|
|
8214
|
+
hint: locale("PickDoorHint"),
|
|
8215
|
+
keys: [
|
|
8216
|
+
{ key: "LMB", action: locale("Toggle") },
|
|
8217
|
+
{ key: "E", action: locale("Confirm") },
|
|
8218
|
+
{ key: "BACKSPACE", action: locale("Cancel") }
|
|
8219
|
+
]
|
|
7534
8220
|
});
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
fetchNui("NUI_READY").catch(() => {
|
|
8221
|
+
fetchNui("ADMIN_TOOL_BEGIN", { id: "pickDoor" }).catch(() => {
|
|
8222
|
+
useAdminToolStore.getState().cancelActive();
|
|
7538
8223
|
});
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
}
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
8224
|
+
return await pending;
|
|
8225
|
+
};
|
|
8226
|
+
}
|
|
8227
|
+
function DoorPickerButton({
|
|
8228
|
+
onPick,
|
|
8229
|
+
compact,
|
|
8230
|
+
label: label2,
|
|
8231
|
+
tooltip
|
|
8232
|
+
}) {
|
|
8233
|
+
const theme2 = core.useMantineTheme();
|
|
8234
|
+
const color = theme2.colors[theme2.primaryColor][5];
|
|
8235
|
+
const pickDoor = usePickDoor();
|
|
8236
|
+
const onClick = async () => {
|
|
8237
|
+
const picked = await pickDoor();
|
|
8238
|
+
if (picked && picked.doors.length > 0) onPick(picked);
|
|
8239
|
+
};
|
|
8240
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8241
|
+
core.Tooltip,
|
|
8242
|
+
{
|
|
8243
|
+
label: tooltip ?? locale("PickDoorTooltip"),
|
|
8244
|
+
position: "top",
|
|
8245
|
+
withArrow: true,
|
|
8246
|
+
withinPortal: true,
|
|
8247
|
+
zIndex: 2e3,
|
|
8248
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8249
|
+
framerMotion.motion.button,
|
|
8250
|
+
{
|
|
8251
|
+
onClick,
|
|
8252
|
+
whileHover: { background: core.alpha(color, 0.18) },
|
|
8253
|
+
whileTap: { scale: 0.95 },
|
|
8254
|
+
style: {
|
|
8255
|
+
background: core.alpha(color, 0.1),
|
|
8256
|
+
border: `0.1vh solid ${core.alpha(color, 0.35)}`,
|
|
8257
|
+
borderRadius: theme2.radius.xs,
|
|
8258
|
+
padding: compact ? "0.25vh 0.6vh" : "0.5vh 0.8vh",
|
|
8259
|
+
cursor: "pointer",
|
|
8260
|
+
display: "flex",
|
|
8261
|
+
alignItems: "center",
|
|
8262
|
+
gap: compact ? "0.3vh" : "0.4vh"
|
|
8263
|
+
},
|
|
8264
|
+
children: [
|
|
8265
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.DoorOpen, { size: compact ? "1.1vh" : "1.3vh", color }),
|
|
8266
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: label2 ?? locale("PickDoor") })
|
|
8267
|
+
]
|
|
8268
|
+
}
|
|
8269
|
+
)
|
|
7564
8270
|
}
|
|
7565
8271
|
);
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
8272
|
+
}
|
|
8273
|
+
var MapImpl = React4.memo(({
|
|
8274
|
+
children,
|
|
8275
|
+
initialZoom = 2,
|
|
8276
|
+
initialCenter = gameToMap(0, 0),
|
|
8277
|
+
mapStyle = "game"
|
|
8278
|
+
}) => {
|
|
8279
|
+
const mapRef = React4.useRef(null);
|
|
8280
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8281
|
+
reactLeaflet.MapContainer,
|
|
8282
|
+
{
|
|
8283
|
+
maxBoundsViscosity: 1,
|
|
8284
|
+
preferCanvas: true,
|
|
8285
|
+
zoom: Math.round(initialZoom),
|
|
8286
|
+
zoomSnap: 1,
|
|
8287
|
+
zoomDelta: 1,
|
|
8288
|
+
zoomControl: false,
|
|
8289
|
+
crs: leaflet.CRS.Simple,
|
|
8290
|
+
style: {
|
|
8291
|
+
height: "100%",
|
|
8292
|
+
width: "100%",
|
|
8293
|
+
overflow: "hidden",
|
|
8294
|
+
outline: "none !important",
|
|
8295
|
+
border: "none !important",
|
|
8296
|
+
boxShadow: "none !important",
|
|
8297
|
+
backgroundColor: "#384950"
|
|
8298
|
+
},
|
|
8299
|
+
center: initialCenter,
|
|
8300
|
+
attributionControl: false,
|
|
8301
|
+
doubleClickZoom: false,
|
|
8302
|
+
inertia: false,
|
|
8303
|
+
zoomAnimation: false,
|
|
8304
|
+
ref: mapRef,
|
|
8305
|
+
maxBounds: [[-250, -250], [250, 250]],
|
|
8306
|
+
children: [
|
|
8307
|
+
/* @__PURE__ */ jsxRuntime.jsx(MapLayer, { mapLayer: mapStyle }),
|
|
8308
|
+
children
|
|
8309
|
+
]
|
|
7584
8310
|
}
|
|
8311
|
+
);
|
|
8312
|
+
});
|
|
8313
|
+
MapImpl.displayName = "DirkMap";
|
|
8314
|
+
var Map2 = MapImpl;
|
|
8315
|
+
var MapLayer = ({ mapLayer }) => {
|
|
8316
|
+
const map = reactLeaflet.useMap();
|
|
8317
|
+
const layerRef = React4.useRef(null);
|
|
8318
|
+
React4.useEffect(() => {
|
|
8319
|
+
if (layerRef.current) {
|
|
8320
|
+
map.removeLayer(layerRef.current);
|
|
8321
|
+
}
|
|
8322
|
+
const layer = leaflet.tileLayer(
|
|
8323
|
+
`https://s.rsg.sc/sc/images/games/GTAV/map/${mapLayer}/{z}/{x}/{y}.jpg`,
|
|
8324
|
+
{
|
|
8325
|
+
maxZoom: 6,
|
|
8326
|
+
minZoom: 4,
|
|
8327
|
+
bounds: leaflet.latLngBounds(leaflet.latLng(0, 128), leaflet.latLng(-192, 0)),
|
|
8328
|
+
tileSize: 256,
|
|
8329
|
+
updateWhenZooming: false,
|
|
8330
|
+
keepBuffer: 2,
|
|
8331
|
+
opacity: 0.75
|
|
8332
|
+
}
|
|
8333
|
+
);
|
|
8334
|
+
layer.addTo(map);
|
|
8335
|
+
layerRef.current = layer;
|
|
7585
8336
|
return () => {
|
|
7586
|
-
|
|
8337
|
+
if (layerRef.current) {
|
|
8338
|
+
map.removeLayer(layerRef.current);
|
|
8339
|
+
}
|
|
7587
8340
|
};
|
|
7588
|
-
}, []);
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
const
|
|
7593
|
-
const
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
8341
|
+
}, [mapLayer, map]);
|
|
8342
|
+
return null;
|
|
8343
|
+
};
|
|
8344
|
+
function ZoomControls() {
|
|
8345
|
+
const theme2 = core.useMantineTheme();
|
|
8346
|
+
const map = reactLeaflet.useMap();
|
|
8347
|
+
const buttons = [
|
|
8348
|
+
{ Icon: lucideReact.Plus, fn: () => map.zoomIn() },
|
|
8349
|
+
{ Icon: lucideReact.Minus, fn: () => map.zoomOut() }
|
|
8350
|
+
];
|
|
8351
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8352
|
+
framerMotion.motion.div,
|
|
8353
|
+
{
|
|
8354
|
+
style: {
|
|
8355
|
+
position: "absolute",
|
|
8356
|
+
right: "2vh",
|
|
8357
|
+
top: "2vh",
|
|
8358
|
+
display: "flex",
|
|
8359
|
+
flexDirection: "column",
|
|
8360
|
+
zIndex: 999999,
|
|
8361
|
+
boxShadow: `0 0 1vh ${core.alpha(theme2.colors.dark[9], 0.85)}`,
|
|
8362
|
+
background: core.alpha(theme2.colors.dark[9], 0.85),
|
|
8363
|
+
borderRadius: theme2.radius.xs
|
|
8364
|
+
},
|
|
8365
|
+
initial: { opacity: 0, y: -20 },
|
|
8366
|
+
animate: { opacity: 1, y: 0 },
|
|
8367
|
+
exit: { opacity: 0, y: -20 },
|
|
8368
|
+
children: buttons.map(({ Icon, fn }, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
8369
|
+
framerMotion.motion.div,
|
|
8370
|
+
{
|
|
8371
|
+
whileHover: { scale: 1.1, filter: "brightness(1.5)" },
|
|
8372
|
+
onClick: fn,
|
|
8373
|
+
style: {
|
|
8374
|
+
padding: theme2.spacing.xs,
|
|
8375
|
+
cursor: "pointer",
|
|
8376
|
+
display: "flex"
|
|
8377
|
+
},
|
|
8378
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: 34, color: theme2.colors.gray[5] })
|
|
8379
|
+
},
|
|
8380
|
+
i
|
|
8381
|
+
))
|
|
8382
|
+
}
|
|
7600
8383
|
);
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
8384
|
+
}
|
|
8385
|
+
var DEFAULT_SPRITE = 162;
|
|
8386
|
+
var DEFAULT_COLOR = 5;
|
|
8387
|
+
function BlipMarker({
|
|
8388
|
+
position,
|
|
8389
|
+
sprite,
|
|
8390
|
+
color,
|
|
8391
|
+
scale = 1,
|
|
8392
|
+
onClick,
|
|
8393
|
+
selected,
|
|
8394
|
+
disabled,
|
|
8395
|
+
fallbackSprite = DEFAULT_SPRITE,
|
|
8396
|
+
fallbackColor = DEFAULT_COLOR
|
|
8397
|
+
}) {
|
|
8398
|
+
const [hovered, setHovered] = React4.useState(false);
|
|
8399
|
+
const mapCoords = React4.useMemo(() => gameToMap(position.x, position.y), [position.x, position.y]);
|
|
8400
|
+
const effectiveSprite = sprite ?? fallbackSprite;
|
|
8401
|
+
const effectiveColor = color ?? fallbackColor;
|
|
8402
|
+
const url = blipUrlForSprite(effectiveSprite);
|
|
8403
|
+
const colorHex = getBlipColor(effectiveColor)?.hex ?? "#ffffff";
|
|
8404
|
+
const handleClick = (e) => {
|
|
8405
|
+
e.originalEvent?.stopPropagation?.();
|
|
8406
|
+
if (disabled) return;
|
|
8407
|
+
onClick?.();
|
|
8408
|
+
};
|
|
8409
|
+
const baseSize = 1.8 * scale;
|
|
8410
|
+
const size = `${baseSize}vh`;
|
|
8411
|
+
const ringSize = `${baseSize * 1.6}vh`;
|
|
8412
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8413
|
+
reactLeafletComponentMarker.Marker,
|
|
7606
8414
|
{
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
8415
|
+
position: mapCoords,
|
|
8416
|
+
eventHandlers: onClick ? { click: handleClick } : void 0,
|
|
8417
|
+
icon: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8418
|
+
framerMotion.motion.div,
|
|
8419
|
+
{
|
|
8420
|
+
onHoverStart: () => setHovered(true),
|
|
8421
|
+
onHoverEnd: () => setHovered(false),
|
|
8422
|
+
style: {
|
|
8423
|
+
position: "relative",
|
|
8424
|
+
display: "flex",
|
|
8425
|
+
alignItems: "center",
|
|
8426
|
+
justifyContent: "center",
|
|
8427
|
+
cursor: disabled ? "not-allowed" : onClick ? "pointer" : "default",
|
|
8428
|
+
opacity: disabled ? 0.35 : 1,
|
|
8429
|
+
width: size,
|
|
8430
|
+
height: size
|
|
8431
|
+
},
|
|
8432
|
+
animate: { scale: hovered && !disabled ? 1.2 : selected ? 1.15 : 1 },
|
|
8433
|
+
transition: { duration: 0.15, ease: "easeOut" },
|
|
8434
|
+
children: [
|
|
8435
|
+
(selected || hovered) && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8436
|
+
framerMotion.motion.div,
|
|
8437
|
+
{
|
|
8438
|
+
style: {
|
|
8439
|
+
position: "absolute",
|
|
8440
|
+
width: ringSize,
|
|
8441
|
+
height: ringSize,
|
|
8442
|
+
borderRadius: "50%",
|
|
8443
|
+
border: `0.18vh solid ${core.alpha(colorHex, 0.85)}`,
|
|
8444
|
+
boxShadow: `0 0 1vh ${core.alpha(colorHex, 0.55)}`
|
|
8445
|
+
},
|
|
8446
|
+
initial: { opacity: 0, scale: 0.8 },
|
|
8447
|
+
animate: { opacity: 1, scale: 1 }
|
|
8448
|
+
}
|
|
8449
|
+
),
|
|
8450
|
+
url && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8451
|
+
"div",
|
|
8452
|
+
{
|
|
8453
|
+
style: {
|
|
8454
|
+
width: size,
|
|
8455
|
+
height: size,
|
|
8456
|
+
backgroundColor: colorHex,
|
|
8457
|
+
WebkitMaskImage: `url(${url})`,
|
|
8458
|
+
maskImage: `url(${url})`,
|
|
8459
|
+
WebkitMaskRepeat: "no-repeat",
|
|
8460
|
+
maskRepeat: "no-repeat",
|
|
8461
|
+
WebkitMaskPosition: "center",
|
|
8462
|
+
maskPosition: "center",
|
|
8463
|
+
WebkitMaskSize: "contain",
|
|
8464
|
+
maskSize: "contain",
|
|
8465
|
+
filter: [
|
|
8466
|
+
"drop-shadow(0.12vh 0 0 #000)",
|
|
8467
|
+
"drop-shadow(-0.12vh 0 0 #000)",
|
|
8468
|
+
"drop-shadow(0 0.12vh 0 #000)",
|
|
8469
|
+
"drop-shadow(0 -0.12vh 0 #000)",
|
|
8470
|
+
`drop-shadow(0 0 0.4vh ${core.alpha("#000", 0.7)})`
|
|
8471
|
+
].join(" "),
|
|
8472
|
+
pointerEvents: "none",
|
|
8473
|
+
userSelect: "none"
|
|
8474
|
+
}
|
|
8475
|
+
}
|
|
8476
|
+
)
|
|
8477
|
+
]
|
|
8478
|
+
}
|
|
8479
|
+
)
|
|
7611
8480
|
}
|
|
7612
|
-
)
|
|
7613
|
-
|
|
8481
|
+
);
|
|
8482
|
+
}
|
|
8483
|
+
function useTornEdges() {
|
|
8484
|
+
const game = useSettings((state) => state.game);
|
|
8485
|
+
return game === "rdr3" ? "torn-edge-wrapper" : "";
|
|
8486
|
+
}
|
|
8487
|
+
function TornEdgeSVGFilter() {
|
|
8488
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8489
|
+
"svg",
|
|
8490
|
+
{
|
|
8491
|
+
style: { position: "absolute", width: 0, height: 0, pointerEvents: "none" },
|
|
8492
|
+
"aria-hidden": "true",
|
|
8493
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: "torn-edge-filter", x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
|
|
8494
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8495
|
+
"feTurbulence",
|
|
8496
|
+
{
|
|
8497
|
+
type: "fractalNoise",
|
|
8498
|
+
baseFrequency: "0.018 0.022",
|
|
8499
|
+
numOctaves: "5",
|
|
8500
|
+
seed: "9",
|
|
8501
|
+
result: "noise1"
|
|
8502
|
+
}
|
|
8503
|
+
),
|
|
8504
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8505
|
+
"feTurbulence",
|
|
8506
|
+
{
|
|
8507
|
+
type: "fractalNoise",
|
|
8508
|
+
baseFrequency: "0.08 0.12",
|
|
8509
|
+
numOctaves: "2",
|
|
8510
|
+
seed: "3",
|
|
8511
|
+
result: "noise2"
|
|
8512
|
+
}
|
|
8513
|
+
),
|
|
8514
|
+
/* @__PURE__ */ jsxRuntime.jsx("feBlend", { in: "noise1", in2: "noise2", mode: "multiply", result: "combinedNoise" }),
|
|
8515
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8516
|
+
"feDisplacementMap",
|
|
8517
|
+
{
|
|
8518
|
+
in: "SourceGraphic",
|
|
8519
|
+
in2: "combinedNoise",
|
|
8520
|
+
scale: "52",
|
|
8521
|
+
xChannelSelector: "R",
|
|
8522
|
+
yChannelSelector: "G",
|
|
8523
|
+
result: "displaced"
|
|
8524
|
+
}
|
|
8525
|
+
),
|
|
8526
|
+
/* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "0.8", in: "displaced", result: "blurred" }),
|
|
8527
|
+
/* @__PURE__ */ jsxRuntime.jsx("feComponentTransfer", { in: "blurred", result: "alphaFade", children: /* @__PURE__ */ jsxRuntime.jsx("feFuncA", { type: "gamma", amplitude: "1", exponent: "1.3", offset: "-0.05" }) }),
|
|
8528
|
+
/* @__PURE__ */ jsxRuntime.jsx("feMorphology", { operator: "erode", radius: "0.4", in: "alphaFade", result: "eroded" }),
|
|
8529
|
+
/* @__PURE__ */ jsxRuntime.jsx("feMerge", { children: /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "eroded" }) })
|
|
8530
|
+
] }) })
|
|
8531
|
+
}
|
|
8532
|
+
);
|
|
8533
|
+
}
|
|
8534
|
+
var moduleCache = /* @__PURE__ */ new Map();
|
|
8535
|
+
function useValidModels(names) {
|
|
8536
|
+
const cacheKey = React4.useMemo(() => {
|
|
8537
|
+
const unique = Array.from(new Set(names.filter((n) => typeof n === "string" && n.length > 0)));
|
|
8538
|
+
unique.sort();
|
|
8539
|
+
return unique.join("|");
|
|
8540
|
+
}, [names]);
|
|
8541
|
+
const [version, setVersion] = React4.useState(0);
|
|
8542
|
+
const inflight = React4.useRef(/* @__PURE__ */ new Set());
|
|
8543
|
+
React4.useEffect(() => {
|
|
8544
|
+
if (!cacheKey) return;
|
|
8545
|
+
const all = cacheKey.split("|").filter(Boolean);
|
|
8546
|
+
const missing = all.filter((n) => !moduleCache.has(n) && !inflight.current.has(n));
|
|
8547
|
+
if (missing.length === 0) return;
|
|
8548
|
+
missing.forEach((n) => inflight.current.add(n));
|
|
8549
|
+
let cancelled = false;
|
|
8550
|
+
fetchNui(
|
|
8551
|
+
"ADMIN_TOOL_QUERY",
|
|
8552
|
+
{ id: "validateModels", value: missing },
|
|
8553
|
+
// Fallback when running outside FiveM (browser dev) — assume valid so the
|
|
8554
|
+
// dev shell doesn't grey out every row.
|
|
8555
|
+
Object.fromEntries(missing.map((n) => [n, true]))
|
|
8556
|
+
).then((result) => {
|
|
8557
|
+
if (cancelled) return;
|
|
8558
|
+
const map = result && typeof result === "object" ? result : {};
|
|
8559
|
+
missing.forEach((n) => {
|
|
8560
|
+
moduleCache.set(n, !!map[n]);
|
|
8561
|
+
inflight.current.delete(n);
|
|
8562
|
+
});
|
|
8563
|
+
setVersion((v) => v + 1);
|
|
8564
|
+
}).catch(() => {
|
|
8565
|
+
if (cancelled) return;
|
|
8566
|
+
missing.forEach((n) => {
|
|
8567
|
+
inflight.current.delete(n);
|
|
8568
|
+
});
|
|
8569
|
+
});
|
|
8570
|
+
return () => {
|
|
8571
|
+
cancelled = true;
|
|
8572
|
+
};
|
|
8573
|
+
}, [cacheKey]);
|
|
8574
|
+
return React4.useMemo(() => {
|
|
8575
|
+
const out = /* @__PURE__ */ new Set();
|
|
8576
|
+
if (!cacheKey) return out;
|
|
8577
|
+
for (const n of cacheKey.split("|")) {
|
|
8578
|
+
if (n && moduleCache.get(n) === true) out.add(n);
|
|
8579
|
+
}
|
|
8580
|
+
return out;
|
|
8581
|
+
}, [cacheKey, version]);
|
|
7614
8582
|
}
|
|
7615
8583
|
var Vector2Schema = zod.z.object({
|
|
7616
8584
|
x: zod.z.number(),
|
|
@@ -7635,6 +8603,7 @@ exports.AsyncSaveButton = AsyncSaveButton;
|
|
|
7635
8603
|
exports.BlipColorSelect = BlipColorSelect;
|
|
7636
8604
|
exports.BlipDisplaySelect = BlipDisplaySelect;
|
|
7637
8605
|
exports.BlipIconSelect = BlipIconSelect;
|
|
8606
|
+
exports.BlipMarker = BlipMarker;
|
|
7638
8607
|
exports.BorderedIcon = BorderedIcon;
|
|
7639
8608
|
exports.ConfigPanel = ConfigPanel;
|
|
7640
8609
|
exports.ConfirmModal = ConfirmModal;
|
|
@@ -7643,6 +8612,7 @@ exports.ControlSelect = ControlSelect;
|
|
|
7643
8612
|
exports.Counter = Counter;
|
|
7644
8613
|
exports.DirkProvider = DirkProvider;
|
|
7645
8614
|
exports.DiscordRoleSelect = DiscordRoleSelect;
|
|
8615
|
+
exports.DoorPickerButton = DoorPickerButton;
|
|
7646
8616
|
exports.FiveMKeyBindInput = FiveMKeyBindInput;
|
|
7647
8617
|
exports.FloatingParticles = FloatingParticles;
|
|
7648
8618
|
exports.FormProvider = FormProvider;
|
|
@@ -7655,8 +8625,11 @@ exports.INPUT_MAPPER_KEYS_BY_PRIMARY = INPUT_MAPPER_KEYS_BY_PRIMARY;
|
|
|
7655
8625
|
exports.INPUT_MAPPER_PRIMARY_OPTIONS = INPUT_MAPPER_PRIMARY_OPTIONS;
|
|
7656
8626
|
exports.InfoBox = InfoBox;
|
|
7657
8627
|
exports.InputContainer = InputContainer;
|
|
8628
|
+
exports.InstructionPanel = InstructionPanel;
|
|
7658
8629
|
exports.LevelBanner = LevelBanner;
|
|
7659
8630
|
exports.LevelPanel = LevelPanel;
|
|
8631
|
+
exports.Map = Map2;
|
|
8632
|
+
exports.MapLayer = MapLayer;
|
|
7660
8633
|
exports.MissingItemsBanner = MissingItemsBanner;
|
|
7661
8634
|
exports.Modal = Modal;
|
|
7662
8635
|
exports.ModalContext = ModalContext;
|
|
@@ -7668,6 +8641,7 @@ exports.MotionText = MotionText;
|
|
|
7668
8641
|
exports.NavBar = NavBar;
|
|
7669
8642
|
exports.NavigationContext = NavigationContext;
|
|
7670
8643
|
exports.NavigationProvider = NavigationProvider;
|
|
8644
|
+
exports.PlayerSelect = PlayerSelect;
|
|
7671
8645
|
exports.PositionPicker = PositionPicker;
|
|
7672
8646
|
exports.PromptModal = PromptModal;
|
|
7673
8647
|
exports.ScenarioSelect = ScenarioSelect;
|
|
@@ -7685,17 +8659,26 @@ exports.Vector4DeleteButton = Vector4DeleteButton;
|
|
|
7685
8659
|
exports.Vector4Display = Vector4Display;
|
|
7686
8660
|
exports.Vector4Schema = Vector4Schema;
|
|
7687
8661
|
exports.WorldPositionGotoButton = WorldPositionGotoButton;
|
|
8662
|
+
exports.WorldPositionPicker = WorldPositionPicker;
|
|
7688
8663
|
exports.WorldPositionSetButton = WorldPositionSetButton;
|
|
8664
|
+
exports.ZoomControls = ZoomControls;
|
|
8665
|
+
exports.blipUrl = blipUrl;
|
|
8666
|
+
exports.blipUrlForSprite = blipUrlForSprite;
|
|
8667
|
+
exports.clearAdminState = clearAdminState;
|
|
7689
8668
|
exports.colorWithAlpha = colorWithAlpha;
|
|
7690
8669
|
exports.copyToClipboard = copyToClipboard;
|
|
7691
8670
|
exports.createFormStore = createFormStore;
|
|
7692
8671
|
exports.createScriptConfig = createScriptConfig;
|
|
7693
8672
|
exports.createSkill = createSkill;
|
|
8673
|
+
exports.dirkQueryClient = dirkQueryClient;
|
|
8674
|
+
exports.ensureFrameworkGroups = ensureFrameworkGroups;
|
|
7694
8675
|
exports.extractDefaults = extractDefaults;
|
|
7695
8676
|
exports.fetchLuaTable = fetchLuaTable;
|
|
7696
8677
|
exports.fetchNui = fetchNui;
|
|
7697
8678
|
exports.formatGtaControl = formatGtaControl;
|
|
7698
8679
|
exports.gameToMap = gameToMap;
|
|
8680
|
+
exports.getBlipColor = getBlipColor;
|
|
8681
|
+
exports.getBlipEntry = getBlipEntry;
|
|
7699
8682
|
exports.getGtaControl = getGtaControl;
|
|
7700
8683
|
exports.getImageShape = getImageShape;
|
|
7701
8684
|
exports.getItemImageUrl = getItemImageUrl;
|
|
@@ -7719,6 +8702,8 @@ exports.selectAllGroups = selectAllGroups;
|
|
|
7719
8702
|
exports.splitFAString = splitFAString;
|
|
7720
8703
|
exports.updatePresignedURL = updatePresignedURL;
|
|
7721
8704
|
exports.uploadImage = uploadImage;
|
|
8705
|
+
exports.useAdminState = useAdminState;
|
|
8706
|
+
exports.useAdminToolStore = useAdminToolStore;
|
|
7722
8707
|
exports.useAudio = useAudio;
|
|
7723
8708
|
exports.useAutoFetcher = useAutoFetcher;
|
|
7724
8709
|
exports.useForm = useForm;
|
|
@@ -7736,8 +8721,11 @@ exports.useModalActions = useModalActions;
|
|
|
7736
8721
|
exports.useNavigation = useNavigation;
|
|
7737
8722
|
exports.useNavigationStore = useNavigationStore;
|
|
7738
8723
|
exports.useNuiEvent = useNuiEvent;
|
|
8724
|
+
exports.usePickDoor = usePickDoor;
|
|
8725
|
+
exports.usePlayers = usePlayers;
|
|
7739
8726
|
exports.useProfanityStore = useProfanityStore;
|
|
7740
8727
|
exports.useSettings = useSettings;
|
|
7741
8728
|
exports.useTornEdges = useTornEdges;
|
|
8729
|
+
exports.useValidModels = useValidModels;
|
|
7742
8730
|
//# sourceMappingURL=index.cjs.map
|
|
7743
8731
|
//# sourceMappingURL=index.cjs.map
|