dirk-cfx-react 1.1.53 → 1.1.55

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,15 +1,16 @@
1
1
  'use strict';
2
2
 
3
- var React3 = require('react');
3
+ var core = require('@mantine/core');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var React4 = require('react');
4
6
  var zustand = require('zustand');
5
7
  var axios = require('axios');
6
8
  var reactFontawesome = require('@fortawesome/react-fontawesome');
7
- var core = require('@mantine/core');
8
- var jsxRuntime = require('react/jsx-runtime');
9
9
  var framerMotion = require('framer-motion');
10
10
  var clickSoundUrl = require('./click_sound-PNCRRTM4.mp3');
11
11
  var hoverSoundUrl = require('./hover_sound-NBUA222C.mp3');
12
- var hooks = require('@mantine/hooks');
12
+ var lucideReact = require('lucide-react');
13
+ var reactQuery = require('@tanstack/react-query');
13
14
  require('@mantine/core/styles.css');
14
15
  require('@mantine/notifications/styles.css');
15
16
  require('./styles/fonts.css');
@@ -23,7 +24,7 @@ var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
23
24
 
24
25
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
25
26
 
26
- var React3__default = /*#__PURE__*/_interopDefault(React3);
27
+ var React4__default = /*#__PURE__*/_interopDefault(React4);
27
28
  var axios__default = /*#__PURE__*/_interopDefault(axios);
28
29
  var clickSoundUrl__default = /*#__PURE__*/_interopDefault(clickSoundUrl);
29
30
  var hoverSoundUrl__default = /*#__PURE__*/_interopDefault(hoverSoundUrl);
@@ -31,6 +32,1053 @@ var hoverSoundUrl__default = /*#__PURE__*/_interopDefault(hoverSoundUrl);
31
32
  var __defProp = Object.defineProperty;
32
33
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
33
34
  var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
