dirk-cfx-react 1.0.46 → 1.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,10 +1,15 @@
1
1
  'use strict';
2
2
 
3
- var reactFontawesome = require('@fortawesome/react-fontawesome');
4
- var core = require('@mantine/core');
5
3
  var react = require('react');
6
4
  var zustand = require('zustand');
5
+ var axios = require('axios');
6
+ var reactFontawesome = require('@fortawesome/react-fontawesome');
7
+ var core = require('@mantine/core');
7
8
  var jsxRuntime = require('react/jsx-runtime');
9
+ var framerMotion = require('framer-motion');
10
+ var clickSoundUrl = require('./click_sound-PNCRRTM4.mp3');
11
+ var hoverSoundUrl = require('./hover_sound-NBUA222C.mp3');
12
+ var hooks = require('@mantine/hooks');
8
13
  require('@mantine/core/styles.css');
9
14
  require('@mantine/notifications/styles.css');
10
15
  require('./styles/notify.css');
@@ -15,18 +20,13 @@ var fontawesomeSvgCore = require('@fortawesome/fontawesome-svg-core');
15
20
  var freeBrandsSvgIcons = require('@fortawesome/free-brands-svg-icons');
16
21
  var freeRegularSvgIcons = require('@fortawesome/free-regular-svg-icons');
17
22
  var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
18
- var framerMotion = require('framer-motion');
19
- var clickSoundUrl = require('./click_sound-PNCRRTM4.mp3');
20
- var hoverSoundUrl = require('./hover_sound-NBUA222C.mp3');
21
- var hooks = require('@mantine/hooks');
22
23
 
23
24
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
24
25
 
26
+ var axios__default = /*#__PURE__*/_interopDefault(axios);
25
27
  var clickSoundUrl__default = /*#__PURE__*/_interopDefault(clickSoundUrl);
26
28
  var hoverSoundUrl__default = /*#__PURE__*/_interopDefault(hoverSoundUrl);
27
29
 
28
- // src/components/BorderedIcon.tsx
29
-
30
30
  // src/utils/colorWithAlpha.ts
31
31
  var colorNames = {
32
32
  AliceBlue: { r: 240, g: 248, b: 255 },
@@ -224,216 +224,7 @@ var openLink = (url) => {
224
224
  }
225
225
  };
226
226
 
