Florr.io Rebinds

Customizable key rebinding interface for Florr.io

  1. // ==UserScript==
  2. // @name Florr.io Rebinds
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0.0
  5. // @description Customizable key rebinding interface for Florr.io
  6. // @author VortexPrime
  7. // @match https://florr.io/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=florr.io
  9. // @grant none
  10. // @run-at document-start
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. document.addEventListener('DOMContentLoaded', function() {
  18. const keybinds = {
  19. '0': null,
  20. '1': null,
  21. '2': null,
  22. '3': null,
  23. '4': null,
  24. '5': null,
  25. '6': null,
  26. '7': null,
  27. '8': null,
  28. '9': null,
  29. 'R': null,
  30. 'L': null,
  31. 'K': null,
  32. 'M': null
  33. };
  34.  
  35. const bindableKeys = new Set(Object.keys(keybinds));
  36. const reverseKeybinds = {};
  37. const keyState = {};
  38.  
  39. function updateReverseMapping() {
  40. Object.keys(reverseKeybinds).forEach(key => delete reverseKeybinds[key]);
  41.  
  42. Object.keys(keybinds).forEach(target => {
  43. const bind = keybinds[target];
  44. if (bind) {
  45. reverseKeybinds[bind.toUpperCase()] = target;
  46. }
  47. });
  48. }
  49.  
  50. updateReverseMapping();
  51.  
  52. const keyDisplayMap = {
  53. 'ESCAPE': 'ESC',
  54. 'BACKSPACE': 'BSP',
  55. 'DELETE': 'DEL',
  56. 'INSERT': 'INS',
  57. 'PAGEUP': 'PUP',
  58. 'PAGEDOWN': 'PDN',
  59. 'ARROWUP': 'UP',
  60. 'ARROWDOWN': 'DWN',
  61. 'ARROWLEFT': 'LFT',
  62. 'ARROWRIGHT': 'RGT',
  63. 'SPACE': 'SPC',
  64. 'CONTROL': 'CTL',
  65. 'SHIFT': 'SHF',
  66. 'ENTER': 'ENT',
  67. 'TAB': 'TAB'
  68. };
  69.  
  70. const keyCodeMap = {
  71. '0': 'Digit0',
  72. '1': 'Digit1',
  73. '2': 'Digit2',
  74. '3': 'Digit3',
  75. '4': 'Digit4',
  76. '5': 'Digit5',
  77. '6': 'Digit6',
  78. '7': 'Digit7',
  79. '8': 'Digit8',
  80. '9': 'Digit9',
  81. 'A': 'KeyA',
  82. 'B': 'KeyB',
  83. 'C': 'KeyC',
  84. 'D': 'KeyD',
  85. 'E': 'KeyE',
  86. 'F': 'KeyF',
  87. 'G': 'KeyG',
  88. 'H': 'KeyH',
  89. 'I': 'KeyI',
  90. 'J': 'KeyJ',
  91. 'K': 'KeyK',
  92. 'L': 'KeyL',
  93. 'M': 'KeyM',
  94. 'N': 'KeyN',
  95. 'O': 'KeyO',
  96. 'P': 'KeyP',
  97. 'Q': 'KeyQ',
  98. 'R': 'KeyR',
  99. 'S': 'KeyS',
  100. 'T': 'KeyT',
  101. 'U': 'KeyU',
  102. 'V': 'KeyV',
  103. 'W': 'KeyW',
  104. 'X': 'KeyX',
  105. 'Y': 'KeyY',
  106. 'Z': 'KeyZ',
  107. 'SPACE': 'Space',
  108. 'SHIFT': 'ShiftLeft',
  109. 'CONTROL': 'ControlLeft',
  110. 'TAB': 'Tab'
  111. };
  112.  
  113. const groupDescriptions = {
  114. loadout: 'Loadout Slots',
  115. utility: {
  116. 'R': 'Swap all loadouts',
  117. 'L': 'Load saved builds',
  118. 'K': 'Load saved builds',
  119. 'M': 'Toggle expanded minimap'
  120. }
  121. };
  122.  
  123. const style = document.createElement('style');
  124. style.textContent = `
  125. .florrBinds-modal {
  126. position: absolute;
  127. top: 50px;
  128. left: 50px;
  129. width: 280px;
  130. background-color: #374151;
  131. border-radius: 8px;
  132. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
  133. border: 1px solid #4B5563;
  134. font-family: Arial, sans-serif;
  135. color: #E5E7EB;
  136. z-index: 10000;
  137. overflow: hidden;
  138. user-select: none;
  139. }
  140.  
  141. .florrBinds-modal.hidden {
  142. display: none;
  143. }
  144.  
  145. .florrBinds-header {
  146. background-color: #1F2937;
  147. padding: 10px 16px;
  148. border-bottom: 1px solid #4B5563;
  149. cursor: move;
  150. display: flex;
  151. justify-content: space-between;
  152. }
  153.  
  154. .florrBinds-header-left, .florrBinds-header-right {
  155. display: flex;
  156. flex-direction: column;
  157. justify-content: center;
  158. }
  159.  
  160. .florrBinds-header-right {
  161. align-items: flex-end;
  162. text-align: right;
  163. }
  164.  
  165. .florrBinds-title {
  166. color: #FBBF24;
  167. font-weight: bold;
  168. font-size: 18px;
  169. margin: 0;
  170. padding: 0;
  171. line-height: 1.2;
  172. }
  173.  
  174. .florrBinds-subtitle {
  175. color: #9CA3AF;
  176. font-size: 12px;
  177. margin: 0;
  178. }
  179.  
  180. .florrBinds-author {
  181. color: #9CA3AF;
  182. font-size: 11px;
  183. margin-top: 2px;
  184. }
  185.  
  186. .florrBinds-author a {
  187. color: #93C5FD;
  188. text-decoration: none;
  189. }
  190.  
  191. .florrBinds-author a:hover {
  192. text-decoration: underline;
  193. }
  194.  
  195. .florrBinds-drag-hint {
  196. color: #6B7280;
  197. font-size: 11px;
  198. margin-bottom: 2px;
  199. }
  200.  
  201. .florrBinds-content {
  202. padding: 8px;
  203. overflow: hidden;
  204. }
  205.  
  206. .florrBinds-modal.collapsed .florrBinds-content,
  207. .florrBinds-modal.collapsed .florrBinds-footer {
  208. display: none;
  209. }
  210.  
  211. .florrBinds-group {
  212. margin-bottom: 8px;
  213. }
  214.  
  215. .florrBinds-group-title {
  216. color: #9CA3AF;
  217. font-size: 14px;
  218. margin-bottom: 4px;
  219. padding-bottom: 4px;
  220. border-bottom: 1px solid #4B5563;
  221. }
  222.  
  223. .florrBinds-loadout-grid {
  224. display: grid;
  225. grid-template-columns: repeat(5, 1fr);
  226. gap: 8px;
  227. }
  228.  
  229. .florrBinds-key-item {
  230. display: flex;
  231. flex-direction: column;
  232. align-items: center;
  233. margin-bottom: 6px;
  234. }
  235.  
  236. .florrBinds-key-label {
  237. color: #D1D5DB;
  238. font-size: 14px;
  239. margin-bottom: 4px;
  240. }
  241.  
  242. .florrBinds-key-value {
  243. background-color: #1F2937;
  244. color: #FFF;
  245. padding: 4px 12px;
  246. border-radius: 4px;
  247. border: 1px solid #4B5563;
  248. font-family: monospace;
  249. font-size: 14px;
  250. cursor: pointer;
  251. text-align: center;
  252. width: 100%;
  253. box-sizing: border-box;
  254. transition: transform 0.2s ease;
  255. }
  256.  
  257. .florrBinds-key-value:hover {
  258. transform: translateY(-2px);
  259. }
  260.  
  261. .florrBinds-key-value.unbound {
  262. background-color: #111827;
  263. color: #9CA3AF;
  264. border-color: #4B5563;
  265. }
  266.  
  267. .florrBinds-utility {
  268. display: none;
  269. }
  270.  
  271. .florrBinds-utility.show {
  272. display: block;
  273. }
  274.  
  275. .florrBinds-utility-item {
  276. display: flex;
  277. justify-content: space-between;
  278. align-items: center;
  279. margin-bottom: 6px;
  280. }
  281.  
  282. .florrBinds-utility-info {
  283. display: flex;
  284. align-items: center;
  285. min-width: 0;
  286. flex: 1;
  287. }
  288.  
  289. .florrBinds-utility-key {
  290. color: #D1D5DB;
  291. font-size: 14px;
  292. margin-right: 8px;
  293. flex-shrink: 0;
  294. }
  295.  
  296. .florrBinds-utility-desc {
  297. color: #9CA3AF;
  298. font-size: 12px;
  299. white-space: nowrap;
  300. overflow: hidden;
  301. text-overflow: ellipsis;
  302. }
  303.  
  304. .florrBinds-key-value-container {
  305. flex-shrink: 0;
  306. width: 60px;
  307. text-align: right;
  308. }
  309.  
  310. .florrBinds-utility .florrBinds-key-value {
  311. width: 100%;
  312. box-sizing: border-box;
  313. text-align: center;
  314. }
  315.  
  316. .florrBinds-toggle {
  317. width: 100%;
  318. text-align: center;
  319. color: #60A5FA;
  320. background: none;
  321. border: none;
  322. padding: 4px;
  323. margin-bottom: 6px;
  324. font-size: 14px;
  325. cursor: pointer;
  326. }
  327.  
  328. .florrBinds-toggle:hover {
  329. color: #93C5FD;
  330. }
  331.  
  332. .florrBinds-footer {
  333. display: flex;
  334. justify-content: space-between;
  335. align-items: center;
  336. padding: 8px;
  337. border-top: 1px solid #4B5563;
  338. }
  339.  
  340. .florrBinds-reset {
  341. background-color: #2563EB;
  342. color: white;
  343. border: none;
  344. border-radius: 4px;
  345. padding: 4px 8px;
  346. font-size: 12px;
  347. cursor: pointer;
  348. }
  349.  
  350. .florrBinds-reset:hover {
  351. background-color: #3B82F6;
  352. }
  353.  
  354. .florrBinds-hint {
  355. color: #9CA3AF;
  356. font-size: 12px;
  357. }
  358.  
  359. .florrBinds-resize {
  360. position: absolute;
  361. bottom: 0;
  362. right: 0;
  363. width: 12px;
  364. height: 12px;
  365. cursor: ew-resize;
  366. display: flex;
  367. align-items: center;
  368. justify-content: center;
  369. }
  370.  
  371. .florrBinds-resize-icon {
  372. width: 0;
  373. height: 0;
  374. border-style: solid;
  375. border-width: 0 0 8px 8px;
  376. border-color: transparent transparent rgba(200, 200, 200, 0.4) transparent;
  377. }
  378.  
  379. .florrBinds-status {
  380. position: absolute;
  381. bottom: 8px;
  382. left: 8px;
  383. padding: 4px 8px;
  384. background-color: rgba(0, 0, 0, 0.5);
  385. color: white;
  386. border-radius: 4px;
  387. font-size: 12px;
  388. pointer-events: none;
  389. opacity: 0;
  390. transition: opacity 0.3s ease;
  391. }
  392.  
  393. .florrBinds-status.show {
  394. opacity: 1;
  395. }
  396. `;
  397. document.head.appendChild(style);
  398.  
  399. const modal = document.createElement('div');
  400. modal.className = 'florrBinds-modal';
  401.  
  402. const header = document.createElement('div');
  403. header.className = 'florrBinds-header';
  404.  
  405. const headerLeft = document.createElement('div');
  406. headerLeft.className = 'florrBinds-header-left';
  407.  
  408. const title = document.createElement('h3');
  409. title.className = 'florrBinds-title';
  410. title.textContent = 'Florr.io Binds';
  411.  
  412. const subtitle = document.createElement('p');
  413. subtitle.className = 'florrBinds-subtitle';
  414. subtitle.textContent = 'Rebind specific keys!';
  415.  
  416. headerLeft.appendChild(title);
  417. headerLeft.appendChild(subtitle);
  418.  
  419. const headerRight = document.createElement('div');
  420. headerRight.className = 'florrBinds-header-right';
  421.  
  422. const dragHint = document.createElement('div');
  423. dragHint.className = 'florrBinds-drag-hint';
  424. dragHint.textContent = '(Drag to move)';
  425.  
  426. const author = document.createElement('div');
  427. author.className = 'florrBinds-author';
  428. author.innerHTML = 'by <a href="https://ashish.top" target="_blank">VortexPrime</a>';
  429.  
  430. headerRight.appendChild(dragHint);
  431. headerRight.appendChild(author);
  432.  
  433. header.appendChild(headerLeft);
  434. header.appendChild(headerRight);
  435. modal.appendChild(header);
  436.  
  437. const content = document.createElement('div');
  438. content.className = 'florrBinds-content';
  439.  
  440. const loadoutGroup = document.createElement('div');
  441. loadoutGroup.className = 'florrBinds-group';
  442.  
  443. const loadoutTitle = document.createElement('h4');
  444. loadoutTitle.className = 'florrBinds-group-title';
  445. loadoutTitle.textContent = groupDescriptions.loadout;
  446. loadoutGroup.appendChild(loadoutTitle);
  447.  
  448. const loadoutGrid = document.createElement('div');
  449. loadoutGrid.className = 'florrBinds-loadout-grid';
  450.  
  451. for (let i = 0; i <= 9; i++) {
  452. const key = i.toString();
  453. const keyItem = document.createElement('div');
  454. keyItem.className = 'florrBinds-key-item';
  455.  
  456. const keyLabel = document.createElement('span');
  457. keyLabel.className = 'florrBinds-key-label';
  458. keyLabel.textContent = key;
  459.  
  460. const keyValue = document.createElement('div');
  461. keyValue.className = `florrBinds-key-value ${keybinds[key] ? '' : 'unbound'}`;
  462. keyValue.textContent = keybinds[key] ? formatKeyDisplay(keybinds[key]) : '-';
  463. keyValue.dataset.key = key;
  464.  
  465. keyItem.appendChild(keyLabel);
  466. keyItem.appendChild(keyValue);
  467. loadoutGrid.appendChild(keyItem);
  468. }
  469.  
  470. loadoutGroup.appendChild(loadoutGrid);
  471. content.appendChild(loadoutGroup);
  472.  
  473. const utilityGroup = document.createElement('div');
  474. utilityGroup.className = 'florrBinds-group florrBinds-utility';
  475.  
  476. const utilityTitle = document.createElement('h4');
  477. utilityTitle.className = 'florrBinds-group-title';
  478. utilityTitle.textContent = 'Utility Keys';
  479. utilityGroup.appendChild(utilityTitle);
  480.  
  481. const utilityKeys = ['R', 'L', 'K', 'M'];
  482. for (const key of utilityKeys) {
  483. const utilityItem = document.createElement('div');
  484. utilityItem.className = 'florrBinds-utility-item';
  485.  
  486. const utilityInfo = document.createElement('div');
  487. utilityInfo.className = 'florrBinds-utility-info';
  488.  
  489. const utilityKey = document.createElement('span');
  490. utilityKey.className = 'florrBinds-utility-key';
  491. utilityKey.textContent = key;
  492.  
  493. const utilityDesc = document.createElement('span');
  494. utilityDesc.className = 'florrBinds-utility-desc';
  495. utilityDesc.textContent = groupDescriptions.utility[key];
  496.  
  497. utilityInfo.appendChild(utilityKey);
  498. utilityInfo.appendChild(utilityDesc);
  499.  
  500. const keyValueContainer = document.createElement('div');
  501. keyValueContainer.className = 'florrBinds-key-value-container';
  502.  
  503. const keyValue = document.createElement('div');
  504. keyValue.className = `florrBinds-key-value ${keybinds[key] ? '' : 'unbound'}`;
  505. keyValue.textContent = keybinds[key] ? formatKeyDisplay(keybinds[key]) : '-';
  506. keyValue.dataset.key = key;
  507.  
  508. keyValueContainer.appendChild(keyValue);
  509.  
  510. utilityItem.appendChild(utilityInfo);
  511. utilityItem.appendChild(keyValueContainer);
  512. utilityGroup.appendChild(utilityItem);
  513. }
  514.  
  515. content.appendChild(utilityGroup);
  516.  
  517. const toggleBtn = document.createElement('button');
  518. toggleBtn.className = 'florrBinds-toggle';
  519. toggleBtn.textContent = 'Show More »';
  520. content.appendChild(toggleBtn);
  521.  
  522. const footer = document.createElement('div');
  523. footer.className = 'florrBinds-footer';
  524.  
  525. const resetBtn = document.createElement('button');
  526. resetBtn.className = 'florrBinds-reset';
  527. resetBtn.textContent = 'Reset All';
  528.  
  529. const hint = document.createElement('div');
  530. hint.className = 'florrBinds-hint';
  531. hint.textContent = 'Toggle using Right Shift';
  532.  
  533. footer.appendChild(resetBtn);
  534. footer.appendChild(hint);
  535.  
  536. modal.appendChild(content);
  537. modal.appendChild(footer);
  538.  
  539. const resizeHandle = document.createElement('div');
  540. resizeHandle.className = 'florrBinds-resize';
  541.  
  542. const resizeIcon = document.createElement('div');
  543. resizeIcon.className = 'florrBinds-resize-icon';
  544.  
  545. resizeHandle.appendChild(resizeIcon);
  546. modal.appendChild(resizeHandle);
  547.  
  548. const statusNotification = document.createElement('div');
  549. statusNotification.className = 'florrBinds-status';
  550. document.body.appendChild(statusNotification);
  551.  
  552. document.body.appendChild(modal);
  553.  
  554. let isDragging = false;
  555. let dragOffsetX = 0;
  556. let dragOffsetY = 0;
  557.  
  558. let isResizing = false;
  559. let originalWidth = 280;
  560. let originalMouseX = 0;
  561.  
  562. let isRebinding = false;
  563. let rebindElement = null;
  564.  
  565. function formatKeyDisplay(key) {
  566. if (!key) return '-';
  567. const upperKey = key.toUpperCase();
  568. return keyDisplayMap[upperKey] || (upperKey.length > 3 ? upperKey.substring(0, 3) : upperKey);
  569. }
  570.  
  571. function showStatus(message, duration = 2000) {
  572. statusNotification.textContent = message;
  573. statusNotification.classList.add('show');
  574. setTimeout(() => {
  575. statusNotification.classList.remove('show');
  576. }, duration);
  577. }
  578.  
  579. function simulateKeyEvent(type, key, code) {
  580. const event = new KeyboardEvent(type, {
  581. key: key,
  582. code: code,
  583. keyCode: key.charCodeAt(0),
  584. which: key.charCodeAt(0),
  585. bubbles: true,
  586. cancelable: true
  587. });
  588.  
  589. document.dispatchEvent(event);
  590. }
  591.  
  592. function getCodeForKey(key) {
  593. if (key >= '0' && key <= '9') {
  594. return `Digit${key}`;
  595. }
  596. return keyCodeMap[key.toUpperCase()] || `Key${key.toUpperCase()}`;
  597. }
  598.  
  599. toggleBtn.addEventListener('click', () => {
  600. const utilitySection = document.querySelector('.florrBinds-utility');
  601. utilitySection.classList.toggle('show');
  602. toggleBtn.textContent = utilitySection.classList.contains('show') ? '« Show Less' : 'Show More »';
  603. });
  604.  
  605. header.addEventListener('contextmenu', (e) => {
  606. e.preventDefault();
  607. modal.classList.toggle('collapsed');
  608. return false;
  609. });
  610.  
  611. header.addEventListener('mousedown', (e) => {
  612. if (e.button === 0) {
  613. isDragging = true;
  614. dragOffsetX = e.clientX - modal.offsetLeft;
  615. dragOffsetY = e.clientY - modal.offsetTop;
  616. e.preventDefault();
  617. }
  618. });
  619.  
  620. resizeHandle.addEventListener('mousedown', (e) => {
  621. isResizing = true;
  622. originalWidth = modal.offsetWidth;
  623. originalMouseX = e.clientX;
  624. e.preventDefault();
  625. e.stopPropagation();
  626. });
  627.  
  628. document.addEventListener('mousemove', (e) => {
  629. if (isDragging) {
  630. modal.style.left = (e.clientX - dragOffsetX) + 'px';
  631. modal.style.top = (e.clientY - dragOffsetY) + 'px';
  632. } else if (isResizing) {
  633. const width = originalWidth + (e.clientX - originalMouseX);
  634.  
  635. if (width >= 240) {
  636. modal.style.width = width + 'px';
  637. }
  638. }
  639. });
  640.  
  641. document.addEventListener('mouseup', () => {
  642. isDragging = false;
  643. isResizing = false;
  644. });
  645.  
  646. document.addEventListener('keydown', (e) => {
  647. if (e.key === 'Shift' && e.location === 2) {
  648. modal.classList.toggle('hidden');
  649. e.preventDefault();
  650. e.stopPropagation();
  651. return;
  652. }
  653.  
  654. if (isRebinding) return;
  655.  
  656. const pressedKey = e.key.toUpperCase();
  657.  
  658. if (reverseKeybinds[pressedKey]) {
  659. const targetKey = reverseKeybinds[pressedKey];
  660.  
  661. if (!keyState[pressedKey]) {
  662. keyState[pressedKey] = true;
  663.  
  664. const targetCode = getCodeForKey(targetKey);
  665. simulateKeyEvent('keydown', targetKey, targetCode);
  666. }
  667. }
  668. }, true);
  669.  
  670. document.addEventListener('keyup', (e) => {
  671. if (isRebinding) return;
  672.  
  673. const releasedKey = e.key.toUpperCase();
  674.  
  675. if (reverseKeybinds[releasedKey]) {
  676. const targetKey = reverseKeybinds[releasedKey];
  677.  
  678. if (keyState[releasedKey]) {
  679. keyState[releasedKey] = false;
  680.  
  681. const targetCode = getCodeForKey(targetKey);
  682. simulateKeyEvent('keyup', targetKey, targetCode);
  683. }
  684. }
  685. }, true);
  686.  
  687. const keyElements = document.querySelectorAll('.florrBinds-key-value');
  688. keyElements.forEach(element => {
  689. element.addEventListener('click', () => {
  690. if (isRebinding) {
  691. rebindElement.style.boxShadow = '';
  692. isRebinding = false;
  693. }
  694.  
  695. keyElements.forEach(el => el.style.boxShadow = '');
  696. element.style.boxShadow = '0 0 0 2px #60A5FA';
  697.  
  698. isRebinding = true;
  699. rebindElement = element;
  700.  
  701. showStatus(`Press any key to bind to ${element.dataset.key}. ESC/BACKSPACE to unbind.`);
  702.  
  703. const captureKey = (e) => {
  704. e.preventDefault();
  705. e.stopPropagation();
  706.  
  707. const key = e.key.toUpperCase();
  708. const targetKey = element.dataset.key;
  709.  
  710. let conflictKey = null;
  711. for (const k in keybinds) {
  712. if (keybinds[k] && keybinds[k].toUpperCase() === key) {
  713. conflictKey = k;
  714. break;
  715. }
  716. }
  717.  
  718. if (conflictKey && conflictKey !== targetKey) {
  719. showStatus(`Warning: "${key}" was already bound to ${conflictKey}. Binding swapped.`, 3000);
  720.  
  721. const conflictElement = document.querySelector(`.florrBinds-key-value[data-key="${conflictKey}"]`);
  722. if (conflictElement) {
  723. conflictElement.textContent = '-';
  724. conflictElement.classList.add('unbound');
  725. keybinds[conflictKey] = null;
  726. }
  727. }
  728.  
  729. if (key === 'ESCAPE' || key === 'BACKSPACE') {
  730. element.textContent = '-';
  731. element.classList.add('unbound');
  732. keybinds[targetKey] = null;
  733. showStatus(`Removed binding for ${targetKey}`);
  734. } else {
  735. element.textContent = formatKeyDisplay(key);
  736. element.classList.remove('unbound');
  737. keybinds[targetKey] = key;
  738. showStatus(`Bound ${targetKey} to ${key}`);
  739. }
  740.  
  741. updateReverseMapping();
  742.  
  743. element.style.boxShadow = '';
  744. isRebinding = false;
  745. rebindElement = null;
  746.  
  747. document.removeEventListener('keydown', captureKey);
  748. };
  749.  
  750. document.addEventListener('keydown', captureKey);
  751. });
  752. });
  753.  
  754. resetBtn.addEventListener('click', () => {
  755. for (const key in keybinds) {
  756. keybinds[key] = null;
  757.  
  758. const element = document.querySelector(`.florrBinds-key-value[data-key="${key}"]`);
  759. if (element) {
  760. element.textContent = '-';
  761. element.classList.add('unbound');
  762. }
  763. }
  764.  
  765. keybinds['0'] = 'V';
  766. keybinds['1'] = 'B';
  767. keybinds['2'] = 'F';
  768. keybinds['3'] = 'G';
  769. keybinds['4'] = 'E';
  770. keybinds['9'] = 'P';
  771. keybinds['K'] = 'X';
  772.  
  773. for (const key in keybinds) {
  774. if (keybinds[key]) {
  775. const element = document.querySelector(`.florrBinds-key-value[data-key="${key}"]`);
  776. if (element) {
  777. element.textContent = formatKeyDisplay(keybinds[key]);
  778. element.classList.remove('unbound');
  779. }
  780. }
  781. }
  782.  
  783. updateReverseMapping();
  784.  
  785. Object.keys(keyState).forEach(key => delete keyState[key]);
  786.  
  787. showStatus('All keybinds reset to default');
  788. });
  789.  
  790. updateReverseMapping();
  791.  
  792. modal.classList.add('hidden');
  793. showStatus('Keybinds loaded! Press Right Shift to toggle the modal.', 3000);
  794. });
  795. })();