35
+ var BLIP_ENTRIES = [
36
+ [0, "radar_higher", "gif"],
37
+ [1, "radar_level", "png"],
38
+ [2, "radar_lower", "gif"],
39
+ [3, "radar_police_ped", "gif"],
40
+ [4, "radar_wanted_radius", "png"],
41
+ [5, "radar_area_blip", "png"],
42
+ [6, "radar_centre", "png"],
43
+ [7, "radar_north", "png"],
44
+ [8, "radar_waypoint", "png"],
45
+ [9, "radar_radius_blip", "png"],
46
+ [10, "radar_radius_outline_blip", "png"],
47
+ [11, "radar_weapon_higher", "gif"],
48
+ [12, "radar_weapon_lower", "gif"],
49
+ [13, "radar_higher_ai", "gif"],
50
+ [14, "radar_lower_ai", "gif"],
51
+ [15, "radar_police_heli_spin", "gif"],
52
+ [16, "radar_police_plane_move", "png"],
53
+ [27, "radar_mp_crew", "png"],
54
+ [28, "radar_mp_friendlies", "png"],
55
+ [36, "radar_cable_car", "png"],
56
+ [37, "radar_activities", "png"],
57
+ [38, "radar_raceflag", "png"],
58
+ [40, "radar_safehouse", "png"],
59
+ [41, "radar_police", "gif"],
60
+ [42, "radar_police_chase", "gif"],
61
+ [43, "radar_police_heli", "png"],
62
+ [44, "radar_bomb_a", "png"],
63
+ [47, "radar_snitch", "png"],
64
+ [48, "radar_planning_locations", "png"],
65
+ [50, "radar_crim_carsteal", "png"],
66
+ [51, "radar_crim_drugs", "png"],
67
+ [52, "radar_crim_holdups", "png"],
68
+ [54, "radar_crim_player", "png"],
69
+ [56, "radar_cop_patrol", "png"],
70
+ [57, "radar_cop_player", "png"],
71
+ [58, "radar_crim_wanted", "png"],
72
+ [59, "radar_heist", "png"],
73
+ [60, "radar_police_station", "png"],
74
+ [61, "radar_hospital", "png"],
75
+ [62, "radar_assassins_mark", "png"],
76
+ [63, "radar_elevator", "png"],
77
+ [64, "radar_helicopter", "png"],
78
+ [66, "radar_random_character", "png"],
79
+ [67, "radar_security_van", "png"],
80
+ [68, "radar_tow_truck", "png"],
81
+ [70, "radar_illegal_parking", "png"],
82
+ [71, "radar_barber", "png"],
83
+ [72, "radar_car_mod_shop", "png"],
84
+ [73, "radar_clothes_store", "png"],
85
+ [75, "radar_tattoo", "png"],
86
+ [76, "radar_armenian_family", "png"],
87
+ [77, "radar_lester_family", "png"],
88
+ [78, "radar_michael_family", "png"],
89
+ [79, "radar_trevor_family", "png"],
90
+ [80, "radar_jewelry_heist", "png"],
91
+ [82, "radar_drag_race_finish", "png"],
92
+ [84, "radar_rampage", "png"],
93
+ [85, "radar_vinewood_tours", "png"],
94
+ [86, "radar_lamar_family", "png"],
95
+ [88, "radar_franklin_family", "png"],
96
+ [89, "radar_chinese_strand", "png"],
97
+ [90, "radar_flight_school", "png"],
98
+ [91, "radar_eye_sky", "png"],
99
+ [92, "radar_air_hockey", "png"],
100
+ [93, "radar_bar", "png"],
101
+ [94, "radar_base_jump", "png"],
102
+ [95, "radar_basketball", "png"],
103
+ [96, "radar_biolab_heist", "png"],
104
+ [99, "radar_cabaret_club", "png"],
105
+ [100, "radar_car_wash", "png"],
106
+ [102, "radar_comedy_club", "png"],
107
+ [103, "radar_darts", "png"],
108
+ [104, "radar_docks_heist", "png"],
109
+ [105, "radar_fbi_heist", "png"],
110
+ [106, "radar_fbi_officers_strand", "png"],
111
+ [107, "radar_finale_bank_heist", "png"],
112
+ [108, "radar_financier_strand", "png"],
113
+ [109, "radar_golf", "png"],
114
+ [110, "radar_gun_shop", "png"],
115
+ [111, "radar_internet_cafe", "png"],
116
+ [112, "radar_michael_family_exile", "png"],
117
+ [113, "radar_nice_house_heist", "png"],
118
+ [114, "radar_random_female", "png"],
119
+ [115, "radar_random_male", "png"],
120
+ [118, "radar_rural_bank_heist", "png"],
121
+ [119, "radar_shooting_range", "png"],
122
+ [120, "radar_solomon_strand", "png"],
123
+ [121, "radar_strip_club", "png"],
124
+ [122, "radar_tennis", "png"],
125
+ [123, "radar_trevor_family_exile", "png"],
126
+ [124, "radar_michael_trevor_family", "png"],
127
+ [126, "radar_triathlon", "png"],
128
+ [127, "radar_off_road_racing", "png"],
129
+ [128, "radar_gang_cops", "png"],
130
+ [129, "radar_gang_mexicans", "png"],
131
+ [130, "radar_gang_bikers", "png"],
132
+ [133, "radar_snitch_red", "png"],
133
+ [134, "radar_crim_cuff_keys", "png"],
134
+ [135, "radar_cinema", "png"],
135
+ [136, "radar_music_venue", "png"],
136
+ [137, "radar_police_station_blue", "png"],
137
+ [138, "radar_airport", "png"],
138
+ [139, "radar_crim_saved_vehicle", "png"],
139
+ [140, "radar_weed_stash", "png"],
140
+ [141, "radar_hunting", "png"],
141
+ [142, "radar_pool", "png"],
142
+ [143, "radar_objective_blue", "png"],
143
+ [144, "radar_objective_green", "png"],
144
+ [145, "radar_objective_red", "png"],
145
+ [146, "radar_objective_yellow", "png"],
146
+ [147, "radar_arms_dealing", "png"],
147
+ [148, "radar_mp_friend", "png"],
148
+ [149, "radar_celebrity_theft", "png"],
149
+ [150, "radar_weapon_assault_rifle", "png"],
150
+ [151, "radar_weapon_bat", "png"],
151
+ [152, "radar_weapon_grenade", "png"],
152
+ [153, "radar_weapon_health", "png"],
153
+ [154, "radar_weapon_knife", "png"],
154
+ [155, "radar_weapon_molotov", "png"],
155
+ [156, "radar_weapon_pistol", "png"],
156
+ [157, "radar_weapon_rocket", "png"],
157
+ [158, "radar_weapon_shotgun", "png"],
158
+ [159, "radar_weapon_smg", "png"],
159
+ [160, "radar_weapon_sniper", "png"],
160
+ [161, "radar_mp_noise", "gif"],
161
+ [162, "radar_poi", "png"],
162
+ [163, "radar_passive", "png"],
163
+ [164, "radar_usingmenu", "png"],
164
+ [171, "radar_gang_cops_partner", "png"],
165
+ [173, "radar_weapon_minigun", "png"],
166
+ [175, "radar_weapon_armour", "png"],
167
+ [176, "radar_property_takeover", "png"],
168
+ [177, "radar_gang_mexicans_highlight", "png"],
169
+ [178, "radar_gang_bikers_highlight", "png"],
170
+ [179, "radar_triathlon_cycling", "png"],
171
+ [180, "radar_triathlon_swimming", "png"],
172
+ [181, "radar_property_takeover_bikers", "png"],
173
+ [182, "radar_property_takeover_cops", "png"],
174
+ [183, "radar_property_takeover_vagos", "png"],
175
+ [184, "radar_camera", "png"],
176
+ [185, "radar_centre_red", "png"],
177
+ [186, "radar_handcuff_keys_bikers", "png"],
178
+ [187, "radar_handcuff_keys_vagos", "png"],
179
+ [188, "radar_handcuffs_closed_bikers", "png"],
180
+ [189, "radar_handcuffs_closed_vagos", "png"],
181
+ [192, "radar_camera_badger", "png"],
182
+ [193, "radar_camera_facade", "png"],
183
+ [194, "radar_camera_ifruit", "png"],
184
+ [197, "radar_yoga", "png"],
185
+ [198, "radar_taxi", "png"],
186
+ [205, "radar_shrink", "png"],
187
+ [206, "radar_epsilon", "png"],
188
+ [207, "radar_financier_strand_grey", "png"],
189
+ [208, "radar_trevor_family_grey", "png"],
190
+ [209, "radar_trevor_family_red", "png"],
191
+ [210, "radar_franklin_family_grey", "png"],
192
+ [211, "radar_franklin_family_blue", "png"],
193
+ [212, "radar_franklin_a", "png"],
194
+ [213, "radar_franklin_b", "png"],
195
+ [214, "radar_franklin_c", "png"],
196
+ [225, "radar_gang_vehicle", "png"],
197
+ [226, "radar_gang_vehicle_bikers", "png"],
198
+ [227, "radar_gang_vehicle_cops", "png"],
199
+ [228, "radar_gang_vehicle_vagos", "png"],
200
+ [229, "radar_guncar", "png"],
201
+ [230, "radar_driving_bikers", "png"],
202
+ [231, "radar_driving_cops", "png"],
203
+ [232, "radar_driving_vagos", "png"],
204
+ [233, "radar_gang_cops_highlight", "png"],
205
+ [234, "radar_shield_bikers", "png"],
206
+ [235, "radar_shield_cops", "png"],
207
+ [236, "radar_shield_vagos", "png"],
208
+ [237, "radar_custody_bikers", "png"],
209
+ [238, "radar_custody_vagos", "png"],
210
+ [251, "radar_arms_dealing_air", "png"],
211
+ [252, "radar_playerstate_arrested", "png"],
212
+ [253, "radar_playerstate_custody", "png"],
213
+ [254, "radar_playerstate_driving", "png"],
214
+ [255, "radar_playerstate_keyholder", "png"],
215
+ [256, "radar_playerstate_partner", "png"],
216
+ [262, "radar_ztype", "png"],
217
+ [263, "radar_stinger", "png"],
218
+ [264, "radar_packer", "png"],
219
+ [265, "radar_monroe", "png"],
220
+ [266, "radar_fairground", "png"],
221
+ [267, "radar_property", "png"],
222
+ [268, "radar_gang_highlight", "png"],
223
+ [269, "radar_altruist", "png"],
224
+ [270, "radar_ai", "png"],
225
+ [271, "radar_on_mission", "png"],
226
+ [272, "radar_cash_pickup", "png"],
227
+ [273, "radar_chop", "png"],
228
+ [274, "radar_dead", "png"],
229
+ [275, "radar_territory_locked", "png"],
230
+ [276, "radar_cash_lost", "png"],
231
+ [277, "radar_cash_vagos", "png"],
232
+ [278, "radar_cash_cops", "png"],
233
+ [279, "radar_hooker", "png"],
234
+ [280, "radar_friend", "png"],
235
+ [281, "radar_mission_2to4", "png"],
236
+ [282, "radar_mission_2to8", "png"],
237
+ [283, "radar_mission_2to12", "png"],
238
+ [284, "radar_mission_2to16", "png"],
239
+ [285, "radar_custody_dropoff", "png"],
240
+ [286, "radar_onmission_cops", "png"],
241
+ [287, "radar_onmission_lost", "png"],
242
+ [288, "radar_onmission_vagos", "png"],
243
+ [289, "radar_crim_carsteal_cops", "png"],
244
+ [290, "radar_crim_carsteal_bikers", "png"],
245
+ [291, "radar_crim_carsteal_vagos", "png"],
246
+ [292, "radar_band_strand", "png"],
247
+ [293, "radar_simeon_family", "png"],
248
+ [294, "radar_mission_1", "png"],
249
+ [295, "radar_mission_2", "png"],
250
+ [296, "radar_friend_darts", "png"],
251
+ [297, "radar_friend_comedyclub", "png"],
252
+ [298, "radar_friend_cinema", "png"],
253
+ [299, "radar_friend_tennis", "png"],
254
+ [300, "radar_friend_stripclub", "png"],
255
+ [301, "radar_friend_livemusic", "png"],
256
+ [302, "radar_friend_golf", "png"],
257
+ [303, "radar_bounty_hit", "png"],
258
+ [304, "radar_ugc_mission", "png"],
259
+ [305, "radar_horde", "png"],
260
+ [306, "radar_cratedrop", "png"],
261
+ [307, "radar_plane_drop", "png"],
262
+ [308, "radar_sub", "png"],
263
+ [309, "radar_race", "png"],
264
+ [310, "radar_deathmatch", "png"],
265
+ [311, "radar_arm_wrestling", "png"],
266
+ [312, "radar_mission_1to2", "png"],
267
+ [313, "radar_shootingrange_gunshop", "png"],
268
+ [314, "radar_race_air", "png"],
269
+ [315, "radar_race_land", "png"],
270
+ [316, "radar_race_sea", "png"],
271
+ [317, "radar_tow", "png"],
272
+ [318, "radar_garbage", "png"],
273
+ [319, "radar_drill", "png"],
274
+ [320, "radar_spikes", "png"],
275
+ [321, "radar_firetruck", "png"],
276
+ [322, "radar_minigun2", "png"],
277
+ [323, "radar_bugstar", "png"],
278
+ [324, "radar_submarine", "png"],
279
+ [325, "radar_chinook", "png"],
280
+ [326, "radar_getaway_car", "png"],
281
+ [327, "radar_mission_bikers_1", "png"],
282
+ [328, "radar_mission_bikers_1to2", "png"],
283
+ [329, "radar_mission_bikers_2", "png"],
284
+ [330, "radar_mission_bikers_2to4", "png"],
285
+ [331, "radar_mission_bikers_2to8", "png"],
286
+ [332, "radar_mission_bikers_2to12", "png"],
287
+ [333, "radar_mission_bikers_2to16", "png"],
288
+ [334, "radar_mission_cops_1", "png"],
289
+ [335, "radar_mission_cops_1to2", "png"],
290
+ [336, "radar_mission_cops_2", "png"],
291
+ [337, "radar_mission_cops_2to4", "png"],
292
+ [338, "radar_mission_cops_2to8", "png"],
293
+ [339, "radar_mission_cops_2to12", "png"],
294
+ [340, "radar_mission_cops_2to16", "png"],
295
+ [341, "radar_mission_vagos_1", "png"],
296
+ [342, "radar_mission_vagos_1to2", "png"],
297
+ [343, "radar_mission_vagos_2", "png"],
298
+ [344, "radar_mission_vagos_2to4", "png"],
299
+ [345, "radar_mission_vagos_2to8", "png"],
300
+ [346, "radar_mission_vagos_2to12", "png"],
301
+ [347, "radar_mission_vagos_2to16", "png"],
302
+ [348, "radar_gang_bike", "png"],
303
+ [349, "radar_gas_grenade", "png"],
304
+ [350, "radar_property_for_sale", "png"],
305
+ [351, "radar_gang_attack_package", "png"],
306
+ [352, "radar_martin_madrazzo", "png"],
307
+ [353, "radar_enemy_heli_spin", "gif"],
308
+ [354, "radar_boost", "png"],
309
+ [355, "radar_devin", "png"],
310
+ [356, "radar_dock", "png"],
311
+ [357, "radar_garage", "png"],
312
+ [358, "radar_golf_flag", "png"],
313
+ [359, "radar_hangar", "png"],
314
+ [360, "radar_helipad", "png"],
315
+ [361, "radar_jerry_can", "png"],
316
+ [362, "radar_mask", "png"],
317
+ [363, "radar_heist_prep", "png"],
318
+ [364, "radar_incapacitated", "png"],
319
+ [365, "radar_spawn_point_pickup", "png"],
320
+ [366, "radar_boilersuit", "png"],
321
+ [367, "radar_completed", "png"],
322
+ [368, "radar_rockets", "png"],
323
+ [369, "radar_garage_for_sale", "png"],
324
+ [370, "radar_helipad_for_sale", "png"],
325
+ [371, "radar_dock_for_sale", "png"],
326
+ [372, "radar_hangar_for_sale", "png"],
327
+ [373, "radar_placeholder_6", "png"],
328
+ [374, "radar_business", "png"],
329
+ [375, "radar_business_for_sale", "png"],
330
+ [376, "radar_race_bike", "png"],
331
+ [377, "radar_parachute", "png"],
332
+ [378, "radar_team_deathmatch", "png"],
333
+ [379, "radar_race_foot", "png"],
334
+ [380, "radar_vehicle_deathmatch", "png"],
335
+ [381, "radar_barry", "png"],
336
+ [382, "radar_dom", "png"],
337
+ [383, "radar_maryann", "png"],
338
+ [384, "radar_cletus", "png"],
339
+ [385, "radar_josh", "png"],
340
+ [386, "radar_minute", "png"],
341
+ [387, "radar_omega", "png"],
342
+ [388, "radar_tonya", "png"],
343
+ [389, "radar_paparazzo", "png"],
344
+ [390, "radar_aim", "png"],
345
+ [391, "radar_cratedrop_background", "png"],
346
+ [392, "radar_green_and_net_player1", "png"],
347
+ [393, "radar_green_and_net_player2", "png"],
348
+ [394, "radar_green_and_net_player3", "png"],
349
+ [395, "radar_green_and_friendly", "png"],
350
+ [396, "radar_net_player1_and_net_player2", "png"],
351
+ [397, "radar_net_player1_and_net_player3", "png"],
352
+ [398, "radar_creator", "png"],
353
+ [399, "radar_creator_direction", "png"],
354
+ [400, "radar_abigail", "png"],
355
+ [401, "radar_blimp", "png"],
356
+ [402, "radar_repair", "png"],
357
+ [403, "radar_testosterone", "png"],
358
+ [404, "radar_dinghy", "png"],
359
+ [405, "radar_fanatic", "png"],
360
+ [407, "radar_info_icon", "png"],
361
+ [408, "radar_capture_the_flag", "png"],
362
+ [409, "radar_last_team_standing", "png"],
363
+ [410, "radar_boat", "png"],
364
+ [411, "radar_capture_the_flag_base", "png"],
365
+ [412, "radar_mp_crew", "png"],
366
+ [413, "radar_capture_the_flag_outline", "png"],
367
+ [414, "radar_capture_the_flag_base_nobag", "png"],
368
+ [415, "radar_weapon_jerrycan", "png"],
369
+ [416, "radar_rp", "png"],
370
+ [417, "radar_level_inside", "png"],
371
+ [418, "radar_bounty_hit_inside", "png"],
372
+ [419, "radar_capture_the_usaflag", "png"],
373
+ [420, "radar_capture_the_usaflag_outline", "png"],
374
+ [421, "radar_tank", "png"],
375
+ [422, "radar_player_heli", "gif"],
376
+ [423, "radar_player_plane", "png"],
377
+ [424, "radar_player_jet", "png"],
378
+ [425, "radar_centre_stroke", "png"],
379
+ [426, "radar_player_guncar", "png"],
380
+ [427, "radar_player_boat", "png"],
381
+ [428, "radar_mp_heist", "png"],
382
+ [429, "radar_temp_1", "png"],
383
+ [430, "radar_temp_2", "png"],
384
+ [431, "radar_temp_3", "png"],
385
+ [432, "radar_temp_4", "png"],
386
+ [433, "radar_temp_5", "png"],
387
+ [434, "radar_temp_6", "png"],
388
+ [435, "radar_race_stunt", "png"],
389
+ [436, "radar_hot_property", "png"],
390
+ [437, "radar_urbanwarfare_versus", "png"],
391
+ [438, "radar_king_of_the_castle", "png"],
392
+ [439, "radar_player_king", "png"],
393
+ [440, "radar_dead_drop", "png"],
394
+ [441, "radar_penned_in", "png"],
395
+ [442, "radar_beast", "png"],
396
+ [443, "radar_edge_pointer", "png"],
397
+ [444, "radar_edge_crosstheline", "png"],
398
+ [445, "radar_mp_lamar", "png"],
399
+ [446, "radar_bennys", "png"],
400
+ [447, "radar_corner_number_1", "png"],
401
+ [448, "radar_corner_number_2", "png"],
402
+ [449, "radar_corner_number_3", "png"],
403
+ [450, "radar_corner_number_4", "png"],
404
+ [451, "radar_corner_number_5", "png"],
405
+ [452, "radar_corner_number_6", "png"],
406
+ [453, "radar_corner_number_7", "png"],
407
+ [454, "radar_corner_number_8", "png"],
408
+ [455, "radar_yacht", "png"],
409
+ [456, "radar_finders_keepers", "png"],
410
+ [457, "radar_assault_package", "png"],
411
+ [458, "radar_hunt_the_boss", "png"],
412
+ [459, "radar_sightseer", "png"],
413
+ [460, "radar_turreted_limo", "png"],
414
+ [461, "radar_belly_of_the_beast", "png"],
415
+ [462, "radar_yacht_location", "png"],
416
+ [463, "radar_pickup_beast", "png"],
417
+ [464, "radar_pickup_zoned", "png"],
418
+ [465, "radar_pickup_random", "png"],
419
+ [466, "radar_pickup_slow_time", "png"],
420
+ [467, "radar_pickup_swap", "png"],
421
+ [468, "radar_pickup_thermal", "png"],
422
+ [469, "radar_pickup_weed", "png"],
423
+ [470, "radar_weapon_railgun", "png"],
424
+ [471, "radar_seashark", "png"],
425
+ [472, "radar_pickup_hidden", "png"],
426
+ [473, "radar_warehouse", "png"],
427
+ [474, "radar_warehouse_for_sale", "png"],
428
+ [475, "radar_office", "png"],
429
+ [476, "radar_office_for_sale", "png"],
430
+ [477, "radar_truck", "png"],
431
+ [478, "radar_contraband", "png"],
432
+ [479, "radar_trailer", "png"],
433
+ [480, "radar_vip", "png"],
434
+ [481, "radar_cargobob", "png"],
435
+ [482, "radar_area_outline_blip", "png"],
436
+ [483, "radar_pickup_accelerator", "png"],
437
+ [484, "radar_pickup_ghost", "png"],
438
+ [485, "radar_pickup_detonator", "png"],
439
+ [486, "radar_pickup_bomb", "png"],
440
+ [487, "radar_pickup_armoured", "png"],
441
+ [488, "radar_stunt", "png"],
442
+ [489, "radar_weapon_lives", "png"],
443
+ [490, "radar_stunt_premium", "png"],
444
+ [491, "radar_adversary", "png"],
445
+ [492, "radar_biker_clubhouse", "png"],
446
+ [493, "radar_biker_caged_in", "png"],
447
+ [494, "radar_biker_turf_war", "png"],
448
+ [495, "radar_biker_joust", "png"],
449
+ [496, "radar_production_weed", "png"],
450
+ [497, "radar_production_crack", "png"],
451
+ [498, "radar_production_fake_id", "png"],
452
+ [499, "radar_production_meth", "png"],
453
+ [500, "radar_production_money", "png"],
454
+ [501, "radar_package", "png"],
455
+ [502, "radar_capture_1", "png"],
456
+ [503, "radar_capture_2", "png"],
457
+ [504, "radar_capture_3", "png"],
458
+ [505, "radar_capture_4", "png"],
459
+ [506, "radar_capture_5", "png"],
460
+ [507, "radar_capture_6", "png"],
461
+ [508, "radar_capture_7", "png"],
462
+ [509, "radar_capture_8", "png"],
463
+ [510, "radar_capture_9", "png"],
464
+ [511, "radar_capture_10", "png"],
465
+ [512, "radar_quad", "png"],
466
+ [513, "radar_bus", "png"],
467
+ [514, "radar_drugs_package", "png"],
468
+ [515, "radar_pickup_jump", "png"],
469
+ [516, "radar_adversary_4", "png"],
470
+ [517, "radar_adversary_8", "png"],
471
+ [518, "radar_adversary_10", "png"],
472
+ [519, "radar_adversary_12", "png"],
473
+ [520, "radar_adversary_16", "png"],
474
+ [521, "radar_laptop", "png"],
475
+ [522, "radar_pickup_deadline", "png"],
476
+ [523, "radar_sports_car", "png"],
477
+ [524, "radar_warehouse_vehicle", "png"],
478
+ [525, "radar_reg_papers", "png"],
479
+ [526, "radar_police_station_dropoff", "png"],
480
+ [527, "radar_junkyard", "png"],
481
+ [528, "radar_ex_vech_1", "png"],
482
+ [529, "radar_ex_vech_2", "png"],
483
+ [530, "radar_ex_vech_3", "png"],
484
+ [531, "radar_ex_vech_4", "png"],
485
+ [532, "radar_ex_vech_5", "png"],
486
+ [533, "radar_ex_vech_6", "png"],
487
+ [534, "radar_ex_vech_7", "png"],
488
+ [535, "radar_target_a", "png"],
489
+ [536, "radar_target_b", "png"],
490
+ [537, "radar_target_c", "png"],
491
+ [538, "radar_target_d", "png"],
492
+ [539, "radar_target_e", "png"],
493
+ [540, "radar_target_f", "png"],
494
+ [541, "radar_target_g", "png"],
495
+ [542, "radar_target_h", "png"],
496
+ [543, "radar_jugg", "png"],
497
+ [544, "radar_pickup_repair", "png"],
498
+ [545, "radar_steeringwheel", "png"],
499
+ [546, "radar_trophy", "png"],
500
+ [547, "radar_pickup_rocket_boost", "png"],
501
+ [548, "radar_pickup_homing_rocket", "png"],
502
+ [549, "radar_pickup_machinegun", "png"],
503
+ [550, "radar_pickup_parachute", "png"],
504
+ [551, "radar_pickup_time_5", "png"],
505
+ [552, "radar_pickup_time_10", "png"],
506
+ [553, "radar_pickup_time_15", "png"],
507
+ [554, "radar_pickup_time_20", "png"],
508
+ [555, "radar_pickup_time_30", "png"],
509
+ [556, "radar_supplies", "png"],
510
+ [557, "radar_property_bunker", "png"],
511
+ [558, "radar_gr_wvm_1", "png"],
512
+ [559, "radar_gr_wvm_2", "png"],
513
+ [560, "radar_gr_wvm_3", "png"],
514
+ [561, "radar_gr_wvm_4", "png"],
515
+ [562, "radar_gr_wvm_5", "png"],
516
+ [563, "radar_gr_wvm_6", "png"],
517
+ [564, "radar_gr_covert_ops", "png"],
518
+ [565, "radar_adversary_bunker", "png"],
519
+ [566, "radar_gr_moc_upgrade", "png"],
520
+ [567, "radar_gr_w_upgrade", "png"],
521
+ [568, "radar_sm_cargo", "png"],
522
+ [569, "radar_sm_hangar", "png"],
523
+ [570, "radar_tf_checkpoint", "png"],
524
+ [571, "radar_race_tf", "png"],
525
+ [572, "radar_sm_wp1", "png"],
526
+ [573, "radar_sm_wp2", "png"],
527
+ [574, "radar_sm_wp3", "png"],
528
+ [575, "radar_sm_wp4", "png"],
529
+ [576, "radar_sm_wp5", "png"],
530
+ [577, "radar_sm_wp6", "png"],
531
+ [578, "radar_sm_wp7", "png"],
532
+ [579, "radar_sm_wp8", "png"],
533
+ [580, "radar_sm_wp9", "png"],
534
+ [581, "radar_sm_wp10", "png"],
535
+ [582, "radar_sm_wp11", "png"],
536
+ [583, "radar_sm_wp12", "png"],
537
+ [584, "radar_sm_wp13", "png"],
538
+ [585, "radar_sm_wp14", "png"],
539
+ [586, "radar_nhp_bag", "png"],
540
+ [587, "radar_nhp_chest", "png"],
541
+ [588, "radar_nhp_orbit", "png"],
542
+ [589, "radar_nhp_veh1", "png"],
543
+ [590, "radar_nhp_base", "png"],
544
+ [591, "radar_nhp_overlay", "png"],
545
+ [592, "radar_nhp_turret", "png"],
546
+ [593, "radar_nhp_mg_firewall", "png"],
547
+ [594, "radar_nhp_mg_node", "png"],
548
+ [595, "radar_nhp_wp1", "png"],
549
+ [596, "radar_nhp_wp2", "png"],
550
+ [597, "radar_nhp_wp3", "png"],
551
+ [598, "radar_nhp_wp4", "png"],
552
+ [599, "radar_nhp_wp5", "png"],
553
+ [600, "radar_nhp_wp6", "png"],
554
+ [601, "radar_nhp_wp7", "png"],
555
+ [602, "radar_nhp_wp8", "png"],
556
+ [603, "radar_nhp_wp9", "png"],
557
+ [604, "radar_nhp_cctv", "png"],
558
+ [605, "radar_nhp_starterpack", "png"],
559
+ [606, "radar_nhp_turret_console", "png"],
560
+ [607, "radar_nhp_mg_mir_rotate", "png"],
561
+ [608, "radar_nhp_mg_mir_static", "png"],
562
+ [609, "radar_nhp_mg_proxy", "png"],
563
+ [610, "radar_acsr_race_target", "png"],
564
+ [611, "radar_acsr_race_hotring", "png"],
565
+ [612, "radar_acsr_wp1", "png"],
566
+ [613, "radar_acsr_wp2", "png"],
567
+ [614, "radar_bat_club_property", "png"],
568
+ [615, "radar_bat_cargo", "png"],
569
+ [616, "radar_bat_truck", "png"],
570
+ [617, "radar_bat_hack_jewel", "png"],
571
+ [618, "radar_bat_hack_gold", "png"],
572
+ [619, "radar_bat_keypad", "png"],
573
+ [620, "radar_bat_hack_target", "png"],
574
+ [621, "radar_pickup_dtb_health", "png"],
575
+ [622, "radar_pickup_dtb_blast_increase", "png"],
576
+ [623, "radar_pickup_dtb_blast_decrease", "png"],
577
+ [624, "radar_pickup_dtb_bomb_increase", "png"],
578
+ [625, "radar_pickup_dtb_bomb_decrease", "png"],
579
+ [626, "radar_bat_rival_club", "png"],
580
+ [627, "radar_bat_drone", "png"],
581
+ [628, "radar_bat_cash_reg", "png"],
582
+ [629, "radar_cctv", "png"],
583
+ [630, "radar_bat_assassinate", "png"],
584
+ [631, "radar_bat_pbus", "png"],
585
+ [632, "radar_bat_wp1", "png"],
586
+ [633, "radar_bat_wp2", "png"],
587
+ [634, "radar_bat_wp3", "png"],
588
+ [635, "radar_bat_wp4", "png"],
589
+ [636, "radar_bat_wp5", "png"],
590
+ [637, "radar_bat_wp6", "png"],
591
+ [638, "radar_blimp_2", "png"],
592
+ [639, "radar_oppressor_2", "png"],
593
+ [640, "radar_bat_wp7", "png"],
594
+ [641, "radar_arena_series", "png"],
595
+ [642, "radar_arena_premium", "png"],
596
+ [643, "radar_arena_workshop", "png"],
597
+ [644, "radar_race_wars", "png"],
598
+ [645, "radar_arena_turret", "png"],
599
+ [646, "radar_arena_rc_car", "png"],
600
+ [647, "radar_arena_rc_workshop", "png"],
601
+ [648, "radar_arena_trap_fire", "png"],
602
+ [649, "radar_arena_trap_flip", "png"],
603
+ [650, "radar_arena_trap_sea", "png"],
604
+ [651, "radar_arena_trap_turn", "png"],
605
+ [652, "radar_arena_trap_pit", "png"],
606
+ [653, "radar_arena_trap_mine", "png"],
607
+ [654, "radar_arena_trap_bomb", "png"],
608
+ [655, "radar_arena_trap_wall", "png"],
609
+ [656, "radar_arena_trap_brd", "png"],
610
+ [657, "radar_arena_trap_sbrd", "png"],
611
+ [658, "radar_arena_bruiser", "png"],
612
+ [659, "radar_arena_brutus", "png"],
613
+ [660, "radar_arena_cerberus", "png"],
614
+ [661, "radar_arena_deathbike", "png"],
615
+ [662, "radar_arena_dominator", "png"],
616
+ [663, "radar_arena_impaler", "png"],
617
+ [664, "radar_arena_imperator", "png"],
618
+ [665, "radar_arena_issi", "png"],
619
+ [666, "radar_arena_sasquatch", "png"],
620
+ [667, "radar_arena_scarab", "png"],
621
+ [668, "radar_arena_slamvan", "png"],
622
+ [669, "radar_arena_zr380", "png"],
623
+ [670, "radar_ap", "png"],
624
+ [671, "radar_comic_store", "png"],
625
+ [672, "radar_cop_car", "png"],
626
+ [673, "radar_rc_time_trials", "png"],
627
+ [674, "radar_king_of_the_hill", "png"],
628
+ [675, "radar_king_of_the_hill_teams", "png"],
629
+ [676, "radar_rucksack", "png"],
630
+ [677, "radar_shipping_container", "png"],
631
+ [678, "radar_agatha", "png"],
632
+ [679, "radar_casino", "png"],
633
+ [680, "radar_casino_table_games", "png"],
634
+ [681, "radar_casino_wheel", "png"],
635
+ [682, "radar_casino_concierge", "png"],
636
+ [683, "radar_casino_chips", "png"],
637
+ [684, "radar_casino_horse_racing", "png"],
638
+ [685, "radar_adversary_featured", "png"],
639
+ [686, "radar_roulette_1", "png"],
640
+ [687, "radar_roulette_2", "png"],
641
+ [688, "radar_roulette_3", "png"],
642
+ [689, "radar_roulette_4", "png"],
643
+ [690, "radar_roulette_5", "png"],
644
+ [691, "radar_roulette_6", "png"],
645
+ [692, "radar_roulette_7", "png"],
646
+ [693, "radar_roulette_8", "png"],
647
+ [694, "radar_roulette_9", "png"],
648
+ [695, "radar_roulette_10", "png"],
649
+ [696, "radar_roulette_11", "png"],
650
+ [697, "radar_roulette_12", "png"],
651
+ [698, "radar_roulette_13", "png"],
652
+ [699, "radar_roulette_14", "png"],
653
+ [700, "radar_roulette_15", "png"],
654
+ [701, "radar_roulette_16", "png"],
655
+ [702, "radar_roulette_17", "png"],
656
+ [703, "radar_roulette_18", "png"],
657
+ [704, "radar_roulette_19", "png"],
658
+ [705, "radar_roulette_20", "png"],
659
+ [706, "radar_roulette_21", "png"],
660
+ [707, "radar_roulette_22", "png"],
661
+ [708, "radar_roulette_23", "png"],
662
+ [709, "radar_roulette_24", "png"],
663
+ [710, "radar_roulette_25", "png"],
664
+ [711, "radar_roulette_26", "png"],
665
+ [712, "radar_roulette_27", "png"],
666
+ [713, "radar_roulette_28", "png"],
667
+ [714, "radar_roulette_29", "png"],
668
+ [715, "radar_roulette_30", "png"],
669
+ [716, "radar_roulette_31", "png"],
670
+ [717, "radar_roulette_32", "png"],
671
+ [718, "radar_roulette_33", "png"],
672
+ [719, "radar_roulette_34", "png"],
673
+ [720, "radar_roulette_35", "png"],
674
+ [721, "radar_roulette_36", "png"],
675
+ [722, "radar_roulette_0", "png"],
676
+ [723, "radar_roulette_00", "png"],
677
+ [724, "radar_limo", "png"],
678
+ [725, "radar_weapon_alien", "png"],
679
+ [726, "radar_race_open_wheel", "png"],
680
+ [727, "radar_rappel", "png"],
681
+ [728, "radar_swap_car", "png"],
682
+ [729, "radar_scuba_gear", "png"],
683
+ [730, "radar_cpanel_1", "png"],
684
+ [731, "radar_cpanel_2", "png"],
685
+ [732, "radar_cpanel_3", "png"],
686
+ [733, "radar_cpanel_4", "png"],
687
+ [734, "radar_snow_truck", "png"],
688
+ [735, "radar_buggy_1", "png"],
689
+ [736, "radar_buggy_2", "png"],
690
+ [737, "radar_zhaba", "png"],
691
+ [738, "radar_gerald", "png"],
692
+ [739, "radar_ron", "png"],
693
+ [740, "radar_arcade", "png"],
694
+ [741, "radar_drone_controls", "png"],
695
+ [742, "radar_rc_tank", "png"],
696
+ [743, "radar_stairs", "png"],
697
+ [744, "radar_camera_2", "png"],
698
+ [745, "radar_winky", "png"],
699
+ [746, "radar_mini_sub", "png"],
700
+ [747, "radar_kart_retro", "png"],
701
+ [748, "radar_kart_modern", "png"],
702
+ [749, "radar_military_quad", "png"],
703
+ [750, "radar_military_truck", "png"],
704
+ [751, "radar_ship_wheel", "png"],
705
+ [752, "radar_ufo", "png"],
706
+ [753, "radar_seasparrow2", "png"],
707
+ [754, "radar_dinghy2", "png"],
708
+ [755, "radar_patrol_boat", "png"],
709
+ [756, "radar_retro_sports_car", "png"],
710
+ [757, "radar_squadee", "png"],
711
+ [758, "radar_folding_wing_jet", "png"],
712
+ [759, "radar_valkyrie2", "png"],
713
+ [760, "radar_sub2", "png"],
714
+ [761, "radar_bolt_cutters", "png"],
715
+ [762, "radar_rappel_gear", "png"],
716
+ [763, "radar_keycard", "png"],
717
+ [764, "radar_password", "png"],
718
+ [765, "radar_island_heist_prep", "png"],
719
+ [766, "radar_island_party", "png"],
720
+ [767, "radar_control_tower", "png"],
721
+ [768, "radar_underwater_gate", "png"],
722
+ [769, "radar_power_switch", "png"],
723
+ [770, "radar_compound_gate", "png"],
724
+ [771, "radar_rappel_point", "png"],
725
+ [772, "radar_keypad", "png"],
726
+ [773, "radar_sub_controls", "png"],
727
+ [774, "radar_sub_periscope", "png"],
728
+ [775, "radar_sub_missile", "png"],
729
+ [776, "radar_painting", "png"],
730
+ [777, "radar_car_meet", "png"],
731
+ [778, "radar_car_test_area", "png"],
732
+ [779, "radar_auto_shop_property", "png"],
733
+ [780, "radar_docks_export", "png"],
734
+ [781, "radar_prize_car", "png"],
735
+ [782, "radar_test_car", "png"],
736
+ [783, "radar_car_robbery_board", "png"],
737
+ [784, "radar_car_robbery_prep", "png"],
738
+ [785, "radar_street_race_series", "png"],
739
+ [786, "radar_pursuit_series", "png"],
740
+ [787, "radar_car_meet_organiser", "png"],
741
+ [788, "radar_securoserv", "png"],
742
+ [789, "radar_bounty_collectibles", "png"],
743
+ [790, "radar_movie_collectibles", "png"],
744
+ [791, "radar_trailer_ramp", "png"],
745
+ [792, "radar_race_organiser", "png"],
746
+ [793, "radar_chalkboard_list", "png"],
747
+ [794, "radar_export_vehicle", "png"],
748
+ [795, "radar_train", "png"],
749
+ [796, "radar_heist_diamond", "png"],
750
+ [797, "radar_heist_doomsday", "png"],
751
+ [798, "radar_heist_island", "png"],
752
+ [799, "radar_slamvan2", "png"],
753
+ [800, "radar_crusader", "png"],
754
+ [801, "radar_construction_outfit", "png"],
755
+ [802, "radar_overlay_jammed", "png"],
756
+ [803, "radar_heist_island_unavailable", "png"],
757
+ [804, "radar_heist_diamond_unavailable", "png"],
758
+ [805, "radar_heist_doomsday_unavailable", "png"],
759
+ [806, "radar_placeholder_7", "png"],
760
+ [807, "radar_placeholder_8", "png"],
761
+ [808, "radar_placeholder_9", "png"],
762
+ [809, "radar_featured_series", "png"],
763
+ [810, "radar_vehicle_for_sale", "png"],
764
+ [811, "radar_van_keys", "png"],
765
+ [812, "radar_suv_service", "png"],
766
+ [813, "radar_security_contract", "png"],
767
+ [814, "radar_safe", "png"],
768
+ [815, "radar_ped_r", "png"],
769
+ [816, "radar_ped_e", "png"],
770
+ [817, "radar_payphone", "png"],
771
+ [818, "radar_patriot3", "png"],
772
+ [819, "radar_music_studio", "png"],
773
+ [820, "radar_jubilee", "png"],
774
+ [821, "radar_granger2", "png"],
775
+ [822, "radar_explosive_charge", "png"],
776
+ [823, "radar_deity", "png"],
777
+ [824, "radar_d_champion", "png"],
778
+ [825, "radar_buffalo4", "png"],
779
+ [826, "radar_agency", "png"],
780
+ [827, "radar_biker_bar", "png"],
781
+ [828, "radar_simeon_overlay", "png"],
782
+ [829, "radar_junk_skydive", "png"],
783
+ [830, "radar_luxury_car_showroom", "png"],
784
+ [831, "radar_car_showroom", "png"],
785
+ [832, "radar_car_showroom_simeon", "png"],
786
+ [833, "radar_flaming_skull", "png"],
787
+ [834, "radar_weapon_ammo", "png"],
788
+ [835, "radar_community_series", "png"],
789
+ [836, "radar_cayo_series", "png"],
790
+ [837, "radar_clubhouse_contract", "png"],
791
+ [838, "radar_agent_ulp", "png"],
792
+ [839, "radar_acid", "png"],
793
+ [840, "radar_acid_lab", "png"],
794
+ [841, "radar_dax_overlay", "png"],
795
+ [842, "radar_dead_drop_package", "png"],
796
+ [843, "radar_downtown_cab", "png"],
797
+ [844, "radar_gun_van", "png"],
798
+ [845, "radar_stash_house", "png"],
799
+ [846, "radar_tractor", "png"],
800
+ [847, "radar_warehouse_juggalo", "png"],
801
+ [848, "radar_warehouse_juggalo_dax", "png"],
802
+ [849, "radar_weapon_crowbar", "png"],
803
+ [850, "radar_duffel_bag", "png"],
804
+ [851, "radar_oil_tanker", "png"],
805
+ [852, "radar_acid_lab_tent", "png"],
806
+ [853, "radar_van_burrito", "png"],
807
+ [854, "radar_acid_boost", "png"],
808
+ [855, "radar_ped_gang_leader", "png"],
809
+ [856, "radar_multistorey_garage", "png"],
810
+ [857, "radar_seized_asset_sales", "png"],
811
+ [858, "radar_cayo_attrition", "png"],
812
+ [859, "radar_bicycle", "png"],
813
+ [860, "radar_bicycle_trial", "png"],
814
+ [861, "radar_raiju", "png"],
815
+ [862, "radar_conada2", "png"],
816
+ [863, "radar_overlay_ready_for_sell", "png"],
817
+ [864, "radar_overlay_missing_supplies", "png"],
818
+ [865, "radar_streamer216", "png"],
819
+ [866, "radar_signal_jammer", "png"],
820
+ [867, "radar_salvage_yard", "png"],
821
+ [868, "radar_robbery_prep_equipment", "png"],
822
+ [869, "radar_robbery_prep_overlay", "png"],
823
+ [870, "radar_yusuf", "png"],
824
+ [871, "radar_vincent", "png"],
825
+ [872, "radar_vinewood_garage", "png"],
826
+ [873, "radar_lstb", "png"],
827
+ [874, "radar_cctv_workstation", "png"],
828
+ [875, "radar_hacking_device", "png"],
829
+ [876, "radar_race_drag", "png"],
830
+ [877, "radar_race_drift", "png"],
831
+ [878, "radar_casino_prep", "png"],
832
+ [879, "radar_planning_wall", "png"],
833
+ [880, "radar_weapon_crate", "png"],
834
+ [881, "radar_weapon_snowball", "png"],
835
+ [882, "radar_train_signals_green", "png"],
836
+ [883, "radar_train_signals_red", "png"],
837
+ [884, "radar_office_transporter", "png"],
838
+ [885, "radar_yankton_survival", "png"],
839
+ [886, "radar_daily_bounty", "png"],
840
+ [887, "radar_bounty_target", "png"],
841
+ [888, "radar_filming_schedule", "png"],
842
+ [889, "radar_pizza_this", "png"],
843
+ [890, "radar_aircraft_carrier", "png"],
844
+ [891, "radar_weapon_emp", "png"],
845
+ [892, "radar_maude_eccles", "png"],
846
+ [893, "radar_bail_bonds_office", "png"],
847
+ [894, "radar_weapon_emp_mine", "png"],
848
+ [895, "radar_zombie_disease", "png"],
849
+ [896, "radar_zombie_proximity", "png"],
850
+ [897, "radar_zombie_fire", "png"],
851
+ [898, "radar_animal_possessed", "png"],
852
+ [899, "radar_mobile_phone", "png"],
853
+ [900, "radar_garment_factory", "png"],
854
+ [901, "radar_garment_factory_for_sale", "png"],
855
+ [902, "radar_garment_factory_equipment", "png"],
856
+ [903, "radar_field_hangar", "png"],
857
+ [904, "radar_field_hangar_for_sale", "png"],
858
+ [905, "radar_cargobob_ch53", "png"],
859
+ [906, "radar_chopper_lift_ammo", "png"],
860
+ [907, "radar_chopper_lift_armor", "png"],
861
+ [908, "radar_chopper_lift_explosives", "png"],
862
+ [909, "radar_chopper_lift_upgrade", "png"],
863
+ [910, "radar_chopper_lift_weapon", "png"],
864
+ [911, "radar_cargo_ship", "png"],
865
+ [912, "radar_submarine_missile", "png"],
866
+ [913, "radar_propeller_engine", "png"],
867
+ [914, "radar_shark", "png"],
868
+ [915, "radar_fast_travel", "png"],
869
+ [916, "radar_plane_duster2", "png"],
870
+ [917, "radar_plane_titan2", "png"],
871
+ [918, "radar_collectible", "png"],
872
+ [919, "radar_field_hangar_discount", "png"],
873
+ [920, "radar_garment_factory_discount", "png"],
874
+ [921, "radar_weapon_gusenberg_sweeper", "png"],
875
+ [922, "radar_weapon_tear_gas", "png"],
876
+ [923, "radar_dog", "png"],
877
+ [924, "radar_bobcat_security", "png"],
878
+ [925, "radar_smoke_shop", "png"],
879
+ [926, "radar_smoke_shop_for_sale", "png"],
880
+ [927, "radar_smoke_shop_attention", "png"],
881
+ [928, "radar_helitours", "png"],
882
+ [929, "radar_helitours_for_sale", "png"],
883
+ [930, "radar_helitours_attention", "png"],
884
+ [931, "radar_car_wash_business", "png"],
885
+ [932, "radar_car_wash_business_for_sale", "png"],
886
+ [933, "radar_car_wash_business_attention", "png"],
887
+ [934, "radar_attention", "png"],
888
+ [935, "radar_alarm", "png"],
889
+ [936, "radar_helitours_discount", "png"],
890
+ [937, "radar_smoke_shop_discount", "png"],
891
+ [938, "radar_car_wash_business_discount", "png"],
892
+ [939, "radar_real_estate", "png"],
893
+ [940, "radar_medical_courier", "png"],
894
+ [941, "radar_gruppe_sechs", "png"],
895
+ [942, "radar_fire_station", "png"],
896
+ [943, "radar_fire_truck", "png"],
897
+ [944, "radar_alpha_mail", "png"],
898
+ [945, "radar_ls_meteor", "png"],
899
+ [946, "radar_four20_survival", "png"],
900
+ [947, "radar_community_mission_series", "png"],
901
+ [948, "radar_property_mansion", "png"],
902
+ [949, "radar_ai_keypad", "png"],
903
+ [950, "radar_taxi_self_drive", "png"],
904
+ [951, "radar_train_subway", "png"],
905
+ [952, "radar_trashbag", "png"],
906
+ [953, "radar_mission_creator", "png"],
907
+ [954, "radar_cat", "png"],
908
+ [955, "radar_mansion_ai_m", "png"],
909
+ [956, "radar_mansion_ai_f", "png"],
910
+ [957, "radar_mansion_ai_gang", "png"]
911
+ ];
912
+ var BLIP_BASE = "https://docs.fivem.net/blips/";
913
+ function blipUrl(name, ext) {
914
+ return `${BLIP_BASE}${name}.${ext}`;
915
+ }
916
+ var BLIP_COLORS = [
917
+ [0, "White", "#FFFFFF"],
918
+ [1, "Red", "#E54141"],
919
+ [2, "Green", "#3FA83F"],
920
+ [3, "Blue", "#5B8CCF"],
921
+ [4, "White", "#FFFFFF"],
922
+ [5, "Yellow", "#F0D453"],
923
+ [6, "Light Red", "#E88888"],
924
+ [7, "Violet", "#8C5FA8"],
925
+ [8, "Pink", "#E878C8"],
926
+ [9, "Light Orange", "#F0A861"],
927
+ [10, "Light Brown", "#C1A470"],
928
+ [11, "Light Green", "#94D468"],
929
+ [12, "Light Blue", "#68C8E8"],
930
+ [13, "Light Purple", "#B898E8"],
931
+ [14, "Dark Purple", "#583E8E"],
932
+ [15, "Cyan", "#48C8B8"],
933
+ [16, "Light Yellow", "#E8E898"],
934
+ [17, "Orange", "#E87830"],
935
+ [18, "Light Blue", "#78A8E8"],
936
+ [19, "Dark Pink", "#C83878"],
937
+ [20, "Dark Yellow", "#A0A038"],
938
+ [21, "Dark Orange", "#B07828"],
939
+ [22, "Light Gray", "#B0B0B0"],
940
+ [23, "Light Pink", "#E8A8C0"],
941
+ [24, "Lemon Green", "#88F068"],
942
+ [25, "Forest Green", "#388038"],
943
+ [26, "Electric Blue", "#2060E0"],
944
+ [27, "Bright Purple", "#9840E0"],
945
+ [28, "Dark Yellow", "#7C7C28"],
946
+ [29, "Dark Blue", "#283878"],
947
+ [30, "Dark Cyan", "#287078"],
948
+ [31, "Light Brown", "#A08858"],
949
+ [32, "Light Blue", "#78B0E8"],
950
+ [33, "Light Yellow", "#E8E868"],
951
+ [34, "Light Pink", "#F0A0C0"],
952
+ [35, "Light Red", "#E07868"],
953
+ [36, "Beige", "#D8C898"],
954
+ [37, "White", "#FFFFFF"],
955
+ [38, "Blue", "#4870A0"],
956
+ [39, "Light Gray", "#909898"],
957
+ [40, "Dark Gray", "#585858"],
958
+ [41, "Pink Red", "#E07088"],
959
+ [42, "Blue", "#5090B8"],
960
+ [43, "Light Green", "#88C868"],
961
+ [44, "Light Orange", "#E09048"],
962
+ [45, "White", "#F0F0F0"],
963
+ [46, "Gold", "#D8B838"],
964
+ [47, "Orange", "#E07020"]
965
+ ];
966
+ var BLIP_ICON_DATA = BLIP_ENTRIES.map(([id, name]) => ({
967
+ value: String(id),
968
+ label: `${id} \u2014 ${name}`
969
+ }));
970
+ var BLIP_COLOR_DATA = BLIP_COLORS.map(([id, label2]) => ({
971
+ value: String(id),
972
+ label: `${id} \u2014 ${label2}`
973
+ }));
974
+ var blipEntryMap = new Map(BLIP_ENTRIES.map(([id, name, ext]) => [String(id), { id, name, ext }]));
975
+ var blipColorMap = new Map(BLIP_COLORS.map(([id, label2, hex]) => [String(id), { id, label: label2, hex }]));
976
+ var renderBlipOption = ({ option }) => {
977
+ const entry = blipEntryMap.get(option.value);
978
+ if (!entry) return option.label;
979
+ return /* @__PURE__ */ jsxRuntime.jsxs(core.Group, { gap: "sm", wrap: "nowrap", children: [
980
+ /* @__PURE__ */ jsxRuntime.jsx(
981
+ core.Image,
982
+ {
983
+ src: blipUrl(entry.name, entry.ext),
984
+ alt: entry.name,
985
+ w: 24,
986
+ h: 24,
987
+ fit: "contain",
988
+ style: { imageRendering: "pixelated" }
989
+ }
990
+ ),
991
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Text, { size: "xs", truncate: true, children: [
992
+ entry.id,
993
+ " \u2014 ",
994
+ entry.name
995
+ ] })
996
+ ] });
997
+ };
998
+ var renderColorOption = ({ option }) => {
999
+ const entry = blipColorMap.get(option.value);
1000
+ if (!entry) return option.label;
1001
+ return /* @__PURE__ */ jsxRuntime.jsxs(core.Group, { gap: "sm", wrap: "nowrap", children: [
1002
+ /* @__PURE__ */ jsxRuntime.jsx(
1003
+ core.Box,
1004
+ {
1005
+ w: 24,
1006
+ h: 24,
1007
+ style: {
1008
+ borderRadius: 4,
1009
+ backgroundColor: entry.hex,
1010
+ border: "1px solid rgba(255,255,255,0.15)",
1011
+ flexShrink: 0
1012
+ }
1013
+ }
1014
+ ),
1015
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Text, { size: "xs", truncate: true, children: [
1016
+ entry.id,
1017
+ " \u2014 ",
1018
+ entry.label
1019
+ ] })
1020
+ ] });
1021
+ };
1022
+ function BlipIconSelect({ value, onChange, label: label2 = "Blip Icon", size = "xs", ...rest }) {
1023
+ const entry = value != null ? blipEntryMap.get(String(value)) : void 0;
1024
+ return /* @__PURE__ */ jsxRuntime.jsx(
1025
+ core.Select,
1026
+ {
1027
+ label: label2,
1028
+ size,
1029
+ ...rest,
1030
+ searchable: true,
1031
+ data: BLIP_ICON_DATA,
1032
+ value: value != null ? String(value) : null,
1033
+ onChange: (val) => val != null && onChange(Number(val)),
1034
+ renderOption: renderBlipOption,
1035
+ maxDropdownHeight: 300,
1036
+ nothingFoundMessage: "No results",
1037
+ leftSection: entry ? /* @__PURE__ */ jsxRuntime.jsx(
1038
+ core.Image,
1039
+ {
1040
+ src: blipUrl(entry.name, entry.ext),
1041
+ alt: entry.name,
1042
+ w: 18,
1043
+ h: 18,
1044
+ fit: "contain",
1045
+ style: { imageRendering: "pixelated" }
1046
+ }
1047
+ ) : void 0
1048
+ }
1049
+ );
1050
+ }
1051
+ function BlipColorSelect({ value, onChange, label: label2 = "Blip Color", size = "xs", ...rest }) {
1052
+ const entry = value != null ? blipColorMap.get(String(value)) : void 0;
1053
+ return /* @__PURE__ */ jsxRuntime.jsx(
1054
+ core.Select,
1055
+ {
1056
+ label: label2,
1057
+ size,
1058
+ ...rest,
1059
+ searchable: true,
1060
+ data: BLIP_COLOR_DATA,
1061
+ value: value != null ? String(value) : null,
1062
+ onChange: (val) => val != null && onChange(Number(val)),
1063
+ renderOption: renderColorOption,
1064
+ maxDropdownHeight: 300,
1065
+ nothingFoundMessage: "No results",
1066
+ leftSection: entry ? /* @__PURE__ */ jsxRuntime.jsx(
1067
+ core.Box,
1068
+ {
1069
+ w: 18,
1070
+ h: 18,
1071
+ style: {
1072
+ borderRadius: 4,
1073
+ backgroundColor: entry.hex,
1074
+ border: "1px solid rgba(255,255,255,0.15)",
1075
+ flexShrink: 0
1076
+ }
1077
+ }
1078
+ ) : void 0
1079
+ }
1080
+ );
1081
+ }
34
1082
 
