tiny-essentials 1.20.3 → 1.21.1

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.
Files changed (126) hide show
  1. package/README.md +13 -11
  2. package/dist/_/numbers.cjs +136 -0
  3. package/dist/_/numbers.d.mts +24 -0
  4. package/dist/_/numbers.mjs +102 -0
  5. package/dist/v1/TinyAdvancedRaffle.min.js +1 -0
  6. package/dist/v1/TinyArrayPaginator.min.js +1 -0
  7. package/dist/v1/TinyBasicsEs.min.js +1 -1
  8. package/dist/v1/TinyCookieConsent.min.js +1 -0
  9. package/dist/v1/TinyDayNightCycle.min.js +1 -0
  10. package/dist/v1/TinyEssentials.min.js +1 -1
  11. package/dist/v1/TinyGamepad.min.js +1 -0
  12. package/dist/v1/TinyI18.min.js +1 -0
  13. package/dist/v1/TinyInventory.min.js +1 -0
  14. package/dist/v1/TinyInventoryTrader.min.js +1 -0
  15. package/dist/v1/TinyLocalStorage.min.js +1 -1
  16. package/dist/v1/TinyNeedBar.min.js +1 -0
  17. package/dist/v1/TinyRateLimiter.min.js +1 -1
  18. package/dist/v1/TinySmartScroller.min.js +1 -1
  19. package/dist/v1/TinyToastNotify.min.js +1 -1
  20. package/dist/v1/TinyUploadClicker.min.js +1 -1
  21. package/dist/v1/basics/array.cjs +21 -0
  22. package/dist/v1/basics/array.d.mts +8 -0
  23. package/dist/v1/basics/array.mjs +18 -0
  24. package/dist/v1/basics/clock.cjs +127 -11
  25. package/dist/v1/basics/clock.d.mts +26 -0
  26. package/dist/v1/basics/clock.mjs +96 -1
  27. package/dist/v1/basics/index.cjs +2 -8
  28. package/dist/v1/basics/index.d.mts +3 -8
  29. package/dist/v1/basics/index.mjs +2 -3
  30. package/dist/v1/basics/simpleMath.cjs +46 -0
  31. package/dist/v1/basics/simpleMath.d.mts +27 -0
  32. package/dist/v1/basics/simpleMath.mjs +42 -0
  33. package/dist/v1/build/TinyAdvancedRaffle.cjs +7 -0
  34. package/dist/v1/build/TinyAdvancedRaffle.d.mts +3 -0
  35. package/dist/v1/build/TinyAdvancedRaffle.mjs +2 -0
  36. package/dist/v1/build/TinyArrayPaginator.cjs +7 -0
  37. package/dist/v1/build/TinyArrayPaginator.d.mts +3 -0
  38. package/dist/v1/build/TinyArrayPaginator.mjs +2 -0
  39. package/dist/v1/build/TinyCookieConsent.cjs +7 -0
  40. package/dist/v1/build/TinyCookieConsent.d.mts +3 -0
  41. package/dist/v1/build/TinyCookieConsent.mjs +2 -0
  42. package/dist/v1/build/TinyDayNightCycle.cjs +7 -0
  43. package/dist/v1/build/TinyDayNightCycle.d.mts +3 -0
  44. package/dist/v1/build/TinyDayNightCycle.mjs +2 -0
  45. package/dist/v1/build/TinyGamepad.cjs +7 -0
  46. package/dist/v1/build/TinyGamepad.d.mts +3 -0
  47. package/dist/v1/build/TinyGamepad.mjs +2 -0
  48. package/dist/v1/build/TinyI18.cjs +7 -0
  49. package/dist/v1/build/TinyI18.d.mts +3 -0
  50. package/dist/v1/build/TinyI18.mjs +2 -0
  51. package/dist/v1/build/TinyInventory.cjs +7 -0
  52. package/dist/v1/build/TinyInventory.d.mts +3 -0
  53. package/dist/v1/build/TinyInventory.mjs +2 -0
  54. package/dist/v1/build/TinyInventoryTrader.cjs +7 -0
  55. package/dist/v1/build/TinyInventoryTrader.d.mts +3 -0
  56. package/dist/v1/build/TinyInventoryTrader.mjs +2 -0
  57. package/dist/v1/build/TinyNeedBar.cjs +7 -0
  58. package/dist/v1/build/TinyNeedBar.d.mts +3 -0
  59. package/dist/v1/build/TinyNeedBar.mjs +2 -0
  60. package/dist/v1/css/TinyCookieConsent.min.css +1 -0
  61. package/dist/v1/index.cjs +20 -8
  62. package/dist/v1/index.d.mts +12 -8
  63. package/dist/v1/index.mjs +11 -3
  64. package/dist/v1/libs/TinyAdvancedRaffle.cjs +1654 -0
  65. package/dist/v1/libs/TinyAdvancedRaffle.d.mts +851 -0
  66. package/dist/v1/libs/TinyAdvancedRaffle.mjs +1477 -0
  67. package/dist/v1/libs/TinyArrayPaginator.cjs +132 -0
  68. package/dist/v1/libs/TinyArrayPaginator.d.mts +78 -0
  69. package/dist/v1/libs/TinyArrayPaginator.mjs +119 -0
  70. package/dist/v1/libs/TinyCookieConsent.cjs +278 -0
  71. package/dist/v1/libs/TinyCookieConsent.d.mts +142 -0
  72. package/dist/v1/libs/TinyCookieConsent.mjs +248 -0
  73. package/dist/v1/libs/TinyDayNightCycle.cjs +1389 -0
  74. package/dist/v1/libs/TinyDayNightCycle.d.mts +673 -0
  75. package/dist/v1/libs/TinyDayNightCycle.mjs +1232 -0
  76. package/dist/v1/libs/TinyGamepad.cjs +2690 -0
  77. package/dist/v1/libs/TinyGamepad.d.mts +1286 -0
  78. package/dist/v1/libs/TinyGamepad.mjs +2386 -0
  79. package/dist/v1/libs/TinyHtml.d.mts +2 -2
  80. package/dist/v1/libs/TinyI18.cjs +946 -0
  81. package/dist/v1/libs/TinyI18.d.mts +418 -0
  82. package/dist/v1/libs/TinyI18.mjs +873 -0
  83. package/dist/v1/libs/TinyInventory.cjs +1788 -0
  84. package/dist/v1/libs/TinyInventory.d.mts +871 -0
  85. package/dist/v1/libs/TinyInventory.mjs +1650 -0
  86. package/dist/v1/libs/TinyInventoryTrader.cjs +242 -0
  87. package/dist/v1/libs/TinyInventoryTrader.d.mts +95 -0
  88. package/dist/v1/libs/TinyInventoryTrader.mjs +212 -0
  89. package/dist/v1/libs/TinyLocalStorage.cjs +14 -1
  90. package/dist/v1/libs/TinyLocalStorage.mjs +8 -1
  91. package/dist/v1/libs/TinyNeedBar.cjs +272 -0
  92. package/dist/v1/libs/TinyNeedBar.d.mts +223 -0
  93. package/dist/v1/libs/TinyNeedBar.mjs +241 -0
  94. package/dist/v1/libs/TinyRateLimiter.cjs +0 -13
  95. package/dist/v1/libs/TinyRateLimiter.d.mts +0 -8
  96. package/dist/v1/libs/TinyRateLimiter.mjs +0 -12
  97. package/dist/v1/libs/TinySmartScroller.cjs +0 -51
  98. package/dist/v1/libs/TinySmartScroller.d.mts +0 -36
  99. package/dist/v1/libs/TinySmartScroller.mjs +0 -46
  100. package/dist/v1/libs/TinyToastNotify.cjs +2 -2
  101. package/dist/v1/libs/TinyToastNotify.mjs +2 -2
  102. package/dist/v1/libs/TinyUploadClicker.cjs +1 -1
  103. package/docs/v1/Ai-Tips.md +51 -0
  104. package/docs/v1/Personal-Ai-Prompts(portuguese).md +134 -0
  105. package/docs/v1/Personal-Ai-Prompts.md +113 -0
  106. package/docs/v1/README.md +24 -0
  107. package/docs/v1/basics/array.md +17 -0
  108. package/docs/v1/basics/clock.md +51 -11
  109. package/docs/v1/basics/simpleMath.md +73 -0
  110. package/docs/v1/libs/TinyAdvancedRaffle.md +674 -0
  111. package/docs/v1/libs/TinyArrayPaginator.md +150 -0
  112. package/docs/v1/libs/TinyCookieConsent.md +152 -0
  113. package/docs/v1/libs/TinyDayNightCycle.md +711 -0
  114. package/docs/v1/libs/TinyGamepad.md +980 -0
  115. package/docs/v1/libs/TinyI18.md +515 -0
  116. package/docs/v1/libs/TinyInventory.md +777 -0
  117. package/docs/v1/libs/TinyInventoryTrader.md +114 -0
  118. package/docs/v1/libs/TinyNeedBar.md +226 -0
  119. package/package.json +7 -5
  120. package/dist/v1/basics/html_deprecated.cjs +0 -124
  121. package/dist/v1/basics/html_deprecated.d.mts +0 -40
  122. package/dist/v1/basics/html_deprecated.mjs +0 -97
  123. package/dist/v1/css/TinyDraggerExample.css +0 -21
  124. package/dist/v1/css/TinyNotify.css +0 -350
  125. package/dist/v1/css/aiMarker.css +0 -4
  126. package/docs/v1/basics/html_deprecated.md +0 -127