227
- // src/hooks/useNuiEvent.ts
228
- var useNuiEvent = (action, handler) => {
229
- const savedHandler = react.useRef(noop);
230
- react.useEffect(() => {
231
- savedHandler.current = handler;
232
- }, [handler]);
233
- react.useEffect(() => {
234
- const eventListener = (event) => {
235
- const { action: eventAction, data } = event.data;
236
- if (savedHandler.current) {
237
- if (eventAction === action) {
238
- savedHandler.current(data);
239
- }
240
- }
241
- };
242
- window.addEventListener("message", eventListener);
243
- return () => window.removeEventListener("message", eventListener);
244
- }, [action]);
245
- };
246
- function getNested(obj, path) {
247
- return path.split(".").reduce((acc, key) => acc ? acc[key] : void 0, obj);
248
- }
249
- function setNested(obj, path, value) {
250
- const keys = path.split(".");
251
- const newObj = { ...obj };
252
- let current = newObj;
253
- for (let i = 0; i < keys.length - 1; i++) {
254
- const key = keys[i];
255
- current[key] = { ...current[key] || {} };
256
- current = current[key];
257
- }
258
- current[keys[keys.length - 1]] = value;
259
- return newObj;
260
- }
261
- function deleteNested(obj, path) {
262
- const keys = path.split(".");
263
- const newObj = { ...obj };
264
- let current = newObj;
265
- for (let i = 0; i < keys.length - 1; i++) {
266
- const key = keys[i];
267
- if (!current[key]) return obj;
268
- current[key] = { ...current[key] };
269
- current = current[key];
270
- }
271
- delete current[keys[keys.length - 1]];
272
- return newObj;
273
- }
274
- function flattenRules(rules, prefix = "") {
275
- const result = {};
276
- for (const key in rules) {
277
- const fullPath = prefix ? `${prefix}.${key}` : key;
278
- const val = rules[key];
279
- if (typeof val === "function") result[fullPath] = val;
280
- else if (typeof val === "object")
281
- Object.assign(result, flattenRules(val, fullPath));
282
- }
283
- return result;
284
- }
285
- function createFormStore(initialValues, validationRules, onSubmit) {
286
- const flatRules = validationRules ? flattenRules(validationRules) : {};
287
- const history = [];
288
- const future = [];
289
- const changed = /* @__PURE__ */ new Set();
290
- return zustand.createStore((set, get) => ({
291
- initialValues,
292
- values: initialValues,
293
- errors: {},
294
- canBack: false,
295
- canForward: false,
296
- changedFields: [],
297
- changedCount: 0,
298
- onSubmit,
299
- submit: () => {
300
- const state = get();
301
- const isValid = state.validate();
302
- if (isValid && state.onSubmit) state.onSubmit(get());
303
- },
304
- resetChangeCount: () => {
305
- changed.clear();
306
- set(() => ({
307
- changedFields: [],
308
- changedCount: 0
309
- }));
310
- },
311
- setInitialValues: (newInitialValues) => set({ initialValues: newInitialValues }),
312
- setValue: (path, value) => {
313
- const currentValues = get().values;
314
- const newValues = setNested(currentValues, path, value);
315
- const oldValue = getNested(get().initialValues, path);
316
- history.push(currentValues);
317
- future.length = 0;
318
- if (value !== oldValue) changed.add(path);
319
- else changed.delete(path);
320
- set({
321
- values: newValues,
322
- canBack: history.length > 0,
323
- canForward: false,
324
- changedFields: Array.from(changed),
325
- changedCount: changed.size
326
- });
327
- const rule = flatRules[path];
328
- if (rule) {
329
- const error2 = rule(value, newValues);
330
- if (error2)
331
- set((state) => ({ errors: setNested(state.errors, path, error2) }));
332
- else set((state) => ({ errors: deleteNested(state.errors, path) }));
333
- }
334
- },
335
- setError: (path, message) => set((state) => ({ errors: setNested(state.errors, path, message) })),
336
- clearError: (path) => set((state) => ({ errors: deleteNested(state.errors, path) })),
337
- validateField: (path) => {
338
- const state = get();
339
- const rule = flatRules[path];
340
- if (!rule) return true;
341
- const value = getNested(state.values, path);
342
- const error2 = rule(value, state.values);
343
- if (error2) {
344
- set((state2) => ({ errors: setNested(state2.errors, path, error2) }));
345
- return false;
346
- } else {
347
- set((state2) => ({ errors: deleteNested(state2.errors, path) }));
348
- return true;
349
- }
350
- },
351
- validate: () => {
352
- const state = get();
353
- let isValid = true;
354
- let newErrors = {};
355
- for (const path in flatRules) {
356
- const rule = flatRules[path];
357
- const value = getNested(state.values, path);
358
- const error2 = rule(value, state.values);
359
- if (error2) {
360
- isValid = false;
361
- newErrors = setNested(newErrors, path, error2);
362
- }
363
- }
364
- set({ errors: newErrors });
365
- return isValid;
366
- },
367
- reset: () => {
368
- history.length = 0;
369
- future.length = 0;
370
- changed.clear();
371
- set({
372
- values: initialValues,
373
- errors: {},
374
- canBack: false,
375
- canForward: false,
376
- changedFields: [],
377
- changedCount: 0
378
- });
379
- },
380
- back: () => {
381
- const state = get();
382
- if (history.length === 0) return;
383
- const prev = history.pop();
384
- future.push(state.values);
385
- changed.clear();
386
- const current = prev;
387
- const initial = get().initialValues;
388
- for (const key in current) {
389
- if (JSON.stringify(current[key]) !== JSON.stringify(initial[key]))
390
- changed.add(key);
391
- }
392
- set({
393
- values: prev,
394
- canBack: history.length > 0,
395
- canForward: true,
396
- changedFields: Array.from(changed),
397
- changedCount: changed.size
398
- });
399
- },
400
- forward: () => {
401
- const state = get();
402
- if (future.length === 0) return;
403
- const next = future.pop();
404
- history.push(state.values);
405
- changed.clear();
406
- const current = next;
407
- const initial = get().initialValues;
408
- for (const key in current) {
409
- if (JSON.stringify(current[key]) !== JSON.stringify(initial[key]))
410
- changed.add(key);
411
- }
412
- set({
413
- values: next,
414
- canBack: true,
415
- canForward: future.length > 0,
416
- changedFields: Array.from(changed),
417
- changedCount: changed.size
418
- });
419
- }
420
- }));
421
- }
422
- var FormContext = react.createContext(null);
423
- function FormProvider({
424
- initialValues,
425
- validate,
426
- onSubmit,
427
- children
428
- }) {
429
- const storeRef = react.useRef(createFormStore(initialValues, validate, onSubmit));
430
- return /* @__PURE__ */ jsxRuntime.jsx(FormContext.Provider, { value: storeRef.current, children });
431
- }
432
- function useForm() {
433
- const store = react.useContext(FormContext);
434
- if (!store) throw new Error("useForm must be used inside a <FormProvider>");
435
- return zustand.useStore(store);
436
- }
227
+ // src/utils/fetchNui.ts
437
228
  async function fetchNui(eventName, data, mockData) {
438
229
  const options = {
439
230
  method: "post",
@@ -960,273 +751,51 @@ function createSkill(defaultSettings) {
960
751
  useSkill
961
752
  };
962
753
  }
963
- var label = {
964
- fontSize: "var(--mantine-font-size-xs)",
965
- fontFamily: "Akrobat Bold",
966
- letterSpacing: "0.05em",
967
- textTransform: "uppercase"
968
- };
969
- var error = {
970
- fontSize: "var(--mantine-font-size-xs)",
971
- fontFamily: "Akrobat Regular"
972
- };
973
- var theme = core.createTheme({
974
- primaryColor: "dirk",
975
- primaryShade: 9,
976
- defaultRadius: "xs",
977
- fontFamily: "Akrobat Regular, sans-serif",
978
- radius: {
979
- xxs: "0.2vh",
980
- xs: "0.4vh",
981
- sm: "0.75vh",
982
- md: "1vh",
983
- lg: "1.5vh",
984
- xl: "2vh",
985
- xxl: "3vh"
986
- },
987
- fontSizes: {
988
- xxs: "1.2vh",
989
- xs: "1.5vh",
990
- sm: "1.8vh",
991
- md: "2.2vh",
992
- lg: "2.8vh",
993
- xl: "3.3vh",
994
- xxl: "3.8vh"
995
- },
996
- lineHeights: {
997
- xxs: "1.4vh",
998
- xs: "1.8vh",
999
- sm: "2.2vh",
1000
- md: "2.8vh",
1001
- lg: "3.3vh",
1002
- xl: "3.8vh"
1003
- },
1004
- spacing: {
1005
- xxs: "0.5vh",
1006
- xs: "0.75vh",
1007
- sm: "1.5vh",
1008
- md: "2vh",
1009
- lg: "3vh",
1010
- xl: "4vh",
1011
- xxl: "5vh"
1012
- },
1013
- components: {
1014
- Progress: {
1015
- styles: {
1016
- label: {
1017
- fontFamily: "Akrobat Bold",
1018
- letterSpacing: "0.05em",
1019
- textTransform: "uppercase"
1020
- },
1021
- root: {
1022
- backgroundColor: "rgba(77, 77, 77, 0.4)"
1023
- }
1024
- }
1025
- },
1026
- Textarea: {
1027
- styles: {
1028
- label,
1029
- error
1030
- }
1031
- },
1032
- Button: {
1033
- styles: {
1034
- root: {
1035
- fontSize: "var(--mantine-font-size-xs)"
1036
- }
1037
- }
1038
- },
1039
- Select: {
1040
- styles: {
1041
- input: {
1042
- padding: "var(--mantine-spacing-sm)"
1043
- }
1044
- }
1045
- },
1046
- Pill: {
1047
- styles: (theme2) => ({
1048
- root: {
1049
- display: "inline-flex",
1050
- alignItems: "center",
1051
- justifyContent: "space-between",
1052
- backgroundColor: "rgba(76, 76, 76, 0.3)",
1053
- height: "fit-content",
1054
- textTransform: "uppercase",
1055
- letterSpacing: "0.05em",
1056
- fontFamily: "Akrobat Bold",
1057
- fontSize: theme2.fontSizes.xs,
1058
- borderRadius: theme2.defaultRadius,
1059
- padding: `${theme2.spacing.xs} ${theme2.spacing.sm}`
1060
- }
1061
- })
1062
- },
1063
- Input: {
1064
- styles: {
1065
- label,
1066
- error,
1067
- input: {
1068
- padding: "var(--mantine-spacing-sm)",
1069
- backgroundColor: "rgba(76, 76, 76, 0.3)"
1070
- }
1071
- }
1072
- },
1073
- ColorInput: {
1074
- styles: {
1075
- label,
1076
- input: {
1077
- padding: "var(--mantine-spacing-sm)"
1078
- }
1079
- }
1080
- },
1081
- TextInput: {
1082
- styles: {
1083
- label,
1084
- wrapper: {},
1085
- section: {
1086
- marginRight: "0.2vh"
1087
- },
1088
- input: {
1089
- padding: "var(--mantine-spacing-sm)"
1090
- }
1091
- }
1092
- },
1093
- NumberInput: {
1094
- styles: {
1095
- label,
1096
- input: {
1097
- padding: "var(--mantine-spacing-sm)"
1098
- },
1099
- section: {
1100
- pointerEvents: "all"
1101
- }
1102
- }
1103
- }
1104
- },
1105
- colors: {
1106
- dirk: [
1107
- "#ffffff",
1108
- "#f3fce9",
1109
- "#dbf5bd",
1110
- "#c3ee91",
1111
- "#ace765",
1112
- "#94e039",
1113
- "#7ac61f",
1114
- "#5f9a18",
1115
- "#29420a",
1116
- "#446e11"
1117
- ]
1118
- }
1119
- });
1120
- var theme_default = theme;
1121
- fontawesomeSvgCore.library.add(freeSolidSvgIcons.fas, freeRegularSvgIcons.far, freeBrandsSvgIcons.fab);
1122
- var useSettings = zustand.create((set) => ({
1123
- game: "fivem",
1124
- primaryColor: "dirk",
1125
- primaryShade: 9,
1126
- itemImgPath: "https://assets.dirkcfx.com/items/",
1127
- customTheme: {}
1128
- }));
1129
- function DirkProvider(props) {
1130
- const primaryColor = useSettings((data) => data.primaryColor);
1131
- const primaryShade = useSettings((data) => data.primaryShade);
1132
- const customTheme = useSettings((data) => data.customTheme);
1133
- const game = useSettings((data) => data.game);
1134
- const mergedTheme = react.useMemo(() => ({
1135
- ...theme_default,
1136
- primaryColor,
1137
- primaryShade,
1138
- colors: {
1139
- ...theme_default.colors,
1140
- ...customTheme
1141
- // Custom theme colors will override/extend base colors
1142
- }
1143
- }), [primaryColor, primaryShade, customTheme]);
1144
- react.useEffect(() => {
1145
- document.fonts.ready.then(() => {
1146
- document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : game === "fivem" ? '"Akrobat Regular", sans-serif' : "sans-serif";
1147
- console.log(`Game set to ${game}, applied corresponding font family.: ${document.body.style.fontFamily}`);
1148
- });
1149
- }, [game]);
1150
- react.useEffect(() => {
1151
- fetchNui("NUI_READY");
1152
- }, []);
1153
- useAutoFetcher();
1154
- return /* @__PURE__ */ jsxRuntime.jsx(core.MantineProvider, { theme: mergedTheme, defaultColorScheme: "dark", children: /* @__PURE__ */ jsxRuntime.jsx(Wrapper, { children: props.children }) });
1155
- }
1156
- function Wrapper({ children }) {
1157
- const game = useSettings((data) => data.game);
1158
- return isEnvBrowser() ? /* @__PURE__ */ jsxRuntime.jsx(
1159
- core.BackgroundImage,
1160
- {
1161
- w: "100vw",
1162
- h: "100vh",
1163
- style: { overflow: "hidden" },
1164
- 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",
1165
- children
1166
- }
1167
- ) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
1168
- }
1169
- function useTornEdges() {
1170
- const game = useSettings((state) => state.game);
1171
- return game === "rdr3" ? "torn-edge-wrapper" : "";
754
+ var dummyURL = "https://fmapi.net/api/v2/presigned-url/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJON0UxM0tzejFRM0NuSzRHWFBPbmUiLCJ0ZWFtSWQiOiJlMDQ1YnpwZzg5TGpoaUFTaURIdVoiLCJmaWxlVHlwZSI6ImltYWdlIiwidG9rZW5JZCI6ImpwczJ4Z0M1eFZqcnRoeWZTZnFsYSIsInNldHRpbmdzIjp7IlRlYW1JRCI6ImUwNDVienBnODlMamhpQVNpREh1WiIsIkltYWdlTm90aWZpY2F0aW9uVHlwZSI6IiIsIkRpc2NvcmRXZWJob29rIjoiIiwiRGlzY29yZEltYWdlQ2hhbm5lbCI6IiIsIlZpZGVvTm90aWZpY2F0aW9uVHlwZSI6IiIsIkRpc2NvcmRWaWRlb1dlYmhvb2siOiIiLCJEaXNjb3JkVmlkZW9DaGFubmVsIjoiIiwiQXVkaW9Ob3RpZmljYXRpb25UeXBlIjoiIiwiRGlzY29yZEF1ZGlvV2ViaG9vayI6IiIsIkRpc2NvcmRBdWRpb0NoYW5uZWwiOiIiLCJEaXNjb3JkQm90VG9rZW4iOiIiLCJSZXRlbnRpb25FbmFibGVkIjpmYWxzZSwiUmV0ZW50aW9uRGF5cyI6NywiVmlkZW9SZXRlbnRpb25FbmFibGVkIjpmYWxzZSwiVmlkZW9SZXRlbnRpb25EYXlzIjo3LCJBdWRpb1JldGVudGlvbkVuYWJsZWQiOmZhbHNlLCJBdWRpb1JldGVudGlvbkRheXMiOjcsIkxvZ0FsZXJ0RW5hYmxlZCI6ZmFsc2UsIkxvZ0FsZXJ0TGV2ZWxzIjpbXSwiTG9nQWxlcnREaXNjb3JkV2ViaG9vayI6IiIsIk92ZXJyaWRlSW1hZ2VRdWFsaXR5IjpmYWxzZSwiSW1hZ2VRdWFsaXR5Ijo1MH0sImV4cCI6MTc2MTg1MTEzNH0.fpPeQ0GCm5GNTddjttUQ78VMqRUAufXoOvv5C7Vh3WA";
755
+ async function updatePresignedURL() {
756
+ return await fetchNui("GET_PRESIGNED_URL", void 0, dummyURL);
1172
757
  }
1173
- function TornEdgeSVGFilter() {
1174
- return /* @__PURE__ */ jsxRuntime.jsx(
1175
- "svg",
1176
- {
1177
- style: { position: "absolute", width: 0, height: 0, pointerEvents: "none" },
1178
- "aria-hidden": "true",
1179
- children: /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: "torn-edge-filter", x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
1180
- /* @__PURE__ */ jsxRuntime.jsx(
1181
- "feTurbulence",
1182
- {
1183
- type: "fractalNoise",
1184
- baseFrequency: "0.018 0.022",
1185
- numOctaves: "5",
1186
- seed: "9",
1187
- result: "noise1"
1188
- }
1189
- ),
1190
- /* @__PURE__ */ jsxRuntime.jsx(
1191
- "feTurbulence",
1192
- {
1193
- type: "fractalNoise",
1194
- baseFrequency: "0.08 0.12",
1195
- numOctaves: "2",
1196
- seed: "3",
1197
- result: "noise2"
1198
- }
1199
- ),
1200
- /* @__PURE__ */ jsxRuntime.jsx("feBlend", { in: "noise1", in2: "noise2", mode: "multiply", result: "combinedNoise" }),
1201
- /* @__PURE__ */ jsxRuntime.jsx(
1202
- "feDisplacementMap",
1203
- {
1204
- in: "SourceGraphic",
1205
- in2: "combinedNoise",
1206
- scale: "52",
1207
- xChannelSelector: "R",
1208
- yChannelSelector: "G",
1209
- result: "displaced"
1210
- }
1211
- ),
1212
- /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "0.8", in: "displaced", result: "blurred" }),
1213
- /* @__PURE__ */ jsxRuntime.jsx("feComponentTransfer", { in: "blurred", result: "alphaFade", children: /* @__PURE__ */ jsxRuntime.jsx("feFuncA", { type: "gamma", amplitude: "1", exponent: "1.3", offset: "-0.05" }) }),
1214
- /* @__PURE__ */ jsxRuntime.jsx("feMorphology", { operator: "erode", radius: "0.4", in: "alphaFade", result: "eroded" }),
1215
- /* @__PURE__ */ jsxRuntime.jsx("feMerge", { children: /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "eroded" }) })
1216
- ] }) })
1217
- }
758
+ async function uploadImage(props) {
759
+ const uploadURL = await updatePresignedURL();
760
+ const response = await fetch(props.fileURL);
761
+ const blob = await response.blob();
762
+ const file = new File([blob], "upload.png", { type: blob.type });
763
+ const formData = new FormData();
764
+ formData.append("file", file);
765
+ formData.append(
766
+ "metadata",
767
+ JSON.stringify({
768
+ name: props.name || file.name,
769
+ description: props.description || "Uploaded via DirkScripts"
770
+ })
1218
771
  );
772
+ const uploadRes = await axios__default.default.post(uploadURL, formData, {
773
+ headers: { "Content-Type": "multipart/form-data" }
774
+ });
775
+ const finalUrl = uploadRes.data?.data?.url ?? uploadRes.data?.url;
776
+ if (!finalUrl) throw new Error("Upload succeeded but no URL returned");
777
+ return finalUrl;
778
+ }
779
+ async function getImageShape(file) {
780
+ return new Promise((resolve, reject) => {
781
+ const img = new Image();
782
+ img.onload = () => {
783
+ if (img.width > img.height) resolve("wide");
784
+ else resolve("square");
785
+ };
786
+ img.onerror = () => reject(new Error("Failed to load image"));
787
+ img.src = typeof file === "string" ? file : URL.createObjectURL(file);
788
+ });
1219
789
  }