35
1083
  // src/utils/colorWithAlpha.ts
36
1084
  var colorNames = {
@@ -177,11 +1225,11 @@ var colorNames = {
177
1225
  Yellow: { r: 255, g: 255, b: 0 },
178
1226
  YellowGreen: { r: 154, g: 205, b: 50 }
179
1227
  };
180
- function colorWithAlpha(color, alpha5) {
1228
+ function colorWithAlpha(color, alpha8) {
181
1229
  const lowerCasedColor = color.toLowerCase();
182
1230
  if (colorNames[lowerCasedColor]) {
183
1231
  const rgb = colorNames[lowerCasedColor];
184
- return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha5})`;
1232
+ return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha8})`;
185
1233
  }
186
1234
  if (/^#([A-Fa-f0-9]{6})$/.test(color)) {
187
1235
  const hex = color.slice(1);
@@ -189,12 +1237,12 @@ function colorWithAlpha(color, alpha5) {
189
1237
  const r = bigint >> 16 & 255;
190
1238
  const g = bigint >> 8 & 255;
191
1239
  const b = bigint & 255;
192
- return `rgba(${r}, ${g}, ${b}, ${alpha5})`;
1240
+ return `rgba(${r}, ${g}, ${b}, ${alpha8})`;
193
1241
  }
194
1242
  if (/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/.test(color)) {
195
1243
  const result = color.match(/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/);
196
1244
  if (result) {
197
- return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${alpha5})`;
1245
+ return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${alpha8})`;
198
1246
  }
199
1247
  }
200
1248
  return color;
@@ -234,6 +1282,7 @@ var useSettings = zustand.create(() => ({
234
1282
  primaryColor: "dirk",
235
1283
  primaryShade: 9,
236
1284
  itemImgPath: "",
1285
+ resourceVersion: "dev",
237
1286
  customTheme: [
238
1287
  "#f0f4ff",
239
1288
  "#d9e3ff",
@@ -284,7 +1333,7 @@ async function runFetches() {
284
1333
  );
285
1334
  }
286
1335
  var useAutoFetcher = () => {
287
- React3.useEffect(() => {
1336
+ React4.useEffect(() => {
288
1337
  if (isEnvBrowser()) return;
289
1338
  const run = async () => {
290
1339
  await runFetches();
@@ -765,7 +1814,7 @@ function createSkill(defaultSettings) {
765
1814
  }));
766
1815
  const useSkill = (xp) => {
767
1816
  const { settings, levelMap } = useStore4();
768
- return React3.useMemo(() => {
1817
+ return React4.useMemo(() => {
769
1818
  const currentLevel = getLevelFromXP(xp, levelMap, settings);
770
1819
  const nextLevel = Math.min(currentLevel + 1, settings.maxLevel);
771
1820
  const currentLevelXP = levelMap[currentLevel.toString()] || 0;
@@ -836,6 +1885,321 @@ async function getImageShape(file) {
836
1885
  img.src = typeof file === "string" ? file : URL.createObjectURL(file);
837
1886
  });
838
1887
  }
1888
+ var useItems = zustand.create(() => ({}));
1889
+ var useItemsList = (excludeItemNames = []) => {
1890
+ const excludeSet = new Set(excludeItemNames);
1891
+ return Object.values(useItems.getState()).filter((item) => !excludeSet.has(item.name));
1892
+ };
1893
+ var getItemImageUrl = (itemName) => {
1894
+ return useItems.getState()[itemName]?.image || "";
1895
+ };
1896
+ registerInitialFetch("FETCH_ALL_ITEMS", null, {
1897
+ item1: { name: "item1", label: "Item 1", weight: 0.5, image: "item1.png" },
1898
+ item2: { name: "item2", label: "Item 2", weight: 1, image: "item2.png" },
1899
+ item3: { name: "item3", label: "Item 3", weight: 2.5, image: "item3.png" }
1900
+ }).then((fetchedItems) => {
1901
+ if (!fetchedItems) return;
1902
+ useItems.setState(fetchedItems);
1903
+ });
1904
+
1905
+ // src/utils/inputMapper.ts
1906
+ var INPUT_MAPPER_PRIMARY_OPTIONS = [
1907
+ "DIGITALBUTTON_AXIS",
1908
+ "GAME_CONTROLLED",
1909
+ "JOYSTICK_AXIS",
1910
+ "JOYSTICK_AXIS_NEGATIVE",
1911
+ "JOYSTICK_AXIS_POSITIVE",
1912
+ "JOYSTICK_BUTTON",
1913
+ "JOYSTICK_IAXIS",
1914
+ "JOYSTICK_POV",
1915
+ "JOYSTICK_POV_AXIS",
1916
+ "KEYBOARD",
1917
+ "MKB_AXIS",
1918
+ "MOUSE_ABSOLUTEAXIS",
1919
+ "MOUSE_BUTTON",
1920
+ "MOUSE_CENTEREDAXIS",
1921
+ "MOUSE_NORMALIZED",
1922
+ "MOUSE_RELATIVEAXIS",
1923
+ "MOUSE_SCALEDAXIS",
1924
+ "MOUSE_WHEEL",
1925
+ "PAD_ANALOGBUTTON",
1926
+ "PAD_AXIS",
1927
+ "PAD_DEBUGBUTTON",
1928
+ "PAD_DIGITALBUTTON",
1929
+ "TOUCHPAD_ABSOLUTE_AXIS",
1930
+ "TOUCHPAD_CENTERED_AXIS"
1931
+ ];
1932
+ var KEYBOARD_KEYS = [
1933
+ "BACK",
1934
+ "TAB",
1935
+ "RETURN",
1936
+ "PAUSE",
1937
+ "CAPITAL",
1938
+ "ESCAPE",
1939
+ "SPACE",
1940
+ "PAGEUP",
1941
+ "PAGEDOWN",
1942
+ "END",
1943
+ "HOME",
1944
+ "LEFT",
1945
+ "UP",
1946
+ "RIGHT",
1947
+ "DOWN",
1948
+ "INSERT",
1949
+ "DELETE",
1950
+ "0",
1951
+ "1",
1952
+ "2",
1953
+ "3",
1954
+ "4",
1955
+ "5",
1956
+ "6",
1957
+ "7",
1958
+ "8",
1959
+ "9",
1960
+ "A",
1961
+ "B",
1962
+ "C",
1963
+ "D",
1964
+ "E",
1965
+ "F",
1966
+ "G",
1967
+ "H",
1968
+ "I",
1969
+ "J",
1970
+ "K",
1971
+ "L",
1972
+ "M",
1973
+ "N",
1974
+ "O",
1975
+ "P",
1976
+ "Q",
1977
+ "R",
1978
+ "S",
1979
+ "T",
1980
+ "U",
1981
+ "V",
1982
+ "W",
1983
+ "X",
1984
+ "Y",
1985
+ "Z",
1986
+ "F1",
1987
+ "F2",
1988
+ "F3",
1989
+ "F4",
1990
+ "F5",
1991
+ "F6",
1992
+ "F7",
1993
+ "F8",
1994
+ "F9",
1995
+ "F10",
1996
+ "F11",
1997
+ "F12",
1998
+ "NUMPAD0",
1999
+ "NUMPAD1",
2000
+ "NUMPAD2",
2001
+ "NUMPAD3",
2002
+ "NUMPAD4",
2003
+ "NUMPAD5",
2004
+ "NUMPAD6",
2005
+ "NUMPAD7",
2006
+ "NUMPAD8",
2007
+ "NUMPAD9",
2008
+ "MULTIPLY",
2009
+ "ADD",
2010
+ "SUBTRACT",
2011
+ "DECIMAL",
2012
+ "DIVIDE",
2013
+ "NUMPADENTER",
2014
+ "LSHIFT",
2015
+ "RSHIFT",
2016
+ "LCONTROL",
2017
+ "RCONTROL",
2018
+ "LMENU",
2019
+ "RMENU",
2020
+ "LWIN",
2021
+ "RWIN",
2022
+ "APPS",
2023
+ "NUMLOCK",
2024
+ "SCROLL",
2025
+ "OEM_1",
2026
+ "SEMICOLON",
2027
+ "EQUALS",
2028
+ "PLUS",
2029
+ "COMMA",
2030
+ "MINUS",
2031
+ "PERIOD",
2032
+ "SLASH",
2033
+ "OEM_2",
2034
+ "OEM_3",
2035
+ "GRAVE",
2036
+ "LBRACKET",
2037
+ "OEM_4",
2038
+ "BACKSLASH",
2039
+ "OEM_5",
2040
+ "RBRACKET",
2041
+ "OEM_6",
2042
+ "APOSTROPHE",
2043
+ "OEM_7",
2044
+ "OEM_102"
2045
+ ];
2046
+ var MOUSE_BUTTON_KEYS = [
2047
+ "MOUSE_LEFT",
2048
+ "MOUSE_RIGHT",
2049
+ "MOUSE_MIDDLE",
2050
+ "MOUSE_EXTRABTN1",
2051
+ "MOUSE_EXTRABTN2",
2052
+ "MOUSE_EXTRABTN3",
2053
+ "MOUSE_EXTRABTN4",
2054
+ "MOUSE_EXTRABTN5",
2055
+ "IOM_WHEEL_UP",
2056
+ "IOM_WHEEL_DOWN"
2057
+ ];
2058
+ var MOUSE_WHEEL_KEYS = ["IOM_WHEEL_UP", "IOM_WHEEL_DOWN"];
2059
+ var MOUSE_AXIS_KEYS = [
2060
+ "IOM_AXIS_X",
2061
+ "IOM_AXIS_Y",
2062
+ "IOM_AXIS_WHEEL",
2063
+ "IOM_AXIS_WHEEL_DELTA",
2064
+ "IOM_AXIS_WHEEL_RELATIVE",
2065
+ "IOM_IAXIS_X",
2066
+ "IOM_IAXIS_Y",
2067
+ "IOM_IAXIS_WHEEL",
2068
+ "IOM_IAXIS_WHEEL_DELTA",
2069
+ "IOM_IAXIS_WHEEL_RELATIVE",
2070
+ "IOM_AXIS_X_LEFT",
2071
+ "IOM_AXIS_X_RIGHT",
2072
+ "IOM_AXIS_Y_UP",
2073
+ "IOM_AXIS_Y_DOWN",
2074
+ "BASIC_MOUSE_AXIS_MAX",
2075
+ "MOUSE_AXIS_MAX"
2076
+ ];
2077
+ var PAD_BUTTON_KEYS = [
2078
+ "L1_INDEX",
2079
+ "R1_INDEX",
2080
+ "L2_INDEX",
2081
+ "R2_INDEX",
2082
+ "L3_INDEX",
2083
+ "R3_INDEX",
2084
+ "LUP_INDEX",
2085
+ "LRIGHT_INDEX",
2086
+ "LDOWN_INDEX",
2087
+ "LLEFT_INDEX",
2088
+ "RUP_INDEX",
2089
+ "RRIGHT_INDEX",
2090
+ "RDOWN_INDEX",
2091
+ "RLEFT_INDEX",
2092
+ "SELECT_INDEX",
2093
+ "START_INDEX",
2094
+ "TOUCH_INDEX"
2095
+ ];
2096
+ var PAD_DEBUG_KEYS = [
2097
+ "L1",
2098
+ "R1",
2099
+ "L2",
2100
+ "R2",
2101
+ "L3",
2102
+ "R3",
2103
+ "LUP",
2104
+ "LRIGHT",
2105
+ "LDOWN",
2106
+ "LLEFT",
2107
+ "RUP",
2108
+ "RRIGHT",
2109
+ "RDOWN",
2110
+ "RLEFT",
2111
+ "SELECT",
2112
+ "START",
2113
+ "TOUCH"
2114
+ ];
2115
+ var PAD_AXIS_KEYS = [
2116
+ "IOM_AXIS_LX",
2117
+ "IOM_AXIS_LY",
2118
+ "IOM_AXIS_RX",
2119
+ "IOM_AXIS_RY",
2120
+ "IOM_AXIS_LUP",
2121
+ "IOM_AXIS_LDOWN",
2122
+ "IOM_AXIS_LLEFT",
2123
+ "IOM_AXIS_LRIGHT",
2124
+ "IOM_AXIS_LUR",
2125
+ "IOM_AXIS_LUL",
2126
+ "IOM_AXIS_LDR",
2127
+ "IOM_AXIS_LDL",
2128
+ "IOM_AXIS_RUP",
2129
+ "IOM_AXIS_RDOWN",
2130
+ "IOM_AXIS_RLEFT",
2131
+ "IOM_AXIS_RRIGHT",
2132
+ "IOM_AXIS_RUR",
2133
+ "IOM_AXIS_RUL",
2134
+ "IOM_AXIS_RDR",
2135
+ "IOM_AXIS_RDL",
2136
+ "IOM_AXIS_DPADX",
2137
+ "IOM_AXIS_DPADY",
2138
+ "IOM_AXIS_LY_UP",
2139
+ "IOM_AXIS_LY_DOWN",
2140
+ "IOM_AXIS_LX_LEFT",
2141
+ "IOM_AXIS_LX_RIGHT",
2142
+ "IOM_AXIS_RY_UP",
2143
+ "IOM_AXIS_RY_DOWN",
2144
+ "IOM_AXIS_RX_LEFT",
2145
+ "IOM_AXIS_RX_RIGHT"
2146
+ ];
2147
+ var JOYSTICK_AXIS_KEYS = Array.from({ length: 8 }, (_, i) => `IOM_JOYSTICK_AXIS${i + 1}`);
2148
+ var JOYSTICK_BUTTON_KEYS = Array.from({ length: 32 }, (_, i) => `IOM_JOYSTICK_BUTTON${i + 1}`);
2149
+ var JOYSTICK_POV_KEYS = Array.from({ length: 4 }, (_, p) => {
2150
+ const idx = p + 1;
2151
+ return [
2152
+ `IOM_POV${idx}_UP`,
2153
+ `IOM_POV${idx}_RIGHT`,
2154
+ `IOM_POV${idx}_DOWN`,
2155
+ `IOM_POV${idx}_LEFT`
2156
+ ];
2157
+ }).flat();
2158
+ var INPUT_MAPPER_KEYS_BY_PRIMARY = {
2159
+ DIGITALBUTTON_AXIS: [],
2160
+ GAME_CONTROLLED: [],
2161
+ JOYSTICK_AXIS: [...JOYSTICK_AXIS_KEYS],
2162
+ JOYSTICK_AXIS_NEGATIVE: [...JOYSTICK_AXIS_KEYS],
2163
+ JOYSTICK_AXIS_POSITIVE: [...JOYSTICK_AXIS_KEYS],
2164
+ JOYSTICK_BUTTON: [...JOYSTICK_BUTTON_KEYS],
2165
+ JOYSTICK_IAXIS: [...JOYSTICK_AXIS_KEYS],
2166
+ JOYSTICK_POV: [...JOYSTICK_POV_KEYS],
2167
+ JOYSTICK_POV_AXIS: [...JOYSTICK_POV_KEYS],
2168
+ KEYBOARD: [...KEYBOARD_KEYS],
2169
+ MKB_AXIS: [],
2170
+ MOUSE_ABSOLUTEAXIS: [...MOUSE_AXIS_KEYS],
2171
+ MOUSE_BUTTON: [...MOUSE_BUTTON_KEYS],
2172
+ MOUSE_CENTEREDAXIS: [...MOUSE_AXIS_KEYS],
2173
+ MOUSE_NORMALIZED: [...MOUSE_AXIS_KEYS],
2174
+ MOUSE_RELATIVEAXIS: [...MOUSE_AXIS_KEYS],
2175
+ MOUSE_SCALEDAXIS: [...MOUSE_AXIS_KEYS],
2176
+ MOUSE_WHEEL: [...MOUSE_WHEEL_KEYS],
2177
+ PAD_ANALOGBUTTON: [...PAD_BUTTON_KEYS],
2178
+ PAD_AXIS: [...PAD_AXIS_KEYS],
2179
+ PAD_DEBUGBUTTON: [...PAD_DEBUG_KEYS],
2180
+ PAD_DIGITALBUTTON: [...PAD_BUTTON_KEYS],
2181
+ TOUCHPAD_ABSOLUTE_AXIS: [],
2182
+ TOUCHPAD_CENTERED_AXIS: []
2183
+ };
2184
+
2185
+ // src/utils/extractDefaults.ts
2186
+ function extractDefaults(schema) {
2187
+ if (!schema || typeof schema !== "object") return void 0;
2188
+ if (schema.default !== void 0) return schema.default;
2189
+ if (schema.type === "object" && schema.properties) {
2190
+ const result = {};
2191
+ let hasValue = false;
2192
+ for (const [key, child] of Object.entries(schema.properties)) {
2193
+ const val = extractDefaults(child);
2194
+ if (val !== void 0) {
2195
+ result[key] = val;
2196
+ hasValue = true;
2197
+ }
2198
+ }
2199
+ return hasValue ? result : void 0;
2200
+ }
2201
+ return void 0;
2202
+ }
839
2203
  function BorderedIcon(props) {
840
2204
  const theme2 = core.useMantineTheme();
841
2205
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -906,8 +2270,8 @@ var FloatingParticles = ({
906
2270
  mouseRepelStrength = 50,
907
2271
  backgroundColor = "transparent"
908
2272
  }) => {
909
- const containerRef = React3.useRef(null);
910
- const [particles, setParticles] = React3.useState([]);
2273
+ const containerRef = React4.useRef(null);
2274
+ const [particles, setParticles] = React4.useState([]);
911
2275
  const mouseX = framerMotion.useMotionValue(0);
912
2276
  const mouseY = framerMotion.useMotionValue(0);
913
2277
  const durationMap = {
@@ -920,7 +2284,7 @@ var FloatingParticles = ({
920
2284
  const x = Math.sin(seed) * 1e4;
921
2285
  return x - Math.floor(x);
922
2286
  };
923
- React3.useEffect(() => {
2287
+ React4.useEffect(() => {
924
2288
  if (!containerRef.current) return;
925
2289
  const bounds = containerRef.current.getBoundingClientRect();
926
2290
  const newParticles = [...Array(particleCount)].map((_, i) => {
@@ -941,7 +2305,7 @@ var FloatingParticles = ({
941
2305
  });
942
2306
  setParticles(newParticles);
943
2307
  }, [particleCount, icons.length, duration.base, duration.variance]);
944
- React3.useEffect(() => {
2308
+ React4.useEffect(() => {
945
2309
  if (!containerRef.current) return;
946
2310
  const handleMouseMove = (e) => {
947
2311
  const bounds = containerRef.current.getBoundingClientRect();
@@ -990,7 +2354,7 @@ var FloatingParticles = ({
990
2354
  container.removeEventListener("mouseleave", handleMouseLeave);
991
2355
  };
992
2356
  }, [mouseX, mouseY, mouseRepelDistance, mouseRepelStrength]);
993
- React3.useEffect(() => {
2357
+ React4.useEffect(() => {
994
2358
  const handleResize = () => {
995
2359
  if (!containerRef.current) return;
996
2360
  const bounds = containerRef.current.getBoundingClientRect();
@@ -1418,23 +2782,23 @@ function Segment(props) {
1418
2782
  }
1419
2783
  );
1420
2784
  }
1421
- var NavigationContext = React3.createContext(null);
2785
+ var NavigationContext = React4.createContext(null);
1422
2786
  function useNavigation(selector) {
1423
- const navigation = React3.useContext(NavigationContext);
2787
+ const navigation = React4.useContext(NavigationContext);
1424
2788
  if (!navigation) {
1425
2789
  throw new Error("useNavigation must be used within a NavigationProvider");
1426
2790
  }
1427
2791
  return zustand.useStore(navigation, selector);
1428
2792
  }
1429
2793
  function useNavigationStore() {
1430
- const navigation = React3.useContext(NavigationContext);
2794
+ const navigation = React4.useContext(NavigationContext);
1431
2795
  if (!navigation) {
1432
2796
  throw new Error("useNavigationStore must be used within a NavigationProvider");
1433
2797
  }
1434
2798
  return navigation;
1435
2799
  }
1436
2800
  function NavigationProvider({ children, defaultPage }) {
1437
- const storeRef = React3.useRef(
2801
+ const storeRef = React4.useRef(
1438
2802
  zustand.create(() => ({
1439
2803
  pageId: defaultPage || "home"
1440
2804
  }))
@@ -1776,149 +3140,142 @@ function LevelPanel(props) {
1776
3140
  }
1777
3141
  );
1778
3142
  }
1779
- var ModalContext = React3.createContext(null);
1780
- function useModal(selector) {
1781
- const modal = React3.useContext(ModalContext);
1782
- if (!modal) {
1783
- throw new Error("useModal must be used within a ModalProvider");
1784
- }
1785
- return zustand.useStore(modal, selector);
1786
- }
1787
- function ModalProvider({ children, defaultPage }) {
1788
- const storeRef = React3.useRef(
1789
- zustand.create(() => ({
1790
- active: null
1791
- }))
1792
- );
1793
- return /* @__PURE__ */ jsxRuntime.jsxs(ModalContext.Provider, { value: storeRef.current, children: [
1794
- /* @__PURE__ */ jsxRuntime.jsx(Modal, {}),
1795
- children
1796
- ] });
1797
- }
1798
- function useModalActions() {
1799
- const modal = React3.useContext(ModalContext);
1800
- if (!modal) throw new Error("useModalActions must be used within a ModalProvider");
1801
- const showModal = (openModal) => {
1802
- modal.setState({ active: openModal });
1803
- };
1804
- const hideModal = () => {
1805
- modal.setState({ active: null });
1806
- };
1807
- return { showModal, hideModal };
1808
- }
1809
- function Modal() {
1810
- const active = useModal((state) => state.active);
1811
- const { hideModal } = useModalActions();
1812
- const ref = hooks.useClickOutside(() => {
1813
- if (!active) return;
1814
- if (active.clickOutside == false) return;
1815
- if (active) {
1816
- hideModal();
1817
- }
1818
- });
3143
+ function Modal({
3144
+ title,
3145
+ icon: Icon,
3146
+ iconColor,
3147
+ description: description2,
3148
+ badge,
3149
+ onClose,
3150
+ width = "52vh",
3151
+ maxHeight = "85vh",
3152
+ height,
3153
+ zIndex = 100,
3154
+ clickOutside = true,
3155
+ children
3156
+ }) {
1819
3157
  const theme2 = core.useMantineTheme();
1820
- return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: active && /* @__PURE__ */ jsxRuntime.jsx(
1821
- MotionFlex,
3158
+ return /* @__PURE__ */ jsxRuntime.jsx(core.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
3159
+ framerMotion.motion.div,
1822
3160
  {
1823
- h: "100%",
1824
- w: "100%",
1825
- bg: "rgba(0, 0, 0, 0.3)",
1826
- pos: "absolute",
1827
- style: {
1828
- zIndex: 2e3,
1829
- filter: "drop-shadow(0 0 2vh black)"
1830
- },
1831
3161
  initial: { opacity: 0 },
1832
3162
  animate: { opacity: 1 },
1833
3163
  exit: { opacity: 0 },
1834
- align: "center",
1835
- justify: "center",
3164
+ style: {
3165
+ position: "fixed",
3166
+ inset: 0,
3167
+ zIndex,
3168
+ display: "flex",
3169
+ alignItems: "center",
3170
+ justifyContent: "center",
3171
+ background: "rgba(0,0,0,0.65)"
3172
+ },
3173
+ onClick: clickOutside ? onClose : void 0,
1836
3174
  children: /* @__PURE__ */ jsxRuntime.jsxs(
1837
- MotionFlex,
3175
+ framerMotion.motion.div,
1838
3176
  {
1839
- pos: "absolute",
1840
- top: "50%",
1841
- left: "50%",
1842
- ref,
1843
- w: active.width || "40%",
3177
+ initial: { opacity: 0, scale: 0.96, y: 8 },
3178
+ animate: { opacity: 1, scale: 1, y: 0 },
3179
+ exit: { opacity: 0, scale: 0.96, y: 8 },
3180
+ transition: { duration: 0.18, ease: "easeOut" },
3181
+ onClick: (e) => e.stopPropagation(),
1844
3182
  style: {
1845
- transform: "translate(-50%, -50%)",
1846
- borderRadius: theme2.radius.xs,
1847
- boxShadow: theme2.shadows.xl,
1848
- zIndex: 2100
3183
+ background: core.alpha(theme2.colors.dark[9], 0.98),
3184
+ border: `0.1vh solid ${theme2.colors.dark[7]}`,
3185
+ borderRadius: theme2.radius.sm,
3186
+ width,
3187
+ maxHeight,
3188
+ height,
3189
+ display: "flex",
3190
+ flexDirection: "column",
3191
+ overflow: "hidden",
3192
+ userSelect: "none"
1849
3193
  },
1850
- bg: core.alpha(theme2.colors.dark[9], 0.9),
1851
- initial: { scale: 0.8, opacity: 0, transform: "translate(-50%, -50%)" },
1852
- animate: { scale: 1, opacity: 1, transform: "translate(-50%, -50%)" },
1853
- exit: { scale: 0.8, opacity: 0, transform: "translate(-50%, -50%)" },
1854
- p: "sm",
1855
- direction: "column",
1856
- maw: "70%",
1857
- gap: "xs",
1858
3194
  children: [
1859
3195
  /* @__PURE__ */ jsxRuntime.jsxs(
1860
3196
  core.Flex,
1861
3197
  {
1862
- direction: "column",
1863
- w: "100%",
3198
+ justify: "space-between",
3199
+ align: "center",
3200
+ px: "sm",
3201
+ py: "xs",
3202
+ style: {
3203
+ borderBottom: `0.1vh solid ${theme2.colors.dark[7]}`,
3204
+ flexShrink: 0
3205
+ },
1864
3206
  children: [
1865
- /* @__PURE__ */ jsxRuntime.jsxs(
1866
- core.Flex,
1867
- {
1868
- w: "100%",
1869
- align: "center",
1870
- gap: "xs",
1871
- children: [
1872
- active.icon && /* @__PURE__ */ jsxRuntime.jsx(
1873
- reactFontawesome.FontAwesomeIcon,
1874
- {
1875
- icon: active.icon,
1876
- style: {
1877
- fontSize: theme2.fontSizes.xs
1878
- }
1879
- }
1880
- ),
1881
- /* @__PURE__ */ jsxRuntime.jsx(
3207
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "xs", children: [
3208
+ Icon && /* @__PURE__ */ jsxRuntime.jsx(
3209
+ Icon,
3210
+ {
3211
+ color: iconColor ?? "rgba(255,255,255,0.6)",
3212
+ size: "2vh"
3213
+ }
3214
+ ),
3215
+ /* @__PURE__ */ jsxRuntime.jsx(
3216
+ core.Text,
3217
+ {
3218
+ ff: "Akrobat Bold",
3219
+ size: "sm",
3220
+ tt: "uppercase",
3221
+ lts: "0.06em",
3222
+ c: "rgba(255,255,255,0.85)",
3223
+ children: title
3224
+ }
3225
+ ),
3226
+ badge && /* @__PURE__ */ jsxRuntime.jsx(
3227
+ "div",
3228
+ {
3229
+ style: {
3230
+ background: core.alpha(badge.color, 0.12),
3231
+ border: `0.1vh solid ${core.alpha(badge.color, 0.35)}`,
3232
+ borderRadius: theme2.radius.xs,
3233
+ padding: `0 ${theme2.spacing.xxs}`
3234
+ },
3235
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1882
3236
  core.Text,
1883
3237
  {
1884
- size: "sm",
1885
- children: active.title
1886
- }
1887
- ),
1888
- /* @__PURE__ */ jsxRuntime.jsx(
1889
- MotionIcon,
1890
- {
1891
- icon: "times",
1892
- color: "rgba(255, 255, 255, 0.7)",
1893
- whileHover: {
1894
- scale: 1.1,
1895
- filter: "brightness(1.2)"
1896
- },
1897
- style: {
1898
- marginLeft: "auto",
1899
- cursor: "pointer",
1900
- fontSize: theme2.fontSizes.sm
1901
- },
1902
- onClick: () => {
1903
- hideModal();
1904
- }
3238
+ ff: "Akrobat Bold",
3239
+ size: "xxs",
3240
+ tt: "uppercase",
3241
+ lts: "0.06em",
3242
+ c: badge.color,
3243
+ children: badge.label
1905
3244
  }
1906
3245
  )
1907
- ]
1908
- }
1909
- ),
1910
- active.description && /* @__PURE__ */ jsxRuntime.jsx(
1911
- core.Text,
3246
+ }
3247
+ )
3248
+ ] }),
3249
+ /* @__PURE__ */ jsxRuntime.jsx(
3250
+ framerMotion.motion.button,
1912
3251
  {
1913
- size: "xs",
1914
- c: "rgba(255, 255, 255, 0.7)",
1915
- children: active.description
3252
+ onClick: onClose,
3253
+ whileHover: { background: core.alpha(theme2.colors.dark[7], 0.5) },
3254
+ style: {
3255
+ background: "transparent",
3256
+ border: "none",
3257
+ cursor: "pointer",
3258
+ padding: theme2.spacing.xxs,
3259
+ borderRadius: theme2.radius.xs,
3260
+ display: "flex"
3261
+ },
3262
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { color: "rgba(255,255,255,0.4)" })
1916
3263
  }
1917
3264
  )
1918
3265
  ]
1919
3266
  }
1920
3267
  ),
1921
- active.children
3268
+ description2 && /* @__PURE__ */ jsxRuntime.jsx(core.Flex, { px: "sm", pt: "xs", children: /* @__PURE__ */ jsxRuntime.jsx(
3269
+ core.Text,
3270
+ {
3271
+ ff: "Akrobat Regular",
3272
+ size: "xs",
3273
+ c: "rgba(255,255,255,0.65)",
3274
+ style: { lineHeight: 1.5 },
3275
+ children: description2
3276
+ }
3277
+ ) }),
3278
+ children
1922
3279
  ]
1923
3280
  }
1924
3281
  )
@@ -1972,24 +3329,299 @@ function PromptModal(props) {
1972
3329
  }
1973
3330
  );
1974
3331
  }
1975
- var useNuiEvent = (action, handler) => {
1976
- const savedHandler = React3.useRef(noop);
1977
- React3.useEffect(() => {
1978
- savedHandler.current = handler;
1979
- }, [handler]);
1980
- React3.useEffect(() => {
1981
- const eventListener = (event) => {
1982
- const { action: eventAction, data } = event.data;
1983
- if (savedHandler.current) {
1984
- if (eventAction === action) {
1985
- savedHandler.current(data);
3332
+ var ModalContext = React4.createContext(null);
3333
+ function useModal(selector) {
3334
+ const modal = React4.useContext(ModalContext);
3335
+ if (!modal) {
3336
+ throw new Error("useModal must be used within a ModalProvider");
3337
+ }
3338
+ return zustand.useStore(modal, selector);
3339
+ }
3340
+ function StoreModal() {
3341
+ const active = useModal((state) => state.active);
3342
+ const { hideModal } = useModalActions();
3343
+ return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: active && /* @__PURE__ */ jsxRuntime.jsx(
3344
+ Modal,
3345
+ {
3346
+ title: active.title,
3347
+ icon: active.icon,
3348
+ iconColor: active.iconColor,
3349
+ description: active.description,
3350
+ badge: active.badge,
3351
+ onClose: hideModal,
3352
+ width: active.width,
3353
+ maxHeight: active.maxHeight,
3354
+ height: active.height,
3355
+ zIndex: active.zIndex,
3356
+ clickOutside: active.clickOutside,
3357
+ children: active.children
3358
+ }
3359
+ ) });
3360
+ }
3361
+ function ModalProvider({ children }) {
3362
+ const storeRef = React4.useRef(
3363
+ zustand.create(() => ({
3364
+ active: null
3365
+ }))
3366
+ );
3367
+ return /* @__PURE__ */ jsxRuntime.jsxs(ModalContext.Provider, { value: storeRef.current, children: [
3368
+ /* @__PURE__ */ jsxRuntime.jsx(StoreModal, {}),
3369
+ children
3370
+ ] });
3371
+ }
3372
+ function useModalActions() {
3373
+ const modal = React4.useContext(ModalContext);
3374
+ if (!modal) throw new Error("useModalActions must be used within a ModalProvider");
3375
+ const showModal = (openModal) => {
3376
+ modal.setState({ active: openModal });
3377
+ };
3378
+ const hideModal = () => {
3379
+ modal.setState({ active: null });
3380
+ };
3381
+ return { showModal, hideModal };
3382
+ }
3383
+ function ConfirmModal({
3384
+ title,
3385
+ description: description2,
3386
+ confirmLabel = "Delete",
3387
+ confirmText,
3388
+ onConfirm,
3389
+ onClose,
3390
+ zIndex = 200
3391
+ }) {
3392
+ const theme2 = core.useMantineTheme();
3393
+ const [typed, setTyped] = React4.useState("");
3394
+ const canConfirm = !confirmText || typed === confirmText;
3395
+ return /* @__PURE__ */ jsxRuntime.jsx(core.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
3396
+ framerMotion.motion.div,
3397
+ {
3398
+ initial: { opacity: 0 },
3399
+ animate: { opacity: 1 },
3400
+ exit: { opacity: 0 },
3401
+ style: {
3402
+ position: "fixed",
3403
+ inset: 0,
3404
+ zIndex,
3405
+ display: "flex",
3406
+ alignItems: "center",
3407
+ justifyContent: "center",
3408
+ background: "rgba(0,0,0,0.7)"
3409
+ },
3410
+ onClick: onClose,
3411
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
3412
+ framerMotion.motion.div,
3413
+ {
3414
+ initial: { opacity: 0, scale: 0.95, y: 8 },
3415
+ animate: { opacity: 1, scale: 1, y: 0 },
3416
+ exit: { opacity: 0, scale: 0.95, y: 8 },
3417
+ transition: { duration: 0.18, ease: "easeOut" },
3418
+ onClick: (e) => e.stopPropagation(),
3419
+ style: {
3420
+ background: core.alpha(theme2.colors.dark[9], 0.98),
3421
+ border: `0.1vh solid ${core.alpha("#ef4444", 0.3)}`,
3422
+ borderRadius: theme2.radius.sm,
3423
+ width: "44vh",
3424
+ display: "flex",
3425
+ flexDirection: "column",
3426
+ overflow: "hidden"
3427
+ },
3428
+ children: [
3429
+ /* @__PURE__ */ jsxRuntime.jsxs(
3430
+ core.Flex,
3431
+ {
3432
+ justify: "space-between",
3433
+ align: "center",
3434
+ px: "sm",
3435
+ py: "xs",
3436
+ style: {
3437
+ borderBottom: `0.1vh solid ${core.alpha("#ef4444", 0.2)}`,
3438
+ background: core.alpha("#ef4444", 0.06),
3439
+ flexShrink: 0
3440
+ },
3441
+ children: [
3442
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "xs", children: [
3443
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { size: "1.8vh", color: "#ef4444" }),
3444
+ /* @__PURE__ */ jsxRuntime.jsx(
3445
+ core.Text,
3446
+ {
3447
+ ff: "Akrobat Bold",
3448
+ size: "sm",
3449
+ tt: "uppercase",
3450
+ lts: "0.05em",
3451
+ c: "#ef4444",
3452
+ children: title
3453
+ }
3454
+ )
3455
+ ] }),
3456
+ /* @__PURE__ */ jsxRuntime.jsx(
3457
+ framerMotion.motion.button,
3458
+ {
3459
+ onClick: onClose,
3460
+ whileHover: { background: core.alpha(theme2.colors.dark[7], 0.5) },
3461
+ style: {
3462
+ background: "transparent",
3463
+ border: "none",
3464
+ cursor: "pointer",
3465
+ padding: theme2.spacing.xxs,
3466
+ borderRadius: theme2.radius.xs,
3467
+ display: "flex"
3468
+ },
3469
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { color: "rgba(255,255,255,0.4)" })
3470
+ }
3471
+ )
3472
+ ]
3473
+ }
3474
+ ),
3475
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", gap: "sm", p: "sm", children: [
3476
+ /* @__PURE__ */ jsxRuntime.jsx(
3477
+ core.Text,
3478
+ {
3479
+ ff: "Akrobat Regular",
3480
+ size: "xs",
3481
+ c: "rgba(255,255,255,0.65)",
3482
+ style: { lineHeight: 1.5 },
3483
+ children: description2
3484
+ }
3485
+ ),
3486
+ confirmText && /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", gap: "xxs", children: [
3487
+ /* @__PURE__ */ jsxRuntime.jsxs(
3488
+ core.Text,
3489
+ {
3490
+ ff: "Akrobat Bold",
3491
+ size: "xxs",
3492
+ tt: "uppercase",
3493
+ lts: "0.07em",
3494
+ c: "rgba(255,255,255,0.35)",
3495
+ children: [
3496
+ "Type",
3497
+ " ",
3498
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { component: "span", ff: "Akrobat Bold", c: "#ef4444", children: confirmText }),
3499
+ " ",
3500
+ "to confirm"
3501
+ ]
3502
+ }
3503
+ ),
3504
+ /* @__PURE__ */ jsxRuntime.jsx(
3505
+ core.TextInput,
3506
+ {
3507
+ size: "xs",
3508
+ placeholder: confirmText,
3509
+ value: typed,
3510
+ onChange: (e) => setTyped(e.currentTarget.value),
3511
+ styles: (t) => ({
3512
+ input: {
3513
+ backgroundColor: core.alpha(t.colors.dark[7], 0.5),
3514
+ border: `0.1vh solid ${core.alpha(
3515
+ typed === confirmText ? "#ef4444" : t.colors.dark[5],
3516
+ 0.5
3517
+ )}`,
3518
+ color: "rgba(255,255,255,0.85)",
3519
+ fontFamily: "Akrobat Regular"
3520
+ }
3521
+ }),
3522
+ autoFocus: true
3523
+ }
3524
+ )
3525
+ ] })
3526
+ ] }),
3527
+ /* @__PURE__ */ jsxRuntime.jsxs(
3528
+ core.Flex,
3529
+ {
3530
+ justify: "flex-end",
3531
+ gap: "xs",
3532
+ px: "sm",
3533
+ py: "sm",
3534
+ style: {
3535
+ borderTop: `0.1vh solid ${theme2.colors.dark[7]}`,
3536
+ flexShrink: 0
3537
+ },
3538
+ children: [
3539
+ /* @__PURE__ */ jsxRuntime.jsxs(
3540
+ framerMotion.motion.button,
3541
+ {
3542
+ onClick: onClose,
3543
+ whileHover: { background: core.alpha(theme2.colors.dark[7], 0.5) },
3544
+ whileTap: { scale: 0.97 },
3545
+ style: {
3546
+ background: "transparent",
3547
+ border: `0.1vh solid ${theme2.colors.dark[6]}`,
3548
+ borderRadius: theme2.radius.xs,
3549
+ padding: "0.5vh 1vh",
3550
+ cursor: "pointer",
3551
+ display: "flex",
3552
+ alignItems: "center",
3553
+ gap: "0.4vh"
3554
+ },
3555
+ children: [
3556
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: "1.4vh", color: "rgba(255,255,255,0.4)" }),
3557
+ /* @__PURE__ */ jsxRuntime.jsx(
3558
+ core.Text,
3559
+ {
3560
+ ff: "Akrobat Bold",
3561
+ size: "xxs",
3562
+ tt: "uppercase",
3563
+ lts: "0.05em",
3564
+ c: "rgba(255,255,255,0.4)",
3565
+ children: "Cancel"
3566
+ }
3567
+ )
3568
+ ]
3569
+ }
3570
+ ),
3571
+ /* @__PURE__ */ jsxRuntime.jsxs(
3572
+ framerMotion.motion.button,
3573
+ {
3574
+ onClick: () => {
3575
+ if (canConfirm) {
3576
+ onConfirm();
3577
+ onClose();
3578
+ }
3579
+ },
3580
+ whileHover: canConfirm ? {
3581
+ background: core.alpha("#ef4444", 0.22),
3582
+ borderColor: core.alpha("#ef4444", 0.6)
3583
+ } : void 0,
3584
+ whileTap: canConfirm ? { scale: 0.97 } : void 0,
3585
+ style: {
3586
+ background: core.alpha("#ef4444", canConfirm ? 0.14 : 0.05),
3587
+ border: `0.1vh solid ${core.alpha(
3588
+ "#ef4444",
3589
+ canConfirm ? 0.45 : 0.15
3590
+ )}`,
3591
+ borderRadius: theme2.radius.xs,
3592
+ padding: "0.5vh 1vh",
3593
+ cursor: canConfirm ? "pointer" : "not-allowed",
3594
+ display: "flex",
3595
+ alignItems: "center",
3596
+ gap: "0.4vh",
3597
+ opacity: canConfirm ? 1 : 0.45,
3598
+ transition: "opacity 0.15s"
3599
+ },
3600
+ children: [
3601
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { size: "1.4vh", color: "#ef4444" }),
3602
+ /* @__PURE__ */ jsxRuntime.jsx(
3603
+ core.Text,
3604
+ {
3605
+ ff: "Akrobat Bold",
3606
+ size: "xxs",
3607
+ tt: "uppercase",
3608
+ lts: "0.05em",
3609
+ c: "#ef4444",
3610
+ children: confirmLabel
3611
+ }
3612
+ )
3613
+ ]
3614
+ }
3615
+ )
3616
+ ]
3617
+ }
3618
+ )
3619
+ ]
1986
3620
  }
1987
- }
1988
- };
1989
- window.addEventListener("message", eventListener);
1990
- return () => window.removeEventListener("message", eventListener);
1991
- }, [action]);
1992
- };
3621
+ )
3622
+ }
3623
+ ) });
3624
+ }
1993
3625
  function getNested(obj, path) {
1994
3626
  return path.split(".").reduce((acc, key) => acc ? acc[key] : void 0, obj);
1995
3627
  }
@@ -2021,7 +3653,47 @@ function deleteNested(obj, path) {
2021
3653
  delete current[keys[keys.length - 1]];
2022
3654
  return newObj;
2023
3655
  }
2024
- function flattenRules(rules, prefix = "") {
3656
+ function isPlainObject(value) {
3657
+ return value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
3658
+ }
3659
+ function collectChangedPaths(values, initial, prefix = "") {
3660
+ if (Object.is(values, initial)) return [];
3661
+ const valuesIsObj = isPlainObject(values);
3662
+ const initialIsObj = isPlainObject(initial);
3663
+ const valuesIsArr = Array.isArray(values);
3664
+ const initialIsArr = Array.isArray(initial);
3665
+ if (valuesIsArr || initialIsArr) {
3666
+ const maxLen = Math.max(values?.length ?? 0, initial?.length ?? 0);
3667
+ const fields = [];
3668
+ for (let i = 0; i < maxLen; i++) {
3669
+ const nextPrefix = prefix ? `${prefix}.${i}` : `${i}`;
3670
+ fields.push(...collectChangedPaths(values?.[i], initial?.[i], nextPrefix));
3671
+ }
3672
+ return fields;
3673
+ }
3674
+ if (valuesIsObj || initialIsObj) {
3675
+ const keys = /* @__PURE__ */ new Set([
3676
+ ...Object.keys(values ?? {}),
3677
+ ...Object.keys(initial ?? {})
3678
+ ]);
3679
+ const fields = [];
3680
+ for (const key of keys) {
3681
+ const nextPrefix = prefix ? `${prefix}.${key}` : key;
3682
+ fields.push(...collectChangedPaths(values?.[key], initial?.[key], nextPrefix));
3683
+ }
3684
+ return fields;
3685
+ }
3686
+ return prefix ? [prefix] : [];
3687
+ }
3688
+ function computeChangedState(values, initialVals) {
3689
+ const fields = collectChangedPaths(values, initialVals);
3690
+ let partial = {};
3691
+ for (const path of fields) {
3692
+ partial = setNested(partial, path, getNested(values, path));
3693
+ }
3694
+ return { fields, partial };
3695
+ }
3696
+ function flattenRules(rules, prefix = "") {
2025
3697
  const result = {};
2026
3698
  for (const key in rules) {
2027
3699
  const fullPath = prefix ? `${prefix}.${key}` : key;
@@ -2041,21 +3713,6 @@ function createFormStore(initialValues, validationRules, onSubmit) {
2041
3713
  const history = [];
2042
3714
  const future = [];
2043
3715
  const changed = /* @__PURE__ */ new Set();
2044
- function computeChanged(values, initialVals) {
2045
- const allKeys = /* @__PURE__ */ new Set([
2046
- ...Object.keys(values),
2047
- ...Object.keys(initialVals)
2048
- ]);
2049
- const fields = [];
2050
- let partial = {};
2051
- for (const key of allKeys) {
2052
- if (values[key] !== initialVals[key]) {
2053
- fields.push(key);
2054
- partial = setNested(partial, key, values[key]);
2055
- }
2056
- }
2057
- return { fields, partial };
2058
- }
2059
3716
  return zustand.createStore((set, get) => ({
2060
3717
  initialValues,
2061
3718
  values: initialValues,
@@ -2185,7 +3842,7 @@ function createFormStore(initialValues, validationRules, onSubmit) {
2185
3842
  if (!history.length) return;
2186
3843
  const prev = history.pop();
2187
3844
  future.push(get().values);
2188
- const { fields, partial } = computeChanged(prev, get().initialValues);
3845
+ const { fields, partial } = computeChangedState(prev, get().initialValues);
2189
3846
  set({
2190
3847
  values: prev,
2191
3848
  partialChanged: partial,
@@ -2199,7 +3856,7 @@ function createFormStore(initialValues, validationRules, onSubmit) {
2199
3856
  if (!future.length) return;
2200
3857
  const next = future.pop();
2201
3858
  history.push(get().values);
2202
- const { fields, partial } = computeChanged(next, get().initialValues);
3859
+ const { fields, partial } = computeChangedState(next, get().initialValues);
2203
3860
  set({
2204
3861
  values: next,
2205
3862
  partialChanged: partial,
@@ -2211,42 +3868,38 @@ function createFormStore(initialValues, validationRules, onSubmit) {
2211
3868
  }
2212
3869
  }));
2213
3870
  }
2214
- var FormContext = React3.createContext(null);
3871
+ var FormContext = React4.createContext(null);
2215
3872
  function FormProvider({
2216
3873
  initialValues,
2217
3874
  validate,
2218
3875
  onSubmit,
2219
3876
  children
2220
3877
  }) {
2221
- const storeRef = React3.useRef(
3878
+ const storeRef = React4.useRef(
2222
3879
  createFormStore(initialValues, validate, onSubmit)
2223
3880
  );
2224
3881
  return /* @__PURE__ */ jsxRuntime.jsx(FormContext.Provider, { value: storeRef.current, children });
2225
3882
  }
2226
3883
  function useForm() {
2227
- const store = React3.useContext(FormContext);
3884
+ const store = React4.useContext(FormContext);
2228
3885
  if (!store) {
2229
3886
  throw new Error("useForm must be used inside <FormProvider>");
2230
3887
  }
2231
3888
  const state = zustand.useStore(store);
2232
- const changedFields = React3.useMemo(() => {
2233
- const vals = state.values;
2234
- const initial = state.initialValues;
2235
- if (!vals || !initial) return [];
2236
- const allKeys = /* @__PURE__ */ new Set([...Object.keys(vals), ...Object.keys(initial)]);
2237
- return Array.from(allKeys).filter((k) => vals[k] !== initial[k]);
3889
+ const changedFields = React4.useMemo(() => {
3890
+ return collectChangedPaths(state.values, state.initialValues);
2238
3891
  }, [state.values, state.initialValues]);
2239
3892
  return { ...state, changedFields, changedCount: changedFields.length };
2240
3893
  }
2241
3894
  function useFormField(path) {
2242
- const store = React3.useContext(FormContext);
3895
+ const store = React4.useContext(FormContext);
2243
3896
  if (!store) {
2244
3897
  throw new Error("useFormField must be used inside <FormProvider>");
2245
3898
  }
2246
3899
  return zustand.useStore(store, (s) => getNested(s.values, path));
2247
3900
  }
2248
3901
  function useFormFields(...paths) {
2249
- const store = React3.useContext(FormContext);
3902
+ const store = React4.useContext(FormContext);
2250
3903
  if (!store) {
2251
3904
  throw new Error("useFormFields must be used inside <FormProvider>");
2252
3905
  }
@@ -2259,14 +3912,14 @@ function useFormFields(...paths) {
2259
3912
  });
2260
3913
  }
2261
3914
  function useFormError(path) {
2262
- const store = React3.useContext(FormContext);
3915
+ const store = React4.useContext(FormContext);
2263
3916
  if (!store) {
2264
3917
  throw new Error("useFormError must be used inside <FormProvider>");
2265
3918
  }
2266
3919
  return zustand.useStore(store, (s) => s.errors[path]);
2267
3920
  }
2268
3921
  function useFormErrors(...paths) {
2269
- const store = React3.useContext(FormContext);
3922
+ const store = React4.useContext(FormContext);
2270
3923
  if (!store) {
2271
3924
  throw new Error("useFormErrors must be used inside <FormProvider>");
2272
3925
  }
@@ -2279,12 +3932,867 @@ function useFormErrors(...paths) {
2279
3932
  });
2280
3933
  }
2281
3934
  function useFormActions() {
2282
- const store = React3.useContext(FormContext);
3935
+ const store = React4.useContext(FormContext);
2283
3936
  if (!store) {
2284
3937
  throw new Error("useFormActions must be used inside <FormProvider>");
2285
3938
  }
2286
3939
  return store.getState();
2287
3940
  }
3941
+ var useNuiEvent = (action, handler) => {
3942
+ const savedHandler = React4.useRef(noop);
3943
+ React4.useEffect(() => {
3944
+ savedHandler.current = handler;
3945
+ }, [handler]);
3946
+ React4.useEffect(() => {
3947
+ const eventListener = (event) => {
3948
+ const { action: eventAction, data } = event.data;
3949
+ if (savedHandler.current) {
3950
+ if (eventAction === action) {
3951
+ savedHandler.current(data);
3952
+ }
3953
+ }
3954
+ };
3955
+ window.addEventListener("message", eventListener);
3956
+ return () => window.removeEventListener("message", eventListener);
3957
+ }, [action]);
3958
+ };
3959
+ var _instance = null;
3960
+ function getScriptSettingsInstance() {
3961
+ if (!_instance) throw new Error("[dirk-cfx-react] createScriptSettings must be called before using SettingsPanel");
3962
+ return _instance;
3963
+ }
3964
+ function createScriptSettings(defaultValue) {
3965
+ const store = zustand.create(() => defaultValue);
3966
+ let clientVersion = 0;
3967
+ const useScriptSettingHooks = () => {
3968
+ useNuiEvent("UPDATE_SCRIPT_SETTINGS", (data) => {
3969
+ if (!data) return;
3970
+ if (typeof data.clientVersion === "number") {
3971
+ clientVersion = data.clientVersion;
3972
+ }
3973
+ if (data.settings && typeof data.settings === "object") {
3974
+ store.setState((prev) => ({ ...prev, ...data.settings }));
3975
+ }
3976
+ });
3977
+ };
3978
+ const fetchScriptSettings = async () => {
3979
+ try {
3980
+ const response = await fetchNui("GET_FULL_SCRIPT_SETTINGS");
3981
+ if (response?.success && response.data?.settings) {
3982
+ store.setState(() => response.data.settings);
3983
+ if (typeof response.data.clientVersion === "number") {
3984
+ clientVersion = response.data.clientVersion;
3985
+ }
3986
+ return response.data.settings;
3987
+ }
3988
+ } catch {
3989
+ }
3990
+ return null;
3991
+ };
3992
+ const updateScriptSettings = async (newSettings) => {
3993
+ store.setState((prev) => ({ ...prev, ...newSettings }));
3994
+ const response = await fetchNui("UPDATE_SCRIPT_SETTINGS", {
3995
+ data: newSettings,
3996
+ expectedVersion: clientVersion
3997
+ });
3998
+ if (response?.meta?.client_version != null) {
3999
+ clientVersion = response.meta.client_version;
4000
+ }
4001
+ if (response?.success === false && response?.meta?.latestData) {
4002
+ store.setState((prev) => ({ ...prev, ...response.meta.latestData }));
4003
+ }
4004
+ return response;
4005
+ };
4006
+ const getScriptSettingsHistory = async (params = {}) => {
4007
+ return fetchNui("GET_SCRIPT_SETTINGS_HISTORY", params);
4008
+ };
4009
+ _instance = {
4010
+ store,
4011
+ updateSettings: updateScriptSettings,
4012
+ getHistory: getScriptSettingsHistory,
4013
+ fetchSettings: fetchScriptSettings
4014
+ };
4015
+ return { store, updateScriptSettings, getScriptSettingsHistory, useScriptSettingHooks, fetchScriptSettings };
4016
+ }
4017
+ var settingsPanelQueryClient = new reactQuery.QueryClient({
4018
+ defaultOptions: { queries: { staleTime: 3e4, gcTime: 5 * 6e4 } }
4019
+ });
4020
+ function NavItemButton({
4021
+ icon: Icon,
4022
+ label: label2,
4023
+ active,
4024
+ onClick
4025
+ }) {
4026
+ const theme2 = core.useMantineTheme();
4027
+ const color = theme2.colors[theme2.primaryColor][5];
4028
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4029
+ framerMotion.motion.button,
4030
+ {
4031
+ onClick,
4032
+ whileHover: { background: active ? core.alpha(color, 0.15) : "rgba(255,255,255,0.04)" },
4033
+ whileTap: { scale: 0.97 },
4034
+ style: {
4035
+ width: "100%",
4036
+ background: active ? core.alpha(color, 0.12) : "transparent",
4037
+ border: "none",
4038
+ borderLeft: `0.2vh solid ${active ? color : "transparent"}`,
4039
+ borderRadius: `0 ${theme2.radius.xs} ${theme2.radius.xs} 0`,
4040
+ padding: "0.7vh 1vh",
4041
+ cursor: "pointer",
4042
+ display: "flex",
4043
+ alignItems: "center",
4044
+ gap: "0.7vh",
4045
+ transition: "border-color 0.15s, background 0.15s"
4046
+ },
4047
+ children: [
4048
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { color: active ? color : "rgba(255,255,255,0.35)" }),
4049
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.06em", c: active ? color : "rgba(255,255,255,0.35)", children: label2 }),
4050
+ active && /* @__PURE__ */ jsxRuntime.jsx(
4051
+ framerMotion.motion.div,
4052
+ {
4053
+ layoutId: "nav-active-dot",
4054
+ style: { marginLeft: "auto", width: "0.4vh", height: "0.4vh", borderRadius: "50%", background: color }
4055
+ }
4056
+ )
4057
+ ]
4058
+ }
4059
+ );
4060
+ }
4061
+ function SettingsJsonModal({
4062
+ onClose,
4063
+ schema
4064
+ }) {
4065
+ const theme2 = core.useMantineTheme();
4066
+ const color = theme2.colors[theme2.primaryColor][5];
4067
+ const form = useForm();
4068
+ const [json, setJson] = React4.useState(() => JSON.stringify(form.values, null, 2));
4069
+ const [error2, setError] = React4.useState(null);
4070
+ const handleSave = () => {
4071
+ try {
4072
+ const parsed = JSON.parse(json);
4073
+ if (schema) {
4074
+ const result = schema.safeParse(parsed);
4075
+ if (!result.success) {
4076
+ setError(result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("\n"));
4077
+ return;
4078
+ }
4079
+ const current = form.values;
4080
+ Object.keys(result.data).forEach((key) => {
4081
+ if (JSON.stringify(result.data[key]) !== JSON.stringify(current[key])) {
4082
+ form.setValue(key, result.data[key]);
4083
+ }
4084
+ });
4085
+ } else {
4086
+ const current = form.values;
4087
+ Object.keys(parsed).forEach((key) => {
4088
+ if (JSON.stringify(parsed[key]) !== JSON.stringify(current[key])) {
4089
+ form.setValue(key, parsed[key]);
4090
+ }
4091
+ });
4092
+ }
4093
+ onClose();
4094
+ } catch (e) {
4095
+ setError(e.message);
4096
+ }
4097
+ };
4098
+ return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { title: "Settings JSON", icon: lucideReact.Code2, iconColor: color, onClose, width: "60vh", maxHeight: "80vh", zIndex: 200, children: [
4099
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Box, { flex: 1, p: "0.8vh", style: { overflowY: "auto" }, children: [
4100
+ /* @__PURE__ */ jsxRuntime.jsx(
4101
+ core.JsonInput,
4102
+ {
4103
+ value: json,
4104
+ spellCheck: false,
4105
+ onChange: setJson,
4106
+ rows: 22,
4107
+ formatOnBlur: true,
4108
+ validationError: "Invalid JSON",
4109
+ styles: () => ({
4110
+ input: { fontFamily: "monospace", fontSize: "1.3vh", lineHeight: 1.6, resize: "none" }
4111
+ })
4112
+ }
4113
+ ),
4114
+ error2 && /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "#ef4444", mt: "xxs", children: error2 })
4115
+ ] }),
4116
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { justify: "flex-end", gap: "xs", px: "sm", py: "xs", style: { borderTop: `0.1vh solid ${theme2.colors.dark[7]}`, flexShrink: 0 }, children: [
4117
+ /* @__PURE__ */ jsxRuntime.jsxs(
4118
+ framerMotion.motion.button,
4119
+ {
4120
+ onClick: onClose,
4121
+ whileHover: { background: core.alpha(theme2.colors.dark[7], 0.5) },
4122
+ whileTap: { scale: 0.97 },
4123
+ style: { background: "transparent", border: `0.1vh solid ${theme2.colors.dark[6]}`, borderRadius: theme2.radius.xs, padding: `${theme2.spacing.xxs} ${theme2.spacing.xs}`, cursor: "pointer", display: "flex", alignItems: "center", gap: theme2.spacing.xxs },
4124
+ children: [
4125
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { color: "rgba(255,255,255,0.4)" }),
4126
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.05em", c: "rgba(255,255,255,0.4)", children: "Cancel" })
4127
+ ]
4128
+ }
4129
+ ),
4130
+ /* @__PURE__ */ jsxRuntime.jsxs(
4131
+ framerMotion.motion.button,
4132
+ {
4133
+ onClick: handleSave,
4134
+ whileHover: { background: core.alpha(color, 0.25) },
4135
+ whileTap: { scale: 0.97 },
4136
+ style: { background: core.alpha(color, 0.14), border: `0.1vh solid ${core.alpha(color, 0.4)}`, borderRadius: theme2.radius.xs, padding: `${theme2.spacing.xxs} ${theme2.spacing.xs}`, cursor: "pointer", display: "flex", alignItems: "center", gap: theme2.spacing.xxs },
4137
+ children: [
4138
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { color }),
4139
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.05em", c: color, children: "Apply" })
4140
+ ]
4141
+ }
4142
+ )
4143
+ ] })
4144
+ ] });
4145
+ }
4146
+ function formatValue(value) {
4147
+ if (value === null) return "null";
4148
+ if (value === void 0) return "undefined";
4149
+ if (typeof value === "string") return value;
4150
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
4151
+ try {
4152
+ return JSON.stringify(value);
4153
+ } catch {
4154
+ return String(value);
4155
+ }
4156
+ }
4157
+ function formatHistoryDateTime(entry) {
4158
+ if (entry.at_unix) {
4159
+ const date = new Date(entry.at_unix * 1e3);
4160
+ if (!Number.isNaN(date.getTime())) {
4161
+ return date.toLocaleString(void 0, { year: "numeric", month: "short", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit" });
4162
+ }
4163
+ }
4164
+ if (entry.at_utc) {
4165
+ const date = new Date(entry.at_utc);
4166
+ if (!Number.isNaN(date.getTime())) {
4167
+ return date.toLocaleString(void 0, { year: "numeric", month: "short", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit" });
4168
+ }
4169
+ }
4170
+ return "Unknown time";
4171
+ }
4172
+ function historyEntryKey(entry, index) {
4173
+ return `${entry.at_unix}-${entry.applied_version}-${index}`;
4174
+ }
4175
+ function ChangeDetails({ entry }) {
4176
+ const theme2 = core.useMantineTheme();
4177
+ return /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", gap: "0.45vh", p: "0.8vh", style: { border: `0.1vh solid ${core.alpha(theme2.colors.dark[6], 0.8)}`, borderRadius: theme2.radius.xs, background: core.alpha(theme2.colors.dark[9], 0.35) }, children: [
4178
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", children: [
4179
+ "Version ",
4180
+ entry.expected_version ?? "?",
4181
+ " ",
4182
+ "\u2192",
4183
+ " ",
4184
+ entry.applied_version ?? "?"
4185
+ ] }),
4186
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gridTemplateColumns: "minmax(18vh, 22vh) minmax(0, 1fr) minmax(0, 1fr)", gap: "0.1vh", border: `0.1vh solid ${core.alpha(theme2.colors.dark[6], 0.9)}`, borderRadius: theme2.radius.xs, overflow: "hidden", background: core.alpha(theme2.colors.dark[6], 0.8) }, children: [
4187
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", px: "0.6vh", py: "0.45vh", style: { background: core.alpha(theme2.colors.dark[8], 0.85) }, children: "Path" }),
4188
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", px: "0.6vh", py: "0.45vh", style: { background: core.alpha(theme2.colors.dark[8], 0.85) }, children: "From" }),
4189
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", px: "0.6vh", py: "0.45vh", style: { background: core.alpha(theme2.colors.dark[8], 0.85) }, children: "To" }),
4190
+ (entry.changes || []).map((change, idx) => {
4191
+ const bg = idx % 2 === 0 ? core.alpha(theme2.colors.dark[9], 0.5) : core.alpha(theme2.colors.dark[8], 0.42);
4192
+ return [
4193
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "#8ad1ff", px: "0.6vh", py: "0.55vh", style: { background: bg, wordBreak: "break-word" }, children: change.path }, `${idx}-p`),
4194
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "monospace", size: "xxs", c: "rgba(255,255,255,0.5)", px: "0.6vh", py: "0.55vh", style: { background: bg, wordBreak: "break-word", whiteSpace: "pre-wrap" }, children: formatValue(change.old) }, `${idx}-o`),
4195
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "monospace", size: "xxs", c: "rgba(255,255,255,0.78)", px: "0.6vh", py: "0.55vh", style: { background: bg, wordBreak: "break-word", whiteSpace: "pre-wrap" }, children: formatValue(change.new) }, `${idx}-n`)
4196
+ ];
4197
+ })
4198
+ ] })
4199
+ ] });
4200
+ }
4201
+ function HistoryTableRow({ entry, expanded, onToggle }) {
4202
+ const theme2 = core.useMantineTheme();
4203
+ const admin = entry.admin?.name || entry.admin?.identifier || "unknown";
4204
+ const firstPath = entry.changes?.[0]?.path || "-";
4205
+ const changeCount = entry.changes?.length || 0;
4206
+ const versionText = `${entry.expected_version ?? "?"} \u2192 ${entry.applied_version ?? "?"}`;
4207
+ return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.motion.div, { layout: true, initial: { opacity: 0, y: 6 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.16, ease: "easeOut" }, children: /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", gap: "0.45vh", children: [
4208
+ /* @__PURE__ */ jsxRuntime.jsx(
4209
+ framerMotion.motion.button,
4210
+ {
4211
+ onClick: onToggle,
4212
+ whileHover: { scale: 1.002 },
4213
+ whileTap: { scale: 0.997 },
4214
+ transition: { duration: 0.12 },
4215
+ style: { background: expanded ? core.alpha(theme2.colors.dark[7], 0.45) : core.alpha(theme2.colors.dark[8], 0.35), border: `0.1vh solid ${expanded ? core.alpha(theme2.colors[theme2.primaryColor][5], 0.35) : core.alpha(theme2.colors.dark[6], 0.75)}`, borderRadius: theme2.radius.xs, padding: "0.65vh 0.75vh", cursor: "pointer", textAlign: "left" },
4216
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gridTemplateColumns: "2.2vh 20vh 12vh 6vh 1fr minmax(16vh, auto)", gap: "0.8vh", alignItems: "center" }, children: [
4217
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.motion.div, { animate: { rotate: expanded ? 0 : -90 }, transition: { duration: 0.18, ease: "easeOut" }, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: "1.5vh", color: expanded ? "rgba(255,255,255,0.6)" : "rgba(255,255,255,0.45)" }) }) }),
4218
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.75)", lineClamp: 1, children: formatHistoryDateTime(entry) }),
4219
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.68)", lineClamp: 1, children: admin }),
4220
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.68)", children: changeCount }),
4221
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.58)", lineClamp: 1, children: firstPath }),
4222
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "monospace", size: "xxs", c: "rgba(255,255,255,0.68)", children: versionText })
4223
+ ] })
4224
+ }
4225
+ ),
4226
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: expanded && /* @__PURE__ */ jsxRuntime.jsx(framerMotion.motion.div, { initial: { opacity: 0, height: 0, y: -4 }, animate: { opacity: 1, height: "auto", y: 0 }, exit: { opacity: 0, height: 0, y: -4 }, transition: { duration: 0.2, ease: "easeInOut" }, style: { overflow: "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx(ChangeDetails, { entry }) }, "details") })
4227
+ ] }) });
4228
+ }
4229
+ function HistoryTableHeader() {
4230
+ const theme2 = core.useMantineTheme();
4231
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gridTemplateColumns: "2.2vh 20vh 12vh 6vh 1fr minmax(16vh, auto)", gap: "0.8vh", alignItems: "center", border: `0.1vh solid ${core.alpha(theme2.colors.dark[6], 0.8)}`, borderRadius: theme2.radius.xs, background: core.alpha(theme2.colors.dark[8], 0.55), padding: "0.55vh 0.75vh" }, children: [
4232
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.35)", children: " " }),
4233
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", children: "Time" }),
4234
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", children: "Admin" }),
4235
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", children: "#" }),
4236
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", children: "First Change" }),
4237
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", children: "Version" })
4238
+ ] });
4239
+ }
4240
+ function SettingsHistoryModal({
4241
+ onClose
4242
+ }) {
4243
+ const { getHistory } = getScriptSettingsInstance();
4244
+ const theme2 = core.useMantineTheme();
4245
+ const color = theme2.colors[theme2.primaryColor][5];
4246
+ const [queryInput, setQueryInput] = React4.useState("");
4247
+ const [pathInput, setPathInput] = React4.useState("");
4248
+ const [adminInput, setAdminInput] = React4.useState("");
4249
+ const [query, setQuery] = React4.useState("");
4250
+ const [path, setPath] = React4.useState("");
4251
+ const [admin, setAdmin] = React4.useState("");
4252
+ const [expandedKey, setExpandedKey] = React4.useState(null);
4253
+ const filters = React4.useMemo(() => ({ query, path, admin }), [query, path, admin]);
4254
+ const historyQuery = reactQuery.useInfiniteQuery({
4255
+ queryKey: ["scriptSettingsHistory", filters],
4256
+ initialPageParam: 0,
4257
+ queryFn: async ({ pageParam }) => {
4258
+ const response = await getHistory({
4259
+ offset: pageParam,
4260
+ limit: 25,
4261
+ query: filters.query || void 0,
4262
+ path: filters.path || void 0,
4263
+ admin: filters.admin || void 0
4264
+ });
4265
+ if (!response?.success || !response.data) {
4266
+ throw new Error(response?._error || "Failed to load settings history");
4267
+ }
4268
+ return response.data;
4269
+ },
4270
+ getNextPageParam: (lastPage) => lastPage.nextOffset
4271
+ });
4272
+ const rows = historyQuery.data?.pages.flatMap((page) => page.items) ?? [];
4273
+ const total = historyQuery.data?.pages[0]?.total ?? 0;
4274
+ const handleListScroll = (e) => {
4275
+ const el = e.currentTarget;
4276
+ if (el.scrollHeight - el.scrollTop - el.clientHeight < 280 && historyQuery.hasNextPage && !historyQuery.isFetchingNextPage) {
4277
+ historyQuery.fetchNextPage();
4278
+ }
4279
+ };
4280
+ return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { title: "Settings History", icon: lucideReact.History, iconColor: color, onClose, width: "88vh", maxHeight: "82vh", zIndex: 260, children: [
4281
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { flex: 1, minHeight: 0 }, children: [
4282
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { gap: "xs", p: "sm", style: { borderBottom: `0.1vh solid ${core.alpha(theme2.colors.dark[7], 0.8)}` }, children: [
4283
+ /* @__PURE__ */ jsxRuntime.jsx(core.TextInput, { leftSection: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { size: "1.4vh" }), placeholder: "Search path/admin/value", value: queryInput, onChange: (e) => setQueryInput(e.currentTarget.value), size: "xs", style: { flex: 1 } }),
4284
+ /* @__PURE__ */ jsxRuntime.jsx(core.TextInput, { leftSection: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { size: "1.4vh" }), placeholder: "Path filter (e.g. basic.weightUnit)", value: pathInput, onChange: (e) => setPathInput(e.currentTarget.value), size: "xs", style: { flex: 1 } }),
4285
+ /* @__PURE__ */ jsxRuntime.jsx(core.TextInput, { leftSection: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { size: "1.4vh" }), placeholder: "Admin filter", value: adminInput, onChange: (e) => setAdminInput(e.currentTarget.value), size: "xs", style: { flex: 1 } }),
4286
+ /* @__PURE__ */ jsxRuntime.jsx(
4287
+ framerMotion.motion.button,
4288
+ {
4289
+ onClick: () => {
4290
+ setExpandedKey(null);
4291
+ setQuery(queryInput.trim());
4292
+ setPath(pathInput.trim().toLowerCase());
4293
+ setAdmin(adminInput.trim().toLowerCase());
4294
+ },
4295
+ whileHover: { background: core.alpha(color, 0.2) },
4296
+ whileTap: { scale: 0.97 },
4297
+ style: { background: core.alpha(color, 0.12), border: `0.1vh solid ${core.alpha(color, 0.35)}`, borderRadius: theme2.radius.xs, padding: "0.55vh 0.85vh", cursor: "pointer" },
4298
+ children: /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: color, children: "Apply" })
4299
+ }
4300
+ )
4301
+ ] }),
4302
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", gap: "xs", p: "sm", style: { flex: 1, minHeight: 0, overflowY: "auto" }, onScroll: handleListScroll, children: [
4303
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", children: historyQuery.isFetching && !historyQuery.data ? "Loading history..." : `${total} entries` }),
4304
+ /* @__PURE__ */ jsxRuntime.jsx(HistoryTableHeader, {}),
4305
+ historyQuery.isError && /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xs", c: "#ef4444", children: historyQuery.error.message }),
4306
+ !historyQuery.isLoading && rows.length === 0 && !historyQuery.isError && /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xs", c: "rgba(255,255,255,0.45)", children: "No history found for current filters." }),
4307
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: rows.map((entry, index) => {
4308
+ const key = historyEntryKey(entry, index);
4309
+ return /* @__PURE__ */ jsxRuntime.jsx(HistoryTableRow, { entry, expanded: expandedKey === key, onToggle: () => setExpandedKey(expandedKey === key ? null : key) }, key);
4310
+ }) }),
4311
+ (historyQuery.isFetchingNextPage || historyQuery.isLoading) && /* @__PURE__ */ jsxRuntime.jsx(core.Flex, { justify: "center", py: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(core.Loader, { size: "sm", color }) })
4312
+ ] })
4313
+ ] }),
4314
+ /* @__PURE__ */ jsxRuntime.jsx(core.Flex, { justify: "flex-end", gap: "xs", px: "sm", py: "xs", style: { borderTop: `0.1vh solid ${theme2.colors.dark[7]}`, flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
4315
+ framerMotion.motion.button,
4316
+ {
4317
+ onClick: onClose,
4318
+ whileHover: { background: core.alpha(theme2.colors.dark[7], 0.5) },
4319
+ whileTap: { scale: 0.97 },
4320
+ style: { background: "transparent", border: `0.1vh solid ${theme2.colors.dark[6]}`, borderRadius: theme2.radius.xs, padding: `${theme2.spacing.xxs} ${theme2.spacing.xs}`, cursor: "pointer", display: "flex", alignItems: "center", gap: theme2.spacing.xxs },
4321
+ children: [
4322
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { color: "rgba(255,255,255,0.4)", size: "1.5vh" }),
4323
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.05em", c: "rgba(255,255,255,0.4)", children: "Close" })
4324
+ ]
4325
+ }
4326
+ ) })
4327
+ ] });
4328
+ }
4329
+ function SettingsPanelInner({
4330
+ navItems,
4331
+ title,
4332
+ subtitle,
4333
+ children,
4334
+ isSaving,
4335
+ onClose,
4336
+ schema,
4337
+ resetConfirmText,
4338
+ defaultSettings,
4339
+ width,
4340
+ height
4341
+ }) {
4342
+ const { updateSettings, getHistory } = getScriptSettingsInstance();
4343
+ const form = useForm();
4344
+ const theme2 = core.useMantineTheme();
4345
+ const color = theme2.colors[theme2.primaryColor][5];
4346
+ const version = useSettings((s) => s.resourceVersion);
4347
+ const [activeTab, setActiveTab] = React4.useState(navItems[0]?.id ?? "");
4348
+ const [jsonOpen, setJsonOpen] = React4.useState(false);
4349
+ const [historyOpen, setHistoryOpen] = React4.useState(false);
4350
+ const [resetOpen, setResetOpen] = React4.useState(false);
4351
+ const [closeConfirmOpen, setCloseConfirmOpen] = React4.useState(false);
4352
+ const changedCount = form.changedCount ?? 0;
4353
+ const isDirty = changedCount > 0;
4354
+ React4.useEffect(() => {
4355
+ function handleKeyDown(e) {
4356
+ if (e.key !== "Escape") return;
4357
+ if (isDirty) {
4358
+ e.preventDefault();
4359
+ setCloseConfirmOpen(true);
4360
+ return;
4361
+ }
4362
+ onClose();
4363
+ }
4364
+ window.addEventListener("keydown", handleKeyDown);
4365
+ return () => window.removeEventListener("keydown", handleKeyDown);
4366
+ }, [isDirty, onClose]);
4367
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4368
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: jsonOpen && /* @__PURE__ */ jsxRuntime.jsx(SettingsJsonModal, { onClose: () => setJsonOpen(false), schema }) }),
4369
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: historyOpen && /* @__PURE__ */ jsxRuntime.jsx(SettingsHistoryModal, { onClose: () => setHistoryOpen(false) }) }),
4370
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: resetOpen && /* @__PURE__ */ jsxRuntime.jsx(
4371
+ ConfirmModal,
4372
+ {
4373
+ title: "Reset to Defaults",
4374
+ description: "This will permanently reset ALL settings back to their defaults. Every setting you have configured will be overwritten. This cannot be undone.",
4375
+ confirmLabel: "Reset Settings",
4376
+ confirmText: resetConfirmText,
4377
+ onConfirm: () => {
4378
+ updateSettings(defaultSettings).then(() => form.reinitialize(cloneSettings(defaultSettings)));
4379
+ setResetOpen(false);
4380
+ },
4381
+ onClose: () => setResetOpen(false),
4382
+ zIndex: 300
4383
+ }
4384
+ ) }),
4385
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: closeConfirmOpen && /* @__PURE__ */ jsxRuntime.jsx(
4386
+ ConfirmModal,
4387
+ {
4388
+ title: "Discard Unsaved Changes?",
4389
+ description: "You have unsaved changes. Closing now will discard them.",
4390
+ confirmLabel: "Close Without Saving",
4391
+ onConfirm: () => {
4392
+ setCloseConfirmOpen(false);
4393
+ onClose();
4394
+ },
4395
+ onClose: () => setCloseConfirmOpen(false),
4396
+ zIndex: 300
4397
+ }
4398
+ ) }),
4399
+ /* @__PURE__ */ jsxRuntime.jsxs(
4400
+ MotionFlex,
4401
+ {
4402
+ pos: "absolute",
4403
+ left: "50%",
4404
+ top: "50%",
4405
+ bg: core.alpha(theme2.colors.dark[9], 0.9),
4406
+ w: width ?? "120vh",
4407
+ h: height ?? "80vh",
4408
+ bdrs: "sm",
4409
+ style: {
4410
+ userSelect: "none",
4411
+ overflow: "hidden",
4412
+ transform: "translate(-50%, -50%)",
4413
+ boxShadow: "0 0 10px rgba(0,0,0,0.5)",
4414
+ border: `0.1vh solid ${theme2.colors.dark[7]}`
4415
+ },
4416
+ direction: "row",
4417
+ initial: { scale: 0.3, opacity: 0, transform: "translate(-50%, -50%)" },
4418
+ animate: { scale: 1, opacity: 1, transform: "translate(-50%, -50%)" },
4419
+ exit: { scale: 0.3, opacity: 0, transform: "translate(-50%, -50%)" },
4420
+ children: [
4421
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { width: "18vh", flexShrink: 0, borderRight: `0.1vh solid ${core.alpha(theme2.colors.dark[6], 0.8)}`, background: core.alpha(theme2.colors.dark[8], 0.6), overflow: "hidden" }, children: [
4422
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "baseline", gap: "0.3vh", px: "sm", py: "sm", style: { borderBottom: `0.1vh solid ${core.alpha(theme2.colors.dark[6], 0.5)}`, flexShrink: 0 }, children: [
4423
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "lg", ff: "Akrobat Bold", tt: "uppercase", children: title }),
4424
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx(core.Text, { tt: "uppercase", fw: 600, c: color, children: subtitle })
4425
+ ] }),
4426
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { gap: "xxs", px: "xs", py: "xs", style: { borderBottom: `0.1vh solid ${core.alpha(theme2.colors.dark[6], 0.4)}`, flexShrink: 0 }, children: [
4427
+ /* @__PURE__ */ jsxRuntime.jsx(
4428
+ framerMotion.motion.button,
4429
+ {
4430
+ title: "Undo",
4431
+ onClick: () => form.canBack && form.back(),
4432
+ disabled: !form.canBack,
4433
+ whileHover: form.canBack ? { background: "rgba(255,255,255,0.07)" } : void 0,
4434
+ whileTap: form.canBack ? { scale: 0.97 } : void 0,
4435
+ style: { flex: 1, aspectRatio: "1 / 1", background: "transparent", border: `0.1vh solid ${core.alpha(theme2.colors.dark[5], form.canBack ? 0.6 : 0.3)}`, borderRadius: theme2.radius.xs, cursor: form.canBack ? "pointer" : "default", display: "flex", alignItems: "center", justifyContent: "center", opacity: form.canBack ? 1 : 0.35, transition: "opacity 0.2s" },
4436
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Undo2, { size: "1.5vh", color: "rgba(255,255,255,0.7)" })
4437
+ }
4438
+ ),
4439
+ /* @__PURE__ */ jsxRuntime.jsx(
4440
+ framerMotion.motion.button,
4441
+ {
4442
+ title: "Redo",
4443
+ onClick: () => form.canForward && form.forward(),
4444
+ disabled: !form.canForward,
4445
+ whileHover: form.canForward ? { background: "rgba(255,255,255,0.07)" } : void 0,
4446
+ whileTap: form.canForward ? { scale: 0.97 } : void 0,
4447
+ style: { flex: 1, aspectRatio: "1 / 1", background: "transparent", border: `0.1vh solid ${core.alpha(theme2.colors.dark[5], form.canForward ? 0.6 : 0.3)}`, borderRadius: theme2.radius.xs, cursor: form.canForward ? "pointer" : "default", display: "flex", alignItems: "center", justifyContent: "center", opacity: form.canForward ? 1 : 0.35, transition: "opacity 0.2s" },
4448
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Redo2, { size: "1.5vh", color: "rgba(255,255,255,0.7)" })
4449
+ }
4450
+ ),
4451
+ /* @__PURE__ */ jsxRuntime.jsx(
4452
+ framerMotion.motion.button,
4453
+ {
4454
+ title: isSaving ? "Saving..." : isDirty ? `Save (${changedCount})` : "Save",
4455
+ onClick: () => isDirty && !isSaving && form.submit(),
4456
+ disabled: !isDirty || isSaving,
4457
+ whileHover: isDirty && !isSaving ? { background: core.alpha(color, 0.25), borderColor: core.alpha(color, 0.5) } : void 0,
4458
+ whileTap: isDirty && !isSaving ? { scale: 0.97 } : void 0,
4459
+ style: { flex: 1, aspectRatio: "1 / 1", background: isDirty ? core.alpha(color, 0.14) : "transparent", border: `0.1vh solid ${isDirty ? core.alpha(color, 0.35) : core.alpha(theme2.colors.dark[5], 0.3)}`, borderRadius: theme2.radius.xs, cursor: isDirty && !isSaving ? "pointer" : "default", display: "flex", alignItems: "center", justifyContent: "center", opacity: isDirty ? 1 : 0.35, transition: "opacity 0.2s, background 0.15s" },
4460
+ children: isSaving ? /* @__PURE__ */ jsxRuntime.jsx(core.Loader, { size: "1.5vh", color, type: "dots" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Save, { color: isDirty ? color : "rgba(255,255,255,0.35)", size: "1.5vh" })
4461
+ }
4462
+ ),
4463
+ /* @__PURE__ */ jsxRuntime.jsx(
4464
+ framerMotion.motion.button,
4465
+ {
4466
+ title: "History",
4467
+ onClick: () => setHistoryOpen(true),
4468
+ whileHover: { background: core.alpha("#22d3ee", 0.16), borderColor: core.alpha("#22d3ee", 0.5) },
4469
+ whileTap: { scale: 0.97 },
4470
+ style: { flex: 1, aspectRatio: "1 / 1", background: core.alpha("#22d3ee", 0.07), border: `0.1vh solid ${core.alpha("#22d3ee", 0.25)}`, borderRadius: theme2.radius.xs, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" },
4471
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { color: "#22d3ee", size: "1.5vh" })
4472
+ }
4473
+ )
4474
+ ] }),
4475
+ /* @__PURE__ */ jsxRuntime.jsx(core.Flex, { direction: "column", gap: "xxs", p: "xs", style: { flex: 1, overflowY: "auto" }, children: navItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(NavItemButton, { icon: item.icon, label: item.label, active: activeTab === item.id, onClick: () => setActiveTab(item.id) }, item.id)) }),
4476
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", p: "xs", gap: "xs", style: { borderTop: `0.1vh solid ${core.alpha(theme2.colors.dark[6], 0.5)}`, flexShrink: 0 }, children: [
4477
+ /* @__PURE__ */ jsxRuntime.jsxs(
4478
+ framerMotion.motion.button,
4479
+ {
4480
+ onClick: () => isDirty && form.reset(),
4481
+ disabled: !isDirty,
4482
+ whileHover: isDirty ? { background: core.alpha("#f97316", 0.12), borderColor: core.alpha("#f97316", 0.45) } : void 0,
4483
+ whileTap: isDirty ? { scale: 0.97 } : void 0,
4484
+ style: { width: "100%", background: "transparent", border: `0.1vh solid ${isDirty ? core.alpha("#f97316", 0.35) : core.alpha(theme2.colors.dark[5], 0.3)}`, borderRadius: theme2.radius.xs, padding: "0.65vh 0.8vh", cursor: isDirty ? "pointer" : "default", display: "flex", alignItems: "center", gap: "0.55vh", opacity: isDirty ? 1 : 0.35, transition: "opacity 0.2s" },
4485
+ children: [
4486
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { color: isDirty ? "#f97316" : "rgba(255,255,255,0.35)", size: "1.6vh" }),
4487
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: isDirty ? "#f97316" : "rgba(255,255,255,0.35)", children: "Discard" })
4488
+ ]
4489
+ }
4490
+ ),
4491
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "0.05vh", background: "rgba(255,255,255,0.07)", margin: "0.1vh 0" } }),
4492
+ /* @__PURE__ */ jsxRuntime.jsxs(
4493
+ framerMotion.motion.button,
4494
+ {
4495
+ onClick: () => setJsonOpen(true),
4496
+ whileHover: { background: core.alpha(color, 0.16), borderColor: core.alpha(color, 0.45) },
4497
+ whileTap: { scale: 0.97 },
4498
+ style: { width: "100%", background: core.alpha(color, 0.07), border: `0.1vh solid ${core.alpha(color, 0.28)}`, borderRadius: theme2.radius.xs, padding: "0.65vh 0.8vh", cursor: "pointer", display: "flex", alignItems: "center", gap: "0.55vh" },
4499
+ children: [
4500
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code2, { color, size: "1.6vh" }),
4501
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: "Manual Edit" })
4502
+ ]
4503
+ }
4504
+ ),
4505
+ /* @__PURE__ */ jsxRuntime.jsxs(
4506
+ framerMotion.motion.button,
4507
+ {
4508
+ onClick: () => setResetOpen(true),
4509
+ whileHover: { background: core.alpha("#ef4444", 0.16), borderColor: core.alpha("#ef4444", 0.5) },
4510
+ whileTap: { scale: 0.97 },
4511
+ style: { width: "100%", background: core.alpha("#ef4444", 0.07), border: `0.1vh solid ${core.alpha("#ef4444", 0.25)}`, borderRadius: theme2.radius.xs, padding: "0.65vh 0.8vh", cursor: "pointer", display: "flex", alignItems: "center", gap: "0.55vh" },
4512
+ children: [
4513
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { color: "#ef4444", size: "1.6vh" }),
4514
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: "#ef4444", children: "Reset Defaults" })
4515
+ ]
4516
+ }
4517
+ ),
4518
+ version && /* @__PURE__ */ jsxRuntime.jsxs(core.Text, { size: "0.95vh", c: "dimmed", ta: "center", style: { letterSpacing: "0.04em", opacity: 0.8 }, children: [
4519
+ "Version ",
4520
+ version
4521
+ ] })
4522
+ ] })
4523
+ ] }),
4524
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxRuntime.jsx(
4525
+ framerMotion.motion.div,
4526
+ {
4527
+ initial: { opacity: 0, y: 4 },
4528
+ animate: { opacity: 1, y: 0 },
4529
+ exit: { opacity: 0, y: -4 },
4530
+ transition: { duration: 0.15 },
4531
+ style: { flex: 1, display: "flex", flexDirection: "column", overflowY: "auto" },
4532
+ children: children(activeTab)
4533
+ },
4534
+ activeTab
4535
+ ) })
4536
+ ]
4537
+ }
4538
+ )
4539
+ ] });
4540
+ }
4541
+ function cloneSettings(value) {
4542
+ return JSON.parse(JSON.stringify(value));
4543
+ }
4544
+ var defaultOnClose = () => fetchNui("CLOSE_ADMIN_SECTION");
4545
+ function SettingsPanel(props) {
4546
+ const { open, onClose = defaultOnClose } = props;
4547
+ const { store, updateSettings, fetchSettings } = getScriptSettingsInstance();
4548
+ const [isSaving, setIsSaving] = React4.useState(false);
4549
+ const [loaded, setLoaded] = React4.useState(false);
4550
+ React4.useEffect(() => {
4551
+ if (!open) {
4552
+ setLoaded(false);
4553
+ return;
4554
+ }
4555
+ let cancelled = false;
4556
+ fetchSettings().then(() => {
4557
+ if (!cancelled) setLoaded(true);
4558
+ }).catch(() => {
4559
+ if (!cancelled) setLoaded(true);
4560
+ });
4561
+ return () => {
4562
+ cancelled = true;
4563
+ };
4564
+ }, [open]);
4565
+ if (!open || !loaded) return null;
4566
+ return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: settingsPanelQueryClient, children: /* @__PURE__ */ jsxRuntime.jsx(
4567
+ FormProvider,
4568
+ {
4569
+ initialValues: cloneSettings(store.getState()),
4570
+ onSubmit: async (form) => {
4571
+ if (isSaving) return;
4572
+ setIsSaving(true);
4573
+ try {
4574
+ const result = await updateSettings(form.values);
4575
+ if (result?.success) {
4576
+ form.reinitialize(cloneSettings(form.values));
4577
+ settingsPanelQueryClient.invalidateQueries({ queryKey: ["scriptSettingsHistory"] });
4578
+ return;
4579
+ }
4580
+ form.reinitialize(cloneSettings(store.getState()));
4581
+ if (result?._error) {
4582
+ console.warn(`[SettingsPanel] settings save failed: ${result._error}`);
4583
+ }
4584
+ } finally {
4585
+ setIsSaving(false);
4586
+ }
4587
+ },
4588
+ children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: open && /* @__PURE__ */ jsxRuntime.jsx(
4589
+ SettingsPanelInner,
4590
+ {
4591
+ ...props,
4592
+ onClose,
4593
+ isSaving
4594
+ }
4595
+ ) })
4596
+ }
4597
+ ) });
4598
+ }
4599
+ function LazyImage({ src, alt, style }) {
4600
+ const [visible, setVisible] = React4.useState(false);
4601
+ const ref = React4.useRef(null);
4602
+ React4.useEffect(() => {
4603
+ const observer = new IntersectionObserver(([entry]) => {
4604
+ if (entry.isIntersecting) {
4605
+ setVisible(true);
4606
+ observer.disconnect();
4607
+ }
4608
+ });
4609
+ if (ref.current) observer.observe(ref.current);
4610
+ return () => observer.disconnect();
4611
+ }, []);
4612
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, style: { width: "4vh", height: "4vh" }, children: visible && /* @__PURE__ */ jsxRuntime.jsx(core.Image, { src, alt, fit: "contain", style }) });
4613
+ }
4614
+ function SelectItem(props) {
4615
+ const invItems = useItems();
4616
+ const formattedItems = React4.useMemo(() => {
4617
+ const seen = /* @__PURE__ */ new Set();
4618
+ return useItemsList(props.excludeItemNames ?? []).filter((item) => {
4619
+ if (seen.has(item.name)) return false;
4620
+ seen.add(item.name);
4621
+ return true;
4622
+ }).map((item) => ({ value: item.name, label: item.label, image: item.image }));
4623
+ }, [invItems, props.excludeItemNames]);
4624
+ return /* @__PURE__ */ jsxRuntime.jsx(
4625
+ core.Select,
4626
+ {
4627
+ maxDropdownHeight: "30vh",
4628
+ label: locale(props.label),
4629
+ size: "xs",
4630
+ flex: 1,
4631
+ style: props.style,
4632
+ limit: 50,
4633
+ value: props.value,
4634
+ onChange: (v) => props.onChange(v),
4635
+ data: formattedItems,
4636
+ allowDeselect: false,
4637
+ searchable: true,
4638
+ leftSectionWidth: "4vh",
4639
+ leftSection: props.value ? /* @__PURE__ */ jsxRuntime.jsx(
4640
+ core.Image,
4641
+ {
4642
+ fallbackSrc: "/placeholder.png",
4643
+ src: invItems[props.value]?.image || "",
4644
+ alt: props.value,
4645
+ fit: "contain",
4646
+ maw: "4vh",
4647
+ style: { aspectRatio: "1 / 1" }
4648
+ }
4649
+ ) : null,
4650
+ nothingFoundMessage: locale("NoItemsFound"),
4651
+ renderOption: (item) => /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "xs", w: "100%", children: [
4652
+ /* @__PURE__ */ jsxRuntime.jsx(
4653
+ LazyImage,
4654
+ {
4655
+ src: invItems[item.option.value]?.image || "",
4656
+ alt: item.option.label,
4657
+ style: { aspectRatio: "1 / 1" }
4658
+ }
4659
+ ),
4660
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", children: [
4661
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "sm", children: item.option.label }),
4662
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xxs", c: "dimmed", children: item.option.value })
4663
+ ] })
4664
+ ] })
4665
+ }
4666
+ );
4667
+ }
4668
+ var KeyBindContext = React4.createContext(null);
4669
+ function useKeyBindContext() {
4670
+ const ctx = React4.useContext(KeyBindContext);
4671
+ if (!ctx) {
4672
+ throw new Error("FiveMKeyBindInput.* must be used inside <FiveMKeyBindInput>");
4673
+ }
4674
+ return ctx;
4675
+ }
4676
+ function Root({ value, onChange, children }) {
4677
+ return /* @__PURE__ */ jsxRuntime.jsx(KeyBindContext.Provider, { value: { value, onChange }, children: /* @__PURE__ */ jsxRuntime.jsx(core.Flex, { gap: "xs", style: { flex: 1 }, children }) });
4678
+ }
4679
+ function Category({ label: label2 = "Primary" }) {
4680
+ const { value, onChange } = useKeyBindContext();
4681
+ return /* @__PURE__ */ jsxRuntime.jsx(
4682
+ core.Select,
4683
+ {
4684
+ label: label2,
4685
+ size: "xs",
4686
+ style: { flex: 1 },
4687
+ value: value._type,
4688
+ data: [...INPUT_MAPPER_PRIMARY_OPTIONS],
4689
+ onChange: (nextType) => {
4690
+ if (!nextType) return;
4691
+ const keyOptions = INPUT_MAPPER_KEYS_BY_PRIMARY[nextType] ?? [];
4692
+ const hasCurrentKey = keyOptions.includes(value._key);
4693
+ const nextKey = hasCurrentKey ? value._key : keyOptions[0] ?? value._key;
4694
+ onChange({
4695
+ ...value,
4696
+ _type: nextType,
4697
+ _key: nextKey
4698
+ });
4699
+ },
4700
+ searchable: true,
4701
+ allowDeselect: false
4702
+ }
4703
+ );
4704
+ }
4705
+ function Key({ label: label2 = "Key" }) {
4706
+ const { value, onChange } = useKeyBindContext();
4707
+ const keyOptions = INPUT_MAPPER_KEYS_BY_PRIMARY[value._type] ?? [];
4708
+ if (keyOptions.length === 0) {
4709
+ return /* @__PURE__ */ jsxRuntime.jsx(
4710
+ core.TextInput,
4711
+ {
4712
+ label: label2,
4713
+ size: "xs",
4714
+ style: { flex: 1 },
4715
+ value: value._key,
4716
+ onChange: (e) => onChange({ ...value, _key: e.currentTarget.value }),
4717
+ placeholder: "Type key value"
4718
+ }
4719
+ );
4720
+ }
4721
+ return /* @__PURE__ */ jsxRuntime.jsx(
4722
+ core.Select,
4723
+ {
4724
+ label: label2,
4725
+ size: "xs",
4726
+ style: { flex: 1 },
4727
+ value: value._key,
4728
+ data: keyOptions,
4729
+ onChange: (nextKey) => {
4730
+ if (!nextKey) return;
4731
+ onChange({ ...value, _key: nextKey });
4732
+ },
4733
+ searchable: true,
4734
+ allowDeselect: false
4735
+ }
4736
+ );
4737
+ }
4738
+ var FiveMKeyBindInput = Object.assign(Root, {
4739
+ Category,
4740
+ Key
4741
+ });
4742
+ function AsyncSaveButton({
4743
+ onSave,
4744
+ color,
4745
+ label: label2 = "Save Changes",
4746
+ style
4747
+ }) {
4748
+ const theme2 = core.useMantineTheme();
4749
+ const [state, setState] = React4.useState("idle");
4750
+ const handleClick = async () => {
4751
+ if (state === "pending") return;
4752
+ setState("pending");
4753
+ try {
4754
+ const result = await onSave();
4755
+ setState(result?.success === false ? "error" : "success");
4756
+ } catch {
4757
+ setState("error");
4758
+ }
4759
+ setTimeout(() => setState("idle"), 2e3);
4760
+ };
4761
+ const c = state === "error" ? "#ef4444" : color;
4762
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4763
+ framerMotion.motion.button,
4764
+ {
4765
+ onClick: handleClick,
4766
+ disabled: state === "pending",
4767
+ whileHover: state === "pending" ? {} : { background: core.alpha(c, 0.25) },
4768
+ whileTap: state === "pending" ? {} : { scale: 0.98 },
4769
+ style: {
4770
+ background: core.alpha(c, 0.14),
4771
+ border: `0.1vh solid ${core.alpha(c, 0.4)}`,
4772
+ borderRadius: theme2.radius.xs,
4773
+ padding: `${theme2.spacing.xxs} ${theme2.spacing.xs}`,
4774
+ cursor: state === "pending" ? "default" : "pointer",
4775
+ display: "flex",
4776
+ alignItems: "center",
4777
+ justifyContent: "center",
4778
+ gap: theme2.spacing.xxs,
4779
+ transition: "background 0.2s, border-color 0.2s",
4780
+ alignSelf: "flex-end",
4781
+ ...style
4782
+ },
4783
+ children: [
4784
+ state === "pending" ? /* @__PURE__ */ jsxRuntime.jsx(core.Loader, { size: "1.4vh", color: c, type: "oval" }) : state === "error" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: "1.4vh", color: c }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { size: "1.4vh", color: c }),
4785
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.06em", c, children: state === "success" ? "Saved!" : state === "error" ? "Failed!" : label2 })
4786
+ ]
4787
+ }
4788
+ );
4789
+ }
4790
+ function AdminPageTitle(props) {
4791
+ return /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "xs", children: [
4792
+ /* @__PURE__ */ jsxRuntime.jsx(props.icon, { color: props.color }),
4793
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", tt: "uppercase", lts: "0.1em", size: "sm", c: "rgba(255,255,255,0.6)", children: locale(props.title) })
4794
+ ] });
4795
+ }
2288
4796
  function useTornEdges() {
2289
4797
  const game = useSettings((state) => state.game);
2290
4798
  return game === "rdr3" ? "torn-edge-wrapper" : "";
@@ -2336,23 +4844,6 @@ function TornEdgeSVGFilter() {
2336
4844
  }
2337
4845
  );