@@ -0,0 +1 @@
1
+ (()=>{"use strict";var e={d:(t,n)=>{for(var i in n)e.o(n,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:n[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{TinyGamepad:()=>i});class n{#e=!1;#t=new Set;#n=new Map;#i=new Map;#s=null;#a=[];#r={};#o=[];#p=null;#d=null;#c;#u;#l;#m;#h;#y;#f;#g;#v=[];#b=0;#w=0;#I=[];#E=0;#M=null;#S=new Set;#k=new Set;#T=new Map;#K=new Map;#A=new Map;static#C={" ":"Space","\n":"Enter","\r":"Enter","\t":"Tab","-":"Minus",_:"Minus","=":"Equal","+":"Equal","[":"BracketLeft","{":"BracketLeft","]":"BracketRight","}":"BracketRight","\\":"Backslash","|":"Backslash",";":"Semicolon",":":"Semicolon","'":"Quote",'"':"Quote",",":"Comma","<":"Comma",".":"Period",">":"Period","/":"Slash","?":"Slash","`":"Backquote","~":"Backquote"};static addSpecialKey(e,t){if("string"!=typeof e)throw new TypeError("Invalid char type: expected string, got "+typeof e);if(1!==e.length)throw new Error(`Invalid char length: "${e}" (must be exactly one character)`);if("string"!=typeof t)throw new TypeError("Invalid code type: expected string, got "+typeof t);n.#C[e]=t}static removeSpecialKey(e){if("string"!=typeof e)throw new TypeError("Invalid char type: expected string, got "+typeof e);if(1!==e.length)throw new Error(`Invalid char length: "${e}" (must be exactly one character)`);delete n.#C[e]}static getSpecialKey(e){if("string"!=typeof e)throw new TypeError("Invalid char type: expected string, got "+typeof e);if(1!==e.length)throw new Error(`Invalid char length: "${e}" (must be exactly one character)`);return n.#C[e]}static getAllSpecialKeys(){return{...n.#C}}static stringToKeys(e){if("string"!=typeof e)throw new TypeError("Invalid text type: expected string, got "+typeof e);if(!e.length)throw new Error("Invalid text: cannot be empty");return Array.from(e).map(e=>{const t=e.toUpperCase();if(t>="A"&&t<="Z")return`Key${t}`;if(t>="0"&&t<="9")return`Digit${t}`;const i=n.#C[e];if(void 0!==i)return i;throw new Error(`Unsupported character: "${e}"`)})}constructor({expectedId:e=null,inputMode:t="both",ignoreIds:n=[],deadZone:i=.1,axisActiveSensitivity:s=.3,timeoutComboKeys:a=500,allowMouse:r=!1,elementBase:o=window}={}){if(null!==e&&"string"!=typeof e)throw new TypeError('"expectedId" must be a string or null, received: '+typeof e);if(!["keyboard-only","gamepad-only","both"].includes(t))throw new TypeError(`"inputMode" must be 'keyboard-only', 'gamepad-only', or 'both', received: ${t}`);if(!Array.isArray(n)||!n.every(e=>"string"==typeof e))throw new TypeError('"ignoreIds" must be an array of strings');if("number"!=typeof i||i<0||i>1)throw new RangeError(`"deadZone" must be a number between 0 and 1, received: ${i}`);if("number"!=typeof s||s<0||s>1)throw new RangeError(`"axisActiveSensitivity" must be a number between 0 and 1, received: ${s}`);if("number"!=typeof a||a<0)throw new RangeError(`"timeoutComboKeys" must be a positive number, received: ${a}`);if("boolean"!=typeof r)throw new TypeError('"allowMouse" must be a boolean, received: '+typeof r);if(!(o instanceof Window||o instanceof Element))throw new TypeError('"elementBase" must be a Window or Element instance');this.#m=e,this.#c=t,this.#u=new Set(n),this.#l=i,this.#h=r,this.#y=o,this.#f=a,this.#g=s,["gamepad-only","both"].includes(this.#c)&&this.#N(),["keyboard-only","both"].includes(this.#c)&&this.#x()}#$=e=>this.#q(e.gamepad);#B=e=>this.#D(e.gamepad);#N(){window.addEventListener("gamepadconnected",this.#$),window.addEventListener("gamepaddisconnected",this.#B)}#q(e){this.#e||this.#u.has(e.id)||this.#m&&e.id!==this.#m||this.#s||(this.#s=e,this.#m=e.id,this.#G(),this.#H("connected",{id:e.id,gp:e,timestamp:e.timestamp}))}#D(e){this.#e||this.#s&&e.id===this.#s.id&&(this.#s=null,this.#p&&(cancelAnimationFrame(this.#p),this.#p=null),this.#H("disconnected",{id:e.id,gp:e,timestamp:e.timestamp}))}#G(){const e=()=>{this.#e||(this.#L(),this.#p=requestAnimationFrame(e))};e()}#L(){if(this.#e)return;const e=navigator.getGamepads(),t=Array.from(e).find(e=>e&&e.id===this.#m);t&&(this.#s=t,t.buttons.forEach((e,n)=>{const i=`Button${n}`,s=this.#a[n]?.pressed||!1;let a,r,o=!1;e.pressed&&!s?(r=1,a="down"):!e.pressed&&s?(r=0,a="up"):e.pressed&&s&&(r=1,a="hold"),e.pressed&&e.value>0&&e.value<1&&1!==e.value&&(r=e.value,o=!0),"number"==typeof r&&"string"==typeof a&&this.#j({key:i,source:"gamepad-button",value:r,value2:NaN,type:a,gp:t,isPressure:o,pressed:e.pressed,prevPressed:s,timestamp:t.timestamp,id:t.id}),this.#a[n]={pressed:e.pressed,value:"number"==typeof r?r:this.#a[n]?.value,value2:NaN}}),t.axes.forEach((e,n)=>{Math.abs(e)<this.#l&&(e=0);const i=`Axis${n}`;e!==(this.#o[n]??0)&&this.#j({key:i,source:"gamepad-analog",value:e,value2:NaN,type:"change",timestamp:t.timestamp,id:t.id,gp:t}),this.#o[n]=e}))}#z=e=>{if(!this.#e){if(!(e instanceof KeyboardEvent))throw new Error("Expected KeyboardEvent in keydown listener.");this.#t.has(e.code)||(this.#t.add(e.code),this.#j({event:e,key:e.code,source:"keyboard",value:1,value2:NaN,type:"down",pressed:!0,prevPressed:this.#r[e.code]?.pressed??!1,id:"native_keyboard",timestamp:e.timeStamp}),this.#r[e.code]={pressed:!0})}};#Z=e=>{if(!this.#e){if(!(e instanceof KeyboardEvent))throw new Error("Expected KeyboardEvent in keyup listener.");this.#t.has(e.code)&&(this.#t.delete(e.code),this.#j({event:e,key:e.code,source:"keyboard",value:0,value2:NaN,type:"up",pressed:!1,prevPressed:this.#r[e.code]?.pressed??!1,id:"native_keyboard",timestamp:e.timeStamp}),this.#r[e.code]={pressed:!1})}};#P=e=>{if(this.#e)return;if(!(e instanceof MouseEvent))throw new Error("Expected MouseEvent in mousedown listener.");const t=`Mouse${e.button}`;this.#t.add(t),this.#j({event:e,key:t,source:"mouse",value:1,value2:NaN,type:"down",pressed:!0,prevPressed:this.#r[t]?.pressed??!1,id:"native_mouse",timestamp:e.timeStamp}),this.#r[t]={pressed:!0}};#O=e=>{if(this.#e)return;if(!(e instanceof MouseEvent))throw new Error("Expected MouseEvent in mouseup listener.");const t=`Mouse${e.button}`;this.#t.delete(t),this.#j({event:e,key:t,source:"mouse",value:0,value2:NaN,type:"up",pressed:!1,prevPressed:this.#r[t]?.pressed??!1,id:"native_mouse",timestamp:e.timeStamp}),this.#r[t]={pressed:!1}};#F=e=>{if(!this.#e){if(!(e instanceof MouseEvent))throw new Error("Expected MouseEvent in mousemove listener.");if(0!==e.movementX||0!==e.movementY){const t="MouseMove",n=this.#r[t]??{pressed:!1,value:0,value2:0};this.#j({event:e,key:t,source:"mouse",value:e.movementX+(n.value??0),value2:e.movementY+(n.value??0),id:"native_mouse",type:"move",pressed:!0,prevPressed:null,timestamp:e.timeStamp}),this.#r[t]={pressed:!1,value:e.movementX,value2:e.movementY}}}};#x(){this.#y.addEventListener("keydown",this.#z),this.#y.addEventListener("keyup",this.#Z),this.#h&&(this.#y.addEventListener("mousedown",this.#P),this.#y.addEventListener("mouseup",this.#O),this.#y.addEventListener("mousemove",this.#F));const e=()=>{this.#e||(this.#t.forEach(e=>{const t=e.startsWith("Mouse")?"mouse":"keyboard";this.#j({key:e,source:t,id:`native_${t}`,value:1,value2:NaN,type:"hold",pressed:!0,prevPressed:this.#r[e]?.pressed??!1,timestamp:NaN})}),this.#d=requestAnimationFrame(e))};e()}#j(e){if(this.#e)return;const t=this.#i.get("input-*")||[],{pressed:n,key:i}=e,s=i.startsWith("Axis"),a="boolean"==typeof n&&n||s&&(e.value>this.#g||e.value<-Math.abs(this.#g)),r=s?`${i}${e.value>0?"+":e.value<0?"-":""}`:i;let o=null;if("move"!==e.type&&"hold"!==e.type){if(a){if(!s&&!this.#S.has(i)||s&&!this.#S.has(i)&&!this.#S.has(`${i}+`)&&!this.#S.has(`${i}-`)){0===this.#E&&(this.#E=Date.now()),this.#S.add(r),o=!0,this.#I.push(r),this.#v.length<1&&(this.#M&&clearTimeout(this.#M),this.#M=setTimeout(()=>this.resetComboMapped(),this.#f));const e=this.#i.get("mapped-key-start")??[];for(const t of e)t({key:r,activeTime:this.#E})}}else if(!s&&this.#S.has(i)||s&&(this.#S.has(i)||this.#S.has(`${i}+`)||this.#S.has(`${i}-`))){this.#S.delete(i),this.#S.delete(`${i}+`),this.#S.delete(`${i}-`),o=!1;const e=this.#i.get("mapped-key-end")??[];for(const t of e)t({key:r,activeTime:this.#E})}for(const{sequence:e,callback:t,triggered:n}of this.#K.values()){const i=this.#K.get(e.join("+"));if(!i)continue;const s=e.every((e,t)=>this.#I[t]===e);s&&!n?(i.triggered=!0,t(this.#E)):!s&&n&&(i.triggered=!1)}}for(const[n,p]of this.#n.entries()){const d=e=>"string"==typeof p&&e===p||Array.isArray(p)&&p.findIndex((t,n)=>e===p[n])>-1,c=d(r),u=s&&d(`${i}+`),l=s&&d(`${i}-`);if(c||u||l){if(a&&c){if(o||!this.#k.has(n)){0===this.#w&&(this.#w=Date.now()),this.#k.add(n),0===this.#b&&(this.#b=Date.now()),this.#M&&clearTimeout(this.#M),this.#v.push(n),this.#M=setTimeout(()=>this.resetComboMapped(),this.#f);const e=this.#i.get("mapped-input-start")??[];for(const t of e)t({logicalName:n,activeTime:this.#w,comboTime:this.#b})}}else if(!o||this.#k.has(n)){this.#k.delete(n),this.#k.size<1&&(this.#w=0);const e=this.#i.get("mapped-input-end")??[];for(const t of e)t({logicalName:n,activeTime:this.#w,comboTime:this.#b})}for(const{sequence:e,callback:t,triggered:n}of this.#T.values()){const i=this.#T.get(e.join("+"));if(!i)continue;const s=Array.from(this.#k),a=e.every((e,t)=>s[t]===e);a&&!n?(i.triggered=!0,t(this.#w)):!a&&n&&(i.triggered=!1)}}const m=[];if(s&&0===e.value){const{value:t}=this.#A.get(`${i}-`)??{value:0,value2:NaN},{value:n}=this.#A.get(`${i}+`)??{value:0,value2:NaN};e.value!==t&&m.push(`${i}-`),e.value!==n&&m.push(`${i}+`)}else m.push(r);m.forEach(i=>{if(!("*"===p||p===i||Array.isArray(p)&&p.includes(i)))return;const s=this.#i.get(`input-${e.type}-${n}`)||[],a=this.#i.get(`input-${n}`)||[];if(a.length<1&&s.length<1&&t.length<1)return;const r={...e,key:i,logicalName:n};for(const e of t)e(r);for(const e of a)e(r);for(const e of s)e(r);this.#A.set(i,{value:e.value,value2:e.value2})})}}#H(e,t){const n=this.#i.get(e)||[];for(const e of n)e(t)}#J(e,t,n){if("string"!=typeof e)throw new TypeError(`"logicalName" must be a string, received ${e}`);if("function"!=typeof t)throw new TypeError('"callback" must be a function, received '+typeof t);const i=n.replace("{logicalName}",e);let s=this.#i.get(i);Array.isArray(s)||(s=[],this.#i.set(i,s)),s.push(t)}#R(e,t,n){if("string"!=typeof e)throw new TypeError(`"logicalName" must be a string, received ${e}`);if("function"!=typeof t)throw new TypeError('"callback" must be a function, received '+typeof t);const i=s=>{this.#_(e,i,n),t(s)};this.#J(e,i,n)}#V(e,t,n){if("string"!=typeof e)throw new TypeError(`"logicalName" must be a string, received ${e}`);if("function"!=typeof t)throw new TypeError('"callback" must be a function, received '+typeof t);const i=n.replace("{logicalName}",e),s=this.#i.get(i)??[];s.unshift(t),this.#i.set(i,s)}#_(e,t,n){if("string"!=typeof e)throw new TypeError(`"logicalName" must be a string, received ${e}`);if("function"!=typeof t)throw new TypeError('"callback" must be a function, received '+typeof t);const i=n.replace("{logicalName}",e),s=this.#i.get(i);Array.isArray(s)&&this.#i.set(i,s.filter(e=>e!==t))}awaitInputMapping({timeout:e=1e4,eventName:t="MappingInput",canMove:n=!1}={}){return new Promise((i,s)=>{if("number"!=typeof e||Number.isNaN(e)||e<0)return s(new TypeError(`Invalid "timeout": expected a positive number, got ${e}`));if("string"!=typeof t||!t.trim())return s(new TypeError(`Invalid "eventName": expected a non-empty string, got ${t}`));if("boolean"!=typeof n)return s(new TypeError(`Invalid "canMove": expected a boolean, got ${n}`));const a={key:null,source:null},r=({key:e,type:s,source:p,gp:d,value:c})=>{(n||"move"!==s)&&(a.key=e,a.source=p,a.gp=d,clearTimeout(o),this.offInputStart(t,r),this.offInputChange(t,r),n&&this.offInputMove(t,r),i(a))},o=setTimeout(()=>i(a),e);this.mapInput(t,"*"),this.onInputStart(t,r),this.onInputChange(t,r),n&&this.onInputMove(t,r)})}mapInput(e,t){if("string"!=typeof e||!e.trim())throw new TypeError(`Invalid "logicalName": expected a non-empty string, got ${e}`);if(!("string"==typeof t||Array.isArray(t)&&t.every(e=>"string"==typeof e)))throw new TypeError(`Invalid "physicalInput": expected string or array of strings, got ${JSON.stringify(t)}`);this.#n.set(e,t)}unmapInput(e){if("string"!=typeof e||!e.trim())throw new TypeError(`Invalid "logicalName": expected a non-empty string, got ${e}`);this.#n.delete(e)}hasMappedInput(e){if("string"!=typeof e||!e.trim())throw new TypeError(`Invalid "logicalName": expected a non-empty string, got ${e}`);return this.#n.has(e)}getMappedInput(e){if("string"!=typeof e||!e.trim())throw new TypeError(`Invalid "logicalName": expected a non-empty string, got ${e}`);const t=this.#n.get(e);if(!t)throw new Error(`No physical input mapped for logicalName: "${e}"`);return t}clearMapInputs(){this.#n.clear()}registerInputSequence(e,t){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new TypeError(`'sequence' must be an array of strings, got: ${JSON.stringify(e)}`);if("function"!=typeof t)throw new TypeError("'callback' must be a function, got: "+typeof t);if(0===e.length)throw new Error("'sequence' must contain at least one input name.");const n=e.join("+");this.#T.set(n,{sequence:e,callback:t,triggered:!1})}unregisterInputSequence(e){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new TypeError(`'sequence' must be an array of strings, got: ${JSON.stringify(e)}`);const t=e.join("+");this.#T.delete(t)}unregisterAllInputSequences(){this.#T.clear()}hasInputSequence(e){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new TypeError(`'sequence' must be an array of strings, got: ${JSON.stringify(e)}`);const t=e.join("+");return this.#T.has(t)}registerKeySequence(e,t){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new TypeError(`'sequence' must be an array of strings, got: ${JSON.stringify(e)}`);if("function"!=typeof t)throw new TypeError("'callback' must be a function, got: "+typeof t);if(0===e.length)throw new Error("'sequence' must contain at least one input name.");const n=e.join("+");this.#K.set(n,{sequence:e,callback:t,triggered:!1})}unregisterKeySequence(e){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new TypeError(`'sequence' must be an array of strings, got: ${JSON.stringify(e)}`);const t=e.join("+");this.#K.delete(t)}unregisterAllKeySequences(){this.#K.clear()}hasKeySequence(e){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new TypeError(`'sequence' must be an array of strings, got: ${JSON.stringify(e)}`);const t=e.join("+");return this.#K.has(t)}renewComboMapped(){this.#M&&(clearTimeout(this.#M),this.#M=setTimeout(()=>this.resetComboMapped(),this.#f))}resetComboMapped(){this.#M&&clearTimeout(this.#M),this.#I=[],this.#M=null,this.#E=0,this.#v=[],this.#b=0}onMappedKeyStart(e){return this.#J("",e,"mapped-key-start")}onceMappedKeyStart(e){return this.#R("",e,"mapped-key-start")}prependMappedKeyStart(e){return this.#V("",e,"mapped-key-start")}offMappedKeyStart(e){return this.#_("",e,"mapped-key-start")}offAllMappedKeyStart(){this.#i.delete("mapped-key-start")}onMappedKeyEnd(e){return this.#J("",e,"mapped-key-end")}onceMappedKeyEnd(e){return this.#R("",e,"mapped-key-end")}prependMappedKeyEnd(e){return this.#V("",e,"mapped-key-end")}offMappedKeyEnd(e){return this.#_("",e,"mapped-key-end")}offAllMappedKeyEnd(){this.#i.delete("mapped-key-end")}onMappedInputStart(e){return this.#J("",e,"mapped-input-start")}onceMappedInputStart(e){return this.#R("",e,"mapped-input-start")}prependMappedInputStart(e){return this.#V("",e,"mapped-input-start")}offMappedInputStart(e){return this.#_("",e,"mapped-input-start")}offAllMappedInputStart(){this.#i.delete("mapped-input-start")}onMappedInputEnd(e){return this.#J("",e,"mapped-input-end")}onceMappedInputEnd(e){return this.#R("",e,"mapped-input-end")}prependMappedInputEnd(e){return this.#V("",e,"mapped-input-end")}offMappedInputEnd(e){return this.#_("",e,"mapped-input-end")}offAllMappedInputEnd(){this.#i.delete("mapped-input-end")}onInput(e,t){return this.#J(e,t,"input-{logicalName}")}onceInput(e,t){return this.#R(e,t,"input-{logicalName}")}prependInput(e,t){return this.#V(e,t,"input-{logicalName}")}offInput(e,t){return this.#_(e,t,"input-{logicalName}")}onInputStart(e,t){return this.#J(e,t,"input-down-{logicalName}")}onceInputStart(e,t){return this.#R(e,t,"input-down-{logicalName}")}prependInputStart(e,t){return this.#V(e,t,"input-down-{logicalName}")}offInputStart(e,t){return this.#_(e,t,"input-down-{logicalName}")}onInputEnd(e,t){return this.#J(e,t,"input-up-{logicalName}")}onceInputEnd(e,t){return this.#R(e,t,"input-up-{logicalName}")}prependInputEnd(e,t){return this.#V(e,t,"input-up-{logicalName}")}offInputEnd(e,t){return this.#_(e,t,"input-up-{logicalName}")}onInputHold(e,t){return this.#J(e,t,"input-hold-{logicalName}")}onceInputHold(e,t){return this.#R(e,t,"input-hold-{logicalName}")}prependInputHold(e,t){return this.#V(e,t,"input-hold-{logicalName}")}offInputHold(e,t){return this.#_(e,t,"input-hold-{logicalName}")}onInputChange(e,t){return this.#J(e,t,"input-change-{logicalName}")}onceInputChange(e,t){return this.#R(e,t,"input-change-{logicalName}")}prependInputChange(e,t){return this.#V(e,t,"input-change-{logicalName}")}offInputChange(e,t){return this.#_(e,t,"input-change-{logicalName}")}onInputMove(e,t){return this.#J(e,t,"input-move-{logicalName}")}onceInputMove(e,t){return this.#R(e,t,"input-move-{logicalName}")}prependInputMove(e,t){return this.#V(e,t,"input-move-{logicalName}")}offInputMove(e,t){return this.#_(e,t,"input-move-{logicalName}")}getCalls(e,t="all"){if("string"!=typeof e||""===e.trim())throw new TypeError(`"logicalName" must be a non-empty string, received ${e}`);const n=["all","start","end","hold","change","move"];if(!n.includes(t))throw new TypeError(`"type" must be one of ${n.join(", ")}, received ${t}`);const i=`${{all:"input-",start:"input-down-",end:"input-up-",hold:"input-hold-",change:"input-change-",move:"input-move-"}[t]}${e}`,s=this.#i.get(i);return Array.isArray(s)?[...s]:[]}offAllInputs(e,t="all"){if("string"!=typeof e||""===e.trim())throw new TypeError(`"logicalName" must be a non-empty string, received ${e}`);const n=["all","start","end","hold","change","move"];if(!n.includes(t))throw new TypeError(`"type" must be one of ${n.join(", ")}, received ${t}`);const i={all:"input-",start:"input-down-",end:"input-up-",hold:"input-hold-",change:"input-change-",move:"input-move-"}[t];i&&this.#i.delete(`${i}${e}`)}getCallSize(e,t="all"){if("string"!=typeof e||""===e.trim())throw new TypeError(`"logicalName" must be a non-empty string, received ${e}`);const n=["all","start","end","hold","change","move"];if(!n.includes(t))throw new TypeError(`"type" must be one of ${n.join(", ")}, received ${t}`);const i={all:"input-",start:"input-down-",end:"input-up-",hold:"input-hold-",change:"input-change-",move:"input-move-"}[t],s=this.#i.get(`${i}${e}`);return Array.isArray(s)?s.length:0}#W={type:"dual-rumble",params:{startDelay:0,duration:200,weakMagnitude:.5,strongMagnitude:1}};get defaultHapticEffect(){return{type:this.#W.type,params:{...this.#W.params}}}setDefaultHapticEffect(e,t){if("string"!=typeof e)throw new TypeError(`"type" must be a valid GamepadHapticEffectType string, received ${e}`);if("object"!=typeof t||null===t)throw new TypeError(`"params" must be a non-null object, received ${t}`);this.#W.type=e,this.#W.params=t}hasHapticEffect(){const e=this.#s;return!!e&&e.vibrationActuator instanceof GamepadHapticActuator}vibrate(e,t){if(void 0!==e&&("object"!=typeof e||null===e))throw new TypeError(`"params" must be an object if provided, received ${e}`);if(void 0!==t&&"string"!=typeof t)throw new TypeError(`"type" must be a valid GamepadHapticEffectType string if provided, received ${t}`);const n=this.#s;if(!n)return new Promise(e=>e("complete"));const i=n.vibrationActuator;return i instanceof GamepadHapticActuator?i.playEffect(t??this.#W.type,{...this.#W.params,...e}):new Promise(e=>e("complete"))}ignoreId(e){if("string"!=typeof e||""===e.trim())throw new TypeError(`"id" must be a non-empty string, received ${e}`);this.#u.add(e)}unignoreId(e){if("string"!=typeof e||""===e.trim())throw new TypeError(`"id" must be a non-empty string, received ${e}`);this.#u.delete(e)}onConnected(e){return this.#J("",e,"connected")}onceConnected(e){return this.#R("",e,"connected")}prependConnected(e){return this.#V("",e,"connected")}offConnected(e){return this.#_("",e,"connected")}offAllConnected(){this.#i.delete("connected")}onDisconnected(e){return this.#J("",e,"disconnected")}onceDisconnected(e){return this.#R("",e,"disconnected")}prependDisconnected(e){return this.#V("",e,"disconnected")}offDisconnected(e){return this.#_("",e,"disconnected")}offAllDisconnected(){this.#i.delete("disconnected")}hasGamepad(){return this.#s instanceof Gamepad}getGamepad(){if(!this.#s)throw new Error("No gamepad is currently connected.");return this.#s}hasLastButtonState(e){return!!this.#a[e]}getLastButtonState(e){if(!this.#a[e])throw new Error(`No last button state found for index ${e}`);return{...this.#a[e]}}exportConfig(){return{expectedId:this.#m,ignoreIds:Array.from(this.#u),deadZone:this.#l,timeoutComboKeys:this.#f,axisActiveSensitivity:this.#g,inputMap:Array.from(this.#n.entries())}}importConfig(e){if("string"!=typeof e&&("object"!=typeof e||null===e))throw new TypeError(`"json" must be a string or a non-null object, received: ${e}`);const t="string"==typeof e?JSON.parse(e):e;if(void 0!==t.expectedId&&"string"!=typeof t.expectedId&&null!==t.expectedId)throw new TypeError('"expectedId" must be a string or null if provided');if(void 0!==t.ignoreIds&&!Array.isArray(t.ignoreIds))throw new TypeError('"ignoreIds" must be an array if provided');if(void 0!==t.deadZone&&"number"!=typeof t.deadZone)throw new TypeError('"deadZone" must be a number if provided');if(void 0!==t.timeoutComboKeys&&"number"!=typeof t.timeoutComboKeys)throw new TypeError('"timeoutComboKeys" must be a number if provided');if(void 0!==t.axisActiveSensitivity&&"number"!=typeof t.axisActiveSensitivity)throw new TypeError('"axisActiveSensitivity" must be a number if provided');if(void 0!==t.inputMap&&!Array.isArray(t.inputMap))throw new TypeError('"inputMap" must be an array if provided');void 0!==t.expectedId&&(this.#m=t.expectedId),Array.isArray(t.ignoreIds)&&(this.#u=new Set(t.ignoreIds)),"number"==typeof t.deadZone&&(this.#l=t.deadZone),"number"==typeof t.timeoutComboKeys&&(this.#f=t.timeoutComboKeys),"number"==typeof t.axisActiveSensitivity&&(this.#g=t.axisActiveSensitivity),Array.isArray(t.inputMap)&&(this.#n=new Map(t.inputMap))}get mappedKeyStartCalls(){const e=this.#i.get("mapped-key-start");return Array.isArray(e)?[...e]:[]}get mappedKeyEndCalls(){const e=this.#i.get("mapped-key-end");return Array.isArray(e)?[...e]:[]}get comboMappedKeys(){return[...this.#I]}get comboMappedInputs(){return[...this.#v]}get keySequenceSize(){return this.#K.size}get keySequences(){const e=[];for(const[,t]of this.#K.entries())e.push(t.callback);return e}get activeMappedKeys(){return[...this.#S]}get mappedInputStartCalls(){const e=this.#i.get("mapped-input-start");return Array.isArray(e)?[...e]:[]}get mappedInputEndCalls(){const e=this.#i.get("mapped-input-end");return Array.isArray(e)?[...e]:[]}get inputSequenceSize(){return this.#T.size}get inputSequences(){const e=[];for(const[,t]of this.#T.entries())e.push(t.callback);return e}get activeMappedInputs(){return[...this.#k]}get mappedInputs(){const e={};for(const[t,n]of this.#n.entries())e[t]=n;return e}get mappedInputSize(){return this.#n.size}get connectedCalls(){const e=this.#i.get("connected");return Array.isArray(e)?[...e]:[]}get disconnectedCalls(){const e=this.#i.get("disconnected");return Array.isArray(e)?[...e]:[]}get ignoredDeviceIds(){return[...this.#u]}get heldKeys(){return[...this.#t]}get eventsSize(){let e=0;return this.#i.forEach(t=>{e+=t.length}),e}get callSize(){return this.#i.size}get connectedCallSize(){const e=this.#i.get("connected");return Array.isArray(e)?e.length:0}get disconnectedCallSize(){const e=this.#i.get("disconnected");return Array.isArray(e)?e.length:0}get mappedKeyStartCallSize(){const e=this.#i.get("mapped-key-start");return Array.isArray(e)?e.length:0}get mappedKeyEndCallSize(){const e=this.#i.get("mapped-key-end");return Array.isArray(e)?e.length:0}get mappedInputStartCallSize(){const e=this.#i.get("mapped-input-start");return Array.isArray(e)?e.length:0}get mappedInputEndCallSize(){const e=this.#i.get("mapped-input-end");return Array.isArray(e)?e.length:0}get lastButtonStates(){const e=[];return this.#a.forEach(t=>{e.push({...t})}),e}get lastAxes(){return[...this.#o]}get inputMode(){return this.#c}get elementBase(){return this.#y}get timeComboInputs(){return this.#b}get timeComboKeys(){return this.#E}get timeMappedInputs(){return this.#w}get timeoutComboKeys(){return this.#f}set timeoutComboKeys(e){if("number"!=typeof e||e<0||!Number.isFinite(e))throw new TypeError("Timeout combo keys must be a non-negative finite number.");this.#f=e}get axisActiveSensitivity(){return this.#g}set axisActiveSensitivity(e){if("number"!=typeof e||e<0||e>1)throw new RangeError("Axis sensitivity must be a number between 0 and 1.");this.#g=e}get deadZone(){return this.#l}set deadZone(e){if("number"!=typeof e||e<0||e>1)throw new RangeError("Dead zone must be a number between 0 and 1.");this.#l=e}get expectedId(){return this.#m}set expectedId(e){if("string"!=typeof e)throw new TypeError("Expected device id be a string.");this.#m=e}get isDestroyed(){return this.#e}destroy(){this.#e||(this.#e=!0,this.#p&&cancelAnimationFrame(this.#p),this.#d&&cancelAnimationFrame(this.#d),this.#p=null,this.#d=null,["keyboard-only","both"].includes(this.#c)&&(this.#y.removeEventListener("keydown",this.#z),this.#y.removeEventListener("keyup",this.#Z),this.#h&&(this.#y.removeEventListener("mousedown",this.#P),this.#y.removeEventListener("mouseup",this.#O),this.#y.removeEventListener("mousemove",this.#F))),["gamepad-only","both"].includes(this.#c)&&(window.removeEventListener("gamepadconnected",this.#$),window.removeEventListener("gamepaddisconnected",this.#B)),this.resetComboMapped(),this.#n.clear(),this.#i.clear(),this.#t.clear(),this.#k.clear(),this.#S.clear(),this.#T.clear(),this.#K.clear(),this.#u.clear(),this.#A.clear(),this.#a=[],this.#o=[],this.#r={},this.#s=null,this.#m=null,this.#h=!1,this.#w=0)}}const i=n;window.TinyGamepad=t.TinyGamepad})();
@@ -0,0 +1 @@
1
+ (()=>{var e={606:e=>{var t,r,n=e.exports={};function o(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function s(e){if(t===setTimeout)return setTimeout(e,0);if((t===o||!t)&&setTimeout)return t=setTimeout,setTimeout(e,0);try{return t(e,0)}catch(r){try{return t.call(null,e,0)}catch(r){return t.call(this,e,0)}}}!function(){try{t="function"==typeof setTimeout?setTimeout:o}catch(e){t=o}try{r="function"==typeof clearTimeout?clearTimeout:i}catch(e){r=i}}();var a,l=[],c=!1,f=-1;function h(){c&&a&&(c=!1,a.length?l=a.concat(l):f=-1,l.length&&u())}function u(){if(!c){var e=s(h);c=!0;for(var t=l.length;t;){for(a=l,l=[];++f<t;)a&&a[f].run();f=-1,t=l.length}a=null,c=!1,function(e){if(r===clearTimeout)return clearTimeout(e);if((r===i||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(e);try{return r(e)}catch(t){try{return r.call(null,e)}catch(t){return r.call(this,e)}}}(e)}}function p(e,t){this.fun=e,this.array=t}function g(){}n.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)t[r-1]=arguments[r];l.push(new p(e,t)),1!==l.length||c||s(u)},p.prototype.run=function(){this.fun.apply(null,this.array)},n.title="browser",n.browser=!0,n.env={},n.argv=[],n.version="",n.versions={},n.on=g,n.addListener=g,n.once=g,n.off=g,n.removeListener=g,n.removeAllListeners=g,n.emit=g,n.prependListener=g,n.prependOnceListener=g,n.listeners=function(e){return[]},n.binding=function(e){throw new Error("process.binding is not supported")},n.cwd=function(){return"/"},n.chdir=function(e){throw new Error("process.chdir is not supported")},n.umask=function(){return 0}},766:()=>{},911:()=>{},975:(e,t,r)=>{"use strict";var n=r(606);function o(e){if("string"!=typeof e)throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function i(e,t){for(var r,n="",o=0,i=-1,s=0,a=0;a<=e.length;++a){if(a<e.length)r=e.charCodeAt(a);else{if(47===r)break;r=47}if(47===r){if(i===a-1||1===s);else if(i!==a-1&&2===s){if(n.length<2||2!==o||46!==n.charCodeAt(n.length-1)||46!==n.charCodeAt(n.length-2))if(n.length>2){var l=n.lastIndexOf("/");if(l!==n.length-1){-1===l?(n="",o=0):o=(n=n.slice(0,l)).length-1-n.lastIndexOf("/"),i=a,s=0;continue}}else if(2===n.length||1===n.length){n="",o=0,i=a,s=0;continue}t&&(n.length>0?n+="/..":n="..",o=2)}else n.length>0?n+="/"+e.slice(i+1,a):n=e.slice(i+1,a),o=a-i-1;i=a,s=0}else 46===r&&-1!==s?++s:s=-1}return n}var s={resolve:function(){for(var e,t="",r=!1,s=arguments.length-1;s>=-1&&!r;s--){var a;s>=0?a=arguments[s]:(void 0===e&&(e=n.cwd()),a=e),o(a),0!==a.length&&(t=a+"/"+t,r=47===a.charCodeAt(0))}return t=i(t,!r),r?t.length>0?"/"+t:"/":t.length>0?t:"."},normalize:function(e){if(o(e),0===e.length)return".";var t=47===e.charCodeAt(0),r=47===e.charCodeAt(e.length-1);return 0!==(e=i(e,!t)).length||t||(e="."),e.length>0&&r&&(e+="/"),t?"/"+e:e},isAbsolute:function(e){return o(e),e.length>0&&47===e.charCodeAt(0)},join:function(){if(0===arguments.length)return".";for(var e,t=0;t<arguments.length;++t){var r=arguments[t];o(r),r.length>0&&(void 0===e?e=r:e+="/"+r)}return void 0===e?".":s.normalize(e)},relative:function(e,t){if(o(e),o(t),e===t)return"";if((e=s.resolve(e))===(t=s.resolve(t)))return"";for(var r=1;r<e.length&&47===e.charCodeAt(r);++r);for(var n=e.length,i=n-r,a=1;a<t.length&&47===t.charCodeAt(a);++a);for(var l=t.length-a,c=i<l?i:l,f=-1,h=0;h<=c;++h){if(h===c){if(l>c){if(47===t.charCodeAt(a+h))return t.slice(a+h+1);if(0===h)return t.slice(a+h)}else i>c&&(47===e.charCodeAt(r+h)?f=h:0===h&&(f=0));break}var u=e.charCodeAt(r+h);if(u!==t.charCodeAt(a+h))break;47===u&&(f=h)}var p="";for(h=r+f+1;h<=n;++h)h!==n&&47!==e.charCodeAt(h)||(0===p.length?p+="..":p+="/..");return p.length>0?p+t.slice(a+f):(a+=f,47===t.charCodeAt(a)&&++a,t.slice(a))},_makeLong:function(e){return e},dirname:function(e){if(o(e),0===e.length)return".";for(var t=e.charCodeAt(0),r=47===t,n=-1,i=!0,s=e.length-1;s>=1;--s)if(47===(t=e.charCodeAt(s))){if(!i){n=s;break}}else i=!1;return-1===n?r?"/":".":r&&1===n?"//":e.slice(0,n)},basename:function(e,t){if(void 0!==t&&"string"!=typeof t)throw new TypeError('"ext" argument must be a string');o(e);var r,n=0,i=-1,s=!0;if(void 0!==t&&t.length>0&&t.length<=e.length){if(t.length===e.length&&t===e)return"";var a=t.length-1,l=-1;for(r=e.length-1;r>=0;--r){var c=e.charCodeAt(r);if(47===c){if(!s){n=r+1;break}}else-1===l&&(s=!1,l=r+1),a>=0&&(c===t.charCodeAt(a)?-1===--a&&(i=r):(a=-1,i=l))}return n===i?i=l:-1===i&&(i=e.length),e.slice(n,i)}for(r=e.length-1;r>=0;--r)if(47===e.charCodeAt(r)){if(!s){n=r+1;break}}else-1===i&&(s=!1,i=r+1);return-1===i?"":e.slice(n,i)},extname:function(e){o(e);for(var t=-1,r=0,n=-1,i=!0,s=0,a=e.length-1;a>=0;--a){var l=e.charCodeAt(a);if(47!==l)-1===n&&(i=!1,n=a+1),46===l?-1===t?t=a:1!==s&&(s=1):-1!==t&&(s=-1);else if(!i){r=a+1;break}}return-1===t||-1===n||0===s||1===s&&t===n-1&&t===r+1?"":e.slice(t,n)},format:function(e){if(null===e||"object"!=typeof e)throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return function(e,t){var r=t.dir||t.root,n=t.base||(t.name||"")+(t.ext||"");return r?r===t.root?r+n:r+"/"+n:n}(0,e)},parse:function(e){o(e);var t={root:"",dir:"",base:"",ext:"",name:""};if(0===e.length)return t;var r,n=e.charCodeAt(0),i=47===n;i?(t.root="/",r=1):r=0;for(var s=-1,a=0,l=-1,c=!0,f=e.length-1,h=0;f>=r;--f)if(47!==(n=e.charCodeAt(f)))-1===l&&(c=!1,l=f+1),46===n?-1===s?s=f:1!==h&&(h=1):-1!==s&&(h=-1);else if(!c){a=f+1;break}return-1===s||-1===l||0===h||1===h&&s===l-1&&s===a+1?-1!==l&&(t.base=t.name=0===a&&i?e.slice(1,l):e.slice(a,l)):(0===a&&i?(t.name=e.slice(1,s),t.base=e.slice(1,l)):(t.name=e.slice(a,s),t.base=e.slice(a,l)),t.ext=e.slice(s,l)),a>0?t.dir=e.slice(0,a-1):i&&(t.dir="/"),t},sep:"/",delimiter:":",win32:null,posix:null};s.posix=s,e.exports=s}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var n={};(()=>{"use strict";r.d(n,{TinyI18:()=>i});var e=r(911),t=r(766),o=r(975);const i=class{static async mergeLocaleFiles({files:r,output:n,spaces:o=0}){if("number"!=typeof o||Number.isNaN(o)||o<0)throw new TypeError('mergeLocaleFiles: "spaces" must be a non-negative number');if(!Array.isArray(r)||0===r.length)throw new TypeError('mergeLocaleFiles: "files" must be a non-empty array of file paths');if("string"!=typeof n||!n)throw new TypeError('mergeLocaleFiles: "output" must be a non-empty string path');const i={};for(const n of r){if("string"!=typeof n||!n)throw new TypeError("mergeLocaleFiles: each file path must be a non-empty string");if(!(0,t.existsSync)(n))throw new Error(`mergeLocaleFiles: file "${n}" does not exist`);const r=await(0,e.readFile)(n,"utf-8");let o;try{o=JSON.parse(r)}catch(e){throw new Error(`mergeLocaleFiles: file "${n}" is not valid JSON`)}Object.assign(i,o)}await(0,e.writeFile)(n,JSON.stringify(i,null,o),"utf-8")}#e;#t;#r=null;#n;#o=null;#i=new Map;#s=new Map;#a=new Map;#l=new Map;get currentLocale(){return this.#r}get defaultLocale(){return this.#t}get mode(){return this.#e}get strict(){return this.#n}get basePath(){return this.#o}get stats(){const e=[];for(const t of this.#i.keys())e.push(this.getStatsForLocale(t));return e}get stringTables(){const e={};for(const[t,r]of this.#i.entries())e[t]=this.#c(r);return e}get patternTables(){const e={};for(const[t,r]of this.#s.entries())e[t]=r.map(e=>({$pattern:new RegExp(e.$pattern.source,e.$pattern.flags),value:this.#c(e.value),elseValue:this.#c(e.elseValue)}));return e}get helpers(){const e={};for(const[t,r]of this.#a.entries())e[t]=r;return e}get regexCache(){const e={};for(const[t,r]of this.#l.entries())e[t]=new RegExp(r.source,r.flags);return e}#c(e){if(null==e||"string"==typeof e||"function"==typeof e||"number"==typeof e)return e;if(e instanceof RegExp)return new RegExp(e.source,e.flags);if(Array.isArray(e))return e.map(e=>this.#c(e));if("object"==typeof e){const t={};for(const[r,n]of Object.entries(e))t[r]=this.#c(n);return t}return e}#f(e){if(void 0!==e&&"string"!=typeof e)throw new TypeError('#resolveOrder: "forceLocale" must be a string if provided');const t=[];return e&&"string"==typeof e&&this.#i.has(e)?t.push(e):this.#r&&t.push(this.#r),t.push(this.#t),t}#h(e,t){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new TypeError('#resolveExact: "order" must be an array of strings');if("string"!=typeof t||!t)throw new TypeError('#resolveExact: "key" must be a non-empty string');for(const r of e){const e=this.#i.get(r);if(e&&Object.prototype.hasOwnProperty.call(e,t))return e[t]}}#u(e,t){if(!Array.isArray(e)||!e.every(e=>"string"==typeof e))throw new TypeError('#resolveByPattern: "order" must be an array of strings');if("string"!=typeof t||!t)throw new TypeError('#resolveByPattern: "key" must be a non-empty string');for(const r of e){const e=this.#s.get(r)||[];for(const r of e)return r.$pattern.test(t)?r.value:r.elseValue??void 0}}#p(e,t){if(null==e){if(this.#n)throw new TypeError('#materialize: "value" cannot be null or undefined');return""}if("string"==typeof e)return this.#g(e,t);if("function"==typeof e)return e(t??{},this.#y());if(e&&"object"==typeof e&&"string"==typeof e.$fn){const r=this.#a.get(e.$fn);if("function"!=typeof r){if(this.#n)throw new Error(`TinyI18: helper "${e.$fn}" is not registered`);return""}return r({...t??{},args:void 0!==e.args?e.args:void 0},this.#y())}if(this.#n)throw new Error("TinyI18: unsupported entry type");return""}#g(e,t){if("string"!=typeof e)throw new TypeError('#interpolate: "template" must be a string');if(void 0!==t&&(null===t||"object"!=typeof t))throw new TypeError('#interpolate: "params" must be an object if provided');return t&&"object"==typeof t?e.replace(/\{([a-zA-Z0-9_.$-]+)\}/g,(e,r)=>{const n=this.#d(t,r);return null==n?"":String(n)}):e}#d(e,t){if(!e||"object"!=typeof e)throw new TypeError('#dotGet: "obj" must be an object');if("string"!=typeof t||!t)throw new TypeError('#dotGet: "path" must be a non-empty string');const r=t.split(".");let n=e;for(const e of r){if(null==n)return;n=n[e]}return n}#y(){return{has:e=>this.#a.has(e),call:(e,t,r)=>{const n=this.#a.get(e);if("function"!=typeof n)throw new Error(`Helper "${e}" not found`);return n(t,r??{})}}}#b(e,t){if("string"!=typeof e||!e)throw new TypeError('#ingestLocale: "locale" must be a non-empty string');if(!t||"object"!=typeof t)throw new TypeError('#ingestLocale: "raw" must be an object');if("string"!=typeof e||!e)throw new TypeError("#ingestLocale: invalid locale");if(!t||"object"!=typeof t)throw new TypeError('#ingestLocale: "raw" must be an object');const r={...this.#i.get(e)??{}},n=[...this.#s.get(e)??[]],o=(e,t)=>{if(null!=t)if("string"==typeof t||"function"==typeof t||t&&"object"==typeof t&&"string"==typeof t.$fn){if(!e)throw new TypeError("Leaf value requires a key path");r[e]=t}else if(t&&"object"==typeof t){if(t.$pattern instanceof RegExp&&Object.prototype.hasOwnProperty.call(t,"value"))return void n.push({$pattern:t.$pattern,value:t.value,elseValue:t.elseValue});for(const[r,n]of Object.entries(t))o(e?`${e}.${r}`:r,n)}};o("",t),this.#i.set(e,r),this.#s.set(e,n),this.#i.has(this.#t)||(this.#i.set(this.#t,{}),this.#s.set(this.#t,[]))}#w(e){if("string"!=typeof e||!e)throw new TypeError('#unloadLocale: "locale" must be a non-empty string');e!==this.#t&&(this.#i.delete(e),this.#s.delete(e))}async#m(t){if("string"!=typeof t||!t)throw new TypeError('#loadLocaleFromFile: "locale" must be a non-empty string');if("string"!=typeof this.#o||!this.#o)throw new TypeError('#loadLocaleFromFile: "this.#basePath" must be a non-empty string');const r=(0,o.join)(this.#o,`${t}.json`);let n;try{const t=await(0,e.readFile)(r,"utf8");n=JSON.parse(t)}catch(e){if(!(e instanceof Error))return;if(this.#n)throw new Error(`TinyI18: failed to load or parse ${r}: ${e.message}`);return this.#i.set(t,{}),void this.#s.set(t,[])}const i={...this.#i.get(t)??{}},s=[...this.#s.get(t)??[]],a=(e,t)=>{if(null!=t){if(t&&"object"==typeof t&&"string"==typeof t.$pattern&&Object.prototype.hasOwnProperty.call(t,"value")){const e=this.#T(t.$pattern);return void s.push({$pattern:e,value:this.#v(t.value),elseValue:this.#v(t.elseValue)})}if("string"==typeof t||t&&"object"==typeof t&&"string"==typeof t.$fn){if(!e)throw new TypeError("Leaf value requires a key path");i[e]=this.#v(t)}else if(t&&"object"==typeof t)for(const[r,n]of Object.entries(t))a(e?`${e}.${r}`:r,n)}};a("",n),this.#i.set(t,i),this.#s.set(t,s)}#T(e){if("string"!=typeof e||!e)throw new TypeError('#safeRegExp: "src" must be a non-empty string');const t=this.#l.get(e);if(t)return t;try{const t=new RegExp(e);return this.#l.set(e,t),t}catch{if(this.#n)throw new Error(`TinyI18: invalid regex "${e}" in file`);return/^$/}}#v(e){if("string"==typeof e)return e;if(e&&"object"==typeof e&&"string"==typeof e.$fn)return{$fn:String(e.$fn),args:e.args};if(this.#n)throw new Error("TinyI18: unsupported value in file JSON");return""}constructor(e){if(!e||"object"!=typeof e)throw new TypeError("TinyI18: options must be an object");const{mode:t,defaultLocale:r,basePath:n,localResources:o,strict:i=!0}=e;if("local"!==t&&"file"!==t)throw new TypeError('TinyI18: "mode" must be "local" or "file"');if("string"!=typeof r||!r)throw new TypeError('TinyI18: "defaultLocale" must be a non-empty string');if("boolean"!=typeof i)throw new TypeError('TinyI18: "strict" must be a boolean');if("file"===t){if("string"!=typeof n||!n)throw new TypeError('TinyI18: "basePath" is required in file mode');this.#o=n}if(this.#e=t,this.#t=r,this.#n=i,"local"===t&&o&&"object"==typeof o)for(const[e,t]of Object.entries(o))this.#b(e,t);this.#i.has(this.#t)||(this.#i.set(this.#t,{}),this.#s.set(this.#t,[]))}clearRegexCache(){this.#l.clear()}registerHelper(e,t){if("string"!=typeof e||!e)throw new TypeError('registerHelper: "name" must be non-empty string');if("function"!=typeof t)throw new TypeError('registerHelper: "fn" must be a function');this.#a.set(e,t)}unregisterHelper(e){if("string"!=typeof e||!e)throw new TypeError('unregisterHelper: "name" must be non-empty string');return this.#a.delete(e)}loadLocaleLocal(e,t){if("local"!==this.#e)throw new TypeError('loadLocaleLocal is only available in "local" mode');this.#b(e,t)}async setLocale(e){if(null!==e&&("string"!=typeof e||!e))throw new TypeError('setLocale: "locale" must be string or null');const t=this.#r;null!==e&&("file"===this.#e?await this.#m(e):this.#i.has(e)||(this.#i.set(e,{}),this.#s.set(e,[]))),"file"===this.#e&&t&&t!==this.#t&&t!==e&&this.#w(t),this.#r=e}t(e,t=void 0,r=void 0){return this.get(e,t,r)}get(e,t=void 0,r=void 0){if("string"!=typeof e||!e)throw new TypeError('get: "key" must be a non-empty string');const{locale:n}=r||{},o=this.#f(n);let i=this.#h(o,e);if(void 0===i){if(this.#n)throw new Error(`TinyI18: missing translation for key "${e}"`);return e}return this.#p(i,t)}p(e,t){return this.resolveByPattern(e,t)}resolveByPattern(e,t){if("string"!=typeof e||!e)throw new TypeError('get: "key" must be a non-empty string');const{locale:r}=t||{},n=this.#f(r);let o=this.#u(n,e);if(void 0===o){if(this.#n)throw new Error(`TinyI18: missing translation for key "${e}"`);return e}return o}resetToDefaultOnly(){if("file"===this.#e)for(const e of Array.from(this.#i.keys()))e!==this.#t&&this.#w(e);this.#r=null}getStatsForLocale(e){if("string"!=typeof e||!e)throw new TypeError('getStatsForLocale: "locale" must be a non-empty string');if(!this.#i.has(e))throw new Error(`getStatsForLocale: locale "${e}" is not registered`);return{locale:e,strings:Object.keys(this.#i.get(e)??{}).length,patterns:this.#s.get(e)?.length??0,isDefault:e===this.#t,isCurrent:e===this.#r}}}})(),window.TinyI18=n.TinyI18})();
@@ -0,0 +1 @@
1
+ (()=>{"use strict";var t={d:(e,i)=>{for(var r in i)t.o(i,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:i[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{TinyInventory:()=>r});class i{static#t=new Map;static get itemRegistry(){const t={},e=Object.fromEntries(i.#t);for(const i in e)t[i]={...e[i],metadata:{...e[i].metadata}};return t}static defineItem(t){if(!t||"object"!=typeof t)throw new TypeError("Config must be a valid object.");if(!t.id||"string"!=typeof t.id)throw new TypeError("Item must have a valid string 'id'.");if(void 0!==t.weight&&("number"!=typeof t.weight||t.weight<0))throw new TypeError(`weight must be a number >= 0. Received: ${t.weight}`);if(void 0!==t.maxStack&&(!Number.isInteger(t.maxStack)||t.maxStack<=0))throw new TypeError(`maxStack must be a positive integer. Received: ${t.maxStack}`);if(void 0!==t.metadata&&"object"!=typeof t.metadata)throw new TypeError("metadata must be an object.");if(void 0!==t.onUse&&null!==t.onUse&&"function"!=typeof t.onUse)throw new TypeError("onUse must be a function or null.");if(void 0!==t.type&&null!==t.type&&"string"!=typeof t.type)throw new TypeError("type must be a string or null.");i.#t.set(t.id,{id:t.id,weight:t.weight||0,maxStack:t.maxStack||1,metadata:t.metadata||{},type:t.type??null,onUse:"function"==typeof t.onUse?t.onUse:null})}static removeItem(t){if("string"!=typeof t)throw new TypeError("itemId must be a string.");return i.#t.delete(t)}static hasItem(t){if("string"!=typeof t)throw new TypeError("itemId must be a string.");return i.#t.has(t)}static getItem(t){if("string"!=typeof t)throw new TypeError("itemId must be a string.");const e=i.#t.get(t);if(!e)throw new Error(`Item '${t}' not defined in registry.`);return e}#e=new Map;#i={add:[],remove:[],use:[],set:[]};#r=[];#o;#n;#s;#a;get maxStack(){return this.#o}set maxStack(t){if(!Number.isInteger(t)||Number.isFinite(t)&&t<=0)throw new TypeError(`maxStack must be a positive integer. Received: ${t}`);this.#o=t}get maxSize(){return this.#n}set maxSize(t){if(null!==t&&(!Number.isInteger(t)||t<=0))throw new TypeError(`maxSize must be null or a positive integer. Received: ${t}`);this.#n=t}get maxSlots(){return this.#s}set maxSlots(t){if(null!==t&&(!Number.isInteger(t)||t<=0))throw new TypeError(`maxSlots must be null or a positive integer. Received: ${t}`);this.#s=t}get maxWeight(){return this.#a}set maxWeight(t){if(null!==t&&("number"!=typeof t||t<=0))throw new TypeError(`maxWeight must be null or a positive number. Received: ${t}`);this.#a=t}get events(){return{add:[...this.#i.add],remove:[...this.#i.remove],use:[...this.#i.use],set:[...this.#i.set]}}get items(){return[...this.#r].map(t=>t?this.#l(t):null)}get specialSlots(){return new Map([...this.#e.entries()].map(([t,e])=>[t,{type:e.type,item:e.item?this.#l(e.item):null}]))}get size(){const t=this.getAllItems();let e=0;for(const i of t)e+=i.quantity;return e}get slotsSize(){return this.getAllItems().length}get weight(){return this.getAllItems().reduce((t,e)=>{const r=i.getItem(e.id);return t+(r?.weight||0)*e.quantity},0)}_cleanNulls(){let t=this.#r.length-1;for(;t>=0&&null===this.#r[t];)t--;this.#r=this.#r.slice(0,t+1)}constructor(t={}){if("object"!=typeof t||null===t)throw new TypeError("`options` must be an object.");if(void 0!==t.maxWeight&&null!==t.maxWeight&&"number"!=typeof t.maxWeight)throw new TypeError("`maxWeight` must be a number or null.");if(void 0!==t.maxSlots&&null!==t.maxSlots&&"number"!=typeof t.maxSlots)throw new TypeError("`maxSlots` must be a number or null.");if(void 0!==t.maxSize&&null!==t.maxSize&&"number"!=typeof t.maxSize)throw new TypeError("`maxSize` must be a number or null.");if(void 0!==t.maxStack&&"number"!=typeof t.maxStack)throw new TypeError("`maxStack` must be a number.");if(void 0!==t.specialSlots&&"object"!=typeof t.specialSlots)throw new TypeError("`specialSlots` must be an object if defined.");if(this.#a=t.maxWeight??null,this.#s=t.maxSlots??null,this.#n=t.maxSize??null,this.#o=t.maxStack??1/0,t.specialSlots)for(const e in t.specialSlots){const i=t.specialSlots[e];if("object"!=typeof i||null===i)throw new TypeError("Each `specialSlot` entry must be an object.");if(void 0!==i.type&&null!==i.type&&"string"!=typeof i.type)throw new TypeError("`specialSlot.type` must be a string or null.");this.#e.set(e,{type:i.type??null,item:null})}}hasSpace({weight:t=0,sizeLength:e=0,slotsLength:i=0}={}){if("number"!=typeof t)throw new TypeError("`weight` must be a number.");if("number"!=typeof e)throw new TypeError("`sizeLength` must be a number.");if("number"!=typeof i)throw new TypeError("`slotsLength` must be a number.");return!(this.areFull(e)||this.areFullSlots(i)||this.isHeavy(t))}isHeavy(t=0){if("number"!=typeof t)throw new TypeError("`extraWeight` must be a number.");return null!==this.#a&&this.weight+t>this.#a}areFull(t=0){if("number"!=typeof t)throw new TypeError("`extraLength` must be a number.");return null!==this.#n&&this.size+t>this.#n}isFull(t=0){if("number"!=typeof t)throw new TypeError("`extraLength` must be a number.");return null!==this.#n&&this.size+t>=this.#n}areFullSlots(t=0){if("number"!=typeof t)throw new TypeError("`extraLength` must be a number.");return null!==this.#s&&this.slotsSize+t>this.#s}isFullSlots(t=0){if("number"!=typeof t)throw new TypeError("`extraLength` must be a number.");return null!==this.#s&&this.slotsSize+t>=this.#s}#m(t,e){if("string"!=typeof t)throw new TypeError("`type` must be a string.");if("object"!=typeof e||null===e)throw new TypeError("`payload` must be an object.");if(this.#i[t])for(const i of this.#i[t])i(e)}off(t,e){if("string"!=typeof t)throw new TypeError("`eventType` must be a string.");if("function"!=typeof e)throw new TypeError("`callback` must be a function.");if(!this.#i[t])return;const i=this.#i[t],r=i.indexOf(e);-1!==r&&i.splice(r,1)}offAll(t){if("string"!=typeof t)throw new TypeError("`eventType` must be a string.");this.#i[t]&&(this.#i[t]=[])}cloneEventCallbacks(t){if("string"!=typeof t)throw new TypeError("`eventType` must be a string.");return this.#i[t]?[...this.#i[t]]:[]}onAddItem(t){if("function"!=typeof t)throw new TypeError("`callback` must be a function.");this.#i.add.push(t)}onSetItem(t){if("function"!=typeof t)throw new TypeError("`callback` must be a function.");this.#i.set.push(t)}onRemoveItem(t){if("function"!=typeof t)throw new TypeError("`callback` must be a function.");this.#i.remove.push(t)}onUseItem(t){if("function"!=typeof t)throw new TypeError("`callback` must be a function.");this.#i.use.push(t)}compactInventory(){this.#r=this.#r.filter((t,e)=>{const i=null!==t;return i||this.#m("remove",{index:e,item:null,isCollection:!0,specialSlot:null,remove:()=>{}}),i})}addItem({itemId:t,quantity:e=1,metadata:r={},forceSpace:o=!1}){if("string"!=typeof t)throw new TypeError("`itemId` must be a string.");if("number"!=typeof e||!Number.isFinite(e)||e<=0)throw new TypeError("`quantity` must be a positive number.");if("object"!=typeof r||null===r)throw new TypeError("`metadata` must be an object.");if("boolean"!=typeof o)throw new TypeError("`forceSpace` must be a boolean.");const n=i.getItem(t);let s=e;const a=n.maxStack<=this.#o?n.maxStack:this.#o,l=[],m=(t,e)=>JSON.stringify(t)===JSON.stringify(e);let u=!0;for(;s>0&&u;){u=!1;for(const e in this.#r){const i=this.#r[e];if(i&&i.id===t&&i.quantity<a&&m(i.metadata,r)){const t=Math.min(a-i.quantity,s);if(!o&&!this.hasSpace({weight:n.weight*t,sizeLength:t}))continue;i.quantity+=t,s-=t,u=!0;const r=Number(e),m=l.findIndex(t=>t.index===r);if(m<0?l.push({index:r,quantity:t}):l[m].quantity+=t,this.#m("add",{item:this.#l(i),index:r,isCollection:!0,specialSlot:null,remove:this.#u({locationType:"normal",slotIndex:r,forceSpace:o,item:i})}),s<=0)break}}}if(s>0)for(const e in this.#r)if(null===this.#r[e]){const i=Math.min(a,s);if(!o&&!this.hasSpace({weight:n.weight*i,sizeLength:i}))continue;const m={id:t,quantity:i,metadata:r};this.#r[e]=m,s-=i;const u=Number(e),c=l.findIndex(t=>t.index===u);if(c<0?l.push({index:u,quantity:i}):l[c].quantity+=i,this.#m("add",{item:this.#l(m),index:u,isCollection:!0,specialSlot:null,remove:this.#u({locationType:"normal",slotIndex:u,forceSpace:o,item:m})}),s<=0)break}for(;s>0;){const e=Math.min(a,s);if(!o&&!this.hasSpace({weight:n.weight*e,sizeLength:e,slotsLength:1}))break;const i={id:t,quantity:e,metadata:r};this.#r.push(i);const m=this.#r.length-1,u=l.findIndex(t=>t.index===m);u<0?l.push({index:m,quantity:e}):l[u].quantity+=e,this.#m("add",{item:this.#l(i),index:m,isCollection:!0,specialSlot:null,remove:this.#u({locationType:"normal",slotIndex:m,forceSpace:o,item:i})}),s-=e}return{remaining:s,placesAdded:l}}getItemFrom(t){if("number"!=typeof t||!Number.isInteger(t))throw new TypeError("`slotIndex` must be an integer.");if(t<0||t>=this.#r.length)throw new Error(`Slot index '${t}' out of bounds .`);return this.#r[t]?this.#l(this.#r[t]):null}setItem({slotIndex:t,item:e,forceSpace:r=!1}){if("number"!=typeof t||!Number.isInteger(t))throw new TypeError("`slotIndex` must be an integer.");if("boolean"!=typeof r)throw new TypeError("`forceSpace` must be a boolean.");const o=e&&"object"==typeof e&&"string"==typeof e.id&&"number"==typeof e.quantity&&!Number.isNaN(e.quantity)&&Number.isFinite(e.quantity)&&e.quantity>-1&&"object"==typeof e.metadata;if(null!==e&&!o)throw new Error("Invalid item type: must be null or a valid InventoryItem.");const n=e?i.#t.get(e.id):null;if(null!==e&&!n)throw new Error(`Item '${e?.id??"unknown"}' not defined in registry.`);if(n&&e){const t=n.maxStack<=this.#o?n.maxStack:this.#o;if(e.quantity>t)throw new Error(`Item '${e.id}' exceeds max stack size. Allowed: ${t}, got: ${e.quantity}.`)}if(null!==this.#s&&(t<0||t>=this.#s))throw new Error(`Slot index ${t} out of range.`);const s=this.#r[t]??null,a=s?i.#t.get(s.id)??null:null,l=(t,e)=>e?e.weight*(t?t.quantity:0):0,m=t=>t?t.quantity:0;if(!r&&!this.hasSpace({weight:l(e,n)-l(s,a),sizeLength:m(e)-m(s)}))throw new Error("Inventory is full or overweight.");for(;this.#r.length<=t;)this.#r.push(null);this.#r[t]=e,this._cleanNulls(),this.#m("set",{index:t,isCollection:!0,item:e?this.#l(e):null,specialSlot:null,remove:e?this.#u({locationType:"normal",slotIndex:t,forceSpace:r,item:e}):()=>{}})}deleteItem(t,e=!1){if("number"!=typeof t||!Number.isInteger(t))throw new TypeError("`slotIndex` must be an integer.");if("boolean"!=typeof e)throw new TypeError("`forceSpace` must be a boolean.");this.setItem({slotIndex:t,item:null,forceSpace:e})}moveItem(t,e,i=!1){if("number"!=typeof t||!Number.isInteger(t))throw new TypeError("`fromIndex` must be an integer.");if("number"!=typeof e||!Number.isInteger(e))throw new TypeError("`toIndex` must be an integer.");if("boolean"!=typeof i)throw new TypeError("`forceSpace` must be a boolean.");const r=this.#r[t];if(!r)throw new Error(`No item found in slot ${t}.`);this.setItem({slotIndex:e,item:r,forceSpace:i}),this.setItem({slotIndex:t,item:null,forceSpace:i})}removeItem({itemId:t,metadata:e=null,quantity:i=1}){if("string"!=typeof t)throw new TypeError("`itemId` must be a string.");if(null!==e&&"object"!=typeof e)throw new TypeError("`metadata` must be an object or null.");if("number"!=typeof i||!Number.isFinite(i)||i<=0)throw new TypeError("`quantity` must be a positive number.");let r=i;const o=(t,e)=>JSON.stringify(t)===JSON.stringify(e);for(let i=0;i<this.#r.length;i++){const n=this.#r[i];if(n&&n.id===t&&(null===e||o(n.metadata,e))){const t=Math.min(n.quantity,r);n.quantity-=t,r-=t;const e=Number(i);if(n.quantity<=0&&(this.#r[i]=null),r<=0)return this._cleanNulls(),this.#m("remove",{index:e,item:this.#l(n),isCollection:!0,specialSlot:null,remove:this.#u({locationType:"normal",slotIndex:e,item:n})}),!0}}return this._cleanNulls(),this.#e.forEach((i,n)=>{if(r>0&&i.item&&i.item.id===t&&(null===e||o(i.item.metadata,e))){const t=Math.min(i.item.quantity,r);i.item.quantity-=t,i.item.quantity<0&&(i.item.quantity=0),r-=t,i.item.quantity<=0&&(i.item=null),this.#e.set(n,i),this.#m("remove",{index:null,item:i.item?this.#l(i.item):null,isCollection:!1,specialSlot:n,remove:i.item?this.#u({locationType:"special",specialSlot:n,item:i.item}):()=>{}})}}),r<=0}#u({locationType:t,specialSlot:e,slotIndex:i,item:r,forceSpace:o=!1}){if("normal"!==t&&"special"!==t)throw new TypeError("`locationType` must be 'normal' or 'special'.");if("boolean"!=typeof o)throw new TypeError("`forceSpace` must be boolean.");if(!r||"object"!=typeof r)throw new TypeError("`item` must be an InventoryItem object.");if("special"===t&&e&&"string"!=typeof e)throw new TypeError("`specialSlot` must be a string when locationType is 'special'.");if("normal"===t&&"number"!=typeof i)throw new TypeError("`slotIndex` must be a number when locationType is 'normal'.");return(n=o)=>{if("special"===t&&e){const t=this.#e.get(e);if(!t?.item)throw new Error(`Special slot '${e}' is empty.`);t.item.quantity>1?(t.item.quantity-=1,this.#e.set(e,t)):this.setSpecialSlot({slotId:e,item:null,forceSpace:n})}else{if("number"!=typeof i)throw new Error("Invalid remove operation: no valid slotIndex or specialSlot provided.");r.quantity>1?this.setItem({slotIndex:i,item:{...r,quantity:r.quantity-1},forceSpace:n}):this.setItem({slotIndex:i,item:null,forceSpace:n})}}}useItem({slotIndex:t,specialSlot:e,forceSpace:r=!1},...o){if(void 0!==t&&("number"!=typeof t||!Number.isInteger(t)))throw new TypeError("`slotIndex` must be an integer if provided.");if(void 0!==e&&"string"!=typeof e)throw new TypeError("`specialSlot` must be a string if provided.");if("boolean"!=typeof r)throw new TypeError("`forceSpace` must be boolean.");let n=null,s="normal",a=null;if(e){if(!this.#e.has(e))throw new Error(`Special slot '${e}' not found.`);n=this.#e.get(e).item,s="special"}else a=this.#r,n=a[t??-1]??null,s="normal";if(!n)throw new Error("special"===s?`No item found in special slot '${e}'.`:`No item found in slot ${t} of inventory.`);const l=i.getItem(n.id);if(l.onUse){const i={inventory:this,item:this.#l(n),index:t??null,specialSlot:e??null,isCollection:!!a,itemDef:l,remove:this.#u({locationType:s,specialSlot:e,slotIndex:t,forceSpace:r,item:n}),...o},m=l.onUse(i);return this.#m("use",i),m}return null}hasSpecialSlot(t){if("string"!=typeof t)throw new TypeError("`slotId` must be a string.");return this.#e.has(t)}getSpecialItem(t){if("string"!=typeof t)throw new TypeError("`slotId` must be a string.");if(!this.#e.has(t))throw new Error(`Special slot '${t}' does not exist.`);const e=this.#e.get(t);return e?.item?this.#l(e.item):null}getSpecialSlotType(t){if("string"!=typeof t)throw new TypeError("`slotId` must be a string.");if(!this.#e.has(t))throw new Error(`Special slot '${t}' does not exist.`);const e=this.#e.get(t);return e?.type??null}setSpecialSlot({slotId:t,item:e,forceSpace:r=!1}){if("string"!=typeof t)throw new TypeError("`slotId` must be a string.");if("boolean"!=typeof r)throw new TypeError("`forceSpace` must be boolean.");if(!this.#e.has(t))throw new Error(`Special slot '${t}' not found.`);const o=e&&"object"==typeof e&&"string"==typeof e.id&&"number"==typeof e.quantity&&!Number.isNaN(e.quantity)&&Number.isFinite(e.quantity)&&e.quantity>-1&&"object"==typeof e.metadata;if(null!==e&&!o)throw new Error("Invalid item type: must be null or a valid InventoryItem.");const n=e?i.#t.get(e.id):null;if(null!==e&&!n)throw new Error(`Item '${e?.id??"unknown"}' not defined in registry.`);const s=this.#e.get(t);if(!s)throw new Error(`Special slot ${t} out of range for slot '${t}'.`);const a=s.item?i.#t.get(s.item.id):null,l=(t,e)=>e?e.weight*(t?1:0):0,m=t=>t?1:0;if(!r&&!this.hasSpace({weight:l(e,n)-l(s.item,a),sizeLength:m(e)-m(s.item)}))throw new Error("Inventory is full or overweight.");s.item=e,this.#m("set",{index:null,item:e?this.#l(e):null,isCollection:!1,specialSlot:t,remove:e?this.#u({locationType:"special",specialSlot:t,forceSpace:r,item:e}):()=>{}})}deleteSpecialItem(t,e=!1){if("string"!=typeof t)throw new TypeError("`slotId` must be a string.");if("boolean"!=typeof e)throw new TypeError("`forceSpace` must be boolean.");this.setSpecialSlot({slotId:t,item:null,forceSpace:e})}equipItem({slotId:t,slotIndex:e,quantity:r=1,forceSpace:o=!1}){if("string"!=typeof t)throw new TypeError("`slotId` must be a string.");if("number"!=typeof e||!Number.isInteger(e))throw new TypeError("`slotIndex` must be an integer.");if("number"!=typeof r||!Number.isFinite(r)||r<=0)throw new TypeError("`quantity` must be a positive number.");if("boolean"!=typeof o)throw new TypeError("`forceSpace` must be boolean.");if(r<=0||!Number.isFinite(r))throw new Error(`Invalid quantity '${r}'.`);if(!this.#e.has(t))throw new Error(`Special slot '${t}' does not exist.`);const n=this.getItemFrom(e);if(!n)throw new Error(`No item found in inventory slot ${e}.`);if(n.quantity<r)throw new Error(`Not enough quantity of item '${n.id}' in inventory slot.`);const s=i.getItem(n.id),a=this.#e.get(t);if(!a)throw new Error(`Slot '${t}' not defined in registry.`);const l=a.type??null;if(null!==l&&s.type!==l)throw new Error(`Item '${n.id}' cannot be equipped in slot '${t}'.`);const m=Math.min(s.maxStack,this.#o);if(a.item&&a.item.id===n.id){const e=Math.max(0,m-a.item.quantity);if(e<=0)return r;const i=Math.min(r,e);return this.removeItem({itemId:n.id,quantity:i,metadata:null}),a.item.quantity+=i,this.#e.set(t,a),r-i}a.item&&this.unequipItem({slotId:t,forceSpace:o});const u=Math.min(r,m);return this.removeItem({itemId:n.id,quantity:u,metadata:null}),a.item={id:n.id,quantity:u,metadata:n.metadata},this.#e.set(t,a),r-u}unequipItem({slotId:t,quantity:e=null,forceSpace:i=!1}){if("string"!=typeof t)throw new TypeError("`slotId` must be a string.");if(null!==e&&("number"!=typeof e||!Number.isFinite(e)||e<=0))throw new TypeError("`quantity` must be a positive number or null.");if("boolean"!=typeof i)throw new TypeError("`forceSpace` must be boolean.");if(!this.#e.has(t))throw new Error(`Special slot '${t}' does not exist.`);const r=this.#e.get(t);if(!r)throw new Error(`Slot '${t}' not defined in registry.`);if(!r.item)return!1;const o=r.item,n=null===e?o.quantity:e;if(n<=0)throw new Error(`Invalid unequip quantity: ${n}`);if(n>o.quantity)throw new Error(`Not enough items in slot '${t}' to unequip.`);return this.addItem({itemId:o.id,quantity:n,metadata:o.metadata,forceSpace:i}),n===o.quantity?r.item=null:(o.quantity-=n,r.item=o),this.#e.set(t,r),!0}#l(t){if(!t||"object"!=typeof t)throw new TypeError("`item` must be an InventoryItem object.");if("string"!=typeof t.id)throw new TypeError("`item.id` must be a string.");if("number"!=typeof t.quantity||!Number.isFinite(t.quantity))throw new TypeError("`item.quantity` must be a finite number.");if(!t.metadata||"object"!=typeof t.metadata)throw new TypeError("`item.metadata` must be an object.");return{id:t.id,quantity:t.quantity,metadata:{...t.metadata}}}getItemList(){return[...this.#r].map((t,e)=>[t?this.#l(t):null,e]).filter(t=>null!==t[0])}getAllItems(){const t=[...this.#r].filter(t=>null!==t).map(this.#l);return this.#e.forEach(e=>{const i=e.item;i&&t.push(i)}),t}getItemsByMetadata(t){if("function"!=typeof t)throw new TypeError("`filterFn` must be a function.");return this.getAllItems().filter(e=>{const r=i.getItem(e.id);return t(r.metadata,e)})}findItem(t){if("function"!=typeof t)throw new TypeError("`predicate` must be a function.");return this.getAllItems().find(t)}findItems(t){if("function"!=typeof t)throw new TypeError("`predicate` must be a function.");return this.getAllItems().filter(t)}getItemCount(t){if("string"!=typeof t)throw new TypeError("`itemId` must be a string.");return this.getAllItems().filter(e=>e.id===t).reduce((t,e)=>t+e.quantity,0)}hasItem(t,e=1){if("string"!=typeof t)throw new TypeError("`itemId` must be a string.");if("number"!=typeof e||!Number.isFinite(e)||e<0)throw new TypeError("`quantity` must be a non-negative number.");return this.getItemCount(t)>=e}existsItemAt(t){if("number"!=typeof t||!Number.isInteger(t))throw new TypeError("`slotIndex` must be an integer.");return!!this.#r[t]}clear(){this.clearAllItems(),this.clearAllEvents()}clearAllEvents(){this.#i={add:[],remove:[],use:[],set:[]}}clearAllItems(){this.clearItems(),this.clearSpecialItems()}clearItems(){for(let t=this.#r.length-1;t>=0;t--)this.#r[t]&&this.deleteItem(t,!0)}clearSpecialItems(){for(const t of this.#e.keys()){const e=this.#e.get(t);e?.item&&this.deleteSpecialItem(t,!0)}}clone(){const t=this.toObject();return i.fromObject(t)}toObject(){const t={};for(const[e,i]of this.#e.entries())t[e]={type:i?.type??null,item:i?.item?this.#l(i.item):null};return{__schema:"TinyInventory",version:1,maxWeight:this.#a,maxSlots:this.#s,maxSize:this.#n,maxStack:this.#o,items:this.#r.map(t=>t?this.#l(t):null),specialSlots:t}}toJSON(t=0){if("number"!=typeof t||!Number.isFinite(t)||t<0)throw new TypeError("`space` must be a non-negative number.");return JSON.stringify(this.toObject(),null,t)}static fromObject(t){if(!t||"object"!=typeof t)throw new TypeError("Invalid state: expected object.");if("TinyInventory"!==t.__schema||"number"!=typeof t.version)throw new TypeError("Invalid or missing schema header.");if(1!==t.version)throw new TypeError(`Unsupported TinyInventory state version: ${t.version}`);const e={};if(t.specialSlots&&"object"==typeof t.specialSlots)for(const i of Object.keys(t.specialSlots))e[i]={type:t.specialSlots[i]?.type??null};const r=new i({maxWeight:t.maxWeight??null,maxSlots:t.maxSlots??null,maxSize:t.maxSize??null,maxStack:t.maxStack??null,specialSlots:e});if(Array.isArray(t.items))for(const e in t.items){const i=t.items[e];if(null!==i){const t={id:String(i.id),quantity:Math.max(1,Number(i.quantity)||1),metadata:i.metadata&&"object"==typeof i.metadata?i.metadata:{}};r.setItem({slotIndex:Number(e),item:t,forceSpace:!0})}else r.setItem({slotIndex:Number(e),item:null,forceSpace:!0})}if(t.specialSlots&&"object"==typeof t.specialSlots)for(const[e,i]of Object.entries(t.specialSlots)){if(!r.hasSpecialSlot(e))continue;const t=i?.item;if(t&&t.id){const i={id:String(t.id),quantity:Math.max(1,Number(t.quantity)||1),metadata:t.metadata&&"object"==typeof t.metadata?t.metadata:{}};r.setSpecialSlot({slotId:e,item:i,forceSpace:!0})}}return r}static fromJSON(t){if("string"!=typeof t)throw new TypeError("`json` must be a string.");const e=JSON.parse(t);return i.fromObject(e)}}const r=i;window.TinyInventory=e.TinyInventory})();
@@ -0,0 +1 @@
1
+ (()=>{"use strict";var e={d:(t,i)=>{for(var r in i)e.o(i,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:i[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{TinyInventoryTrader:()=>n});class i{static#e=new Map;static get itemRegistry(){const e={},t=Object.fromEntries(i.#e);for(const i in t)e[i]={...t[i],metadata:{...t[i].metadata}};return e}static defineItem(e){if(!e||"object"!=typeof e)throw new TypeError("Config must be a valid object.");if(!e.id||"string"!=typeof e.id)throw new TypeError("Item must have a valid string 'id'.");if(void 0!==e.weight&&("number"!=typeof e.weight||e.weight<0))throw new TypeError(`weight must be a number >= 0. Received: ${e.weight}`);if(void 0!==e.maxStack&&(!Number.isInteger(e.maxStack)||e.maxStack<=0))throw new TypeError(`maxStack must be a positive integer. Received: ${e.maxStack}`);if(void 0!==e.metadata&&"object"!=typeof e.metadata)throw new TypeError("metadata must be an object.");if(void 0!==e.onUse&&null!==e.onUse&&"function"!=typeof e.onUse)throw new TypeError("onUse must be a function or null.");if(void 0!==e.type&&null!==e.type&&"string"!=typeof e.type)throw new TypeError("type must be a string or null.");i.#e.set(e.id,{id:e.id,weight:e.weight||0,maxStack:e.maxStack||1,metadata:e.metadata||{},type:e.type??null,onUse:"function"==typeof e.onUse?e.onUse:null})}static removeItem(e){if("string"!=typeof e)throw new TypeError("itemId must be a string.");return i.#e.delete(e)}static hasItem(e){if("string"!=typeof e)throw new TypeError("itemId must be a string.");return i.#e.has(e)}static getItem(e){if("string"!=typeof e)throw new TypeError("itemId must be a string.");const t=i.#e.get(e);if(!t)throw new Error(`Item '${e}' not defined in registry.`);return t}#t=new Map;#i={add:[],remove:[],use:[],set:[]};#r=[];#n;#o;#s;#a;get maxStack(){return this.#n}set maxStack(e){if(!Number.isInteger(e)||Number.isFinite(e)&&e<=0)throw new TypeError(`maxStack must be a positive integer. Received: ${e}`);this.#n=e}get maxSize(){return this.#o}set maxSize(e){if(null!==e&&(!Number.isInteger(e)||e<=0))throw new TypeError(`maxSize must be null or a positive integer. Received: ${e}`);this.#o=e}get maxSlots(){return this.#s}set maxSlots(e){if(null!==e&&(!Number.isInteger(e)||e<=0))throw new TypeError(`maxSlots must be null or a positive integer. Received: ${e}`);this.#s=e}get maxWeight(){return this.#a}set maxWeight(e){if(null!==e&&("number"!=typeof e||e<=0))throw new TypeError(`maxWeight must be null or a positive number. Received: ${e}`);this.#a=e}get events(){return{add:[...this.#i.add],remove:[...this.#i.remove],use:[...this.#i.use],set:[...this.#i.set]}}get items(){return[...this.#r].map(e=>e?this.#l(e):null)}get specialSlots(){return new Map([...this.#t.entries()].map(([e,t])=>[e,{type:t.type,item:t.item?this.#l(t.item):null}]))}get size(){const e=this.getAllItems();let t=0;for(const i of e)t+=i.quantity;return t}get slotsSize(){return this.getAllItems().length}get weight(){return this.getAllItems().reduce((e,t)=>{const r=i.getItem(t.id);return e+(r?.weight||0)*t.quantity},0)}_cleanNulls(){let e=this.#r.length-1;for(;e>=0&&null===this.#r[e];)e--;this.#r=this.#r.slice(0,e+1)}constructor(e={}){if("object"!=typeof e||null===e)throw new TypeError("`options` must be an object.");if(void 0!==e.maxWeight&&null!==e.maxWeight&&"number"!=typeof e.maxWeight)throw new TypeError("`maxWeight` must be a number or null.");if(void 0!==e.maxSlots&&null!==e.maxSlots&&"number"!=typeof e.maxSlots)throw new TypeError("`maxSlots` must be a number or null.");if(void 0!==e.maxSize&&null!==e.maxSize&&"number"!=typeof e.maxSize)throw new TypeError("`maxSize` must be a number or null.");if(void 0!==e.maxStack&&"number"!=typeof e.maxStack)throw new TypeError("`maxStack` must be a number.");if(void 0!==e.specialSlots&&"object"!=typeof e.specialSlots)throw new TypeError("`specialSlots` must be an object if defined.");if(this.#a=e.maxWeight??null,this.#s=e.maxSlots??null,this.#o=e.maxSize??null,this.#n=e.maxStack??1/0,e.specialSlots)for(const t in e.specialSlots){const i=e.specialSlots[t];if("object"!=typeof i||null===i)throw new TypeError("Each `specialSlot` entry must be an object.");if(void 0!==i.type&&null!==i.type&&"string"!=typeof i.type)throw new TypeError("`specialSlot.type` must be a string or null.");this.#t.set(t,{type:i.type??null,item:null})}}hasSpace({weight:e=0,sizeLength:t=0,slotsLength:i=0}={}){if("number"!=typeof e)throw new TypeError("`weight` must be a number.");if("number"!=typeof t)throw new TypeError("`sizeLength` must be a number.");if("number"!=typeof i)throw new TypeError("`slotsLength` must be a number.");return!(this.areFull(t)||this.areFullSlots(i)||this.isHeavy(e))}isHeavy(e=0){if("number"!=typeof e)throw new TypeError("`extraWeight` must be a number.");return null!==this.#a&&this.weight+e>this.#a}areFull(e=0){if("number"!=typeof e)throw new TypeError("`extraLength` must be a number.");return null!==this.#o&&this.size+e>this.#o}isFull(e=0){if("number"!=typeof e)throw new TypeError("`extraLength` must be a number.");return null!==this.#o&&this.size+e>=this.#o}areFullSlots(e=0){if("number"!=typeof e)throw new TypeError("`extraLength` must be a number.");return null!==this.#s&&this.slotsSize+e>this.#s}isFullSlots(e=0){if("number"!=typeof e)throw new TypeError("`extraLength` must be a number.");return null!==this.#s&&this.slotsSize+e>=this.#s}#m(e,t){if("string"!=typeof e)throw new TypeError("`type` must be a string.");if("object"!=typeof t||null===t)throw new TypeError("`payload` must be an object.");if(this.#i[e])for(const i of this.#i[e])i(t)}off(e,t){if("string"!=typeof e)throw new TypeError("`eventType` must be a string.");if("function"!=typeof t)throw new TypeError("`callback` must be a function.");if(!this.#i[e])return;const i=this.#i[e],r=i.indexOf(t);-1!==r&&i.splice(r,1)}offAll(e){if("string"!=typeof e)throw new TypeError("`eventType` must be a string.");this.#i[e]&&(this.#i[e]=[])}cloneEventCallbacks(e){if("string"!=typeof e)throw new TypeError("`eventType` must be a string.");return this.#i[e]?[...this.#i[e]]:[]}onAddItem(e){if("function"!=typeof e)throw new TypeError("`callback` must be a function.");this.#i.add.push(e)}onSetItem(e){if("function"!=typeof e)throw new TypeError("`callback` must be a function.");this.#i.set.push(e)}onRemoveItem(e){if("function"!=typeof e)throw new TypeError("`callback` must be a function.");this.#i.remove.push(e)}onUseItem(e){if("function"!=typeof e)throw new TypeError("`callback` must be a function.");this.#i.use.push(e)}compactInventory(){this.#r=this.#r.filter((e,t)=>{const i=null!==e;return i||this.#m("remove",{index:t,item:null,isCollection:!0,specialSlot:null,remove:()=>{}}),i})}addItem({itemId:e,quantity:t=1,metadata:r={},forceSpace:n=!1}){if("string"!=typeof e)throw new TypeError("`itemId` must be a string.");if("number"!=typeof t||!Number.isFinite(t)||t<=0)throw new TypeError("`quantity` must be a positive number.");if("object"!=typeof r||null===r)throw new TypeError("`metadata` must be an object.");if("boolean"!=typeof n)throw new TypeError("`forceSpace` must be a boolean.");const o=i.getItem(e);let s=t;const a=o.maxStack<=this.#n?o.maxStack:this.#n,l=[],m=(e,t)=>JSON.stringify(e)===JSON.stringify(t);let u=!0;for(;s>0&&u;){u=!1;for(const t in this.#r){const i=this.#r[t];if(i&&i.id===e&&i.quantity<a&&m(i.metadata,r)){const e=Math.min(a-i.quantity,s);if(!n&&!this.hasSpace({weight:o.weight*e,sizeLength:e}))continue;i.quantity+=e,s-=e,u=!0;const r=Number(t),m=l.findIndex(e=>e.index===r);if(m<0?l.push({index:r,quantity:e}):l[m].quantity+=e,this.#m("add",{item:this.#l(i),index:r,isCollection:!0,specialSlot:null,remove:this.#u({locationType:"normal",slotIndex:r,forceSpace:n,item:i})}),s<=0)break}}}if(s>0)for(const t in this.#r)if(null===this.#r[t]){const i=Math.min(a,s);if(!n&&!this.hasSpace({weight:o.weight*i,sizeLength:i}))continue;const m={id:e,quantity:i,metadata:r};this.#r[t]=m,s-=i;const u=Number(t),c=l.findIndex(e=>e.index===u);if(c<0?l.push({index:u,quantity:i}):l[c].quantity+=i,this.#m("add",{item:this.#l(m),index:u,isCollection:!0,specialSlot:null,remove:this.#u({locationType:"normal",slotIndex:u,forceSpace:n,item:m})}),s<=0)break}for(;s>0;){const t=Math.min(a,s);if(!n&&!this.hasSpace({weight:o.weight*t,sizeLength:t,slotsLength:1}))break;const i={id:e,quantity:t,metadata:r};this.#r.push(i);const m=this.#r.length-1,u=l.findIndex(e=>e.index===m);u<0?l.push({index:m,quantity:t}):l[u].quantity+=t,this.#m("add",{item:this.#l(i),index:m,isCollection:!0,specialSlot:null,remove:this.#u({locationType:"normal",slotIndex:m,forceSpace:n,item:i})}),s-=t}return{remaining:s,placesAdded:l}}getItemFrom(e){if("number"!=typeof e||!Number.isInteger(e))throw new TypeError("`slotIndex` must be an integer.");if(e<0||e>=this.#r.length)throw new Error(`Slot index '${e}' out of bounds .`);return this.#r[e]?this.#l(this.#r[e]):null}setItem({slotIndex:e,item:t,forceSpace:r=!1}){if("number"!=typeof e||!Number.isInteger(e))throw new TypeError("`slotIndex` must be an integer.");if("boolean"!=typeof r)throw new TypeError("`forceSpace` must be a boolean.");const n=t&&"object"==typeof t&&"string"==typeof t.id&&"number"==typeof t.quantity&&!Number.isNaN(t.quantity)&&Number.isFinite(t.quantity)&&t.quantity>-1&&"object"==typeof t.metadata;if(null!==t&&!n)throw new Error("Invalid item type: must be null or a valid InventoryItem.");const o=t?i.#e.get(t.id):null;if(null!==t&&!o)throw new Error(`Item '${t?.id??"unknown"}' not defined in registry.`);if(o&&t){const e=o.maxStack<=this.#n?o.maxStack:this.#n;if(t.quantity>e)throw new Error(`Item '${t.id}' exceeds max stack size. Allowed: ${e}, got: ${t.quantity}.`)}if(null!==this.#s&&(e<0||e>=this.#s))throw new Error(`Slot index ${e} out of range.`);const s=this.#r[e]??null,a=s?i.#e.get(s.id)??null:null,l=(e,t)=>t?t.weight*(e?e.quantity:0):0,m=e=>e?e.quantity:0;if(!r&&!this.hasSpace({weight:l(t,o)-l(s,a),sizeLength:m(t)-m(s)}))throw new Error("Inventory is full or overweight.");for(;this.#r.length<=e;)this.#r.push(null);this.#r[e]=t,this._cleanNulls(),this.#m("set",{index:e,isCollection:!0,item:t?this.#l(t):null,specialSlot:null,remove:t?this.#u({locationType:"normal",slotIndex:e,forceSpace:r,item:t}):()=>{}})}deleteItem(e,t=!1){if("number"!=typeof e||!Number.isInteger(e))throw new TypeError("`slotIndex` must be an integer.");if("boolean"!=typeof t)throw new TypeError("`forceSpace` must be a boolean.");this.setItem({slotIndex:e,item:null,forceSpace:t})}moveItem(e,t,i=!1){if("number"!=typeof e||!Number.isInteger(e))throw new TypeError("`fromIndex` must be an integer.");if("number"!=typeof t||!Number.isInteger(t))throw new TypeError("`toIndex` must be an integer.");if("boolean"!=typeof i)throw new TypeError("`forceSpace` must be a boolean.");const r=this.#r[e];if(!r)throw new Error(`No item found in slot ${e}.`);this.setItem({slotIndex:t,item:r,forceSpace:i}),this.setItem({slotIndex:e,item:null,forceSpace:i})}removeItem({itemId:e,metadata:t=null,quantity:i=1}){if("string"!=typeof e)throw new TypeError("`itemId` must be a string.");if(null!==t&&"object"!=typeof t)throw new TypeError("`metadata` must be an object or null.");if("number"!=typeof i||!Number.isFinite(i)||i<=0)throw new TypeError("`quantity` must be a positive number.");let r=i;const n=(e,t)=>JSON.stringify(e)===JSON.stringify(t);for(let i=0;i<this.#r.length;i++){const o=this.#r[i];if(o&&o.id===e&&(null===t||n(o.metadata,t))){const e=Math.min(o.quantity,r);o.quantity-=e,r-=e;const t=Number(i);if(o.quantity<=0&&(this.#r[i]=null),r<=0)return this._cleanNulls(),this.#m("remove",{index:t,item:this.#l(o),isCollection:!0,specialSlot:null,remove:this.#u({locationType:"normal",slotIndex:t,item:o})}),!0}}return this._cleanNulls(),this.#t.forEach((i,o)=>{if(r>0&&i.item&&i.item.id===e&&(null===t||n(i.item.metadata,t))){const e=Math.min(i.item.quantity,r);i.item.quantity-=e,i.item.quantity<0&&(i.item.quantity=0),r-=e,i.item.quantity<=0&&(i.item=null),this.#t.set(o,i),this.#m("remove",{index:null,item:i.item?this.#l(i.item):null,isCollection:!1,specialSlot:o,remove:i.item?this.#u({locationType:"special",specialSlot:o,item:i.item}):()=>{}})}}),r<=0}#u({locationType:e,specialSlot:t,slotIndex:i,item:r,forceSpace:n=!1}){if("normal"!==e&&"special"!==e)throw new TypeError("`locationType` must be 'normal' or 'special'.");if("boolean"!=typeof n)throw new TypeError("`forceSpace` must be boolean.");if(!r||"object"!=typeof r)throw new TypeError("`item` must be an InventoryItem object.");if("special"===e&&t&&"string"!=typeof t)throw new TypeError("`specialSlot` must be a string when locationType is 'special'.");if("normal"===e&&"number"!=typeof i)throw new TypeError("`slotIndex` must be a number when locationType is 'normal'.");return(o=n)=>{if("special"===e&&t){const e=this.#t.get(t);if(!e?.item)throw new Error(`Special slot '${t}' is empty.`);e.item.quantity>1?(e.item.quantity-=1,this.#t.set(t,e)):this.setSpecialSlot({slotId:t,item:null,forceSpace:o})}else{if("number"!=typeof i)throw new Error("Invalid remove operation: no valid slotIndex or specialSlot provided.");r.quantity>1?this.setItem({slotIndex:i,item:{...r,quantity:r.quantity-1},forceSpace:o}):this.setItem({slotIndex:i,item:null,forceSpace:o})}}}useItem({slotIndex:e,specialSlot:t,forceSpace:r=!1},...n){if(void 0!==e&&("number"!=typeof e||!Number.isInteger(e)))throw new TypeError("`slotIndex` must be an integer if provided.");if(void 0!==t&&"string"!=typeof t)throw new TypeError("`specialSlot` must be a string if provided.");if("boolean"!=typeof r)throw new TypeError("`forceSpace` must be boolean.");let o=null,s="normal",a=null;if(t){if(!this.#t.has(t))throw new Error(`Special slot '${t}' not found.`);o=this.#t.get(t).item,s="special"}else a=this.#r,o=a[e??-1]??null,s="normal";if(!o)throw new Error("special"===s?`No item found in special slot '${t}'.`:`No item found in slot ${e} of inventory.`);const l=i.getItem(o.id);if(l.onUse){const i={inventory:this,item:this.#l(o),index:e??null,specialSlot:t??null,isCollection:!!a,itemDef:l,remove:this.#u({locationType:s,specialSlot:t,slotIndex:e,forceSpace:r,item:o}),...n},m=l.onUse(i);return this.#m("use",i),m}return null}hasSpecialSlot(e){if("string"!=typeof e)throw new TypeError("`slotId` must be a string.");return this.#t.has(e)}getSpecialItem(e){if("string"!=typeof e)throw new TypeError("`slotId` must be a string.");if(!this.#t.has(e))throw new Error(`Special slot '${e}' does not exist.`);const t=this.#t.get(e);return t?.item?this.#l(t.item):null}getSpecialSlotType(e){if("string"!=typeof e)throw new TypeError("`slotId` must be a string.");if(!this.#t.has(e))throw new Error(`Special slot '${e}' does not exist.`);const t=this.#t.get(e);return t?.type??null}setSpecialSlot({slotId:e,item:t,forceSpace:r=!1}){if("string"!=typeof e)throw new TypeError("`slotId` must be a string.");if("boolean"!=typeof r)throw new TypeError("`forceSpace` must be boolean.");if(!this.#t.has(e))throw new Error(`Special slot '${e}' not found.`);const n=t&&"object"==typeof t&&"string"==typeof t.id&&"number"==typeof t.quantity&&!Number.isNaN(t.quantity)&&Number.isFinite(t.quantity)&&t.quantity>-1&&"object"==typeof t.metadata;if(null!==t&&!n)throw new Error("Invalid item type: must be null or a valid InventoryItem.");const o=t?i.#e.get(t.id):null;if(null!==t&&!o)throw new Error(`Item '${t?.id??"unknown"}' not defined in registry.`);const s=this.#t.get(e);if(!s)throw new Error(`Special slot ${e} out of range for slot '${e}'.`);const a=s.item?i.#e.get(s.item.id):null,l=(e,t)=>t?t.weight*(e?1:0):0,m=e=>e?1:0;if(!r&&!this.hasSpace({weight:l(t,o)-l(s.item,a),sizeLength:m(t)-m(s.item)}))throw new Error("Inventory is full or overweight.");s.item=t,this.#m("set",{index:null,item:t?this.#l(t):null,isCollection:!1,specialSlot:e,remove:t?this.#u({locationType:"special",specialSlot:e,forceSpace:r,item:t}):()=>{}})}deleteSpecialItem(e,t=!1){if("string"!=typeof e)throw new TypeError("`slotId` must be a string.");if("boolean"!=typeof t)throw new TypeError("`forceSpace` must be boolean.");this.setSpecialSlot({slotId:e,item:null,forceSpace:t})}equipItem({slotId:e,slotIndex:t,quantity:r=1,forceSpace:n=!1}){if("string"!=typeof e)throw new TypeError("`slotId` must be a string.");if("number"!=typeof t||!Number.isInteger(t))throw new TypeError("`slotIndex` must be an integer.");if("number"!=typeof r||!Number.isFinite(r)||r<=0)throw new TypeError("`quantity` must be a positive number.");if("boolean"!=typeof n)throw new TypeError("`forceSpace` must be boolean.");if(r<=0||!Number.isFinite(r))throw new Error(`Invalid quantity '${r}'.`);if(!this.#t.has(e))throw new Error(`Special slot '${e}' does not exist.`);const o=this.getItemFrom(t);if(!o)throw new Error(`No item found in inventory slot ${t}.`);if(o.quantity<r)throw new Error(`Not enough quantity of item '${o.id}' in inventory slot.`);const s=i.getItem(o.id),a=this.#t.get(e);if(!a)throw new Error(`Slot '${e}' not defined in registry.`);const l=a.type??null;if(null!==l&&s.type!==l)throw new Error(`Item '${o.id}' cannot be equipped in slot '${e}'.`);const m=Math.min(s.maxStack,this.#n);if(a.item&&a.item.id===o.id){const t=Math.max(0,m-a.item.quantity);if(t<=0)return r;const i=Math.min(r,t);return this.removeItem({itemId:o.id,quantity:i,metadata:null}),a.item.quantity+=i,this.#t.set(e,a),r-i}a.item&&this.unequipItem({slotId:e,forceSpace:n});const u=Math.min(r,m);return this.removeItem({itemId:o.id,quantity:u,metadata:null}),a.item={id:o.id,quantity:u,metadata:o.metadata},this.#t.set(e,a),r-u}unequipItem({slotId:e,quantity:t=null,forceSpace:i=!1}){if("string"!=typeof e)throw new TypeError("`slotId` must be a string.");if(null!==t&&("number"!=typeof t||!Number.isFinite(t)||t<=0))throw new TypeError("`quantity` must be a positive number or null.");if("boolean"!=typeof i)throw new TypeError("`forceSpace` must be boolean.");if(!this.#t.has(e))throw new Error(`Special slot '${e}' does not exist.`);const r=this.#t.get(e);if(!r)throw new Error(`Slot '${e}' not defined in registry.`);if(!r.item)return!1;const n=r.item,o=null===t?n.quantity:t;if(o<=0)throw new Error(`Invalid unequip quantity: ${o}`);if(o>n.quantity)throw new Error(`Not enough items in slot '${e}' to unequip.`);return this.addItem({itemId:n.id,quantity:o,metadata:n.metadata,forceSpace:i}),o===n.quantity?r.item=null:(n.quantity-=o,r.item=n),this.#t.set(e,r),!0}#l(e){if(!e||"object"!=typeof e)throw new TypeError("`item` must be an InventoryItem object.");if("string"!=typeof e.id)throw new TypeError("`item.id` must be a string.");if("number"!=typeof e.quantity||!Number.isFinite(e.quantity))throw new TypeError("`item.quantity` must be a finite number.");if(!e.metadata||"object"!=typeof e.metadata)throw new TypeError("`item.metadata` must be an object.");return{id:e.id,quantity:e.quantity,metadata:{...e.metadata}}}getItemList(){return[...this.#r].map((e,t)=>[e?this.#l(e):null,t]).filter(e=>null!==e[0])}getAllItems(){const e=[...this.#r].filter(e=>null!==e).map(this.#l);return this.#t.forEach(t=>{const i=t.item;i&&e.push(i)}),e}getItemsByMetadata(e){if("function"!=typeof e)throw new TypeError("`filterFn` must be a function.");return this.getAllItems().filter(t=>{const r=i.getItem(t.id);return e(r.metadata,t)})}findItem(e){if("function"!=typeof e)throw new TypeError("`predicate` must be a function.");return this.getAllItems().find(e)}findItems(e){if("function"!=typeof e)throw new TypeError("`predicate` must be a function.");return this.getAllItems().filter(e)}getItemCount(e){if("string"!=typeof e)throw new TypeError("`itemId` must be a string.");return this.getAllItems().filter(t=>t.id===e).reduce((e,t)=>e+t.quantity,0)}hasItem(e,t=1){if("string"!=typeof e)throw new TypeError("`itemId` must be a string.");if("number"!=typeof t||!Number.isFinite(t)||t<0)throw new TypeError("`quantity` must be a non-negative number.");return this.getItemCount(e)>=t}existsItemAt(e){if("number"!=typeof e||!Number.isInteger(e))throw new TypeError("`slotIndex` must be an integer.");return!!this.#r[e]}clear(){this.clearAllItems(),this.clearAllEvents()}clearAllEvents(){this.#i={add:[],remove:[],use:[],set:[]}}clearAllItems(){this.clearItems(),this.clearSpecialItems()}clearItems(){for(let e=this.#r.length-1;e>=0;e--)this.#r[e]&&this.deleteItem(e,!0)}clearSpecialItems(){for(const e of this.#t.keys()){const t=this.#t.get(e);t?.item&&this.deleteSpecialItem(e,!0)}}clone(){const e=this.toObject();return i.fromObject(e)}toObject(){const e={};for(const[t,i]of this.#t.entries())e[t]={type:i?.type??null,item:i?.item?this.#l(i.item):null};return{__schema:"TinyInventory",version:1,maxWeight:this.#a,maxSlots:this.#s,maxSize:this.#o,maxStack:this.#n,items:this.#r.map(e=>e?this.#l(e):null),specialSlots:e}}toJSON(e=0){if("number"!=typeof e||!Number.isFinite(e)||e<0)throw new TypeError("`space` must be a non-negative number.");return JSON.stringify(this.toObject(),null,e)}static fromObject(e){if(!e||"object"!=typeof e)throw new TypeError("Invalid state: expected object.");if("TinyInventory"!==e.__schema||"number"!=typeof e.version)throw new TypeError("Invalid or missing schema header.");if(1!==e.version)throw new TypeError(`Unsupported TinyInventory state version: ${e.version}`);const t={};if(e.specialSlots&&"object"==typeof e.specialSlots)for(const i of Object.keys(e.specialSlots))t[i]={type:e.specialSlots[i]?.type??null};const r=new i({maxWeight:e.maxWeight??null,maxSlots:e.maxSlots??null,maxSize:e.maxSize??null,maxStack:e.maxStack??null,specialSlots:t});if(Array.isArray(e.items))for(const t in e.items){const i=e.items[t];if(null!==i){const e={id:String(i.id),quantity:Math.max(1,Number(i.quantity)||1),metadata:i.metadata&&"object"==typeof i.metadata?i.metadata:{}};r.setItem({slotIndex:Number(t),item:e,forceSpace:!0})}else r.setItem({slotIndex:Number(t),item:null,forceSpace:!0})}if(e.specialSlots&&"object"==typeof e.specialSlots)for(const[t,i]of Object.entries(e.specialSlots)){if(!r.hasSpecialSlot(t))continue;const e=i?.item;if(e&&e.id){const i={id:String(e.id),quantity:Math.max(1,Number(e.quantity)||1),metadata:e.metadata&&"object"==typeof e.metadata?e.metadata:{}};r.setSpecialSlot({slotId:t,item:i,forceSpace:!0})}}return r}static fromJSON(e){if("string"!=typeof e)throw new TypeError("`json` must be a string.");const t=JSON.parse(e);return i.fromObject(t)}}const r=i,n=class{#c=null;#h=null;get sender(){return this.#c}get receiver(){return this.#h}set sender(e){if(!(e instanceof r&&this.receiver instanceof r))throw new Error("Both sender and receiver must be TinyInventory instances.");this.#c=e}set receiver(e){if(!(this.sender instanceof r&&e instanceof r))throw new Error("Both sender and receiver must be TinyInventory instances.");this.#h=e}constructor(e,t){if(e||t){if(!(e instanceof r&&t instanceof r))throw new Error("Both sender and receiver must be TinyInventory instances.");this.connect(e,t)}}connect(e,t){if(!(e instanceof r&&t instanceof r))throw new Error("Both sender and receiver must be TinyInventory instances.");this.#c=e,this.#h=t}disconnect(){this.#c=null,this.#h=null}invert(){const e=this.#c,t=this.#h;this.#c=t,this.#h=e}transferItem({slotIndex:e,specialSlot:t,quantity:i=1,receiverSlotIndex:n,forceSpace:o=!1,strict:s=!1}){if(!this.#c||!this.#h)throw new Error("Sender and receiver inventories must be connected.");let a;if(t){if(a=this.#c.getSpecialItem(t),!a)throw new Error(`No item found in sender special slot '${t}'.`)}else{if("number"!=typeof e)throw new Error("Must provide either slotIndex or specialSlot.");if(a=this.#c.getItemFrom(e),!a)throw new Error(`No item found in sender slot ${e}.`)}if(a.quantity<i)throw new Error(`Sender does not have enough quantity of '${a.id}' to transfer.`);const l={id:a.id,quantity:i,metadata:a.metadata};let m;if(s)if("number"==typeof n){const e=this.#h.existsItemAt(n)?this.#h.getItemFrom(n):null;if(e){if(e.id!==l.id)throw new Error(`Receiver slot ${n} contains a different item.`);const t=r.getItem(e.id).maxStack-e.quantity;if(l.quantity>t)throw new Error(`Strict mode: not enough space in receiver slot ${n}.`)}}else if(this.#h.clone().addItem({itemId:l.id,quantity:l.quantity,metadata:l.metadata,forceSpace:o}).remaining>0)throw new Error("Strict mode: not enough space in receiver inventory.");if("number"==typeof n){const e=this.#h.existsItemAt(n)?this.#h.getItemFrom(n):null;let t=l.quantity;if(e){if(e.id!==l.id)throw new Error(`Receiver slot ${n} contains a different item.`);const i=r.getItem(e.id).maxStack-e.quantity;t=Math.min(i,l.quantity),t>0&&this.#h.setItem({slotIndex:n,item:{...e,quantity:e.quantity+t},forceSpace:o})}else this.#h.setItem({slotIndex:n,item:l,forceSpace:o});m={remaining:l.quantity-t}}else m=this.#h.addItem({itemId:l.id,quantity:l.quantity,metadata:l.metadata,forceSpace:o});const u=l.quantity-m.remaining;if(u>0)if(t)this.#c.unequipItem({slotId:t,quantity:u,forceSpace:o});else if("number"==typeof e){const t=a.quantity-u;this.#c.setItem({slotIndex:e,item:t>0?{...a,quantity:t}:null,forceSpace:o})}return m}transferMultiple(e){return e.map(e=>this.transferItem(e))}};window.TinyInventoryTrader=t.TinyInventoryTrader})();
@@ -1 +1 @@
1
- (()=>{"use strict";var e={d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};function r(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)&&"[object Object]"===Object.prototype.toString.call(e)}e.d(t,{TinyLocalStorage:()=>l});const n=class{#e=new Map;#t=10;#r=!1;setThrowOnMaxListeners(e){if("boolean"!=typeof e)throw new TypeError("setThrowOnMaxListeners(value): value must be a boolean");this.#r=e}getThrowOnMaxListeners(){return this.#r}#n(e,t,{once:r=!1}={}){let n=this.#e.get(e);Array.isArray(n)||(n=[],this.#e.set(e,n)),n.unshift({handler:t,config:{once:r}});const s=this.#t;if(s>0&&n.length>s){const t=`Possible memory leak detected. ${n.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#r)throw new Error(t);console.warn(t)}}prependListener(e,t){if("string"!=typeof e)throw new TypeError("prepend(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("prepend(event, handler): handler must be a function");this.#n(e,t)}prependListenerOnce(e,t){if("string"!=typeof e)throw new TypeError("prependOnceListener(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("prependOnceListener(event, handler): handler must be a function");const r=(...n)=>{this.off(e,r),t(...n)};return this.#n(e,r,{once:!0}),r}#s(e,t,{once:r=!1}={}){let n=this.#e.get(e);Array.isArray(n)||(n=[],this.#e.set(e,n)),n.push({handler:t,config:{once:r}});const s=this.#t;if(s>0&&n.length>s){const t=`Possible memory leak detected. ${n.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#r)throw new Error(t);console.warn(t)}}on(e,t){if("string"!=typeof e)throw new TypeError("on(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("on(event, handler): handler must be a function");return this.#s(e,t)}once(e,t){if("string"!=typeof e)throw new TypeError("The event name must be a string.");if("function"!=typeof t)throw new TypeError("once(event, handler): handler must be a function");const r=n=>{this.off(e,r),"function"==typeof t&&t(n)};return this.#s(e,r,{once:!0}),r}appendListener(e,t){return this.on(e,t)}appendListenerOnce(e,t){return this.once(e,t)}off(e,t){if("string"!=typeof e)throw new TypeError("off(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("off(event, handler): handler must be a function");const r=this.#e.get(e);if(!Array.isArray(r))return;const n=r.findIndex(e=>e.handler===t);-1!==n&&r.splice(n,1),0===r.length&&this.#e.delete(e)}offAll(e){if("string"!=typeof e)throw new TypeError("The event name must be a string.");this.#e.delete(e)}offAllTypes(){this.#e.clear()}listenerCount(e){if("string"!=typeof e)throw new TypeError("listenerCount(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?t.length:0}listeners(e){if("string"!=typeof e)throw new TypeError("listeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].filter(e=>!e.config.once).map(e=>e.handler):[]}onceListeners(e){if("string"!=typeof e)throw new TypeError("onceListeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].filter(e=>e.config.once).map(e=>e.handler):[]}allListeners(e){if("string"!=typeof e)throw new TypeError("allListeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].map(e=>e.handler):[]}eventNames(){return[...this.#e.keys()]}emit(e,...t){if("string"!=typeof e)throw new TypeError("emit(event, data): event name must be a string");const r=this.#e.get(e);return!(!Array.isArray(r)||0===r.length||(r.forEach(e=>e.handler(...t)),0))}setMaxListeners(e){if(!Number.isInteger(e)||e<0)throw new TypeError("setMaxListeners(n): n must be a non-negative integer");this.#t=e}getMaxListeners(){return this.#t}},s=new Map,o=new Map,i=new Set(["string","boolean","number","object","array",String,Boolean,Number,Object,Array,BigInt,Symbol]);class a{#o=new n;setThrowOnMaxListeners(e){return this.#o.setThrowOnMaxListeners(e)}getThrowOnMaxListeners(){return this.#o.getThrowOnMaxListeners()}prependListener(e,t){return this.#o.prependListener(e,t)}prependListenerOnce(e,t){return this.#o.prependListenerOnce(e,t)}appendListener(e,t){return this.#o.appendListener(e,t)}appendListenerOnce(e,t){return this.#o.appendListenerOnce(e,t)}on(e,t){return this.#o.on(e,t)}once(e,t){return this.#o.once(e,t)}off(e,t){return this.#o.off(e,t)}offAll(e){return this.#o.offAll(e)}offAllTypes(){return this.#o.offAllTypes()}listenerCount(e){return this.#o.listenerCount(e)}listeners(e){return this.#o.listeners(e)}onceListeners(e){return this.#o.onceListeners(e)}allListeners(e){return this.#o.allListeners(e)}eventNames(){return this.#o.eventNames()}emit(e,...t){return this.#o.emit(e,...t)}setMaxListeners(e){return this.#o.setMaxListeners(e)}getMaxListeners(){return this.#o.getMaxListeners()}static hasJsonType(e){return s.has(e)&&o.has(e)||i.has(e)}static registerJsonType(e,t,r,n=!1){if(i.has(e))throw new Error(`Cannot register type "${e}" because it is frozen.`);s.set(e,t),o.set(e,r),n&&i.add(e)}static deleteJsonType(e){if(i.has(e))throw new Error(`Cannot remove type "${e}" because it is frozen.`);let t=!1;return s.delete(e)&&(t=!0),o.delete(e)&&(t=!0),t}static encodeSpecialJson(e){if(void 0===e)return{__undefined__:!0};if(null===e)return{__null__:!0};for(const[t,r]of s.entries())if("string"!=typeof t&&e instanceof t||typeof e===t)return r(e,a.encodeSpecialJson);if(Array.isArray(e))return e.map(a.encodeSpecialJson);if(r(e)){const t={};for(const r in e)t[r]=a.encodeSpecialJson(e[r]);return t}return e}static decodeSpecialJson(e){const t=r(e);if(t){if(e.__undefined__)return;if(e.__null__)return null}if(Array.isArray(e))return e.map(a.decodeSpecialJson);if(t){for(const[t,r]of o.entries())if(r.check&&r.check(e))return r.decode(e,a.decodeSpecialJson);const t={};for(const r in e)t[r]=a.decodeSpecialJson(e[r]);return t}return e}#i=window.localStorage;#a=null;#l=0;#c=e=>this.emit("storage",e);constructor(e){if(void 0!==e&&"string"!=typeof e)throw new TypeError("TinyLocalStorage: dbName must be a string if provided.");"string"==typeof e&&(this.#a=`LSDB::${e}`),window.addEventListener("storage",this.#c)}#h(e){if("string"==typeof e&&e.startsWith("LSDB::"))throw new Error(`TinyLocalStorage: Key "${e}" may conflict with reserved dbKeys.`)}updateStorageVersion(e,t){if("string"!=typeof this.#a)throw new Error("TinyLocalStorage: Database key is not initialized. Set a valid dbName in the constructor.");if("number"!=typeof e||Number.isNaN(e)||e<1)throw new TypeError("TinyLocalStorage: version must be a positive number.");if("function"!=typeof t)throw new TypeError("TinyLocalStorage: onUpgrade must be a function.");const r=parseInt(localStorage.getItem(this.#a),10)||0;if("number"!=typeof r||Number.isNaN(r)||r<0)throw new TypeError("TinyLocalStorage: saved version in localStorage is not a valid number.");if(e<r)throw new Error(`TinyLocalStorage: Cannot downgrade database version from ${r} to ${e}.`);e>r&&(t(r,e),localStorage.setItem(this.#a,String(e)),this.#l=e)}getDbKey(){return this.#a}getVersion(){return this.#l}setLocalStorage(e){if(!(e instanceof Storage))throw new TypeError("Argument must be a valid instance of Storage.");this.#i=e}localStorageExists(){return this.#i instanceof Storage}#y(e,t){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return a.encodeSpecialJson(t)}setJson(e,t){if(this.#h(e),!(r(t)||Array.isArray(t)||t instanceof Map||t instanceof Set))throw new TypeError("The storage value is not a valid JSON-compatible structure.");const n=this.#y(e,t);return this.emit("setJson",e,t),this.#i.setItem(e,JSON.stringify(n))}#g(e,t){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");const r=this.#i.getItem(e),n={obj:()=>({}),array:()=>[],map:()=>new Map,set:()=>new Set},s="function"==typeof n[t]?n[t]():null;let o;try{o=JSON.parse(r)}catch{return s}return{decoded:a.decodeSpecialJson(o),fallback:s}}getJson(e,t){const{decoded:n,fallback:s}=this.#g(e,t);return n instanceof Map||n instanceof Set||Array.isArray(n)||r(n)?n:s}setDate(e,t){if(this.#h(e),!(t instanceof Date))throw new TypeError("Value must be a Date.");const r=this.#y(e,t);return this.emit("setDate",e,t),this.#i.setItem(e,JSON.stringify(r))}getDate(e){const t=this.#g(e).decoded;return t instanceof Date?t:null}setRegExp(e,t){if(this.#h(e),!(t instanceof RegExp))throw new TypeError("Value must be a RegExp.");const r=this.#y(e,t);return this.emit("setRegExp",e,t),this.#i.setItem(e,JSON.stringify(r))}getRegExp(e){const t=this.#g(e).decoded;return t instanceof RegExp?t:null}setBigInt(e,t){if(this.#h(e),"bigint"!=typeof t)throw new TypeError("Value must be a BigInt.");const r=this.#y(e,t);return this.emit("setBigInt",e,t),this.#i.setItem(e,JSON.stringify(r))}getBigInt(e){const t=this.#g(e).decoded;return"bigint"==typeof t?t:null}setSymbol(e,t){if(this.#h(e),"symbol"!=typeof t)throw new TypeError("Value must be a Symbol.");const r=this.#y(e,t);return this.emit("setSymbol",e,t),this.#i.setItem(e,JSON.stringify(r))}getSymbol(e){const t=this.#g(e).decoded;return"symbol"==typeof t?t:null}getValue(e){return this.#g(e).decoded??null}setItem(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.emit("setItem",e,t),this.#i.setItem(e,t)}getItem(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.#i.getItem(e)}setString(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");if("string"!=typeof t)throw new TypeError("Value must be a string.");return this.emit("setString",e,t),this.#i.setItem(e,JSON.stringify({__string__:!0,value:t}))}getString(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");let t=this.#i.getItem(e);try{if(t=JSON.parse(t),!r(t)||!t.__string__||"string"!=typeof t.value)return null;t=t.value}catch{t=null}return"string"==typeof t?t:null}setNumber(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");if("number"!=typeof t)throw new TypeError("Value must be a number.");return this.emit("setNumber",e,t),this.#i.setItem(e,String(t))}getNumber(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");let t=this.#i.getItem(e);return"number"==typeof t||"string"==typeof t&&t.length>0&&(t=parseFloat(t),!Number.isNaN(t))?t:null}setBool(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");if("boolean"!=typeof t)throw new TypeError("Value must be a boolean.");return this.emit("setBool",e,t),this.#i.setItem(e,String(t))}getBool(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");const t=this.#i.getItem(e);if("boolean"==typeof t)return t;if("string"==typeof t){if("true"===t)return!0;if("false"===t)return!1}return null}removeItem(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.emit("removeItem",e),this.#i.removeItem(e)}clearLocalStorage(){return this.#i.clear()}destroy(){window.removeEventListener("storage",this.#c),this.#o.offAllTypes()}}a.registerJsonType(Map,(e,t)=>({__map__:!0,data:Array.from(e.entries()).map(([e,r])=>[e,t(r)])}),{check:e=>e.__map__,decode:(e,t)=>new Map(e.data.map(([e,r])=>[e,t(r)]))},!0),a.registerJsonType(Set,(e,t)=>({__set__:!0,data:Array.from(e).map(t)}),{check:e=>e.__set__,decode:(e,t)=>new Set(e.data.map(t))},!0),a.registerJsonType(Date,e=>({__date__:!0,value:e.toISOString()}),{check:e=>e.__date__,decode:e=>new Date(e.value)},!0),a.registerJsonType(RegExp,e=>({__regexp__:!0,source:e.source,flags:e.flags}),{check:e=>e.__regexp__,decode:e=>new RegExp(e.source,e.flags)},!0),a.registerJsonType("bigint",e=>({__bigint__:!0,value:e.toString()}),{check:e=>e.__bigint__,decode:e=>BigInt(e.value)},!0),a.registerJsonType("symbol",e=>({__symbol__:!0,key:Symbol.keyFor(e)??e.description??null}),{check:e=>e.__symbol__,decode:e=>{const t=e.key;return null!=t?Symbol.for(t):Symbol()}},!0);const l=a;window.TinyLocalStorage=t.TinyLocalStorage})();
1
+ (()=>{"use strict";var e={d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};function r(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)&&"[object Object]"===Object.prototype.toString.call(e)}e.d(t,{TinyLocalStorage:()=>l});const n=class{#e=new Map;#t=10;#r=!1;setThrowOnMaxListeners(e){if("boolean"!=typeof e)throw new TypeError("setThrowOnMaxListeners(value): value must be a boolean");this.#r=e}getThrowOnMaxListeners(){return this.#r}#n(e,t,{once:r=!1}={}){let n=this.#e.get(e);Array.isArray(n)||(n=[],this.#e.set(e,n)),n.unshift({handler:t,config:{once:r}});const s=this.#t;if(s>0&&n.length>s){const t=`Possible memory leak detected. ${n.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#r)throw new Error(t);console.warn(t)}}prependListener(e,t){if("string"!=typeof e)throw new TypeError("prepend(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("prepend(event, handler): handler must be a function");this.#n(e,t)}prependListenerOnce(e,t){if("string"!=typeof e)throw new TypeError("prependOnceListener(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("prependOnceListener(event, handler): handler must be a function");const r=(...n)=>{this.off(e,r),t(...n)};return this.#n(e,r,{once:!0}),r}#s(e,t,{once:r=!1}={}){let n=this.#e.get(e);Array.isArray(n)||(n=[],this.#e.set(e,n)),n.push({handler:t,config:{once:r}});const s=this.#t;if(s>0&&n.length>s){const t=`Possible memory leak detected. ${n.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#r)throw new Error(t);console.warn(t)}}on(e,t){if("string"!=typeof e)throw new TypeError("on(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("on(event, handler): handler must be a function");return this.#s(e,t)}once(e,t){if("string"!=typeof e)throw new TypeError("The event name must be a string.");if("function"!=typeof t)throw new TypeError("once(event, handler): handler must be a function");const r=n=>{this.off(e,r),"function"==typeof t&&t(n)};return this.#s(e,r,{once:!0}),r}appendListener(e,t){return this.on(e,t)}appendListenerOnce(e,t){return this.once(e,t)}off(e,t){if("string"!=typeof e)throw new TypeError("off(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("off(event, handler): handler must be a function");const r=this.#e.get(e);if(!Array.isArray(r))return;const n=r.findIndex(e=>e.handler===t);-1!==n&&r.splice(n,1),0===r.length&&this.#e.delete(e)}offAll(e){if("string"!=typeof e)throw new TypeError("The event name must be a string.");this.#e.delete(e)}offAllTypes(){this.#e.clear()}listenerCount(e){if("string"!=typeof e)throw new TypeError("listenerCount(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?t.length:0}listeners(e){if("string"!=typeof e)throw new TypeError("listeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].filter(e=>!e.config.once).map(e=>e.handler):[]}onceListeners(e){if("string"!=typeof e)throw new TypeError("onceListeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].filter(e=>e.config.once).map(e=>e.handler):[]}allListeners(e){if("string"!=typeof e)throw new TypeError("allListeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].map(e=>e.handler):[]}eventNames(){return[...this.#e.keys()]}emit(e,...t){if("string"!=typeof e)throw new TypeError("emit(event, data): event name must be a string");const r=this.#e.get(e);return!(!Array.isArray(r)||0===r.length||(r.forEach(e=>e.handler(...t)),0))}setMaxListeners(e){if(!Number.isInteger(e)||e<0)throw new TypeError("setMaxListeners(n): n must be a non-negative integer");this.#t=e}getMaxListeners(){return this.#t}},s=new Map,o=new Map,i=new Set(["string","boolean","object","array",String,Boolean,Number,Object,Array,BigInt,Symbol]);class a{#o=new n;setThrowOnMaxListeners(e){return this.#o.setThrowOnMaxListeners(e)}getThrowOnMaxListeners(){return this.#o.getThrowOnMaxListeners()}prependListener(e,t){return this.#o.prependListener(e,t)}prependListenerOnce(e,t){return this.#o.prependListenerOnce(e,t)}appendListener(e,t){return this.#o.appendListener(e,t)}appendListenerOnce(e,t){return this.#o.appendListenerOnce(e,t)}on(e,t){return this.#o.on(e,t)}once(e,t){return this.#o.once(e,t)}off(e,t){return this.#o.off(e,t)}offAll(e){return this.#o.offAll(e)}offAllTypes(){return this.#o.offAllTypes()}listenerCount(e){return this.#o.listenerCount(e)}listeners(e){return this.#o.listeners(e)}onceListeners(e){return this.#o.onceListeners(e)}allListeners(e){return this.#o.allListeners(e)}eventNames(){return this.#o.eventNames()}emit(e,...t){return this.#o.emit(e,...t)}setMaxListeners(e){return this.#o.setMaxListeners(e)}getMaxListeners(){return this.#o.getMaxListeners()}static hasJsonType(e){return s.has(e)&&o.has(e)||i.has(e)}static registerJsonType(e,t,r,n=!1){if(i.has(e))throw new Error(`Cannot register type "${e}" because it is frozen.`);s.set(e,t),o.set(e,r),n&&i.add(e)}static deleteJsonType(e){if(i.has(e))throw new Error(`Cannot remove type "${e}" because it is frozen.`);let t=!1;return s.delete(e)&&(t=!0),o.delete(e)&&(t=!0),t}static encodeSpecialJson(e){if(void 0===e)return{__undefined__:!0};if(null===e)return{__null__:!0};for(const[t,r]of s.entries())if("string"!=typeof t&&e instanceof t||typeof e===t)return r(e,a.encodeSpecialJson);if(Array.isArray(e))return e.map(a.encodeSpecialJson);if(r(e)){const t={};for(const r in e)t[r]=a.encodeSpecialJson(e[r]);return t}return e}static decodeSpecialJson(e){const t=r(e);if(t){if(e.__undefined__)return;if(e.__null__)return null}if(Array.isArray(e))return e.map(a.decodeSpecialJson);if(t){for(const[t,r]of o.entries())if(r.check&&r.check(e))return r.decode(e,a.decodeSpecialJson);const t={};for(const r in e)t[r]=a.decodeSpecialJson(e[r]);return t}return e}#i=window.localStorage;#a=null;#l=0;#c=e=>this.emit("storage",e);constructor(e){if(void 0!==e&&"string"!=typeof e)throw new TypeError("TinyLocalStorage: dbName must be a string if provided.");"string"==typeof e&&(this.#a=`LSDB::${e}`),window.addEventListener("storage",this.#c)}#h(e){if("string"==typeof e&&e.startsWith("LSDB::"))throw new Error(`TinyLocalStorage: Key "${e}" may conflict with reserved dbKeys.`)}updateStorageVersion(e,t){if("string"!=typeof this.#a)throw new Error("TinyLocalStorage: Database key is not initialized. Set a valid dbName in the constructor.");if("number"!=typeof e||Number.isNaN(e)||e<1)throw new TypeError("TinyLocalStorage: version must be a positive number.");if("function"!=typeof t)throw new TypeError("TinyLocalStorage: onUpgrade must be a function.");const r=parseInt(localStorage.getItem(this.#a),10)||0;if("number"!=typeof r||Number.isNaN(r)||r<0)throw new TypeError("TinyLocalStorage: saved version in localStorage is not a valid number.");if(e<r)throw new Error(`TinyLocalStorage: Cannot downgrade database version from ${r} to ${e}.`);e>r&&(t(r,e),localStorage.setItem(this.#a,String(e)),this.#l=e)}getDbKey(){return this.#a}getVersion(){return this.#l}setLocalStorage(e){if(!(e instanceof Storage))throw new TypeError("Argument must be a valid instance of Storage.");this.#i=e}localStorageExists(){return this.#i instanceof Storage}#y(e,t){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return a.encodeSpecialJson(t)}setJson(e,t){if(this.#h(e),!(r(t)||Array.isArray(t)||t instanceof Map||t instanceof Set))throw new TypeError("The storage value is not a valid JSON-compatible structure.");const n=this.#y(e,t);return this.emit("setJson",e,t),this.#i.setItem(e,JSON.stringify(n))}#g(e,t){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");const r=this.#i.getItem(e),n={obj:()=>({}),array:()=>[],map:()=>new Map,set:()=>new Set},s="function"==typeof n[t]?n[t]():null;let o;try{o=JSON.parse(r)}catch{return s}return{decoded:a.decodeSpecialJson(o),fallback:s}}getJson(e,t){const{decoded:n,fallback:s}=this.#g(e,t);return n instanceof Map||n instanceof Set||Array.isArray(n)||r(n)?n:s}setDate(e,t){if(this.#h(e),!(t instanceof Date))throw new TypeError("Value must be a Date.");const r=this.#y(e,t);return this.emit("setDate",e,t),this.#i.setItem(e,JSON.stringify(r))}getDate(e){const t=this.#g(e).decoded;return t instanceof Date?t:null}setRegExp(e,t){if(this.#h(e),!(t instanceof RegExp))throw new TypeError("Value must be a RegExp.");const r=this.#y(e,t);return this.emit("setRegExp",e,t),this.#i.setItem(e,JSON.stringify(r))}getRegExp(e){const t=this.#g(e).decoded;return t instanceof RegExp?t:null}setBigInt(e,t){if(this.#h(e),"bigint"!=typeof t)throw new TypeError("Value must be a BigInt.");const r=this.#y(e,t);return this.emit("setBigInt",e,t),this.#i.setItem(e,JSON.stringify(r))}getBigInt(e){const t=this.#g(e).decoded;return"bigint"==typeof t?t:null}setSymbol(e,t){if(this.#h(e),"symbol"!=typeof t)throw new TypeError("Value must be a Symbol.");const r=this.#y(e,t);return this.emit("setSymbol",e,t),this.#i.setItem(e,JSON.stringify(r))}getSymbol(e){const t=this.#g(e).decoded;return"symbol"==typeof t?t:null}getValue(e){return this.#g(e).decoded??null}setItem(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.emit("setItem",e,t),this.#i.setItem(e,t)}getItem(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.#i.getItem(e)}setString(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");if("string"!=typeof t)throw new TypeError("Value must be a string.");return this.emit("setString",e,t),this.#i.setItem(e,JSON.stringify({__string__:!0,value:t}))}getString(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");let t=this.#i.getItem(e);try{if(t=JSON.parse(t),!r(t)||!t.__string__||"string"!=typeof t.value)return null;t=t.value}catch{t=null}return"string"==typeof t?t:null}setNumber(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");if("number"!=typeof t)throw new TypeError("Value must be a number.");return this.emit("setNumber",e,t),this.#i.setItem(e,String(t))}getNumber(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");let t=this.#i.getItem(e);return"number"==typeof t||"string"==typeof t&&t.length>0&&(t=parseFloat(t),!Number.isNaN(t))?t:null}setBool(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");if("boolean"!=typeof t)throw new TypeError("Value must be a boolean.");return this.emit("setBool",e,t),this.#i.setItem(e,String(t))}getBool(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");const t=this.#i.getItem(e);if("boolean"==typeof t)return t;if("string"==typeof t){if("true"===t)return!0;if("false"===t)return!1}return null}removeItem(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.emit("removeItem",e),this.#i.removeItem(e)}clearLocalStorage(){return this.#i.clear()}destroy(){window.removeEventListener("storage",this.#c),this.#o.offAllTypes()}}a.registerJsonType(Map,(e,t)=>({__map__:!0,data:Array.from(e.entries()).map(([e,r])=>[e,t(r)])}),{check:e=>e.__map__,decode:(e,t)=>new Map(e.data.map(([e,r])=>[e,t(r)]))},!0),a.registerJsonType(Set,(e,t)=>({__set__:!0,data:Array.from(e).map(t)}),{check:e=>e.__set__,decode:(e,t)=>new Set(e.data.map(t))},!0),a.registerJsonType(Date,e=>({__date__:!0,value:e.toISOString()}),{check:e=>e.__date__,decode:e=>new Date(e.value)},!0),a.registerJsonType(RegExp,e=>({__regexp__:!0,source:e.source,flags:e.flags}),{check:e=>e.__regexp__,decode:e=>new RegExp(e.source,e.flags)},!0),a.registerJsonType("number",e=>({__number__:!0,value:e.toString()}),{check:e=>e.__number__,decode:e=>Number(e.value)},!0),a.registerJsonType("bigint",e=>({__bigint__:!0,value:e.toString()}),{check:e=>e.__bigint__,decode:e=>BigInt(e.value)},!0),a.registerJsonType("symbol",e=>({__symbol__:!0,key:Symbol.keyFor(e)??e.description??null}),{check:e=>e.__symbol__,decode:e=>{const t=e.key;return null!=t?Symbol.for(t):Symbol()}},!0);const l=a;window.TinyLocalStorage=t.TinyLocalStorage})();
@@ -0,0 +1 @@
1
+ (()=>{"use strict";var t={d:(e,r)=>{for(var i in r)t.o(r,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:r[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{TinyNeedBar:()=>i});class r{#t=new Map;#e;#r;#i;get factors(){const t={};for(let[e,r]of this.#t.entries())t[e]={...r};return t}get currentPercent(){return this.#r/this.#e*100}set maxValue(t){this.#e=t,this.#r=Math.min(this.#r,t)}get maxValue(){return this.#e}get currentValue(){return this.#r}set infiniteValue(t){this.#i=t,this.#r=Math.max(0,t),this.#r=Math.min(this.#r,this.#e)}get infiniteValue(){return this.#i}constructor(t=100,e=1,r=1){this.#e=t,this.setFactor("main",e,r),this.#r=t,this.#i=t}getFactor(t){const e=this.#t.get(t);if(!e)throw new Error(`Factor with key "${t}" not found.`);return{...e}}hasFactor(t){return this.#t.has(t)}setFactor(t,e,r=1){this.#t.set(t,{amount:e,multiplier:r})}removeFactor(t){this.#t.delete(t)}tick(){let t=0;for(let[e,r]of this.#t.entries())t+=r.amount*r.multiplier;const e=this.#i;return this.#i-=t,this.#r=Math.max(0,this.#r-t),{prevValue:e,removedTotal:t,removedPercent:t/this.#e*100,currentPercent:this.currentPercent,remainingValue:this.#r,infiniteRemaining:this.#i}}toJSON(){return{maxValue:this.#e,currentValue:this.#r,infiniteValue:this.#i,factors:this.factors}}static fromJSON(t){const e=new r(t.maxValue,0,0);e.infiniteValue=t.infiniteValue,e.#t.clear();for(const[r,i]of Object.entries(t.factors))e.setFactor(r,i.amount,i.multiplier);return e}clone(){return r.fromJSON(this.toJSON())}clearFactors(){this.#t.clear()}}const i=r;window.TinyNeedBar=e.TinyNeedBar})();
@@ -1 +1 @@
1
- (()=>{"use strict";var e={d:(t,r)=>{for(var i in r)e.o(r,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:r[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{TinyRateLimiter:()=>r});const r=class{#e=null;#t=null;#r=null;#i=null;#s=null;#n=null;groupData=new Map;lastSeen=new Map;userToGroup=new Map;groupFlags=new Map;groupTTL=new Map;#o=null;setOnMemoryExceeded(e){if("function"!=typeof e)throw new Error("onMemoryExceeded must be a function");this.#o=e}clearOnMemoryExceeded(){this.#o=null}#a=null;setOnGroupExpired(e){if("function"!=typeof e)throw new Error("onGroupExpired must be a function");this.#a=e}clearOnGroupExpired(){this.#a=null}constructor({maxHits:e,interval:t,cleanupInterval:r,maxIdle:i=3e5,maxMemory:s=1e5}){const n=e=>"number"==typeof e&&Number.isFinite(e)&&e>=1&&Number.isInteger(e),o=n(e),a=n(t),u=n(r),l=n(i);if(!o&&!a)throw new Error("RateLimiter requires at least one valid option: 'maxHits' or 'interval'.");if(void 0!==e&&!o)throw new Error("'maxHits' must be a positive integer if defined.");if(void 0!==t&&!a)throw new Error("'interval' must be a positive integer in milliseconds if defined.");if(void 0!==r&&!u)throw new Error("'cleanupInterval' must be a positive integer in milliseconds if defined.");if(!l)throw new Error("'maxIdle' must be a positive integer in milliseconds.");if("number"==typeof s&&Number.isFinite(s)&&s>0)this.#e=Math.floor(s);else{if(null!=s)throw new Error("maxMemory must be a positive number or null");this.#e=null}this.#r=o?e:null,this.#i=a?t:null,this.#s=u?r:null,this.#n=i,null!==this.#s&&(this.#t=setInterval(()=>this._cleanup(),this.#s))}isGroupId(e){const t=this.groupFlags.get(e);return"boolean"==typeof t&&t}getUsersInGroup(e){const t=[];for(const[r,i]of this.userToGroup.entries())i===e&&t.push(r);return t}setGroupTTL(e,t){if("number"!=typeof t||!Number.isFinite(t)||t<=0)throw new Error("TTL must be a positive number in milliseconds");this.groupTTL.set(e,t)}getGroupTTL(e){return this.groupTTL.get(e)??null}deleteGroupTTL(e){this.groupTTL.delete(e)}assignToGroup(e,t){const r=this.userToGroup.get(e);if(r&&r!==t)throw new Error(`User ${e} is already assigned to group ${r}`);if(r===t)return;const i=this.groupData.get(e);if(this.isGroupId(e)){for(const[r,i]of this.userToGroup.entries())i===e&&this.userToGroup.set(r,t);this.userToGroup.delete(e)}else this.userToGroup.set(e,t);if(!i)return;const s=this.groupData.get(t);if(s)for(const e of i)s.push(e);else{const e=[];for(const t of i)e.push(t);this.groupData.set(t,e)}this.lastSeen.set(t,Date.now()),this.groupFlags.delete(e),this.groupData.delete(e),this.lastSeen.delete(e),this.groupTTL.delete(e),this.groupFlags.set(t,!0)}getGroupId(e){return this.userToGroup.get(e)||e}hit(e){const t=this.getGroupId(e),r=Date.now();this.groupData.has(t)||(this.groupData.set(t,[]),this.groupFlags.set(t,!1));const i=this.groupData.get(t);if(!i)throw new Error(`No data found for groupId: ${t}`);if(i.push(r),this.lastSeen.set(t,r),null!==this.#i){const e=r-this.getInterval();for(;i.length&&i[0]<e;)i.shift()}null!==this.#e&&"number"==typeof this.#e&&i.length>this.#e&&(i.splice(0,i.length-this.#e),"function"==typeof this.#o&&this.#o(t))}isRateLimited(e){const t=this.getGroupId(e);if(!this.groupData.has(t))return!1;const r=this.groupData.get(t);if(!r)throw new Error(`No data found for groupId: ${t}`);if(null!==this.#i){const e=Date.now()-this.getInterval();let t=0;for(let i=r.length-1;i>=0&&r[i]>e;i--)t++;return null!==this.#r?t>this.getMaxHits():t>0}return null!==this.#r&&r.length>this.getMaxHits()}resetGroup(e){this.groupFlags.delete(e),this.groupData.delete(e),this.lastSeen.delete(e),this.groupTTL.delete(e)}reset(e){return this.resetUserGroup(e)}resetUserGroup(e){this.userToGroup.delete(e)}setData(e,t){if(!Array.isArray(t))throw new Error("timestamps must be an array of numbers.");for(const e of t)if("number"!=typeof e||!Number.isFinite(e))throw new Error("All timestamps must be finite numbers.");this.groupData.has(e)||this.groupFlags.set(e,!1),this.groupData.set(e,t),this.lastSeen.set(e,Date.now())}hasData(e){return this.groupData.has(e)}getData(e){return this.groupData.get(e)||[]}getMaxIdle(){if("number"!=typeof this.#n||!Number.isFinite(this.#n)||this.#n<0)throw new Error("'maxIdle' must be a non-negative finite number.");return this.#n}setMaxIdle(e){if("number"!=typeof e||!Number.isFinite(e)||e<0)throw new Error("'maxIdle' must be a non-negative finite number.");this.#n=e}_cleanup(){const e=Date.now();for(const[t,r]of this.lastSeen.entries())e-r>(this.getGroupTTL(t)??this.getMaxIdle())&&(this.groupFlags.delete(t),this.groupData.delete(t),this.lastSeen.delete(t),this.groupTTL.delete(t),"function"==typeof this.#a&&this.#a(t))}getActiveGroups(){return Array.from(this.groupData.keys())}getAllUserMappings(){return Object.fromEntries(this.userToGroup)}getInterval(){if("number"!=typeof this.#i||!Number.isFinite(this.#i))throw new Error("'interval' is not a valid finite number.");return this.#i}getMaxHits(){if("number"!=typeof this.#r||!Number.isFinite(this.#r))throw new Error("'maxHits' is not a valid finite number.");return this.#r}getTotalHits(e){const t=this.groupData.get(e);return Array.isArray(t)?t.length:0}getLastHit(e){const t=this.groupData.get(e);return t?.length?t[t.length-1]:null}getTimeSinceLastHit(e){const t=this.getLastHit(e);return null!==t?Date.now()-t:null}_calculateAverageSpacing(e){if(!Array.isArray(e)||e.length<2)return null;let t=0;for(let r=1;r<e.length;r++)t+=e[r]-e[r-1];return t/(e.length-1)}getAverageHitSpacing(e){return this._calculateAverageSpacing(this.groupData.get(e))}getMetrics(e){const t=this.groupData.get(e);if(!Array.isArray(t)||0===t.length)return{totalHits:0,lastHit:null,timeSinceLastHit:null,averageHitSpacing:null};const r=t.length,i=t[r-1];return{totalHits:r,lastHit:i,timeSinceLastHit:Date.now()-i,averageHitSpacing:this._calculateAverageSpacing(t)}}destroy(){this.#t&&clearInterval(this.#t),this._cleanup(),this.groupData.clear(),this.lastSeen.clear(),this.userToGroup.clear(),this.groupTTL.clear(),this.groupFlags.clear()}};window.TinyRateLimiter=t.TinyRateLimiter})();
1
+ (()=>{"use strict";var e={d:(t,r)=>{for(var i in r)e.o(r,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:r[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{TinyRateLimiter:()=>r});const r=class{#e=null;#t=null;#r=null;#i=null;#s=null;#n=null;groupData=new Map;lastSeen=new Map;userToGroup=new Map;groupFlags=new Map;groupTTL=new Map;#o=null;setOnMemoryExceeded(e){if("function"!=typeof e)throw new Error("onMemoryExceeded must be a function");this.#o=e}clearOnMemoryExceeded(){this.#o=null}#a=null;setOnGroupExpired(e){if("function"!=typeof e)throw new Error("onGroupExpired must be a function");this.#a=e}clearOnGroupExpired(){this.#a=null}constructor({maxHits:e,interval:t,cleanupInterval:r,maxIdle:i=3e5,maxMemory:s=1e5}){const n=e=>"number"==typeof e&&Number.isFinite(e)&&e>=1&&Number.isInteger(e),o=n(e),a=n(t),u=n(r),l=n(i);if(!o&&!a)throw new Error("RateLimiter requires at least one valid option: 'maxHits' or 'interval'.");if(void 0!==e&&!o)throw new Error("'maxHits' must be a positive integer if defined.");if(void 0!==t&&!a)throw new Error("'interval' must be a positive integer in milliseconds if defined.");if(void 0!==r&&!u)throw new Error("'cleanupInterval' must be a positive integer in milliseconds if defined.");if(!l)throw new Error("'maxIdle' must be a positive integer in milliseconds.");if("number"==typeof s&&Number.isFinite(s)&&s>0)this.#e=Math.floor(s);else{if(null!=s)throw new Error("maxMemory must be a positive number or null");this.#e=null}this.#r=o?e:null,this.#i=a?t:null,this.#s=u?r:null,this.#n=i,null!==this.#s&&(this.#t=setInterval(()=>this._cleanup(),this.#s))}isGroupId(e){const t=this.groupFlags.get(e);return"boolean"==typeof t&&t}getUsersInGroup(e){const t=[];for(const[r,i]of this.userToGroup.entries())i===e&&t.push(r);return t}setGroupTTL(e,t){if("number"!=typeof t||!Number.isFinite(t)||t<=0)throw new Error("TTL must be a positive number in milliseconds");this.groupTTL.set(e,t)}getGroupTTL(e){return this.groupTTL.get(e)??null}deleteGroupTTL(e){this.groupTTL.delete(e)}assignToGroup(e,t){const r=this.userToGroup.get(e);if(r&&r!==t)throw new Error(`User ${e} is already assigned to group ${r}`);if(r===t)return;const i=this.groupData.get(e);if(this.isGroupId(e)){for(const[r,i]of this.userToGroup.entries())i===e&&this.userToGroup.set(r,t);this.userToGroup.delete(e)}else this.userToGroup.set(e,t);if(!i)return;const s=this.groupData.get(t);if(s)for(const e of i)s.push(e);else{const e=[];for(const t of i)e.push(t);this.groupData.set(t,e)}this.lastSeen.set(t,Date.now()),this.groupFlags.delete(e),this.groupData.delete(e),this.lastSeen.delete(e),this.groupTTL.delete(e),this.groupFlags.set(t,!0)}getGroupId(e){return this.userToGroup.get(e)||e}hit(e){const t=this.getGroupId(e),r=Date.now();this.groupData.has(t)||(this.groupData.set(t,[]),this.groupFlags.set(t,!1));const i=this.groupData.get(t);if(!i)throw new Error(`No data found for groupId: ${t}`);if(i.push(r),this.lastSeen.set(t,r),null!==this.#i){const e=r-this.getInterval();for(;i.length&&i[0]<e;)i.shift()}null!==this.#e&&"number"==typeof this.#e&&i.length>this.#e&&(i.splice(0,i.length-this.#e),"function"==typeof this.#o&&this.#o(t))}isRateLimited(e){const t=this.getGroupId(e);if(!this.groupData.has(t))return!1;const r=this.groupData.get(t);if(!r)throw new Error(`No data found for groupId: ${t}`);if(null!==this.#i){const e=Date.now()-this.getInterval();let t=0;for(let i=r.length-1;i>=0&&r[i]>e;i--)t++;return null!==this.#r?t>this.getMaxHits():t>0}return null!==this.#r&&r.length>this.getMaxHits()}resetGroup(e){this.groupFlags.delete(e),this.groupData.delete(e),this.lastSeen.delete(e),this.groupTTL.delete(e)}resetUserGroup(e){this.userToGroup.delete(e)}setData(e,t){if(!Array.isArray(t))throw new Error("timestamps must be an array of numbers.");for(const e of t)if("number"!=typeof e||!Number.isFinite(e))throw new Error("All timestamps must be finite numbers.");this.groupData.has(e)||this.groupFlags.set(e,!1),this.groupData.set(e,t),this.lastSeen.set(e,Date.now())}hasData(e){return this.groupData.has(e)}getData(e){return this.groupData.get(e)||[]}getMaxIdle(){if("number"!=typeof this.#n||!Number.isFinite(this.#n)||this.#n<0)throw new Error("'maxIdle' must be a non-negative finite number.");return this.#n}setMaxIdle(e){if("number"!=typeof e||!Number.isFinite(e)||e<0)throw new Error("'maxIdle' must be a non-negative finite number.");this.#n=e}_cleanup(){const e=Date.now();for(const[t,r]of this.lastSeen.entries())e-r>(this.getGroupTTL(t)??this.getMaxIdle())&&(this.groupFlags.delete(t),this.groupData.delete(t),this.lastSeen.delete(t),this.groupTTL.delete(t),"function"==typeof this.#a&&this.#a(t))}getActiveGroups(){return Array.from(this.groupData.keys())}getAllUserMappings(){return Object.fromEntries(this.userToGroup)}getInterval(){if("number"!=typeof this.#i||!Number.isFinite(this.#i))throw new Error("'interval' is not a valid finite number.");return this.#i}getMaxHits(){if("number"!=typeof this.#r||!Number.isFinite(this.#r))throw new Error("'maxHits' is not a valid finite number.");return this.#r}getTotalHits(e){const t=this.groupData.get(e);return Array.isArray(t)?t.length:0}getLastHit(e){const t=this.groupData.get(e);return t?.length?t[t.length-1]:null}getTimeSinceLastHit(e){const t=this.getLastHit(e);return null!==t?Date.now()-t:null}_calculateAverageSpacing(e){if(!Array.isArray(e)||e.length<2)return null;let t=0;for(let r=1;r<e.length;r++)t+=e[r]-e[r-1];return t/(e.length-1)}getAverageHitSpacing(e){return this._calculateAverageSpacing(this.groupData.get(e))}getMetrics(e){const t=this.groupData.get(e);if(!Array.isArray(t)||0===t.length)return{totalHits:0,lastHit:null,timeSinceLastHit:null,averageHitSpacing:null};const r=t.length,i=t[r-1];return{totalHits:r,lastHit:i,timeSinceLastHit:Date.now()-i,averageHitSpacing:this._calculateAverageSpacing(t)}}destroy(){this.#t&&clearInterval(this.#t),this._cleanup(),this.groupData.clear(),this.lastSeen.clear(),this.userToGroup.clear(),this.groupTTL.clear(),this.groupFlags.clear()}};window.TinyRateLimiter=t.TinyRateLimiter})();