1220
790
  function BorderedIcon(props) {
1221
791
  const theme2 = core.useMantineTheme();
1222
- const tornEdgeCSS = useTornEdges();
1223
792
  return /* @__PURE__ */ jsxRuntime.jsx(
1224
- core.Flex,
793
+ reactFontawesome.FontAwesomeIcon,
1225
794
  {
1226
- className: tornEdgeCSS,
1227
- justify: "center",
1228
- align: "center",
795
+ icon: props.icon,
796
+ color: colorWithAlpha(props.color ? props.color : theme2.colors[theme2.primaryColor][theme2.primaryShade], props.hovered ? 0.9 : 0.9),
1229
797
  style: {
798
+ // backgroundColor: colorWithAlpha(props.color ? props.color : theme.colors[theme.primaryColor][7 as number], (props.hoverable ? (props.hovered ? 0.3 : 0.2) : 0.2)),
1230
799
  backgroundColor: "rgba(0, 0, 0, 0.5)",
1231
800
  padding: props.p || theme2.spacing.xs,
1232
801
  transition: "all 0.2s ease-in-out",
@@ -1234,19 +803,9 @@ function BorderedIcon(props) {
1234
803
  fontSize: props.fontSize ? props.fontSize : "2.5vh",
1235
804
  borderRadius: theme2.radius.xs,
1236
805
  // border: `2px solid var(--mantine-primary-color-9)`,
1237
- // outline: `0.2vh solid ${colorWithAlpha(props.color ? props.color : theme.colors[theme.primaryColor][9], 0.8)}`,
806
+ outline: `0.2vh solid ${colorWithAlpha(props.color ? props.color : theme2.colors[theme2.primaryColor][9], 0.8)}`,
1238
807
  boxShadow: `inset 0 0 2vh ${colorWithAlpha(props.color ? props.color : theme2.colors[theme2.primaryColor][7], 0.5)}`
1239
- },
1240
- children: /* @__PURE__ */ jsxRuntime.jsx(
1241
- reactFontawesome.FontAwesomeIcon,
1242
- {
1243
- icon: props.icon,
1244
- color: colorWithAlpha(props.color ? props.color : theme2.colors[theme2.primaryColor][theme2.primaryShade], props.hovered ? 0.9 : 0.9),
1245
- style: {
1246
- // backgroundColor: colorWithAlpha(props.color ? props.color : theme.colors[theme.primaryColor][7 as number], (props.hoverable ? (props.hovered ? 0.3 : 0.2) : 0.2)),
1247
- }
1248
- }
1249
- )
808
+ }
1250
809
  }
1251
810
  );
1252
811
  }