2338
4846
  }
2339
- function createScriptSettings(defaultValue) {
2340
- const store = zustand.create(() => defaultValue);
2341
- if (typeof window !== "undefined") {
2342
- window.addEventListener("message", (event) => {
2343
- if (event.data?.action === "UPDATE_SCRIPT_SETTINGS" && event.data?.data) {
2344
- store.setState((prev) => ({ ...prev, ...event.data.data }));
2345
- }
2346
- });
2347
- }
2348
- const useScriptSettingHooks = () => {
2349
- };
2350
- const updateScriptSettings = async (newSettings) => {
2351
- store.setState((prev) => ({ ...prev, ...newSettings }));
2352
- return await fetchNui("UPDATE_SCRIPT_SETTINGS", newSettings);
2353
- };
2354
- return { store, updateScriptSettings, useScriptSettingHooks };
2355
- }
2356
4847
  var label = {
2357
4848
  fontSize: "var(--mantine-font-size-xs)",
2358
4849
  fontFamily: "Akrobat Bold",
@@ -2372,7 +4863,9 @@ var genericInputStyles = {
2372
4863
  error,
2373
4864
  description,
2374
4865
  input: {
2375
- backgroundColor: "rgba(76, 76, 76, 0.3)",
4866
+ background: "rgba(255,255,255,0.04)",
4867
+ border: "0.1vh solid rgba(255,255,255,0.08)",
4868
+ color: "rgba(255,255,255,0.85)",
2376
4869
  minHeight: "4vh"
2377
4870
  }
2378
4871
  }
@@ -2490,7 +4983,7 @@ function mergeMantineThemeSafe(base, custom, override) {
2490
4983
  }
2491
4984
  };