@@ -1995,27 +1554,114 @@ function Title(props) {
1995
1554
  }
1996
1555
  );
1997
1556
  }
1998
- var ModalContext = react.createContext(null);
1999
- function useModal(selector) {
2000
- const modal = react.useContext(ModalContext);
2001
- if (!modal) {
2002
- throw new Error("useModal must be used within a ModalProvider");
2003
- }
2004
- return zustand.useStore(modal, selector);
2005
- }
2006
- function ModalProvider({ children, defaultPage }) {
2007
- const storeRef = react.useRef(
2008
- zustand.create(() => ({
2009
- active: null
2010
- }))
2011
- );
2012
- return /* @__PURE__ */ jsxRuntime.jsxs(ModalContext.Provider, { value: storeRef.current, children: [
2013
- /* @__PURE__ */ jsxRuntime.jsx(Modal, {}),
2014
- children
2015
- ] });
2016
- }
2017
- function useModalActions() {
2018
- const modal = react.useContext(ModalContext);
1557
+ function LevelBanner(props) {
1558
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1559
+ MotionFlex,
1560
+ {
1561
+ w: "35vh",
1562
+ pos: "absolute",
1563
+ left: "50%",
1564
+ align: "center",
1565
+ gap: "xs",
1566
+ style: {
1567
+ borderRadius: core.useMantineTheme().radius.xxs
1568
+ },
1569
+ initial: { opacity: 0, y: -10, transform: "translateX(-50%)" },
1570
+ animate: { opacity: 1, y: 0, transform: "translateX(-50%)" },
1571
+ exit: { opacity: 0, y: -10, transform: "translateX(-50%)" },
1572
+ transition: { duration: 0.3 },
1573
+ direction: "column",
1574
+ children: [
1575
+ /* @__PURE__ */ jsxRuntime.jsxs(
1576
+ core.Flex,
1577
+ {
1578
+ w: "100%",
1579
+ justify: "space-between",
1580
+ children: [
1581
+ /* @__PURE__ */ jsxRuntime.jsxs(
1582
+ core.Text,
1583
+ {
1584
+ size: "xxs",
1585
+ c: "rgba(255, 255, 255, 0.9)",
1586
+ style: {
1587
+ fontFamily: "Akrobat Bold",
1588
+ letterSpacing: "0.1em"
1589
+ },
1590
+ children: [
1591
+ "LVL ",
1592
+ props.level
1593
+ ]
1594
+ }
1595
+ ),
1596
+ /* @__PURE__ */ jsxRuntime.jsxs(
1597
+ core.Text,
1598
+ {
1599
+ size: "xxs",
1600
+ c: "rgba(255, 255, 255, 0.7)",
1601
+ style: {
1602
+ fontFamily: "Akrobat Bold",
1603
+ letterSpacing: "0.1em"
1604
+ },
1605
+ children: [
1606
+ props.exp,
1607
+ "/",
1608
+ props.nextLevelXP,
1609
+ " XP"
1610
+ ]
1611
+ }
1612
+ ),
1613
+ /* @__PURE__ */ jsxRuntime.jsxs(
1614
+ core.Text,
1615
+ {
1616
+ size: "xxs",
1617
+ c: "rgba(255, 255, 255, 0.7)",
1618
+ style: {
1619
+ fontFamily: "Akrobat Bold",
1620
+ letterSpacing: "0.1em"
1621
+ },
1622
+ children: [
1623
+ "LVL ",
1624
+ props.level + 1
1625
+ ]
1626
+ }
1627
+ )
1628
+ ]
1629
+ }
1630
+ ),
1631
+ /* @__PURE__ */ jsxRuntime.jsx(
1632
+ core.Progress,
1633
+ {
1634
+ color: props.color,
1635
+ w: "100%",
1636
+ size: "sm",
1637
+ value: props.progressToLevel
1638
+ }
1639
+ )
1640
+ ]
1641
+ }
1642
+ );
1643
+ }
1644
+ var ModalContext = react.createContext(null);
1645
+ function useModal(selector) {
1646
+ const modal = react.useContext(ModalContext);
1647
+ if (!modal) {
1648
+ throw new Error("useModal must be used within a ModalProvider");
1649
+ }
1650
+ return zustand.useStore(modal, selector);
1651
+ }
1652
+ function ModalProvider({ children, defaultPage }) {
1653
+ const storeRef = react.useRef(
1654
+ zustand.create(() => ({
1655
+ active: null
1656
+ }))
1657
+ );
1658
+ return /* @__PURE__ */ jsxRuntime.jsxs(ModalContext.Provider, { value: storeRef.current, children: [
1659
+ /* @__PURE__ */ jsxRuntime.jsx(Modal, {}),
1660
+ children
1661
+ ] });
1662
+ }
1663
+ function useModalActions() {
1664
+ const modal = react.useContext(ModalContext);
2019
1665
  if (!modal) throw new Error("useModalActions must be used within a ModalProvider");
2020
1666
  const showModal = (openModal) => {
2021
1667
  modal.setState({ active: openModal });
@@ -2144,6 +1790,472 @@ function Modal() {
2144
1790
  }
2145
1791
  ) });
2146
1792
  }
1793
+ var useNuiEvent = (action, handler) => {
1794
+ const savedHandler = react.useRef(noop);
1795
+ react.useEffect(() => {
1796
+ savedHandler.current = handler;
1797
+ }, [handler]);
1798
+ react.useEffect(() => {
1799
+ const eventListener = (event) => {
1800
+ const { action: eventAction, data } = event.data;
1801
+ if (savedHandler.current) {
1802
+ if (eventAction === action) {
1803
+ savedHandler.current(data);
1804
+ }
1805
+ }
1806
+ };
1807
+ window.addEventListener("message", eventListener);
1808
+ return () => window.removeEventListener("message", eventListener);
1809
+ }, [action]);
1810
+ };
1811
+ function getNested(obj, path) {
1812
+ return path.split(".").reduce((acc, key) => acc ? acc[key] : void 0, obj);
1813
+ }
1814
+ function setNested(obj, path, value) {
1815
+ const keys = path.split(".");
1816
+ const newObj = { ...obj };
1817
+ let current = newObj;
1818
+ for (let i = 0; i < keys.length - 1; i++) {
1819
+ const key = keys[i];
1820
+ current[key] = { ...current[key] || {} };
1821
+ current = current[key];
1822
+ }
1823
+ current[keys[keys.length - 1]] = value;
1824
+ return newObj;
1825
+ }
1826
+ function deleteNested(obj, path) {
1827
+ const keys = path.split(".");
1828
+ const newObj = { ...obj };
1829
+ let current = newObj;
1830
+ for (let i = 0; i < keys.length - 1; i++) {
1831
+ const key = keys[i];
1832
+ if (!current[key]) return obj;
1833
+ current[key] = { ...current[key] };
1834
+ current = current[key];
1835
+ }
1836
+ delete current[keys[keys.length - 1]];
1837
+ return newObj;
1838
+ }
1839
+ function flattenRules(rules, prefix = "") {
1840
+ const result = {};
1841
+ for (const key in rules) {
1842
+ const fullPath = prefix ? `${prefix}.${key}` : key;
1843
+ const val = rules[key];
1844
+ if (typeof val === "function") result[fullPath] = val;
1845
+ else if (typeof val === "object")
1846
+ Object.assign(result, flattenRules(val, fullPath));
1847
+ }
1848
+ return result;
1849
+ }
1850
+ function createFormStore(initialValues, validationRules, onSubmit) {
1851
+ const flatRules = validationRules ? flattenRules(validationRules) : {};
1852
+ const history = [];
1853
+ const future = [];
1854
+ const changed = /* @__PURE__ */ new Set();
1855
+ return zustand.createStore((set, get) => ({
1856
+ initialValues,
1857
+ values: initialValues,
1858
+ errors: {},
1859
+ canBack: false,
1860
+ canForward: false,
1861
+ changedFields: [],
1862
+ changedCount: 0,
1863
+ onSubmit,
1864
+ submit: () => {
1865
+ const state = get();
1866
+ const isValid = state.validate();
1867
+ if (isValid && state.onSubmit) state.onSubmit(get());
1868
+ },
1869
+ resetChangeCount: () => {
1870
+ changed.clear();
1871
+ set(() => ({
1872
+ changedFields: [],
1873
+ changedCount: 0
1874
+ }));
1875
+ },
1876
+ setInitialValues: (newInitialValues) => set({ initialValues: newInitialValues }),
1877
+ setValue: (path, value) => {
1878
+ const currentValues = get().values;
1879
+ const newValues = setNested(currentValues, path, value);
1880
+ const oldValue = getNested(get().initialValues, path);
1881
+ history.push(currentValues);
1882
+ future.length = 0;
1883
+ if (value !== oldValue) changed.add(path);
1884
+ else changed.delete(path);
1885
+ set({
1886
+ values: newValues,
1887
+ canBack: history.length > 0,
1888
+ canForward: false,
1889
+ changedFields: Array.from(changed),
1890
+ changedCount: changed.size
1891
+ });
1892
+ const rule = flatRules[path];
1893
+ if (rule) {
1894
+ const error2 = rule(value, newValues);
1895
+ if (error2)
1896
+ set((state) => ({ errors: setNested(state.errors, path, error2) }));
1897
+ else set((state) => ({ errors: deleteNested(state.errors, path) }));
1898
+ }
1899
+ },
1900
+ setError: (path, message) => set((state) => ({ errors: setNested(state.errors, path, message) })),
1901
+ clearError: (path) => set((state) => ({ errors: deleteNested(state.errors, path) })),
1902
+ validateField: (path) => {
1903
+ const state = get();
1904
+ const rule = flatRules[path];
1905
+ if (!rule) return true;
1906
+ const value = getNested(state.values, path);
1907
+ const error2 = rule(value, state.values);
1908
+ if (error2) {
1909
+ set((state2) => ({ errors: setNested(state2.errors, path, error2) }));
1910
+ return false;
1911
+ } else {
1912
+ set((state2) => ({ errors: deleteNested(state2.errors, path) }));
1913
+ return true;
1914
+ }
1915
+ },
1916
+ validate: () => {
1917
+ const state = get();
1918
+ let isValid = true;
1919
+ let newErrors = {};
1920
+ for (const path in flatRules) {
1921
+ const rule = flatRules[path];
1922
+ const value = getNested(state.values, path);
1923
+ const error2 = rule(value, state.values);
1924
+ if (error2) {
1925
+ isValid = false;
1926
+ newErrors = setNested(newErrors, path, error2);
1927
+ }
1928
+ }
1929
+ set({ errors: newErrors });
1930
+ return isValid;
1931
+ },
1932
+ reset: () => {
1933
+ history.length = 0;
1934
+ future.length = 0;
1935
+ changed.clear();
1936
+ set({
1937
+ values: initialValues,
1938
+ errors: {},
1939
+ canBack: false,
1940
+ canForward: false,
1941
+ changedFields: [],
1942
+ changedCount: 0
1943
+ });
1944
+ },
1945
+ back: () => {
1946
+ const state = get();
1947
+ if (history.length === 0) return;
1948
+ const prev = history.pop();
1949
+ future.push(state.values);
1950
+ changed.clear();
1951
+ const current = prev;
1952
+ const initial = get().initialValues;
1953
+ for (const key in current) {
1954
+ if (JSON.stringify(current[key]) !== JSON.stringify(initial[key]))
1955
+ changed.add(key);
1956
+ }
1957
+ set({
1958
+ values: prev,
1959
+ canBack: history.length > 0,
1960
+ canForward: true,
1961
+ changedFields: Array.from(changed),
1962
+ changedCount: changed.size
1963
+ });
1964
+ },
1965
+ forward: () => {
1966
+ const state = get();
1967
+ if (future.length === 0) return;
1968
+ const next = future.pop();
1969
+ history.push(state.values);
1970
+ changed.clear();
1971
+ const current = next;
1972
+ const initial = get().initialValues;
1973
+ for (const key in current) {
1974
+ if (JSON.stringify(current[key]) !== JSON.stringify(initial[key]))
1975
+ changed.add(key);
1976
+ }
1977
+ set({
1978
+ values: next,
1979
+ canBack: true,
1980
+ canForward: future.length > 0,
1981
+ changedFields: Array.from(changed),
1982
+ changedCount: changed.size
1983
+ });
1984
+ }
1985
+ }));
1986
+ }
1987
+ var FormContext = react.createContext(null);
1988
+ function FormProvider({
1989
+ initialValues,
1990
+ validate,
1991
+ onSubmit,
1992
+ children
1993
+ }) {
1994
+ const storeRef = react.useRef(createFormStore(initialValues, validate, onSubmit));
1995
+ return /* @__PURE__ */ jsxRuntime.jsx(FormContext.Provider, { value: storeRef.current, children });
1996
+ }
1997
+ function useForm() {
1998
+ const store = react.useContext(FormContext);
1999
+ if (!store) throw new Error("useForm must be used inside a <FormProvider>");
2000
+ return zustand.useStore(store);
2001
+ }
2002
+ var label = {
2003
+ fontSize: "var(--mantine-font-size-xs)",
2004
+ fontFamily: "Akrobat Bold",
2005
+ letterSpacing: "0.05em",
2006
+ textTransform: "uppercase"
2007
+ };
2008
+ var error = {
2009
+ fontSize: "var(--mantine-font-size-xs)",
2010
+ fontFamily: "Akrobat Regular"
2011
+ };
2012
+ var theme = core.createTheme({
2013
+ primaryColor: "dirk",
2014
+ primaryShade: 9,
2015
+ defaultRadius: "xs",
2016
+ fontFamily: "Akrobat Regular, sans-serif",
2017
+ radius: {
2018
+ xxs: "0.2vh",
2019
+ xs: "0.4vh",
2020
+ sm: "0.75vh",
2021
+ md: "1vh",
2022
+ lg: "1.5vh",
2023
+ xl: "2vh",
2024
+ xxl: "3vh"
2025
+ },
2026
+ fontSizes: {
2027
+ xxs: "1.2vh",
2028
+ xs: "1.5vh",
2029
+ sm: "1.8vh",
2030
+ md: "2.2vh",
2031
+ lg: "2.8vh",
2032
+ xl: "3.3vh",
2033
+ xxl: "3.8vh"
2034
+ },
2035
+ lineHeights: {
2036
+ xxs: "1.4vh",
2037
+ xs: "1.8vh",
2038
+ sm: "2.2vh",
2039
+ md: "2.8vh",
2040
+ lg: "3.3vh",
2041
+ xl: "3.8vh"
2042
+ },
2043
+ spacing: {
2044
+ xxs: "0.5vh",
2045
+ xs: "0.75vh",
2046
+ sm: "1.5vh",
2047
+ md: "2vh",
2048
+ lg: "3vh",
2049
+ xl: "4vh",
2050
+ xxl: "5vh"
2051
+ },
2052
+ components: {
2053
+ Progress: {
2054
+ styles: {
2055
+ label: {
2056
+ fontFamily: "Akrobat Bold",
2057
+ letterSpacing: "0.05em",
2058
+ textTransform: "uppercase"
2059
+ },
2060
+ root: {
2061
+ backgroundColor: "rgba(77, 77, 77, 0.4)"
2062
+ }
2063
+ }
2064
+ },
2065
+ Textarea: {
2066
+ styles: {
2067
+ label,
2068
+ error
2069
+ }
2070
+ },
2071
+ Button: {
2072
+ styles: {
2073
+ root: {
2074
+ fontSize: "var(--mantine-font-size-xs)"
2075
+ }
2076
+ }
2077
+ },
2078
+ Select: {
2079
+ styles: {
2080
+ input: {
2081
+ padding: "var(--mantine-spacing-sm)"
2082
+ }
2083
+ }
2084
+ },
2085
+ Pill: {
2086
+ styles: (theme2) => ({
2087
+ root: {
2088
+ display: "inline-flex",
2089
+ alignItems: "center",
2090
+ justifyContent: "space-between",
2091
+ backgroundColor: "rgba(76, 76, 76, 0.3)",
2092
+ height: "fit-content",
2093
+ textTransform: "uppercase",
2094
+ letterSpacing: "0.05em",
2095
+ fontFamily: "Akrobat Bold",
2096
+ fontSize: theme2.fontSizes.xs,
2097
+ borderRadius: theme2.defaultRadius,
2098
+ padding: `${theme2.spacing.xs} ${theme2.spacing.sm}`
2099
+ }
2100
+ })
2101
+ },
2102
+ Input: {
2103
+ styles: {
2104
+ label,
2105
+ error,
2106
+ input: {
2107
+ padding: "var(--mantine-spacing-sm)",
2108
+ backgroundColor: "rgba(76, 76, 76, 0.3)"
2109
+ }
2110
+ }
2111
+ },
2112
+ ColorInput: {
2113
+ styles: {
2114
+ label,
2115
+ input: {
2116
+ padding: "var(--mantine-spacing-sm)"
2117
+ }
2118
+ }
2119
+ },
2120
+ TextInput: {
2121
+ styles: {
2122
+ label,
2123
+ wrapper: {},
2124
+ section: {
2125
+ marginRight: "0.2vh"
2126
+ },
2127
+ input: {
2128
+ padding: "var(--mantine-spacing-sm)"
2129
+ }
2130
+ }
2131
+ },
2132
+ NumberInput: {
2133
+ styles: {
2134
+ label,
2135
+ input: {
2136
+ padding: "var(--mantine-spacing-sm)"
2137
+ },
2138
+ section: {
2139
+ pointerEvents: "all"
2140
+ }
2141
+ }
2142
+ }
2143
+ },
2144
+ colors: {
2145
+ dirk: [
2146
+ "#ffffff",
2147
+ "#f3fce9",
2148
+ "#dbf5bd",
2149
+ "#c3ee91",
2150
+ "#ace765",
2151
+ "#94e039",
2152
+ "#7ac61f",
2153
+ "#5f9a18",
2154
+ "#29420a",
2155
+ "#446e11"
2156
+ ]
2157
+ }
2158
+ });
2159
+ var theme_default = theme;
2160
+ fontawesomeSvgCore.library.add(freeSolidSvgIcons.fas, freeRegularSvgIcons.far, freeBrandsSvgIcons.fab);
2161
+ var useSettings = zustand.create((set) => ({
2162
+ game: "fivem",
2163
+ primaryColor: "dirk",
2164
+ primaryShade: 9,
2165
+ itemImgPath: "https://assets.dirkcfx.com/items/",
2166
+ customTheme: {}
2167
+ }));
2168
+ function DirkProvider(props) {
2169
+ const primaryColor = useSettings((data) => data.primaryColor);
2170
+ const primaryShade = useSettings((data) => data.primaryShade);
2171
+ const customTheme = useSettings((data) => data.customTheme);
2172
+ const game = useSettings((data) => data.game);
2173
+ const mergedTheme = react.useMemo(() => ({
2174
+ ...theme_default,
2175
+ primaryColor,
2176
+ primaryShade,
2177
+ colors: {
2178
+ ...theme_default.colors,
2179
+ ...customTheme
2180
+ // Custom theme colors will override/extend base colors
2181
+ }
2182
+ }), [primaryColor, primaryShade, customTheme]);
2183
+ react.useEffect(() => {
2184
+ document.fonts.ready.then(() => {
2185
+ document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : game === "fivem" ? '"Akrobat Regular", sans-serif' : "sans-serif";
2186
+ console.log(`Game set to ${game}, applied corresponding font family.: ${document.body.style.fontFamily}`);
2187
+ });
2188
+ }, [game]);
2189
+ react.useEffect(() => {
2190
+ fetchNui("NUI_READY");
2191
+ }, []);
2192
+ useAutoFetcher();
2193
+ return /* @__PURE__ */ jsxRuntime.jsx(core.MantineProvider, { theme: mergedTheme, defaultColorScheme: "dark", children: /* @__PURE__ */ jsxRuntime.jsx(Wrapper, { children: props.children }) });
2194
+ }
2195
+ function Wrapper({ children }) {
2196
+ const game = useSettings((data) => data.game);
2197
+ return isEnvBrowser() ? /* @__PURE__ */ jsxRuntime.jsx(
2198
+ core.BackgroundImage,
2199
+ {
2200
+ w: "100vw",
2201
+ h: "100vh",
2202
+ style: { overflow: "hidden" },
2203
+ 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",
2204
+ children
2205
+ }
2206
+ ) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
2207
+ }
2208
+ function useTornEdges() {
2209
+ const game = useSettings((state) => state.game);
2210
+ return game === "rdr3" ? "torn-edge-wrapper" : "";
2211
+ }
2212
+ function TornEdgeSVGFilter() {
2213
+ return /* @__PURE__ */ jsxRuntime.jsx(
2214
+ "svg",
2215
+ {
2216
+ style: { position: "absolute", width: 0, height: 0, pointerEvents: "none" },
2217
+ "aria-hidden": "true",
2218
+ children: /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: "torn-edge-filter", x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
2219
+ /* @__PURE__ */ jsxRuntime.jsx(
2220
+ "feTurbulence",
2221
+ {
2222
+ type: "fractalNoise",
2223
+ baseFrequency: "0.018 0.022",
2224
+ numOctaves: "5",
2225
+ seed: "9",
2226
+ result: "noise1"
2227
+ }
2228
+ ),
2229
+ /* @__PURE__ */ jsxRuntime.jsx(
2230
+ "feTurbulence",
2231
+ {
2232
+ type: "fractalNoise",
2233
+ baseFrequency: "0.08 0.12",
2234
+ numOctaves: "2",
2235
+ seed: "3",
2236
+ result: "noise2"
2237
+ }
2238
+ ),
2239
+ /* @__PURE__ */ jsxRuntime.jsx("feBlend", { in: "noise1", in2: "noise2", mode: "multiply", result: "combinedNoise" }),
2240
+ /* @__PURE__ */ jsxRuntime.jsx(
2241
+ "feDisplacementMap",
2242
+ {
2243
+ in: "SourceGraphic",
2244
+ in2: "combinedNoise",
2245
+ scale: "52",
2246
+ xChannelSelector: "R",
2247
+ yChannelSelector: "G",
2248
+ result: "displaced"
2249
+ }
2250
+ ),
2251
+ /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "0.8", in: "displaced", result: "blurred" }),
2252
+ /* @__PURE__ */ jsxRuntime.jsx("feComponentTransfer", { in: "blurred", result: "alphaFade", children: /* @__PURE__ */ jsxRuntime.jsx("feFuncA", { type: "gamma", amplitude: "1", exponent: "1.3", offset: "-0.05" }) }),
2253
+ /* @__PURE__ */ jsxRuntime.jsx("feMorphology", { operator: "erode", radius: "0.4", in: "alphaFade", result: "eroded" }),
2254
+ /* @__PURE__ */ jsxRuntime.jsx("feMerge", { children: /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "eroded" }) })
2255
+ ] }) })
2256
+ }
2257
+ );
2258
+ }
2147
2259
 