2492
4985
  }
2493
- var DirkErrorBoundary = class extends React3__default.default.Component {
4986
+ var DirkErrorBoundary = class extends React4__default.default.Component {
2494
4987
  constructor() {
2495
4988
  super(...arguments);
2496
4989
  __publicField(this, "state", { error: null, stack: void 0 });
@@ -2553,23 +5046,27 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
2553
5046
  customTheme,
2554
5047
  game
2555
5048
  } = useSettings();
2556
- React3.useLayoutEffect(() => {
5049
+ React4.useLayoutEffect(() => {
2557
5050
  useSettings.setState({
2558
5051
  overideResourceName
2559
5052
  });
2560
5053
  }, [overideResourceName]);
2561
- React3.useEffect(() => {
5054
+ React4.useEffect(() => {
2562
5055
  fetchNui("NUI_READY").catch(() => {
2563
5056
  });
2564
- fetchNui("GET_SETTINGS").then((data) => {
5057
+ Promise.all([
5058
+ fetchNui("GET_SETTINGS"),
5059
+ fetchNui("GET_RESOURCE_VERSION", void 0, { version: "dev" })
5060
+ ]).then(([data, resourceInfo]) => {
2565
5061
  useSettings.setState({
2566
- ...data
5062
+ ...data,
5063
+ resourceVersion: resourceInfo?.version || "dev"
2567
5064
  });
2568
5065
  }).catch((err) => {
2569
5066
  console.error("Failed to fetch initial settings within dirk-cfx-react:", err);
2570
5067
  });
2571
5068
  }, []);
2572
- const mergedTheme = React3.useMemo(
5069
+ const mergedTheme = React4.useMemo(
2573
5070
  () => mergeMantineThemeSafe(
2574
5071
  { ...theme_default, primaryColor, primaryShade },
2575
5072
  customTheme,
@@ -2577,7 +5074,7 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
2577
5074
  ),
2578
5075
  [primaryColor, primaryShade, customTheme, themeOverride]
2579
5076
  );
2580
- React3.useEffect(() => {
5077
+ React4.useEffect(() => {
2581
5078
  document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : '"Akrobat Regular", sans-serif';
2582
5079
  }, [game]);
2583
5080
  const content = isEnvBrowser() ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -2592,15 +5089,24 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
2592
5089
  return /* @__PURE__ */ jsxRuntime.jsx(core.MantineProvider, { theme: mergedTheme, defaultColorScheme: "dark", children: /* @__PURE__ */ jsxRuntime.jsx(DirkErrorBoundary, { children: content }) });
2593
5090
  }
2594
5091
 
5092
+ exports.AdminPageTitle = AdminPageTitle;
5093
+ exports.AsyncSaveButton = AsyncSaveButton;
5094
+ exports.BlipColorSelect = BlipColorSelect;
5095
+ exports.BlipIconSelect = BlipIconSelect;
2595
5096
  exports.BorderedIcon = BorderedIcon;
5097
+ exports.ConfirmModal = ConfirmModal;
2596
5098
  exports.Counter = Counter;
2597
5099
  exports.DirkProvider = DirkProvider;
5100
+ exports.FiveMKeyBindInput = FiveMKeyBindInput;
2598
5101
  exports.FloatingParticles = FloatingParticles;
2599
5102
  exports.FormProvider = FormProvider;
5103
+ exports.INPUT_MAPPER_KEYS_BY_PRIMARY = INPUT_MAPPER_KEYS_BY_PRIMARY;
5104
+ exports.INPUT_MAPPER_PRIMARY_OPTIONS = INPUT_MAPPER_PRIMARY_OPTIONS;
2600
5105
  exports.InfoBox = InfoBox;
2601
5106
  exports.InputContainer = InputContainer;
2602
5107
  exports.LevelBanner = LevelBanner;
2603
5108
  exports.LevelPanel = LevelPanel;
5109
+ exports.Modal = Modal;
2604
5110
  exports.ModalContext = ModalContext;
2605
5111
  exports.ModalProvider = ModalProvider;
2606
5112
  exports.MotionFlex = MotionFlex;
@@ -2613,6 +5119,8 @@ exports.NavigationProvider = NavigationProvider;
2613
5119
  exports.PromptModal = PromptModal;
2614
5120
  exports.SegmentedControl = SegmentedControl;
2615
5121
  exports.SegmentedProgress = SegmentedProgress;
5122
+ exports.SelectItem = SelectItem;
5123
+ exports.SettingsPanel = SettingsPanel;
2616
5124
  exports.Title = Title;
2617
5125
  exports.TornEdgeSVGFilter = TornEdgeSVGFilter;
2618
5126
  exports.colorWithAlpha = colorWithAlpha;
@@ -2620,10 +5128,13 @@ exports.copyToClipboard = copyToClipboard;
2620
5128
  exports.createFormStore = createFormStore;
2621
5129
  exports.createScriptSettings = createScriptSettings;
2622
5130
  exports.createSkill = createSkill;
5131
+ exports.extractDefaults = extractDefaults;
2623
5132
  exports.fetchLuaTable = fetchLuaTable;
2624
5133
  exports.fetchNui = fetchNui;
2625
5134
  exports.gameToMap = gameToMap;
2626
5135
  exports.getImageShape = getImageShape;
5136
+ exports.getItemImageUrl = getItemImageUrl;
5137
+ exports.getScriptSettingsInstance = getScriptSettingsInstance;
2627
5138
  exports.initialFetches = initialFetches;
2628
5139
  exports.internalEvent = internalEvent;
2629
5140
  exports.isEnvBrowser = isEnvBrowser;
@@ -2642,6 +5153,7 @@ exports.runFetches = runFetches;
2642
5153
  exports.splitFAString = splitFAString;
2643
5154
  exports.updatePresignedURL = updatePresignedURL;
2644
5155
  exports.uploadImage = uploadImage;
5156
+ exports.useAudio = useAudio;
2645
5157
  exports.useAutoFetcher = useAutoFetcher;
2646
5158
  exports.useForm = useForm;
2647
5159
  exports.useFormActions = useFormActions;
@@ -2649,6 +5161,8 @@ exports.useFormError = useFormError;
2649
5161
  exports.useFormErrors = useFormErrors;
2650
5162
  exports.useFormField = useFormField;
2651
5163
  exports.useFormFields = useFormFields;
5164
+ exports.useItems = useItems;
5165
+ exports.useItemsList = useItemsList;
2652
5166
  exports.useModal = useModal;
2653
5167
  exports.useModalActions = useModalActions;
2654
5168
  exports.useNavigation = useNavigation;