2148
2260
  exports.BorderedIcon = BorderedIcon;
2149
2261
  exports.Counter = Counter;
@@ -2152,6 +2264,7 @@ exports.FloatingParticles = FloatingParticles;
2152
2264
  exports.FormProvider = FormProvider;
2153
2265
  exports.InfoBox = InfoBox;
2154
2266
  exports.InputContainer = InputContainer;
2267
+ exports.LevelBanner = LevelBanner;
2155
2268
  exports.ModalContext = ModalContext;
2156
2269
  exports.ModalProvider = ModalProvider;
2157
2270
  exports.MotionFlex = MotionFlex;
@@ -2170,6 +2283,7 @@ exports.copyToClipboard = copyToClipboard;
2170
2283
  exports.createFormStore = createFormStore;
2171
2284
  exports.createSkill = createSkill;
2172
2285
  exports.fetchNui = fetchNui;
2286
+ exports.getImageShape = getImageShape;
2173
2287
  exports.initialFetches = initialFetches;
2174
2288
  exports.internalEvent = internalEvent;
2175
2289
  exports.isEnvBrowser = isEnvBrowser;
@@ -2182,6 +2296,8 @@ exports.openLink = openLink;
2182
2296
  exports.registerInitialFetch = registerInitialFetch;
2183
2297
  exports.runFetches = runFetches;
2184
2298
  exports.splitFAString = splitFAString;
2299
+ exports.updatePresignedURL = updatePresignedURL;
2300
+ exports.uploadImage = uploadImage;
2185
2301
  exports.useAutoFetcher = useAutoFetcher;
2186
2302
  exports.useForm = useForm;
2187
2303
  exports.useModal = useModal;