tiny-essentials 1.26.4 → 1.27.0

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 (120) hide show
  1. package/.github/workflows/node.js.yml +1 -1
  2. package/README.md +0 -1
  3. package/changelog/1/27/0.md +24 -0
  4. package/dist/v1/ColorSafeStringify.min.js +1 -1
  5. package/dist/v1/TinyAdvancedRaffle.min.js +1 -1
  6. package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
  7. package/dist/v1/TinyAnalogClock.min.js +1 -1
  8. package/dist/v1/TinyArrayComparator.min.js +1 -1
  9. package/dist/v1/TinyArrayPaginator.min.js +1 -1
  10. package/dist/v1/TinyBasicsEs.min.js +1 -1
  11. package/dist/v1/TinyClassManager.min.js +1 -1
  12. package/dist/v1/TinyClipboard.min.js +1 -1
  13. package/dist/v1/TinyColorConverter.min.js +1 -1
  14. package/dist/v1/TinyColorValidator.min.js +1 -1
  15. package/dist/v1/TinyCookieConsent.min.js +1 -1
  16. package/dist/v1/TinyDayNightCycle.min.js +1 -1
  17. package/dist/v1/TinyDomReadyManager.min.js +1 -1
  18. package/dist/v1/TinyDragDropDetector.min.js +1 -1
  19. package/dist/v1/TinyDragger.min.js +1 -1
  20. package/dist/v1/TinyElementObserver.min.js +1 -1
  21. package/dist/v1/TinyEssentials.min.js +1 -1
  22. package/dist/v1/TinyEvents.min.js +1 -1
  23. package/dist/v1/TinyGamepad.min.js +1 -1
  24. package/dist/v1/TinyHtml.min.js +1 -1
  25. package/dist/v1/TinyI18.min.js +1 -1
  26. package/dist/v1/TinyIframeEvents.min.js +1 -1
  27. package/dist/v1/TinyInventory.min.js +1 -1
  28. package/dist/v1/TinyInventoryTrader.min.js +1 -1
  29. package/dist/v1/TinyLevelUp.min.js +1 -1
  30. package/dist/v1/TinyLoadingScreen.min.js +1 -1
  31. package/dist/v1/TinyLocalStorage.min.js +1 -1
  32. package/dist/v1/TinyMaInSys.min.js +1 -1
  33. package/dist/v1/TinyMediaPlayer.min.js +1 -0
  34. package/dist/v1/TinyNeedBar.min.js +1 -1
  35. package/dist/v1/TinyNewWinEvents.min.js +1 -1
  36. package/dist/v1/TinyNotifications.min.js +1 -1
  37. package/dist/v1/TinyNotifyCenter.min.js +1 -1
  38. package/dist/v1/TinyPromiseQueue.min.js +1 -1
  39. package/dist/v1/TinyRadioFm.min.js +1 -0
  40. package/dist/v1/TinyRateLimiter.min.js +1 -1
  41. package/dist/v1/TinySimpleDice.min.js +1 -1
  42. package/dist/v1/TinySmartScroller.min.js +1 -1
  43. package/dist/v1/TinyTextDiffer.min.js +1 -1
  44. package/dist/v1/TinyTextRangeEditor.min.js +1 -1
  45. package/dist/v1/TinyTextarea.min.js +1 -1
  46. package/dist/v1/TinyTimeout.min.js +1 -1
  47. package/dist/v1/TinyToastNotify.min.js +1 -1
  48. package/dist/v1/TinyUploadClicker.min.js +1 -1
  49. package/dist/v1/UltraRandomMsgGen.min.js +1 -1
  50. package/dist/v1/basics/index.cjs +5 -0
  51. package/dist/v1/basics/index.d.mts +5 -1
  52. package/dist/v1/basics/index.mjs +2 -1
  53. package/dist/v1/basics/mediaContent.cjs +644 -0
  54. package/dist/v1/basics/mediaContent.d.mts +296 -0
  55. package/dist/v1/basics/mediaContent.mjs +557 -0
  56. package/dist/v1/build/TinyMediaPlayer.cjs +7 -0
  57. package/dist/v1/build/TinyMediaPlayer.d.mts +3 -0
  58. package/dist/v1/build/TinyMediaPlayer.mjs +2 -0
  59. package/dist/v1/build/TinyRadioFm.cjs +7 -0
  60. package/dist/v1/build/TinyRadioFm.d.mts +3 -0
  61. package/dist/v1/build/TinyRadioFm.mjs +2 -0
  62. package/dist/v1/index.cjs +9 -0
  63. package/dist/v1/index.d.mts +7 -1
  64. package/dist/v1/index.mjs +5 -2
  65. package/dist/v1/libs/ColorSafeStringify.d.mts +1 -1
  66. package/dist/v1/libs/TinyAfterScrollWatcher.cjs +16 -3
  67. package/dist/v1/libs/TinyAfterScrollWatcher.d.mts +7 -3
  68. package/dist/v1/libs/TinyAfterScrollWatcher.mjs +13 -3
  69. package/dist/v1/libs/TinyArrayComparator.cjs +14 -11
  70. package/dist/v1/libs/TinyArrayComparator.d.mts +22 -19
  71. package/dist/v1/libs/TinyArrayComparator.mjs +14 -11
  72. package/dist/v1/libs/TinyArrayPaginator.cjs +23 -16
  73. package/dist/v1/libs/TinyArrayPaginator.d.mts +57 -30
  74. package/dist/v1/libs/TinyArrayPaginator.mjs +22 -16
  75. package/dist/v1/libs/TinyClassManager/TinyPluginInliner.cjs +265 -0
  76. package/dist/v1/libs/TinyClassManager/TinyPluginInliner.d.mts +92 -0
  77. package/dist/v1/libs/TinyClassManager/TinyPluginInliner.mjs +223 -0
  78. package/dist/v1/libs/TinyClassManager.cjs +52 -22
  79. package/dist/v1/libs/TinyClassManager.d.mts +26 -16
  80. package/dist/v1/libs/TinyClassManager.mjs +50 -21
  81. package/dist/v1/libs/TinyColorValidator.d.mts +16 -16
  82. package/dist/v1/libs/TinyDragDropDetector.cjs +9 -34
  83. package/dist/v1/libs/TinyDragDropDetector.d.mts +7 -21
  84. package/dist/v1/libs/TinyDragDropDetector.mjs +9 -24
  85. package/dist/v1/libs/TinyDragger.cjs +5 -5
  86. package/dist/v1/libs/TinyDragger.d.mts +4 -3
  87. package/dist/v1/libs/TinyDragger.mjs +5 -5
  88. package/dist/v1/libs/TinyElementObserver.cjs +6 -21
  89. package/dist/v1/libs/TinyElementObserver.d.mts +6 -15
  90. package/dist/v1/libs/TinyElementObserver.mjs +6 -20
  91. package/dist/v1/libs/TinyGamepad.cjs +4 -6
  92. package/dist/v1/libs/TinyGamepad.d.mts +1 -1
  93. package/dist/v1/libs/TinyHtml/TinyHtmlIcon.d.mts +1 -1
  94. package/dist/v1/libs/TinyHtml/TinyHtmlTemplate.d.mts +1 -1
  95. package/dist/v1/libs/TinyHtml/TinyHtmlTextarea.d.mts +1 -1
  96. package/dist/v1/libs/TinyHtml/index.d.mts +1 -1
  97. package/dist/v1/libs/TinyHtml.cjs +72 -98
  98. package/dist/v1/libs/TinyHtml.d.mts +15 -32
  99. package/dist/v1/libs/TinyHtml.mjs +53 -77
  100. package/dist/v1/libs/TinyInventory.d.mts +1 -1
  101. package/dist/v1/libs/TinyMediaPlayer.cjs +844 -0
  102. package/dist/v1/libs/TinyMediaPlayer.d.mts +306 -0
  103. package/dist/v1/libs/TinyMediaPlayer.mjs +755 -0
  104. package/dist/v1/libs/TinyRadioFm.cjs +1378 -0
  105. package/dist/v1/libs/TinyRadioFm.d.mts +554 -0
  106. package/dist/v1/libs/TinyRadioFm.mjs +1137 -0
  107. package/dist/v1/libs/TinySmartScroller.cjs +39 -26
  108. package/dist/v1/libs/TinySmartScroller.d.mts +16 -62
  109. package/dist/v1/libs/TinySmartScroller.mjs +35 -26
  110. package/dist/v1/libs/UltraRandomMsgGen.d.mts +7 -7
  111. package/docs/v1/README.md +6 -0
  112. package/docs/v1/basics/mediaContent.md +131 -0
  113. package/docs/v1/libs/TinyClassManager/TinyPluginInliner.md +107 -0
  114. package/docs/v1/libs/TinyDragDropDetector.md +5 -9
  115. package/docs/v1/libs/TinyElementObserver.md +3 -6
  116. package/docs/v1/libs/TinyHtml.md +0 -29
  117. package/docs/v1/libs/TinyMediaPlayer.md +100 -0
  118. package/docs/v1/libs/TinyRadioFm.md +141 -0
  119. package/docs/v1/libs/TinySmartScroller.md +3 -3
  120. package/package.json +40 -22
@@ -1 +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})();
1
+ (()=>{"use strict";const t={d:(e,i)=>{if(Array.isArray(i))for(var r=0;r<i.length;){var o=i[r++],n=i[r++];t.o(e,o)?0===n&&r++:0===n?Object.defineProperty(e,o,{enumerable:!0,value:i[r++]}):Object.defineProperty(e,o,{enumerable:!0,get:n})}else for(var o in i)t.o(i,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:i[o]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)};let 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})();
@@ -1 +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
+ (()=>{"use strict";const e={d:(t,i)=>{if(Array.isArray(i))for(var r=0;r<i.length;){var n=i[r++],o=i[r++];e.o(t,n)?0===o&&r++:0===o?Object.defineProperty(t,n,{enumerable:!0,value:i[r++]}):Object.defineProperty(t,n,{enumerable:!0,get:o})}else for(var n in i)e.o(i,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:i[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};let 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:(r,t)=>{for(var a in t)e.o(t,a)&&!e.o(r,a)&&Object.defineProperty(r,a,{enumerable:!0,get:t[a]})},o:(e,r)=>Object.prototype.hasOwnProperty.call(e,r)},r={};e.d(r,{TinyLevelUp:()=>t});const t=class{constructor(e,r){if("number"!=typeof e||Number.isNaN(e))throw new Error("giveExp must be a valid number");if("number"!=typeof r||Number.isNaN(r))throw new Error("expLevel must be a valid number");this.giveExp=e,this.expLevel=r}createUser(){return{exp:0,level:1,totalExp:0}}validateUser(e){if("number"!=typeof e.exp||Number.isNaN(e.exp))throw new Error("exp must be a valid number");if("number"!=typeof e.level||Number.isNaN(e.level))throw new Error("level must be a valid number");if(e.level<1)throw new Error("level must be at least 1");if("number"!=typeof e.totalExp||Number.isNaN(e.totalExp))throw new Error("totalExp must be a valid number")}isValidUser(e){return!("number"!=typeof e.exp||Number.isNaN(e.exp)||"number"!=typeof e.level||Number.isNaN(e.level)||e.level<1||"number"!=typeof e.totalExp||Number.isNaN(e.totalExp))}getGiveExpBase(){if("number"!=typeof this.giveExp||Number.isNaN(this.giveExp))throw new Error("giveExp must be a valid number");return this.giveExp}getExpLevelBase(){if("number"!=typeof this.expLevel||Number.isNaN(this.expLevel))throw new Error("expLevel must be a valid number");return this.expLevel}expValidator(e){const r=this.getExpLevelBase();this.validateUser(e);let t=0;const a=r*e.level;return e.exp>=a&&(e.level++,t=e.exp-a,e.exp=0,t>0)?this.give(e,t,"extra"):e.exp<1&&e.level>1&&(e.level--,t=Math.abs(e.exp),e.exp=r*e.level,t>0)?this.remove(e,t,"extra"):e}getTotalExp(e){this.validateUser(e);let r=0;for(let t=1;t<=e.level;t++)r+=this.getExpLevelBase()*t;return r+=e.exp,r}expGenerator(e=1){if("number"!=typeof e||Number.isNaN(e))throw new Error("multi must be a valid number");return Math.floor(Math.random()*this.getGiveExpBase())*e}getMissingExp(e){return this.getProgress(e)-e.exp}progress(e){return this.getProgress(e)}getProgress(e){return this.validateUser(e),this.getExpLevelBase()*e.level}set(e,r){if("number"!=typeof r||Number.isNaN(r))throw new Error("value must be a valid number");return e.exp=r,this.expValidator(e),e.totalExp=this.getTotalExp(e),e}give(e,r=0,t="add",a=1){if("number"!=typeof a||Number.isNaN(a))throw new Error("multi must be a valid number");if("number"!=typeof r||Number.isNaN(r))throw new Error("extraExp must be a valid number");if("string"!=typeof t)throw new Error("type must be a valid string");return"add"===t?e.exp+=this.expGenerator(a)+r:"extra"===t&&(e.exp+=r),this.expValidator(e),e.totalExp=this.getTotalExp(e),e}remove(e,r=0,t="add",a=1){if("number"!=typeof a||Number.isNaN(a))throw new Error("multi must be a valid number");if("number"!=typeof r||Number.isNaN(r))throw new Error("extraExp must be a valid number");if("string"!=typeof t)throw new Error("type must be a valid string");return"add"===t?e.exp-=this.expGenerator(a)+r:"extra"===t&&(e.exp-=r),this.expValidator(e),e.totalExp=this.getTotalExp(e),e}};window.TinyLevelUp=r.TinyLevelUp})();
1
+ (()=>{"use strict";const e={d:(r,t)=>{if(Array.isArray(t))for(var a=0;a<t.length;){var i=t[a++],l=t[a++];e.o(r,i)?0===l&&a++:0===l?Object.defineProperty(r,i,{enumerable:!0,value:t[a++]}):Object.defineProperty(r,i,{enumerable:!0,get:l})}else for(var i in t)e.o(t,i)&&!e.o(r,i)&&Object.defineProperty(r,i,{enumerable:!0,get:t[i]})},o:(e,r)=>Object.prototype.hasOwnProperty.call(e,r)};let r={};e.d(r,{TinyLevelUp:()=>t});const t=class{constructor(e,r){if("number"!=typeof e||Number.isNaN(e))throw new Error("giveExp must be a valid number");if("number"!=typeof r||Number.isNaN(r))throw new Error("expLevel must be a valid number");this.giveExp=e,this.expLevel=r}createUser(){return{exp:0,level:1,totalExp:0}}validateUser(e){if("number"!=typeof e.exp||Number.isNaN(e.exp))throw new Error("exp must be a valid number");if("number"!=typeof e.level||Number.isNaN(e.level))throw new Error("level must be a valid number");if(e.level<1)throw new Error("level must be at least 1");if("number"!=typeof e.totalExp||Number.isNaN(e.totalExp))throw new Error("totalExp must be a valid number")}isValidUser(e){return!("number"!=typeof e.exp||Number.isNaN(e.exp)||"number"!=typeof e.level||Number.isNaN(e.level)||e.level<1||"number"!=typeof e.totalExp||Number.isNaN(e.totalExp))}getGiveExpBase(){if("number"!=typeof this.giveExp||Number.isNaN(this.giveExp))throw new Error("giveExp must be a valid number");return this.giveExp}getExpLevelBase(){if("number"!=typeof this.expLevel||Number.isNaN(this.expLevel))throw new Error("expLevel must be a valid number");return this.expLevel}expValidator(e){const r=this.getExpLevelBase();this.validateUser(e);let t=0;const a=r*e.level;return e.exp>=a&&(e.level++,t=e.exp-a,e.exp=0,t>0)?this.give(e,t,"extra"):e.exp<1&&e.level>1&&(e.level--,t=Math.abs(e.exp),e.exp=r*e.level,t>0)?this.remove(e,t,"extra"):e}getTotalExp(e){this.validateUser(e);let r=0;for(let t=1;t<=e.level;t++)r+=this.getExpLevelBase()*t;return r+=e.exp,r}expGenerator(e=1){if("number"!=typeof e||Number.isNaN(e))throw new Error("multi must be a valid number");return Math.floor(Math.random()*this.getGiveExpBase())*e}getMissingExp(e){return this.getProgress(e)-e.exp}progress(e){return this.getProgress(e)}getProgress(e){return this.validateUser(e),this.getExpLevelBase()*e.level}set(e,r){if("number"!=typeof r||Number.isNaN(r))throw new Error("value must be a valid number");return e.exp=r,this.expValidator(e),e.totalExp=this.getTotalExp(e),e}give(e,r=0,t="add",a=1){if("number"!=typeof a||Number.isNaN(a))throw new Error("multi must be a valid number");if("number"!=typeof r||Number.isNaN(r))throw new Error("extraExp must be a valid number");if("string"!=typeof t)throw new Error("type must be a valid string");return"add"===t?e.exp+=this.expGenerator(a)+r:"extra"===t&&(e.exp+=r),this.expValidator(e),e.totalExp=this.getTotalExp(e),e}remove(e,r=0,t="add",a=1){if("number"!=typeof a||Number.isNaN(a))throw new Error("multi must be a valid number");if("number"!=typeof r||Number.isNaN(r))throw new Error("extraExp must be a valid number");if("string"!=typeof t)throw new Error("type must be a valid string");return"add"===t?e.exp-=this.expGenerator(a)+r:"extra"===t&&(e.exp-=r),this.expValidator(e),e.totalExp=this.getTotalExp(e),e}};window.TinyLevelUp=r.TinyLevelUp})();
@@ -1 +1 @@
1
- (()=>{"use strict";var e={d:(t,s)=>{for(var n in s)e.o(s,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:s[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{TinyLoadingScreen:()=>s});const s=class{#e=null;get overlay(){return this.#e}#t=null;get messageElement(){return this.#t}#s;get container(){return this.#s}#n={fadeIn:null,fadeOut:null,zIndex:9999};get options(){return{...this.#n}}set options(e){if("object"!=typeof e||null===e)throw new TypeError("options must be an object");if(void 0!==e.fadeIn&&null!==e.fadeIn&&("number"!=typeof e.fadeIn||e.fadeIn<0))throw new TypeError("fadeIn must be a non-negative number or null");if(void 0!==e.fadeOut&&null!==e.fadeOut&&("number"!=typeof e.fadeOut||e.fadeOut<0))throw new TypeError("fadeOut must be a non-negative number or null");if(void 0!==e.zIndex&&("number"!=typeof e.zIndex||!Number.isInteger(e.zIndex)))throw new TypeError("zIndex must be an integer number");this.#n={fadeIn:e.fadeIn??null,fadeOut:e.fadeOut??null,zIndex:e.zIndex??9999}}#a="none";get status(){return this.#a}#i="";get defaultMessage(){return this.#i}set defaultMessage(e){if("string"!=typeof e&&!(e instanceof HTMLElement))throw new TypeError("defaultMessage must be a string or an HTMLElement");this.#i=e}#o=null;get message(){return this.#o}#l=!1;get allowHtmlText(){return this.#l}set allowHtmlText(e){if("boolean"!=typeof e)throw new TypeError("allowHtmlText must be a boolean");this.#l=e}#r=null;get fadeInTimeout(){return null!==this.#r}#u=null;get fadeOutTimeout(){return null!==this.#u}get visible(){return!!this.#e}#d=null;get onChange(){return this.#d}set onChange(e){if(null!==e&&"function"!=typeof e)throw new TypeError("onChange must be a function or null");this.#d=e}_emitChange(){"function"==typeof this.#d&&this.#d(this.#a)}constructor(e=document.body){if(!(e instanceof HTMLElement))throw new TypeError("container must be an HTMLElement");this.#s=e}_updateMessage(e=this.#i){if(!this.#t)throw new Error("messageElement is not initialized");if("string"!=typeof e&&!(e instanceof HTMLElement))throw new TypeError("message must be a string or an HTMLElement");if(this.#o=e,"string"==typeof e)this.#l?this.#t.innerHTML=e:this.#t.textContent=e;else{if(!this.#l)throw new Error("HTMLElement messages require allowHtmlText = true");this.#t.textContent="",this.#t.appendChild(e)}}_removeOldClasses(){this.#e?.classList.remove("active"),this.#e?.classList.remove("fadeIn"),this.#e?.classList.remove("fadeOut")}start(e=this.#i){if("string"!=typeof e&&!(e instanceof HTMLElement))throw new TypeError("message must be a string or an HTMLElement");if(!this.#e){this.#e=document.createElement("div"),this.#e.classList.add("loading-overlay"),this.#e.style.zIndex=String(this.#n.zIndex);const t=document.createElement("div");t.classList.add("loading-container");const s=document.createElement("div");s.classList.add("loading-content");const n=document.createElement("div");n.classList.add("loading-spinner"),this.#t=document.createElement("div"),this.#t.classList.add("loading-message"),s.appendChild(n),s.appendChild(this.#t),t.appendChild(s),this.#e.appendChild(t),this.#s.appendChild(this.#e),this._removeOldClasses(),this.#a="fadeIn",this.#e.classList.add("fadeIn"),this._emitChange();const a=()=>{this._removeOldClasses(),this.#r=null,this.#a="active",this.#e?.classList.add("active"),this._emitChange()};return"number"==typeof this.#n.fadeIn?(this.#r&&clearTimeout(this.#r),this.#r=setTimeout(a,this.#n.fadeIn)):a(),this._updateMessage(e),!0}return this.#t&&this._updateMessage(e),!1}update(e=this.#i){if("string"!=typeof e&&!(e instanceof HTMLElement))throw new TypeError("message must be a string or an HTMLElement");return!!this.#t&&(this._updateMessage(e),!0)}stop(){if(this.#e){this._removeOldClasses(),this.#a="fadeOut",this.#e.classList.add("fadeOut"),this._emitChange();const e=()=>{this._removeOldClasses(),this.#u=null,this.#a="none",this.#e?.remove(),this.#e=null,this.#t=null,this.#o=null,this._emitChange()};return"number"==typeof this.#n.fadeOut?(this.#u&&clearTimeout(this.#u),this.#u=setTimeout(e,this.#n.fadeOut)):e(),!0}return!1}};window.TinyLoadingScreen=t.TinyLoadingScreen})();
1
+ (()=>{"use strict";const e={d:(t,s)=>{if(Array.isArray(s))for(var n=0;n<s.length;){var a=s[n++],i=s[n++];e.o(t,a)?0===i&&n++:0===i?Object.defineProperty(t,a,{enumerable:!0,value:s[n++]}):Object.defineProperty(t,a,{enumerable:!0,get:i})}else for(var a in s)e.o(s,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:s[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};let t={};e.d(t,{TinyLoadingScreen:()=>s});const s=class{#e=null;get overlay(){return this.#e}#t=null;get messageElement(){return this.#t}#s;get container(){return this.#s}#n={fadeIn:null,fadeOut:null,zIndex:9999};get options(){return{...this.#n}}set options(e){if("object"!=typeof e||null===e)throw new TypeError("options must be an object");if(void 0!==e.fadeIn&&null!==e.fadeIn&&("number"!=typeof e.fadeIn||e.fadeIn<0))throw new TypeError("fadeIn must be a non-negative number or null");if(void 0!==e.fadeOut&&null!==e.fadeOut&&("number"!=typeof e.fadeOut||e.fadeOut<0))throw new TypeError("fadeOut must be a non-negative number or null");if(void 0!==e.zIndex&&("number"!=typeof e.zIndex||!Number.isInteger(e.zIndex)))throw new TypeError("zIndex must be an integer number");this.#n={fadeIn:e.fadeIn??null,fadeOut:e.fadeOut??null,zIndex:e.zIndex??9999}}#a="none";get status(){return this.#a}#i="";get defaultMessage(){return this.#i}set defaultMessage(e){if("string"!=typeof e&&!(e instanceof HTMLElement))throw new TypeError("defaultMessage must be a string or an HTMLElement");this.#i=e}#o=null;get message(){return this.#o}#r=!1;get allowHtmlText(){return this.#r}set allowHtmlText(e){if("boolean"!=typeof e)throw new TypeError("allowHtmlText must be a boolean");this.#r=e}#l=null;get fadeInTimeout(){return null!==this.#l}#u=null;get fadeOutTimeout(){return null!==this.#u}get visible(){return!!this.#e}#d=null;get onChange(){return this.#d}set onChange(e){if(null!==e&&"function"!=typeof e)throw new TypeError("onChange must be a function or null");this.#d=e}_emitChange(){"function"==typeof this.#d&&this.#d(this.#a)}constructor(e=document.body){if(!(e instanceof HTMLElement))throw new TypeError("container must be an HTMLElement");this.#s=e}_updateMessage(e=this.#i){if(!this.#t)throw new Error("messageElement is not initialized");if("string"!=typeof e&&!(e instanceof HTMLElement))throw new TypeError("message must be a string or an HTMLElement");if(this.#o=e,"string"==typeof e)this.#r?this.#t.innerHTML=e:this.#t.textContent=e;else{if(!this.#r)throw new Error("HTMLElement messages require allowHtmlText = true");this.#t.textContent="",this.#t.appendChild(e)}}_removeOldClasses(){this.#e?.classList.remove("active"),this.#e?.classList.remove("fadeIn"),this.#e?.classList.remove("fadeOut")}start(e=this.#i){if("string"!=typeof e&&!(e instanceof HTMLElement))throw new TypeError("message must be a string or an HTMLElement");if(!this.#e){this.#e=document.createElement("div"),this.#e.classList.add("loading-overlay"),this.#e.style.zIndex=String(this.#n.zIndex);const t=document.createElement("div");t.classList.add("loading-container");const s=document.createElement("div");s.classList.add("loading-content");const n=document.createElement("div");n.classList.add("loading-spinner"),this.#t=document.createElement("div"),this.#t.classList.add("loading-message"),s.appendChild(n),s.appendChild(this.#t),t.appendChild(s),this.#e.appendChild(t),this.#s.appendChild(this.#e),this._removeOldClasses(),this.#a="fadeIn",this.#e.classList.add("fadeIn"),this._emitChange();const a=()=>{this._removeOldClasses(),this.#l=null,this.#a="active",this.#e?.classList.add("active"),this._emitChange()};return"number"==typeof this.#n.fadeIn?(this.#l&&clearTimeout(this.#l),this.#l=setTimeout(a,this.#n.fadeIn)):a(),this._updateMessage(e),!0}return this.#t&&this._updateMessage(e),!1}update(e=this.#i){if("string"!=typeof e&&!(e instanceof HTMLElement))throw new TypeError("message must be a string or an HTMLElement");return!!this.#t&&(this._updateMessage(e),!0)}stop(){if(this.#e){this._removeOldClasses(),this.#a="fadeOut",this.#e.classList.add("fadeOut"),this._emitChange();const e=()=>{this._removeOldClasses(),this.#u=null,this.#a="none",this.#e?.remove(),this.#e=null,this.#t=null,this.#o=null,this._emitChange()};return"number"==typeof this.#n.fadeOut?(this.#u&&clearTimeout(this.#u),this.#u=setTimeout(e,this.#n.fadeOut)):e(),!0}return!1}};window.TinyLoadingScreen=t.TinyLoadingScreen})();
@@ -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;#n(e,t){if("string"==typeof e)return[e];if(Array.isArray(e)&&e.every(e=>"string"==typeof e))return e;throw new TypeError(`${t}(event): event must be a string or string[]`)}setThrowOnMaxListeners(e){if("boolean"!=typeof e)throw new TypeError("setThrowOnMaxListeners(value): value must be a boolean");this.#r=e}getThrowOnMaxListeners(){return this.#r}#s(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){const r=this.#n(e,"prependListener");if("function"!=typeof t)throw new TypeError("prependListener(event, handler): handler must be a function");for(const e of r)this.#s(e,t)}prependListenerOnce(e,t){const r=this.#n(e,"prependListenerOnce");if("function"!=typeof t)throw new TypeError("prependListenerOnce(event, handler): handler must be a function");const n=[];for(const e of r){const r=(...n)=>{this.off(e,r),t(...n)};this.#s(e,r,{once:!0}),n.push(r)}return n}#o(e,t,{once:r=!1}={}){const n=this.#n(e,"on");for(const e of n){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("function"!=typeof t)throw new TypeError("on(event, handler): handler must be a function");return this.#o(e,t)}once(e,t){const r=this.#n(e,"once");if("function"!=typeof t)throw new TypeError("once(event, handler): handler must be a function");const n=[];for(const e of r){const r=(...n)=>{this.off(e,r),t(...n)};this.#o(e,r,{once:!0}),n.push(r)}return n}appendListener(e,t){return this.on(e,t)}appendListenerOnce(e,t){return this.once(e,t)}off(e,t){const r=this.#n(e,"off");if("function"!=typeof t)throw new TypeError("off(event, handler): handler must be a function");for(const e of r){const r=this.#e.get(e);if(!Array.isArray(r))continue;const n=r.findIndex(e=>e.handler===t);-1!==n&&r.splice(n,1),0===r.length&&this.#e.delete(e)}}offAll(e){const t=this.#n(e,"offAll");for(const e of t)this.#e.delete(e)}offAllTypes(){this.#e.clear()}removeAllListeners(){return this.offAllTypes()}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){const r=this.#n(e,"emit"),n=[];for(const e of r){const r=this.#e.get(e);Array.isArray(r)&&0!==r.length?(r.forEach(e=>e.handler(...t)),n.push(!0)):n.push(!1)}return n}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{#i=new n;setThrowOnMaxListeners(e){return this.#i.setThrowOnMaxListeners(e)}getThrowOnMaxListeners(){return this.#i.getThrowOnMaxListeners()}prependListener(e,t){return this.#i.prependListener(e,t)}prependListenerOnce(e,t){return this.#i.prependListenerOnce(e,t)}appendListener(e,t){return this.#i.appendListener(e,t)}appendListenerOnce(e,t){return this.#i.appendListenerOnce(e,t)}on(e,t){return this.#i.on(e,t)}once(e,t){return this.#i.once(e,t)}off(e,t){return this.#i.off(e,t)}offAll(e){return this.#i.offAll(e)}offAllTypes(){return this.#i.offAllTypes()}listenerCount(e){return this.#i.listenerCount(e)}listeners(e){return this.#i.listeners(e)}onceListeners(e){return this.#i.onceListeners(e)}allListeners(e){return this.#i.allListeners(e)}eventNames(){return this.#i.eventNames()}emit(e,...t){return this.#i.emit(e,...t)}setMaxListeners(e){return this.#i.setMaxListeners(e)}getMaxListeners(){return this.#i.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}#a=window.localStorage;#l=null;#c=0;#h=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.#l=`LSDB::${e}`),window.addEventListener("storage",this.#h)}#f(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.#l)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.#l),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.#l,String(e)),this.#c=e)}getDbKey(){return this.#l}getVersion(){return this.#c}setLocalStorage(e){if(!(e instanceof Storage))throw new TypeError("Argument must be a valid instance of Storage.");this.#a=e}localStorageExists(){return this.#a 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.#f(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.#a.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.#a.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.#f(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.#a.setItem(e,JSON.stringify(r))}getDate(e){const t=this.#g(e).decoded;return t instanceof Date?t:null}setRegExp(e,t){if(this.#f(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.#a.setItem(e,JSON.stringify(r))}getRegExp(e){const t=this.#g(e).decoded;return t instanceof RegExp?t:null}setBigInt(e,t){if(this.#f(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.#a.setItem(e,JSON.stringify(r))}getBigInt(e){const t=this.#g(e).decoded;return"bigint"==typeof t?t:null}setSymbol(e,t){if(this.#f(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.#a.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.#f(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.emit("setItem",e,t),this.#a.setItem(e,t)}getItem(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.#a.getItem(e)}setString(e,t){if(this.#f(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.#a.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.#a.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.#f(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.#a.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.#a.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.#f(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.#a.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.#a.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.#a.removeItem(e)}clearLocalStorage(){return this.#a.clear()}destroy(){window.removeEventListener("storage",this.#h),this.#i.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})();
1
+ (()=>{"use strict";const e={d:(t,r)=>{if(Array.isArray(r))for(var n=0;n<r.length;){var s=r[n++],o=r[n++];e.o(t,s)?0===o&&n++:0===o?Object.defineProperty(t,s,{enumerable:!0,value:r[n++]}):Object.defineProperty(t,s,{enumerable:!0,get:o})}else for(var s in r)e.o(r,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:r[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};let 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;#n(e,t){if("string"==typeof e)return[e];if(Array.isArray(e)&&e.every(e=>"string"==typeof e))return e;throw new TypeError(`${t}(event): event must be a string or string[]`)}setThrowOnMaxListeners(e){if("boolean"!=typeof e)throw new TypeError("setThrowOnMaxListeners(value): value must be a boolean");this.#r=e}getThrowOnMaxListeners(){return this.#r}#s(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){const r=this.#n(e,"prependListener");if("function"!=typeof t)throw new TypeError("prependListener(event, handler): handler must be a function");for(const e of r)this.#s(e,t)}prependListenerOnce(e,t){const r=this.#n(e,"prependListenerOnce");if("function"!=typeof t)throw new TypeError("prependListenerOnce(event, handler): handler must be a function");const n=[];for(const e of r){const r=(...n)=>{this.off(e,r),t(...n)};this.#s(e,r,{once:!0}),n.push(r)}return n}#o(e,t,{once:r=!1}={}){const n=this.#n(e,"on");for(const e of n){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("function"!=typeof t)throw new TypeError("on(event, handler): handler must be a function");return this.#o(e,t)}once(e,t){const r=this.#n(e,"once");if("function"!=typeof t)throw new TypeError("once(event, handler): handler must be a function");const n=[];for(const e of r){const r=(...n)=>{this.off(e,r),t(...n)};this.#o(e,r,{once:!0}),n.push(r)}return n}appendListener(e,t){return this.on(e,t)}appendListenerOnce(e,t){return this.once(e,t)}off(e,t){const r=this.#n(e,"off");if("function"!=typeof t)throw new TypeError("off(event, handler): handler must be a function");for(const e of r){const r=this.#e.get(e);if(!Array.isArray(r))continue;const n=r.findIndex(e=>e.handler===t);-1!==n&&r.splice(n,1),0===r.length&&this.#e.delete(e)}}offAll(e){const t=this.#n(e,"offAll");for(const e of t)this.#e.delete(e)}offAllTypes(){this.#e.clear()}removeAllListeners(){return this.offAllTypes()}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){const r=this.#n(e,"emit"),n=[];for(const e of r){const r=this.#e.get(e);Array.isArray(r)&&0!==r.length?(r.forEach(e=>e.handler(...t)),n.push(!0)):n.push(!1)}return n}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{#i=new n;setThrowOnMaxListeners(e){return this.#i.setThrowOnMaxListeners(e)}getThrowOnMaxListeners(){return this.#i.getThrowOnMaxListeners()}prependListener(e,t){return this.#i.prependListener(e,t)}prependListenerOnce(e,t){return this.#i.prependListenerOnce(e,t)}appendListener(e,t){return this.#i.appendListener(e,t)}appendListenerOnce(e,t){return this.#i.appendListenerOnce(e,t)}on(e,t){return this.#i.on(e,t)}once(e,t){return this.#i.once(e,t)}off(e,t){return this.#i.off(e,t)}offAll(e){return this.#i.offAll(e)}offAllTypes(){return this.#i.offAllTypes()}listenerCount(e){return this.#i.listenerCount(e)}listeners(e){return this.#i.listeners(e)}onceListeners(e){return this.#i.onceListeners(e)}allListeners(e){return this.#i.allListeners(e)}eventNames(){return this.#i.eventNames()}emit(e,...t){return this.#i.emit(e,...t)}setMaxListeners(e){return this.#i.setMaxListeners(e)}getMaxListeners(){return this.#i.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}#a=window.localStorage;#l=null;#c=0;#h=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.#l=`LSDB::${e}`),window.addEventListener("storage",this.#h)}#f(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.#l)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.#l),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.#l,String(e)),this.#c=e)}getDbKey(){return this.#l}getVersion(){return this.#c}setLocalStorage(e){if(!(e instanceof Storage))throw new TypeError("Argument must be a valid instance of Storage.");this.#a=e}localStorageExists(){return this.#a 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.#f(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.#a.setItem(e,JSON.stringify(n))}#u(e,t){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");const r=this.#a.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.#u(e,t);return n instanceof Map||n instanceof Set||Array.isArray(n)||r(n)?n:s}setDate(e,t){if(this.#f(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.#a.setItem(e,JSON.stringify(r))}getDate(e){const t=this.#u(e).decoded;return t instanceof Date?t:null}setRegExp(e,t){if(this.#f(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.#a.setItem(e,JSON.stringify(r))}getRegExp(e){const t=this.#u(e).decoded;return t instanceof RegExp?t:null}setBigInt(e,t){if(this.#f(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.#a.setItem(e,JSON.stringify(r))}getBigInt(e){const t=this.#u(e).decoded;return"bigint"==typeof t?t:null}setSymbol(e,t){if(this.#f(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.#a.setItem(e,JSON.stringify(r))}getSymbol(e){const t=this.#u(e).decoded;return"symbol"==typeof t?t:null}getValue(e){return this.#u(e).decoded??null}setItem(e,t){if(this.#f(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.emit("setItem",e,t),this.#a.setItem(e,t)}getItem(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.#a.getItem(e)}setString(e,t){if(this.#f(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.#a.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.#a.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.#f(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.#a.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.#a.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.#f(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.#a.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.#a.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.#a.removeItem(e)}clearLocalStorage(){return this.#a.clear()}destroy(){window.removeEventListener("storage",this.#h),this.#i.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})();
@@ -1 +1 @@
1
- (()=>{"use strict";var e={d:(t,r)=>{for(var a in r)e.o(r,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:r[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{FuzzySet:()=>s,MamdaniInferenceSystem:()=>o,defuzzifyCentroid:()=>a,trapezoid:()=>i});const r=e=>{if(!Array.isArray(e))throw new TypeError("Parameter 'sets' must be an array.");if(!e.every(e=>e instanceof s))throw new TypeError("All elements in the array must be instances of FuzzySet.")},a=(e,t,a=.5)=>{n(e,"object","defuzzifyCentroid.fuzzyOutput");for(const t in e)n(e[t],"number",`fuzzyOutput['${t}']`);r(t),n(a,"number","defuzzifyCentroid.step");let i=0,s=0;for(let r=0;r<=100;r+=a){let a=0;t.forEach(t=>{const i=e[t.name]||0,n=Math.min(i,t.calculate(r));a=Math.max(a,n)}),i+=r*a,s+=a}return 0===s?0:i/s},i=(e,t,r,a,i,n=!1)=>{if(n){if(e<=t||e>=i)return 0;if(e>=r&&e<=a)return 1}const s=t===r?1:(e-t)/(r-t),o=a===i?1:(i-e)/(i-a),u=Math.max(0,Math.min(s,1,o));return isNaN(u)?0:u},n=(e,t,r)=>{if(typeof e!==t)throw new TypeError(`Parameter '${r}' must be a ${t}.`)};class s{static trapezoid(e,t,r,a,n,s=!1){return i(e,t,r,a,n,s)}#e="";#t=0;#r=0;#a=0;#i=0;#n=!1;get name(){return this.#e}set name(e){n(e,"string","FuzzySet.name"),this.#e=e}get a(){return this.#t}set a(e){n(e,"number","FuzzySet.a"),this.#t=e}get b(){return this.#r}set b(e){n(e,"number","FuzzySet.b"),this.#r=e}get c(){return this.#a}set c(e){n(e,"number","FuzzySet.c"),this.#a=e}get d(){return this.#i}set d(e){n(e,"number","FuzzySet.d"),this.#i=e}get optimize(){return this.#n}set optimize(e){n(e,"boolean","FuzzySet.optimize"),this.#n=e}constructor(e,t,r,a,i,n=!1){this.name=e,this.a=t,this.b=r,this.c=a,this.d=i,this.optimize=n}calculate(e){return n(e,"number","calculate.x"),s.trapezoid(e,this.#t,this.#r,this.#a,this.#i,this.#n)}}class o{#s=new Map;addVariable(e,t){n(e,"string","addVariable.name"),r(t),this.#s.set(e,t)}removeVariable(e){return n(e,"string","removeVariable.name"),this.#s.delete(e)}getVariable(e){n(e,"string","getVariable.name");const t=this.#s.get(e);if(!t)throw new Error(`Linguistic variable '${e}' not found in the inference system.`);return[...t]}hasVariable(e){return n(e,"string","hasVariable.name"),this.#s.has(e)}fuzzify(e,t){n(e,"string","fuzzify.varName"),n(t,"number","fuzzify.value");const r=this.#s.get(e)||[],a={};return r.forEach(e=>{a[e.name]=e.calculate(t)}),a}}window.TinyMaInSys=t})();
1
+ (()=>{"use strict";const e={d:(t,r)=>{if(Array.isArray(r))for(var a=0;a<r.length;){var i=r[a++],n=r[a++];e.o(t,i)?0===n&&a++:0===n?Object.defineProperty(t,i,{enumerable:!0,value:r[a++]}):Object.defineProperty(t,i,{enumerable:!0,get:n})}else 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),r:e=>{Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}};let t={};e.r(t),e.d(t,{FuzzySet:()=>n,MamdaniInferenceSystem:()=>s});const r=e=>{if(!Array.isArray(e))throw new TypeError("Parameter 'sets' must be an array.");if(!e.every(e=>e instanceof n))throw new TypeError("All elements in the array must be instances of FuzzySet.")},a=(e,t,r,a,i,n=!1)=>{if(n){if(e<=t||e>=i)return 0;if(e>=r&&e<=a)return 1}const s=t===r?1:(e-t)/(r-t),o=a===i?1:(i-e)/(i-a),u=Math.max(0,Math.min(s,1,o));return isNaN(u)?0:u},i=(e,t,r)=>{if(typeof e!==t)throw new TypeError(`Parameter '${r}' must be a ${t}.`)};class n{static trapezoid(e,t,r,i,n,s=!1){return a(e,t,r,i,n,s)}#e="";#t=0;#r=0;#a=0;#i=0;#n=!1;get name(){return this.#e}set name(e){i(e,"string","FuzzySet.name"),this.#e=e}get a(){return this.#t}set a(e){i(e,"number","FuzzySet.a"),this.#t=e}get b(){return this.#r}set b(e){i(e,"number","FuzzySet.b"),this.#r=e}get c(){return this.#a}set c(e){i(e,"number","FuzzySet.c"),this.#a=e}get d(){return this.#i}set d(e){i(e,"number","FuzzySet.d"),this.#i=e}get optimize(){return this.#n}set optimize(e){i(e,"boolean","FuzzySet.optimize"),this.#n=e}constructor(e,t,r,a,i,n=!1){this.name=e,this.a=t,this.b=r,this.c=a,this.d=i,this.optimize=n}calculate(e){return i(e,"number","calculate.x"),n.trapezoid(e,this.#t,this.#r,this.#a,this.#i,this.#n)}}class s{#s=new Map;addVariable(e,t){i(e,"string","addVariable.name"),r(t),this.#s.set(e,t)}removeVariable(e){return i(e,"string","removeVariable.name"),this.#s.delete(e)}getVariable(e){i(e,"string","getVariable.name");const t=this.#s.get(e);if(!t)throw new Error(`Linguistic variable '${e}' not found in the inference system.`);return[...t]}hasVariable(e){return i(e,"string","hasVariable.name"),this.#s.has(e)}fuzzify(e,t){i(e,"string","fuzzify.varName"),i(t,"number","fuzzify.value");const r=this.#s.get(e)||[],a={};return r.forEach(e=>{a[e.name]=e.calculate(t)}),a}}e.d(t,["defuzzifyCentroid",0,(e,t,a=.5)=>{i(e,"object","defuzzifyCentroid.fuzzyOutput");for(const t in e)i(e[t],"number",`fuzzyOutput['${t}']`);r(t),i(a,"number","defuzzifyCentroid.step");let n=0,s=0;for(let r=0;r<=100;r+=a){let a=0;t.forEach(t=>{const i=e[t.name]||0,n=Math.min(i,t.calculate(r));a=Math.max(a,n)}),n+=r*a,s+=a}return 0===s?0:n/s},"trapezoid",0,a]),window.TinyMaInSys=t})();
@@ -0,0 +1 @@
1
+ (()=>{"use strict";const e={d:(t,r)=>{if(Array.isArray(r))for(var n=0;n<r.length;){var s=r[n++],i=r[n++];e.o(t,s)?0===i&&n++:0===i?Object.defineProperty(t,s,{enumerable:!0,value:r[n++]}):Object.defineProperty(t,s,{enumerable:!0,get:i})}else for(var s in r)e.o(r,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:r[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};let t={};e.d(t,{TinyMediaPlayer:()=>c});const r=class{#e=new Map;#t=10;#r=!1;#n(e,t){if("string"==typeof e)return[e];if(Array.isArray(e)&&e.every(e=>"string"==typeof e))return e;throw new TypeError(`${t}(event): event must be a string or string[]`)}setThrowOnMaxListeners(e){if("boolean"!=typeof e)throw new TypeError("setThrowOnMaxListeners(value): value must be a boolean");this.#r=e}getThrowOnMaxListeners(){return this.#r}#s(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){const r=this.#n(e,"prependListener");if("function"!=typeof t)throw new TypeError("prependListener(event, handler): handler must be a function");for(const e of r)this.#s(e,t)}prependListenerOnce(e,t){const r=this.#n(e,"prependListenerOnce");if("function"!=typeof t)throw new TypeError("prependListenerOnce(event, handler): handler must be a function");const n=[];for(const e of r){const r=(...n)=>{this.off(e,r),t(...n)};this.#s(e,r,{once:!0}),n.push(r)}return n}#i(e,t,{once:r=!1}={}){const n=this.#n(e,"on");for(const e of n){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("function"!=typeof t)throw new TypeError("on(event, handler): handler must be a function");return this.#i(e,t)}once(e,t){const r=this.#n(e,"once");if("function"!=typeof t)throw new TypeError("once(event, handler): handler must be a function");const n=[];for(const e of r){const r=(...n)=>{this.off(e,r),t(...n)};this.#i(e,r,{once:!0}),n.push(r)}return n}appendListener(e,t){return this.on(e,t)}appendListenerOnce(e,t){return this.once(e,t)}off(e,t){const r=this.#n(e,"off");if("function"!=typeof t)throw new TypeError("off(event, handler): handler must be a function");for(const e of r){const r=this.#e.get(e);if(!Array.isArray(r))continue;const n=r.findIndex(e=>e.handler===t);-1!==n&&r.splice(n,1),0===r.length&&this.#e.delete(e)}}offAll(e){const t=this.#n(e,"offAll");for(const e of t)this.#e.delete(e)}offAllTypes(){this.#e.clear()}removeAllListeners(){return this.offAllTypes()}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){const r=this.#n(e,"emit"),n=[];for(const e of r){const r=this.#e.get(e);Array.isArray(r)&&0!==r.length?(r.forEach(e=>e.handler(...t)),n.push(!0)):n.push(!1)}return n}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}},n=new Map;class s extends Error{constructor(e,t,r){super(e),this.name="MediaLoadingError",this.url=t,this.stage=r}}const i=async e=>{const t=(new TextEncoder).encode(e),r=await crypto.subtle.digest("SHA-1",t);return Array.from(new Uint8Array(r)).map(e=>e.toString(16).padStart(2,"0")).join("").substring(0,8)},o=(e,t="image/jpeg")=>{const r=e=>{const t=URL.createObjectURL(e),r=n.get(t);return n.set(t,"number"==typeof r?r+1:1),t};if(e instanceof Uint8Array)return r(new Blob([e],{type:t}));if("string"==typeof e&&e.startsWith("data:")){const n=e.split(",")[1],s=atob(n),i=new Uint8Array(s.length);for(let e=0;e<s.length;e++)i[e]=s.charCodeAt(e);return r(new Blob([i],{type:t}))}return"string"==typeof e?e:""},a=(e,t)=>{const r=e=>t&&void 0===e,n=e=>r(e)||"string"==typeof e||null===e,s=(e,t)=>!!r(e)||!(!Array.isArray(e)||!e.every(t));if(!n(e.title))throw new TypeError('Invalid metadata: "title" must be a string or null.');if(!n(e.album))throw new TypeError('Invalid metadata: "album" must be a string or null.');if(!n(e.albumartist))throw new TypeError('Invalid metadata: "albumartist" must be a string or null.');if(!n(e.artist))throw new TypeError('Invalid metadata: "artist" must be a string or null.');if(i=e.year,!r(i)&&"number"!=typeof i&&null!==i)throw new TypeError('Invalid metadata: "year" must be a number or null.');var i;if(!s(e.albumartists,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "albumartists" must be an array of string.');if(!s(e.genre,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "genre" must be an array of string.');if(!s(e.label,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "label" must be an array of string.');if(!s(e.composer,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "composer" must be an array of string.');if(!s(e.artists,e=>"string"==typeof e))throw new TypeError('Invalid metadata: "artists" must be an array of string.');if(!s(e.picture,e=>!(void 0!==e.description&&"string"!=typeof e.description||void 0!==e.name&&"string"!=typeof e.name||void 0!==e.type&&"string"!=typeof e.type||"string"!=typeof e.format||!(e.data instanceof Uint8Array||"string"==typeof e.data))))throw new TypeError('Invalid metadata: "picture" must be an array of pictures.');const o=(e,t)=>{if(!r(e)){if(null==e)throw new TypeError(`Invalid metadata: "${t}" is required.`);if("object"!=typeof e)throw new TypeError(`Invalid metadata: "${t}" must be an object or null.`);if("number"!=typeof e.no&&null!==e.no)throw new TypeError(`Invalid metadata: "${t}.no" must be a number or null.`);if("number"!=typeof e.of&&null!==e.of)throw new TypeError(`Invalid metadata: "${t}.of" must be a number or null.`)}};o(e.disk,"disk"),o(e.track,"track")},l=e=>a(e,!1);class h{constructor(){if(new.target===h)throw new Error("BaseMediaAdapter is an abstract class and cannot be instantiated directly.")}canHandle(e){throw new Error('Method "canHandle" must be implemented by the subclass.')}async play(e){throw new Error('Method "play" must be implemented by the subclass.')}async pause(){throw new Error('Method "pause" must be implemented by the subclass.')}async stop(){throw new Error('Method "stop" must be implemented by the subclass.')}async seek(e){throw new Error('Method "seek" must be implemented by the subclass.')}getCurrentTime(){throw new Error('Method "getCurrentTime" must be implemented by the subclass.')}setVolume(e){throw new Error('Method "setVolume" must be implemented by the subclass.')}}class u extends r{static BaseMediaAdapter=h;static#o="Unknown Artist";static get unknownArtist(){return u.#o}static set unknownArtist(e){if("string"!=typeof e&&"function"!=typeof e)throw new TypeError("unknownArtist must have an string or function.");u.#o=e}static async parseContent(e,t,r,n,l){return(async(e,t={},r={},n=e=>new Promise((e,t)=>t(new TypeError("parseFile library not found."))),l={},h="null")=>{if("string"!=typeof e&&!(e instanceof HTMLMediaElement))throw new TypeError("Source must be a string or an HTMLMediaElement.");if(l.onProgress&&"function"!=typeof l.onProgress)throw new TypeError("callbacks.onProgress must be a function.");if(l.onError&&"function"!=typeof l.onError)throw new TypeError("callbacks.onError must be a function.");let u,c="";const p=(t,r)=>{l.onProgress&&l.onProgress({event:r,status:"loading",stage:t,url:c||(e instanceof HTMLMediaElement?e.src:"unknown")})},d=(t,r)=>{l.onError&&l.onError({error:t,url:c||(e instanceof HTMLMediaElement?e.src:"unknown"),stage:r})};try{p("INITIALIZING"),"string"==typeof e?(c=e,u=new Audio(c)):(u=e,c=u.src);try{await new Promise((e,t)=>{const r=e=>p("DOWNLOADING",e),n=()=>{i(),e(void 0)},s=e=>{i(),t(new Error(`HTMLMediaElement failed to load: ${e.message||"Unknown error"}`))},i=()=>{u.removeEventListener("progress",r),u.removeEventListener("loadedmetadata",n),u.removeEventListener("error",s)};u.addEventListener("progress",r),u.addEventListener("loadedmetadata",n),u.addEventListener("error",s),u.readyState>=1&&(i(),e(void 0))}),p("METADATA_LOADED")}catch(e){throw new s(e instanceof Error?e.message:"UNKNOWN ERROR",c,"METADATA")}const y={id:r.id||await i(c),duration:Math.floor(1e3*u.duration),url:c,weight:r.weight??1};let m={};p("EXTRACTING_ID3");try{m=await(async(e,t)=>{if("string"!=typeof e)throw new TypeError(`Expected url to be a string, but received ${typeof e}.`);if("function"!=typeof t)throw new TypeError(`Expected parseFile to be a function, but received ${typeof t}.`);try{const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch audio file: ${r.status} ${r.statusText}`);const n=await r.blob(),s=await t(n);if(!s||"object"!=typeof s.common)throw new TypeError('Invalid metadata: "common" property is missing or not an object.');const i=s.common;return(e=>{a(e,!0)})(i),{title:i?.title??null,album:i?.album??null,albumartist:i?.albumartist??null,albumartists:i?.albumartists??[],genre:i?.genre??[],label:i?.label??[],composer:i?.composer??[],year:i?.year??null,artist:i?.artist??null,artists:i?.artists??[],disk:i?.disk?{no:i.disk.no,of:i.disk.of}:{no:null,of:null},track:i?.track?{no:i.track.no,of:i.track.of}:{no:null,of:null},picture:i?.picture?.map(e=>({...e,data:o(e.data,e.format)}))??[]}}catch(e){throw e}})(c,n)}catch(e){d(e instanceof Error?e:new Error("Unknown Error"),"ID3"),console.warn(`[TinyAudioUtils] ID3 extraction failed for ${c}. Falling back to filename.`)}const f=e=>{try{return(e.split(/[?#]/)[0].split("/").pop()??"").replace(/\.[^/.]+$/,"")||"Unknown Track"}catch{return"Unknown Track"}},w={...y,...t,...m,...r,title:m.title||r.title||f(c),artist:m.artist||r.artist||("string"==typeof h?h:String(h()))};return l.onProgress&&l.onProgress({status:"success",stage:"COMPLETE",url:c}),w}catch(e){if(e instanceof s)throw e;{const t=new s(e instanceof Error?e.message:"UNKNOWN ERROR",c,"INITIALIZING");throw d(t,"INITIALIZING"),t}}})(e,t,r,n,l,u.#o)}#a=new Map;#l=[];#h=-1;#u="NONE";#c=!1;#p=!1;#d=1;#y;#m;constructor(e={}){super(),this.#y=Boolean(e.persistVolume),this.#m="string"==typeof e.volumeStorageKey?e.volumeStorageKey:"tiny_media_player_volume",this.#y&&this.#f()}#f(){try{if("undefined"!=typeof window&&window.localStorage){const e=window.localStorage.getItem(this.#m);if(null!==e){const t=parseFloat(e);!isNaN(t)&&t>=0&&t<=1&&(this.#d=t)}}}catch(e){console.warn("[TinyMediaPlayer] Failed to read volume from localStorage.",e)}}#w(){try{this.#y&&"undefined"!=typeof window&&window.localStorage&&window.localStorage.setItem(this.#m,this.#d.toString())}catch(e){console.warn("[TinyMediaPlayer] Failed to save volume to localStorage.",e)}}_getWeightedRandomIndex(){if(0===this.#l.length)return-1;if(1===this.#l.length)return 0;let e=0;for(let t=0;t<this.#l.length;t++){if(t===this.#h)continue;const r=this.#l[t];e+="number"==typeof r.weight&&r.weight>0?r.weight:1}let t=Math.random()*e;for(let e=0;e<this.#l.length;e++){if(e===this.#h)continue;const r=this.#l[e],n="number"==typeof r.weight&&r.weight>0?r.weight:1;if(t<n)return e;t-=n}return this.#h===this.#l.length-1?0:this.#l.length-1}get playlist(){return[...this.#l]}set playlist(e){if(!Array.isArray(e))throw new TypeError("Playlist must be an array of MediaContent objects.");e.forEach(e=>l(e));const t=this.#p;let r=null;if(-1!==this.#h&&this.#l.length>0)try{r=this.#g()}catch(e){}this.#l=e,this.emit("playlistUpdate",this.playlist),0===this.#l.length?this.#h=-1:(this.#h>=this.#l.length||-1===this.#h)&&(this.#h=0),this.emit("trackChange",this.#h),t&&(async()=>{try{r&&await r.stop(),-1!==this.#h&&await this.play()}catch(e){console.warn("[TinyMediaPlayer] Background transition error on playlist update:",e)}})()}get currentIndex(){return this.#h}set currentIndex(e){if("number"!=typeof e)throw new TypeError("Current index must be a number.");if(e<-1||e>=this.#l.length&&this.#l.length>0)throw new RangeError(`Index ${e} is out of bounds for the current playlist.`);if(this.#h===e)return;const t=this.#p;let r=null;if(-1!==this.#h&&this.#l.length>0)try{r=this.#g()}catch(e){}this.#h=e,this.emit("trackChange",this.#h),t&&(async()=>{try{r&&await r.stop(),-1!==this.#h&&await this.play()}catch(e){console.warn("[TinyMediaPlayer] Background transition error on index update:",e)}})()}get loopMode(){return this.#u}set loopMode(e){const t=["NONE","TRACK","PLAYLIST"];if(!t.includes(e))throw new TypeError(`Loop mode must be one of: ${t.join(", ")}.`);this.#u=e,this.emit("loopModeChange",this.#u)}get isRandom(){return this.#c}set isRandom(e){if("boolean"!=typeof e)throw new TypeError("Random mode state must be a boolean.");this.#c=e,this.emit("randomModeChange",this.#c)}get isPlaying(){return this.#p}get volume(){return this.#d}set volume(e){if("number"!=typeof e)throw new TypeError("Volume must be a number.");if(e<0||e>1)throw new RangeError("Volume must be tightly constrained between 0.0 and 1.0.");if(this.#d=e,this.#w(),this.emit("volumeChange",this.#d),-1!==this.#h&&this.#l.length>0)try{const e=this.#g();e&&e.setVolume(this.#d)}catch(e){}}get persistVolume(){return this.#y}set persistVolume(e){if("boolean"!=typeof e)throw new TypeError("Persist volume parameter must be a boolean.");this.#y=e,e&&this.#w()}get volumeStorageKey(){return this.#m}set volumeStorageKey(e){if("string"!=typeof e)throw new TypeError("Volume storage key must be a string.");if(""===e.trim())throw new TypeError("Volume storage key cannot be an empty string.");const t=this.#m;this.#m=e;try{this.#y&&"undefined"!=typeof window&&window.localStorage&&(window.localStorage.removeItem(t),this.#w())}catch(e){console.warn("[TinyMediaPlayer] Failed to migrate volume storage key.",e)}}registerAdapter(e,t){if("string"!=typeof e)throw new TypeError("Adapter ID must be a string.");if(!(t instanceof h))throw new TypeError("Adapter must be an instance of BaseMediaAdapter.");this.#a.set(e,t)}#g(){if(-1===this.#h||0===this.#l.length)return null;const e=this.#l[this.#h];for(const t of this.#a.values())if(t.canHandle(e))return t;throw new Error(`No compatible adapter found for content ID: ${e.id}.`)}addTrack(e){if(!e||"object"!=typeof e||"string"!=typeof e.url)throw new TypeError("Track content must be a valid MediaContent object containing a URL.");const t={id:"",title:"",artist:"",url:"",duration:0,weight:1,title:null,album:null,albumartist:null,albumartists:[],genre:[],label:[],composer:[],year:null,artist:null,artists:[],disk:{no:null,of:null},track:{no:null,of:null},picture:[],...e};l(t);const r=this.#l.push(t);return-1===this.#h&&(this.#h=0,this.emit("trackChange",this.#h)),this.emit("playlistUpdate",this.playlist),r}existsTrack(e){if("number"!=typeof e)throw new TypeError("Index must be a number.");return e>=0&&e<this.#l.length}getTrack(e){if("number"!=typeof e)throw new TypeError("Index must be a number.");if(!this.existsTrack(e))throw new RangeError(`Index ${e} is out of bounds for the current playlist.`);return this.#l[e]}async removeTrack(e){if("number"!=typeof e)throw new TypeError("Index must be a number.");if(!this.existsTrack(e))throw new RangeError(`Index ${e} is out of bounds for the current playlist.`);e===this.#h?(await this.stop(),this.#l.splice(e,1),0===this.#l.length?this.#h=-1:this.#h>=this.#l.length&&(this.#h=0),this.emit("trackChange",this.#h)):(this.#l.splice(e,1),e<this.#h&&(this.#h-=1,this.emit("trackChange",this.#h))),this.emit("playlistUpdate",this.playlist)}searchTrack(e){if("string"!=typeof e&&"function"!=typeof e)throw new TypeError("Search query must be a string or a boolean evaluation function.");const t=[];for(let r=0;r<this.#l.length;r++){const n=this.#l[r];let s=!1;if("function"==typeof e)s=Boolean(e(n));else{const t=e.toLowerCase(),r=n.title&&n.title.toLowerCase().includes(t),i=n.artist&&n.artist.toLowerCase().includes(t),o=n.album&&n.album.toLowerCase().includes(t);s=Boolean(r||i||o)}s&&t.push({track:n,index:r})}return t}async clearPlaylist(){await this.stop(),this.#l=[],this.#h=-1,this.emit("playlistUpdate",this.playlist),this.emit("trackChange",this.#h)}async play(){const e=this.#g();e&&(e.setVolume(this.#d),await e.play(this.#l[this.#h]),this.#p=!0,this.emit("play",this.#h))}async pause(){const e=this.#g();e&&(await e.pause(),this.#p=!1,this.emit("pause",this.#h))}async stop(){const e=this.#g();e&&(await e.stop(),this.#p=!1,this.emit("stop",this.#h))}async next(){if(0!==this.#l.length)if(await this.stop(),"TRACK"!==this.#u){if(this.#c)this.#h=this._getWeightedRandomIndex();else{let e=this.#h+1;if(e>=this.#l.length){if("PLAYLIST"!==this.#u)return;e=0}this.#h=e}this.emit("trackChange",this.#h),await this.play()}else await this.play()}async prev(){if(0!==this.#l.length){if(await this.stop(),this.#c)this.#h=this._getWeightedRandomIndex();else{let e=this.#h-1;if(e<0){if("PLAYLIST"!==this.#u)return;e=this.#l.length-1}this.#h=e}this.emit("trackChange",this.#h),await this.play()}}async seek(e){if("number"!=typeof e)throw new TypeError("Seek time must be a number in milliseconds.");if(e<0)throw new RangeError("Seek time cannot be negative.");const t=this.#g();t&&(await t.seek(e),this.emit("seek",e))}async step(e){if("number"!=typeof e)throw new TypeError("Step amount must be a number in milliseconds.");const t=this.#g();if(!t)return;let r=t.getCurrentTime()+e;r<0&&(r=0),await this.seek(r)}}const c=u;window.TinyMediaPlayer=t.TinyMediaPlayer})();
@@ -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,{TinyNeedBar:()=>i});class r{#e=new Map;#t;#r;#i;get factors(){const e={};for(let[t,r]of this.#e.entries())e[t]={...r};return e}get currentPercent(){return this.#r/this.#t*100}set maxValue(e){if("number"!=typeof e||Number.isNaN(e)||e<=0)throw new TypeError("maxValue must be a positive number.");this.#t=e,this.#r=Math.min(this.#r,e)}get maxValue(){return this.#t}get currentValue(){return this.#r}set infiniteValue(e){if("number"!=typeof e||Number.isNaN(e))throw new TypeError("infiniteValue must be a number.");this.#i=e,this.#r=Math.max(0,e),this.#r=Math.min(this.#r,this.#t)}get infiniteValue(){return this.#i}constructor(e=100,t=1,r=1){if("number"!=typeof e||Number.isNaN(e)||e<=0)throw new TypeError("maxValue must be a positive number.");this.#t=e,this.setFactor("main",t,r),this.#r=e,this.#i=e}getFactor(e){if("string"!=typeof e||!e)throw new TypeError("Key must be a non-empty string.");const t=this.#e.get(e);if(!t)throw new Error(`Factor with key "${e}" not found.`);return{...t}}hasFactor(e){if("string"!=typeof e||!e)throw new TypeError("Key must be a non-empty string.");return this.#e.has(e)}setFactor(e,t,r=1){if("string"!=typeof e||!e)throw new TypeError("Key must be a non-empty string.");if("number"!=typeof t||Number.isNaN(t))throw new TypeError("Amount must be a valid number.");if("number"!=typeof r||Number.isNaN(r))throw new TypeError("Multiplier must be a valid number.");this.#e.set(e,{amount:t,multiplier:r})}removeFactor(e){if("string"!=typeof e||!e)throw new TypeError("Key must be a non-empty string.");return this.#e.delete(e)}#n(e){const t=this.#i;return this.#i-=e,this.#r=Math.max(0,this.#r-e),{prevValue:t,removedTotal:e,removedPercent:e/this.#t*100,currentPercent:this.currentPercent,remainingValue:this.#r,infiniteRemaining:this.#i}}tick(){let e=0;for(let[t,r]of this.#e.entries())e+=r.amount*r.multiplier;return this.#n(e)}tickWithTempFactor(e){if("object"!=typeof e||null===e)throw new TypeError("You must provide a valid factor object.");if("number"!=typeof e.amount||Number.isNaN(e.amount))throw new TypeError('Temp factor "amount" must be a valid number.');if("multiplier"in e&&("number"!=typeof e.multiplier||Number.isNaN(e.multiplier)))throw new TypeError('Temp factor "multiplier" must be a valid number if provided.');let t=0;for(let[e,r]of this.#e.entries())t+=r.amount*r.multiplier;return e&&(t+=e.amount*(e.multiplier??1)),this.#n(t)}tickSingleFactor(e){if("object"!=typeof e||null===e)throw new TypeError("You must provide a valid factor object.");if("number"!=typeof e.amount||Number.isNaN(e.amount))throw new TypeError('Temp factor "amount" must be a valid number.');if("multiplier"in e&&("number"!=typeof e.multiplier||Number.isNaN(e.multiplier)))throw new TypeError('Temp factor "multiplier" must be a valid number if provided.');if(!e)throw new Error("You must provide a factor to apply.");const t=e.amount*(e.multiplier??1);return this.#n(t)}toJSON(){return{maxValue:this.#t,currentValue:this.#r,infiniteValue:this.#i,factors:this.factors}}static fromJSON(e){const t=new r(e.maxValue,0,0);t.infiniteValue=e.infiniteValue,t.#e.clear();for(const[r,i]of Object.entries(e.factors))t.setFactor(r,i.amount,i.multiplier);return t}clone(){return r.fromJSON(this.toJSON())}clearFactors(){this.#e.clear()}}const i=r;window.TinyNeedBar=t.TinyNeedBar})();
1
+ (()=>{"use strict";const e={d:(t,r)=>{if(Array.isArray(r))for(var i=0;i<r.length;){var n=r[i++],a=r[i++];e.o(t,n)?0===a&&i++:0===a?Object.defineProperty(t,n,{enumerable:!0,value:r[i++]}):Object.defineProperty(t,n,{enumerable:!0,get:a})}else 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)};let t={};e.d(t,{TinyNeedBar:()=>i});class r{#e=new Map;#t;#r;#i;get factors(){const e={};for(let[t,r]of this.#e.entries())e[t]={...r};return e}get currentPercent(){return this.#r/this.#t*100}set maxValue(e){if("number"!=typeof e||Number.isNaN(e)||e<=0)throw new TypeError("maxValue must be a positive number.");this.#t=e,this.#r=Math.min(this.#r,e)}get maxValue(){return this.#t}get currentValue(){return this.#r}set infiniteValue(e){if("number"!=typeof e||Number.isNaN(e))throw new TypeError("infiniteValue must be a number.");this.#i=e,this.#r=Math.max(0,e),this.#r=Math.min(this.#r,this.#t)}get infiniteValue(){return this.#i}constructor(e=100,t=1,r=1){if("number"!=typeof e||Number.isNaN(e)||e<=0)throw new TypeError("maxValue must be a positive number.");this.#t=e,this.setFactor("main",t,r),this.#r=e,this.#i=e}getFactor(e){if("string"!=typeof e||!e)throw new TypeError("Key must be a non-empty string.");const t=this.#e.get(e);if(!t)throw new Error(`Factor with key "${e}" not found.`);return{...t}}hasFactor(e){if("string"!=typeof e||!e)throw new TypeError("Key must be a non-empty string.");return this.#e.has(e)}setFactor(e,t,r=1){if("string"!=typeof e||!e)throw new TypeError("Key must be a non-empty string.");if("number"!=typeof t||Number.isNaN(t))throw new TypeError("Amount must be a valid number.");if("number"!=typeof r||Number.isNaN(r))throw new TypeError("Multiplier must be a valid number.");this.#e.set(e,{amount:t,multiplier:r})}removeFactor(e){if("string"!=typeof e||!e)throw new TypeError("Key must be a non-empty string.");return this.#e.delete(e)}#n(e){const t=this.#i;return this.#i-=e,this.#r=Math.max(0,this.#r-e),{prevValue:t,removedTotal:e,removedPercent:e/this.#t*100,currentPercent:this.currentPercent,remainingValue:this.#r,infiniteRemaining:this.#i}}tick(){let e=0;for(let[t,r]of this.#e.entries())e+=r.amount*r.multiplier;return this.#n(e)}tickWithTempFactor(e){if("object"!=typeof e||null===e)throw new TypeError("You must provide a valid factor object.");if("number"!=typeof e.amount||Number.isNaN(e.amount))throw new TypeError('Temp factor "amount" must be a valid number.');if("multiplier"in e&&("number"!=typeof e.multiplier||Number.isNaN(e.multiplier)))throw new TypeError('Temp factor "multiplier" must be a valid number if provided.');let t=0;for(let[e,r]of this.#e.entries())t+=r.amount*r.multiplier;return e&&(t+=e.amount*(e.multiplier??1)),this.#n(t)}tickSingleFactor(e){if("object"!=typeof e||null===e)throw new TypeError("You must provide a valid factor object.");if("number"!=typeof e.amount||Number.isNaN(e.amount))throw new TypeError('Temp factor "amount" must be a valid number.');if("multiplier"in e&&("number"!=typeof e.multiplier||Number.isNaN(e.multiplier)))throw new TypeError('Temp factor "multiplier" must be a valid number if provided.');if(!e)throw new Error("You must provide a factor to apply.");const t=e.amount*(e.multiplier??1);return this.#n(t)}toJSON(){return{maxValue:this.#t,currentValue:this.#r,infiniteValue:this.#i,factors:this.factors}}static fromJSON(e){const t=new r(e.maxValue,0,0);t.infiniteValue=e.infiniteValue,t.#e.clear();for(const[r,i]of Object.entries(e.factors))t.setFactor(r,i.amount,i.multiplier);return t}clone(){return r.fromJSON(this.toJSON())}clearFactors(){this.#e.clear()}}const i=r;window.TinyNeedBar=t.TinyNeedBar})();
@@ -1 +1 @@
1
- (()=>{"use strict";var e={d:(t,n)=>{for(var s in n)e.o(n,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:n[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{TinyNewWinEvents:()=>r});const n=class{#e=new Map;#t=10;#n=!1;#s(e,t){if("string"==typeof e)return[e];if(Array.isArray(e)&&e.every(e=>"string"==typeof e))return e;throw new TypeError(`${t}(event): event must be a string or string[]`)}setThrowOnMaxListeners(e){if("boolean"!=typeof e)throw new TypeError("setThrowOnMaxListeners(value): value must be a boolean");this.#n=e}getThrowOnMaxListeners(){return this.#n}#r(e,t,{once:n=!1}={}){let s=this.#e.get(e);Array.isArray(s)||(s=[],this.#e.set(e,s)),s.unshift({handler:t,config:{once:n}});const r=this.#t;if(r>0&&s.length>r){const t=`Possible memory leak detected. ${s.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#n)throw new Error(t);console.warn(t)}}prependListener(e,t){const n=this.#s(e,"prependListener");if("function"!=typeof t)throw new TypeError("prependListener(event, handler): handler must be a function");for(const e of n)this.#r(e,t)}prependListenerOnce(e,t){const n=this.#s(e,"prependListenerOnce");if("function"!=typeof t)throw new TypeError("prependListenerOnce(event, handler): handler must be a function");const s=[];for(const e of n){const n=(...s)=>{this.off(e,n),t(...s)};this.#r(e,n,{once:!0}),s.push(n)}return s}#i(e,t,{once:n=!1}={}){const s=this.#s(e,"on");for(const e of s){let s=this.#e.get(e);Array.isArray(s)||(s=[],this.#e.set(e,s)),s.push({handler:t,config:{once:n}});const r=this.#t;if(r>0&&s.length>r){const t=`Possible memory leak detected. ${s.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#n)throw new Error(t);console.warn(t)}}}on(e,t){if("function"!=typeof t)throw new TypeError("on(event, handler): handler must be a function");return this.#i(e,t)}once(e,t){const n=this.#s(e,"once");if("function"!=typeof t)throw new TypeError("once(event, handler): handler must be a function");const s=[];for(const e of n){const n=(...s)=>{this.off(e,n),t(...s)};this.#i(e,n,{once:!0}),s.push(n)}return s}appendListener(e,t){return this.on(e,t)}appendListenerOnce(e,t){return this.once(e,t)}off(e,t){const n=this.#s(e,"off");if("function"!=typeof t)throw new TypeError("off(event, handler): handler must be a function");for(const e of n){const n=this.#e.get(e);if(!Array.isArray(n))continue;const s=n.findIndex(e=>e.handler===t);-1!==s&&n.splice(s,1),0===n.length&&this.#e.delete(e)}}offAll(e){const t=this.#s(e,"offAll");for(const e of t)this.#e.delete(e)}offAllTypes(){this.#e.clear()}removeAllListeners(){return this.offAllTypes()}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){const n=this.#s(e,"emit"),s=[];for(const e of n){const n=this.#e.get(e);Array.isArray(n)&&0!==n.length?(n.forEach(e=>e.handler(...t)),s.push(!0)):s.push(!1)}return s}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 WeakMap,r=class{#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()}setMaxListeners(e){return this.#o.setMaxListeners(e)}getMaxListeners(){return this.#o.getMaxListeners()}#a;#h;#l=[];#f=!1;#d=!1;#w=null;#u="__TNE_READY__";#p="__TNE_ROUTE__";get readyEventName(){return this.#u}set readyEventName(e){if("string"!=typeof e)throw new TypeError("TinyNewWinEvents: readyEventName must be a string.");this.#u=e}get routeEventName(){return this.#p}set routeEventName(e){if("string"!=typeof e)throw new TypeError("TinyNewWinEvents: routeEventName must be a string.");this.#p=e}constructor({targetOrigin:e,url:t,name:n,features:r}={}){if("string"==typeof n&&"_blank"===n)throw new Error('TinyNewWinEvents: The window name "_blank" is not supported. Please use a custom name to allow tracking.');if(void 0!==e&&"string"!=typeof e)throw new TypeError('TinyNewWinEvents: The "targetOrigin" option must be a string.');if(void 0!==t&&"string"!=typeof t)throw new TypeError('TinyNewWinEvents: The "url" option must be a string.');if(void 0!==r&&"string"!=typeof r)throw new TypeError('TinyNewWinEvents: The "features" option must be a string if provided.');if(void 0===t?this.#a=window.opener:(this.#a="string"==typeof t?window.open(t,n,r):t,this.#d=!0),!this.#a||s.has(this.#a))throw new Error("Invalid or duplicate window reference.");this.#h=e??window.location.origin,this._handleMessage=this.#c.bind(this),window.addEventListener("message",this._handleMessage,!1),this.#d||(this.#v(this.#u,null),this.#y())}getWin(){return this.#a}#c(e){if(!e.source||this.#a&&e.source!==this.#a)return;const{type:t,route:n,payload:s}=e.data||{};if(t===this.#u)return this.#f=!0,this.#g(),this.#y(),void(this.#d&&this.#v(this.#u,null));t===this.#p&&this.#o.emit(n,s,e)}#g(){for(;this.#l.length;){const e=this.#l.shift();if(e){const{route:t,payload:n}=e;this.emit(t,n)}}}#v(e,t,n=""){this.#a&&this.#a.closed||this.#a?.postMessage({type:e,route:n,payload:t},this.#h)}close(){if(!this.#d)throw new Error("Only host can close the window.");this.#a&&!this.#a.closed&&this.#a.close()}emit(e,t){if("string"!=typeof e)throw new TypeError("Event name must be a string.");if(this.isDestroyed())throw new Error("Cannot emit: instance has been destroyed.");this.#f?this.#v(this.#p,t,e):this.#l.push({route:e,payload:t})}isConnected(){return!(!this.#f||!this.#a||this.#a.closed)}#y(){this.#a&&!this.#w&&(this.#w=setInterval(()=>{this.#a?.closed&&(this.#o.emit("WINDOW_REF_CLOSED"),this.destroy())},500),s.set(this.#a,this.#w))}onClose(e){return this.#o.on("WINDOW_REF_CLOSED",e)}offClose(e){return this.#o.off("WINDOW_REF_CLOSED",e)}isDestroyed(){return!this.#a}destroy(){this.#a&&(this.#w&&(clearInterval(this.#w),this.#w=null,s.delete(this.#a)),window.removeEventListener("message",this._handleMessage),this.#l=[],this.#f=!1,this.#a=null,this.#o.offAllTypes())}};window.TinyNewWinEvents=t.TinyNewWinEvents})();
1
+ (()=>{"use strict";const e={d:(t,n)=>{if(Array.isArray(n))for(var s=0;s<n.length;){var r=n[s++],i=n[s++];e.o(t,r)?0===i&&s++:0===i?Object.defineProperty(t,r,{enumerable:!0,value:n[s++]}):Object.defineProperty(t,r,{enumerable:!0,get:i})}else for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};let t={};e.d(t,{TinyNewWinEvents:()=>r});const n=class{#e=new Map;#t=10;#n=!1;#s(e,t){if("string"==typeof e)return[e];if(Array.isArray(e)&&e.every(e=>"string"==typeof e))return e;throw new TypeError(`${t}(event): event must be a string or string[]`)}setThrowOnMaxListeners(e){if("boolean"!=typeof e)throw new TypeError("setThrowOnMaxListeners(value): value must be a boolean");this.#n=e}getThrowOnMaxListeners(){return this.#n}#r(e,t,{once:n=!1}={}){let s=this.#e.get(e);Array.isArray(s)||(s=[],this.#e.set(e,s)),s.unshift({handler:t,config:{once:n}});const r=this.#t;if(r>0&&s.length>r){const t=`Possible memory leak detected. ${s.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#n)throw new Error(t);console.warn(t)}}prependListener(e,t){const n=this.#s(e,"prependListener");if("function"!=typeof t)throw new TypeError("prependListener(event, handler): handler must be a function");for(const e of n)this.#r(e,t)}prependListenerOnce(e,t){const n=this.#s(e,"prependListenerOnce");if("function"!=typeof t)throw new TypeError("prependListenerOnce(event, handler): handler must be a function");const s=[];for(const e of n){const n=(...s)=>{this.off(e,n),t(...s)};this.#r(e,n,{once:!0}),s.push(n)}return s}#i(e,t,{once:n=!1}={}){const s=this.#s(e,"on");for(const e of s){let s=this.#e.get(e);Array.isArray(s)||(s=[],this.#e.set(e,s)),s.push({handler:t,config:{once:n}});const r=this.#t;if(r>0&&s.length>r){const t=`Possible memory leak detected. ${s.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#n)throw new Error(t);console.warn(t)}}}on(e,t){if("function"!=typeof t)throw new TypeError("on(event, handler): handler must be a function");return this.#i(e,t)}once(e,t){const n=this.#s(e,"once");if("function"!=typeof t)throw new TypeError("once(event, handler): handler must be a function");const s=[];for(const e of n){const n=(...s)=>{this.off(e,n),t(...s)};this.#i(e,n,{once:!0}),s.push(n)}return s}appendListener(e,t){return this.on(e,t)}appendListenerOnce(e,t){return this.once(e,t)}off(e,t){const n=this.#s(e,"off");if("function"!=typeof t)throw new TypeError("off(event, handler): handler must be a function");for(const e of n){const n=this.#e.get(e);if(!Array.isArray(n))continue;const s=n.findIndex(e=>e.handler===t);-1!==s&&n.splice(s,1),0===n.length&&this.#e.delete(e)}}offAll(e){const t=this.#s(e,"offAll");for(const e of t)this.#e.delete(e)}offAllTypes(){this.#e.clear()}removeAllListeners(){return this.offAllTypes()}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){const n=this.#s(e,"emit"),s=[];for(const e of n){const n=this.#e.get(e);Array.isArray(n)&&0!==n.length?(n.forEach(e=>e.handler(...t)),s.push(!0)):s.push(!1)}return s}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 WeakMap,r=class{#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()}setMaxListeners(e){return this.#o.setMaxListeners(e)}getMaxListeners(){return this.#o.getMaxListeners()}#a;#h;#l=[];#f=!1;#d=!1;#w=null;#u="__TNE_READY__";#p="__TNE_ROUTE__";get readyEventName(){return this.#u}set readyEventName(e){if("string"!=typeof e)throw new TypeError("TinyNewWinEvents: readyEventName must be a string.");this.#u=e}get routeEventName(){return this.#p}set routeEventName(e){if("string"!=typeof e)throw new TypeError("TinyNewWinEvents: routeEventName must be a string.");this.#p=e}constructor({targetOrigin:e,url:t,name:n,features:r}={}){if("string"==typeof n&&"_blank"===n)throw new Error('TinyNewWinEvents: The window name "_blank" is not supported. Please use a custom name to allow tracking.');if(void 0!==e&&"string"!=typeof e)throw new TypeError('TinyNewWinEvents: The "targetOrigin" option must be a string.');if(void 0!==t&&"string"!=typeof t)throw new TypeError('TinyNewWinEvents: The "url" option must be a string.');if(void 0!==r&&"string"!=typeof r)throw new TypeError('TinyNewWinEvents: The "features" option must be a string if provided.');if(void 0===t?this.#a=window.opener:(this.#a="string"==typeof t?window.open(t,n,r):t,this.#d=!0),!this.#a||s.has(this.#a))throw new Error("Invalid or duplicate window reference.");this.#h=e??window.location.origin,this._handleMessage=this.#c.bind(this),window.addEventListener("message",this._handleMessage,!1),this.#d||(this.#y(this.#u,null),this.#v())}getWin(){return this.#a}#c(e){if(!e.source||this.#a&&e.source!==this.#a)return;const{type:t,route:n,payload:s}=e.data||{};if(t===this.#u)return this.#f=!0,this.#g(),this.#v(),void(this.#d&&this.#y(this.#u,null));t===this.#p&&this.#o.emit(n,s,e)}#g(){for(;this.#l.length;){const e=this.#l.shift();if(e){const{route:t,payload:n}=e;this.emit(t,n)}}}#y(e,t,n=""){this.#a&&this.#a.closed||this.#a?.postMessage({type:e,route:n,payload:t},this.#h)}close(){if(!this.#d)throw new Error("Only host can close the window.");this.#a&&!this.#a.closed&&this.#a.close()}emit(e,t){if("string"!=typeof e)throw new TypeError("Event name must be a string.");if(this.isDestroyed())throw new Error("Cannot emit: instance has been destroyed.");this.#f?this.#y(this.#p,t,e):this.#l.push({route:e,payload:t})}isConnected(){return!(!this.#f||!this.#a||this.#a.closed)}#v(){this.#a&&!this.#w&&(this.#w=setInterval(()=>{this.#a?.closed&&(this.#o.emit("WINDOW_REF_CLOSED"),this.destroy())},500),s.set(this.#a,this.#w))}onClose(e){return this.#o.on("WINDOW_REF_CLOSED",e)}offClose(e){return this.#o.off("WINDOW_REF_CLOSED",e)}isDestroyed(){return!this.#a}destroy(){this.#a&&(this.#w&&(clearInterval(this.#w),this.#w=null,s.delete(this.#a)),window.removeEventListener("message",this._handleMessage),this.#l=[],this.#f=!1,this.#a=null,this.#o.offAllTypes())}};window.TinyNewWinEvents=t.TinyNewWinEvents})();
@@ -1 +1 @@
1
- (()=>{"use strict";var e={d:(t,i)=>{for(var n in i)e.o(i,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:i[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{TinyNotifications:()=>i});const i=class{#e=!1;#t=!1;#i=null;#n=100;#o=null;#r;constructor({audio:e=null,defaultIcon:t=null,bodyLimit:i=100,defaultOnClick:n=function(e){e.preventDefault(),window.focus&&window.focus(),this.close()}}={}){if(!(e instanceof HTMLAudioElement)&&"string"!=typeof e&&null!==e)throw new TypeError("audio must be an instance of HTMLAudioElement or null.");if(null!==t&&"string"!=typeof t)throw new TypeError("defaultIcon must be a string or null.");if(!Number.isFinite(i)||i<0)throw new TypeError("bodyLimit must be a non-negative number.");if("function"!=typeof n)throw new TypeError("defaultOnClick must be a function.");this.#i="string"!=typeof e?e:new Audio(e),this.#o=t,this.#n=i,this.#r=n}requestPerm(){const e=this;return new Promise((t,i)=>{e.isCompatible()?"default"===Notification.permission?Notification.requestPermission().then(i=>{this.#t=!0,e.#e="granted"===i,t(e.#e)}).catch(i):(this.#t=!0,e.#e="granted"===Notification.permission,t(e.#e)):(this.#t=!0,e.#e=!1,t(!1))})}isCompatible(){return"Notification"in window}send(e,t={}){if(!this.#t)throw new Error("You must call requestPerm() before sending a notification.");if("string"!=typeof e)throw new TypeError("title must be a string.");if("object"!=typeof t||null===t)throw new TypeError("config must be a non-null object.");if(!this.#e)return null;const{icon:i=this.#o||void 0,vibrate:n=[200,100,200]}=t,o={...t};"string"==typeof i&&(o.icon=i),Array.isArray(n)&&(o.vibrate=n),"string"==typeof o.body&&(o.body=function(e,t,i=.6){if("string"!=typeof e)throw new TypeError("Expected a string for 'text', but received "+typeof e);if(!Number.isInteger(t)||t<=0)throw new TypeError(`Expected 'limit' to be a positive integer, but received ${t}`);if("number"!=typeof i||i<0||i>1)throw new TypeError(`Expected 'safeCutZone' to be a number between 0 and 1, but received ${i}`);let n=e.trim();if(n.length>t){const e=n.lastIndexOf(" ",t);return e>0&&e>=t*i?`${n.substring(0,e).trim()}...`:`${n.substring(0,t).trim()}...`}return n}(o.body,this.#n));const r=new Notification(e,o);return r.addEventListener("show",()=>{this.#i instanceof HTMLAudioElement&&(this.#i.currentTime=0,this.#i.play().catch(e=>console.error(e)))}),"function"==typeof this.#r&&r.addEventListener("click",this.#r),r}wasPermissionRequested(){return this.#t}isAllowed(){return this.#e}getAudio(){return this.#i}setAudio(e){if(!(e instanceof HTMLAudioElement)&&"string"!=typeof e&&null!==e)throw new TypeError("sound must be an instance of HTMLAudioElement or null.");this.#i="string"!=typeof e?e:new Audio(e)}getBodyLimit(){return this.#n}setBodyLimit(e){if(!Number.isFinite(e)||e<0)throw new TypeError("bodyLimit must be a non-negative number.");this.#n=e}getDefaultAvatar(){return this.#o}setDefaultAvatar(e){if("string"!=typeof e&&null!==e)throw new TypeError("defaultIcon must be a string or null.");this.#o=e}getDefaultOnClick(){return this.#r}setDefaultOnClick(e){if("function"!=typeof e)throw new TypeError("defaultOnClick must be a function.");this.#r=e}};window.TinyNotifications=t.TinyNotifications})();
1
+ (()=>{"use strict";const e={d:(t,i)=>{if(Array.isArray(i))for(var n=0;n<i.length;){var o=i[n++],r=i[n++];e.o(t,o)?0===r&&n++:0===r?Object.defineProperty(t,o,{enumerable:!0,value:i[n++]}):Object.defineProperty(t,o,{enumerable:!0,get:r})}else for(var o in i)e.o(i,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:i[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};let t={};e.d(t,{TinyNotifications:()=>i});const i=class{#e=!1;#t=!1;#i=null;#n=100;#o=null;#r;constructor({audio:e=null,defaultIcon:t=null,bodyLimit:i=100,defaultOnClick:n=function(e){e.preventDefault(),window.focus&&window.focus(),this.close()}}={}){if(!(e instanceof HTMLAudioElement)&&"string"!=typeof e&&null!==e)throw new TypeError("audio must be an instance of HTMLAudioElement or null.");if(null!==t&&"string"!=typeof t)throw new TypeError("defaultIcon must be a string or null.");if(!Number.isFinite(i)||i<0)throw new TypeError("bodyLimit must be a non-negative number.");if("function"!=typeof n)throw new TypeError("defaultOnClick must be a function.");this.#i="string"!=typeof e?e:new Audio(e),this.#o=t,this.#n=i,this.#r=n}requestPerm(){const e=this;return new Promise((t,i)=>{e.isCompatible()?"default"===Notification.permission?Notification.requestPermission().then(i=>{this.#t=!0,e.#e="granted"===i,t(e.#e)}).catch(i):(this.#t=!0,e.#e="granted"===Notification.permission,t(e.#e)):(this.#t=!0,e.#e=!1,t(!1))})}isCompatible(){return"Notification"in window}send(e,t={}){if(!this.#t)throw new Error("You must call requestPerm() before sending a notification.");if("string"!=typeof e)throw new TypeError("title must be a string.");if("object"!=typeof t||null===t)throw new TypeError("config must be a non-null object.");if(!this.#e)return null;const{icon:i=this.#o||void 0,vibrate:n=[200,100,200]}=t,o={...t};"string"==typeof i&&(o.icon=i),Array.isArray(n)&&(o.vibrate=n),"string"==typeof o.body&&(o.body=function(e,t,i=.6){if("string"!=typeof e)throw new TypeError("Expected a string for 'text', but received "+typeof e);if(!Number.isInteger(t)||t<=0)throw new TypeError(`Expected 'limit' to be a positive integer, but received ${t}`);if("number"!=typeof i||i<0||i>1)throw new TypeError(`Expected 'safeCutZone' to be a number between 0 and 1, but received ${i}`);let n=e.trim();if(n.length>t){const e=n.lastIndexOf(" ",t);return e>0&&e>=t*i?`${n.substring(0,e).trim()}...`:`${n.substring(0,t).trim()}...`}return n}(o.body,this.#n));const r=new Notification(e,o);return r.addEventListener("show",()=>{this.#i instanceof HTMLAudioElement&&(this.#i.currentTime=0,this.#i.play().catch(e=>console.error(e)))}),"function"==typeof this.#r&&r.addEventListener("click",this.#r),r}wasPermissionRequested(){return this.#t}isAllowed(){return this.#e}getAudio(){return this.#i}setAudio(e){if(!(e instanceof HTMLAudioElement)&&"string"!=typeof e&&null!==e)throw new TypeError("sound must be an instance of HTMLAudioElement or null.");this.#i="string"!=typeof e?e:new Audio(e)}getBodyLimit(){return this.#n}setBodyLimit(e){if(!Number.isFinite(e)||e<0)throw new TypeError("bodyLimit must be a non-negative number.");this.#n=e}getDefaultAvatar(){return this.#o}setDefaultAvatar(e){if("string"!=typeof e&&null!==e)throw new TypeError("defaultIcon must be a string or null.");this.#o=e}getDefaultOnClick(){return this.#r}setDefaultOnClick(e){if("function"!=typeof e)throw new TypeError("defaultOnClick must be a function.");this.#r=e}};window.TinyNotifications=t.TinyNotifications})();
@@ -1 +1 @@
1
- (()=>{"use strict";var e={d:(t,n)=>{for(var o in n)e.o(n,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:n[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{TinyNotifyCenter:()=>o});class n{static getTemplate(){return'\n<div class="notify-overlay hidden">\n <div class="notify-center" id="notifCenter">\n <div class="header">\n <div>Notifications</div>\n <div class="options">\n <button class="clear-all" type="button">\n <svg\n xmlns="http://www.w3.org/2000/svg"\n viewBox="0 0 24 24"\n width="24"\n height="24"\n fill="currentColor"\n >\n <path\n d="M21.6 2.4a1 1 0 0 0-1.4 0L13 9.6l-1.3-1.3a1 1 0 0 0-1.4 0L3 15.6a1 1 0 0 0 0 1.4l4 4a1 1 0 0 0 1.4 0l7.3-7.3a1 1 0 0 0 0-1.4l-1.3-1.3 7.2-7.2a1 1 0 0 0 0-1.4zM6 17l3.5-3.5 1.5 1.5L7.5 18.5 6 17z"\n />\n </svg>\n </button>\n <button class="close">×</button>\n </div>\n </div>\n <div class="list"></div>\n </div>\n</div>\n\n<button class="notify-bell" aria-label="Open notifications">\n <svg\n xmlns="http://www.w3.org/2000/svg"\n width="20"\n height="20"\n fill="currentColor"\n viewBox="0 0 24 24"\n >\n <path\n d="M12 2C10.3 2 9 3.3 9 5v1.1C6.7 7.2 5 9.4 5 12v5l-1 1v1h16v-1l-1-1v-5c0-2.6-1.7-4.8-4-5.9V5c0-1.7-1.3-3-3-3zm0 20c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2z"\n />\n </svg>\n <span class="badge" id="notifBadge">0</span>\n</button>\n '}static insertTemplate(e="afterbegin"){document.body.insertAdjacentHTML(e,n.getTemplate())}#e;#t;#n;#o;#s;#i=0;#r=99;#l=300;#a=!1;#c=new WeakMap;#d(e){if(this.#c.delete(e),!(e instanceof HTMLElement))throw new Error("Invalid HTMLElement to clear.");e.classList.add("removing"),setTimeout(()=>{this.markAsRead(e),e.remove()},this.#l)}#m(e){this.#i=Math.max(0,e),this.#n.setAttribute("data-value",String(this.#i)),this.#n.textContent=this.#i>this.#r?`${this.#r}+`:String(this.#i)}constructor(e={}){const{center:t=document.getElementById("notifCenter"),badge:n=document.getElementById("notifBadge"),button:o=document.querySelector(".notify-bell"),overlay:s=document.querySelector(".notify-overlay")}=e;if(!(t instanceof HTMLElement))throw new Error(`NotificationCenter: "center" must be an HTMLElement. Got: ${t}`);if(!(s instanceof HTMLElement))throw new Error(`NotificationCenter: "overlay" must be an HTMLElement. Got: ${s}`);if(!(n instanceof HTMLElement))throw new Error(`NotificationCenter: "badge" must be an HTMLElement. Got: ${n}`);if(!(o instanceof HTMLElement))throw new Error(`NotificationCenter: "button" must be an HTMLElement. Got: ${o}`);const i=t?.querySelector(".clear-all"),r=t?.querySelector(".list")??null;if(!(r instanceof HTMLElement))throw new Error(`NotificationCenter: ".list" inside center must be an HTMLElement. Got: ${r}`);this.#e=t,this.#t=r,this.#n=n,this.#o=o,this.#s=s,this.#o.addEventListener("click",()=>this.toggle()),this.#e.querySelector(".close")?.addEventListener("click",()=>this.close()),i&&i.addEventListener("click",()=>this.clear()),this.#s.addEventListener("click",e=>{e.target===this.#s&&this.close()})}setMarkAllAsReadOnClose(e){if("boolean"!=typeof e)throw new TypeError("Expected boolean for markAllAsReadOnClose, got "+typeof e);this.#a=e}setRemoveDelay(e){if("number"!=typeof e)throw new Error('NotificationCenter: "ms" must be an number.');this.#l=e}getItemMode(e){const t=this.getItem(e);return t?this.#c.get(t):null}getItem(e){const t=this.#t.children.item(e);if(!(t instanceof HTMLElement))throw new Error(`NotificationCenter: "item" must be an HTMLElement. Got: ${t}`);return t}hasItem(e){return e>=0&&e<this.#t.children.length}markAsRead(e){const t=e instanceof HTMLElement?e:this.getItem(e);t.classList.contains("unread")&&(t.classList.remove("unread"),this.#m(this.#i-1))}add(e,t="text"){const n=document.createElement("div");n.className="item unread";let o=null,s=null,i=null,r=null;if("object"==typeof e&&null!==e?(o=e.title,s=e.message,i=e.avatar,r=e.onClick):s=e,i){const e=document.createElement("div");e.className="avatar",e.style.backgroundImage=`url("${i}")`,n.appendChild(e)}const l=document.createElement("div");if(l.className="content",o){const e=document.createElement("div");e.className="title",e.textContent=o,l.appendChild(e)}const a=document.createElement("div");a.className="message","html"===t?a.innerHTML=s:a.textContent=s,l.appendChild(a),"function"==typeof r&&(n.classList.add("clickable"),n.addEventListener("click",e=>{e.target instanceof HTMLElement&&!e.target.closest(".notify-close")&&r(e)}));const c=document.createElement("button");c.className="notify-close",c.setAttribute("type","button"),c.innerHTML="&times;",c.addEventListener("click",e=>{e.stopPropagation(),this.#d(n)}),n.append(l,c),this.#t.prepend(n),this.#c.set(n,t),this.#m(this.#i+1)}remove(e){const t=this.getItem(e);this.#d(t)}clear(){let e=!0;for(;e;){e=!1;const t=Array.from(this.#t.children);for(const n of t)n instanceof HTMLElement&&!n.classList.contains("removing")&&(this.#d(n),e=!0)}}open(){this.#s.classList.remove("hidden"),this.#e.classList.add("open")}close(){if(this.#s.classList.add("hidden"),this.#e.classList.remove("open"),this.#a){const e=this.#t.querySelectorAll(".item.unread");for(const t of e)t instanceof HTMLElement&&this.markAsRead(t)}}toggle(){this.#e.classList.contains("open")?this.close():this.open()}recount(){const e=this.#t.querySelectorAll(".item.unread").length;this.#m(e)}get count(){return this.#i}destroy(){this.#o?.removeEventListener("click",this.toggle),this.#e?.querySelector(".close")?.removeEventListener("click",this.close),this.#e?.querySelector(".clear-all")?.removeEventListener("click",this.clear),this.#s?.removeEventListener("click",this.close),this.clear(),this.#e?.remove(),this.#s?.remove(),this.#o?.remove(),this.#i=0,this.#c=new WeakMap}}const o=n;window.TinyNotifyCenter=t.TinyNotifyCenter})();
1
+ (()=>{"use strict";const e={d:(t,n)=>{if(Array.isArray(n))for(var o=0;o<n.length;){var s=n[o++],i=n[o++];e.o(t,s)?0===i&&o++:0===i?Object.defineProperty(t,s,{enumerable:!0,value:n[o++]}):Object.defineProperty(t,s,{enumerable:!0,get:i})}else for(var s in n)e.o(n,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:n[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};let t={};e.d(t,{TinyNotifyCenter:()=>o});class n{static getTemplate(){return'\n<div class="notify-overlay hidden">\n <div class="notify-center" id="notifCenter">\n <div class="header">\n <div>Notifications</div>\n <div class="options">\n <button class="clear-all" type="button">\n <svg\n xmlns="http://www.w3.org/2000/svg"\n viewBox="0 0 24 24"\n width="24"\n height="24"\n fill="currentColor"\n >\n <path\n d="M21.6 2.4a1 1 0 0 0-1.4 0L13 9.6l-1.3-1.3a1 1 0 0 0-1.4 0L3 15.6a1 1 0 0 0 0 1.4l4 4a1 1 0 0 0 1.4 0l7.3-7.3a1 1 0 0 0 0-1.4l-1.3-1.3 7.2-7.2a1 1 0 0 0 0-1.4zM6 17l3.5-3.5 1.5 1.5L7.5 18.5 6 17z"\n />\n </svg>\n </button>\n <button class="close">×</button>\n </div>\n </div>\n <div class="list"></div>\n </div>\n</div>\n\n<button class="notify-bell" aria-label="Open notifications">\n <svg\n xmlns="http://www.w3.org/2000/svg"\n width="20"\n height="20"\n fill="currentColor"\n viewBox="0 0 24 24"\n >\n <path\n d="M12 2C10.3 2 9 3.3 9 5v1.1C6.7 7.2 5 9.4 5 12v5l-1 1v1h16v-1l-1-1v-5c0-2.6-1.7-4.8-4-5.9V5c0-1.7-1.3-3-3-3zm0 20c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2z"\n />\n </svg>\n <span class="badge" id="notifBadge">0</span>\n</button>\n '}static insertTemplate(e="afterbegin"){document.body.insertAdjacentHTML(e,n.getTemplate())}#e;#t;#n;#o;#s;#i=0;#r=99;#l=300;#a=!1;#c=new WeakMap;#d(e){if(this.#c.delete(e),!(e instanceof HTMLElement))throw new Error("Invalid HTMLElement to clear.");e.classList.add("removing"),setTimeout(()=>{this.markAsRead(e),e.remove()},this.#l)}#m(e){this.#i=Math.max(0,e),this.#n.setAttribute("data-value",String(this.#i)),this.#n.textContent=this.#i>this.#r?`${this.#r}+`:String(this.#i)}constructor(e={}){const{center:t=document.getElementById("notifCenter"),badge:n=document.getElementById("notifBadge"),button:o=document.querySelector(".notify-bell"),overlay:s=document.querySelector(".notify-overlay")}=e;if(!(t instanceof HTMLElement))throw new Error(`NotificationCenter: "center" must be an HTMLElement. Got: ${t}`);if(!(s instanceof HTMLElement))throw new Error(`NotificationCenter: "overlay" must be an HTMLElement. Got: ${s}`);if(!(n instanceof HTMLElement))throw new Error(`NotificationCenter: "badge" must be an HTMLElement. Got: ${n}`);if(!(o instanceof HTMLElement))throw new Error(`NotificationCenter: "button" must be an HTMLElement. Got: ${o}`);const i=t?.querySelector(".clear-all"),r=t?.querySelector(".list")??null;if(!(r instanceof HTMLElement))throw new Error(`NotificationCenter: ".list" inside center must be an HTMLElement. Got: ${r}`);this.#e=t,this.#t=r,this.#n=n,this.#o=o,this.#s=s,this.#o.addEventListener("click",()=>this.toggle()),this.#e.querySelector(".close")?.addEventListener("click",()=>this.close()),i&&i.addEventListener("click",()=>this.clear()),this.#s.addEventListener("click",e=>{e.target===this.#s&&this.close()})}setMarkAllAsReadOnClose(e){if("boolean"!=typeof e)throw new TypeError("Expected boolean for markAllAsReadOnClose, got "+typeof e);this.#a=e}setRemoveDelay(e){if("number"!=typeof e)throw new Error('NotificationCenter: "ms" must be an number.');this.#l=e}getItemMode(e){const t=this.getItem(e);return t?this.#c.get(t):null}getItem(e){const t=this.#t.children.item(e);if(!(t instanceof HTMLElement))throw new Error(`NotificationCenter: "item" must be an HTMLElement. Got: ${t}`);return t}hasItem(e){return e>=0&&e<this.#t.children.length}markAsRead(e){const t=e instanceof HTMLElement?e:this.getItem(e);t.classList.contains("unread")&&(t.classList.remove("unread"),this.#m(this.#i-1))}add(e,t="text"){const n=document.createElement("div");n.className="item unread";let o=null,s=null,i=null,r=null;if("object"==typeof e&&null!==e?(o=e.title,s=e.message,i=e.avatar,r=e.onClick):s=e,i){const e=document.createElement("div");e.className="avatar",e.style.backgroundImage=`url("${i}")`,n.appendChild(e)}const l=document.createElement("div");if(l.className="content",o){const e=document.createElement("div");e.className="title",e.textContent=o,l.appendChild(e)}const a=document.createElement("div");a.className="message","html"===t?a.innerHTML=s:a.textContent=s,l.appendChild(a),"function"==typeof r&&(n.classList.add("clickable"),n.addEventListener("click",e=>{e.target instanceof HTMLElement&&!e.target.closest(".notify-close")&&r(e)}));const c=document.createElement("button");c.className="notify-close",c.setAttribute("type","button"),c.innerHTML="&times;",c.addEventListener("click",e=>{e.stopPropagation(),this.#d(n)}),n.append(l,c),this.#t.prepend(n),this.#c.set(n,t),this.#m(this.#i+1)}remove(e){const t=this.getItem(e);this.#d(t)}clear(){let e=!0;for(;e;){e=!1;const t=Array.from(this.#t.children);for(const n of t)n instanceof HTMLElement&&!n.classList.contains("removing")&&(this.#d(n),e=!0)}}open(){this.#s.classList.remove("hidden"),this.#e.classList.add("open")}close(){if(this.#s.classList.add("hidden"),this.#e.classList.remove("open"),this.#a){const e=this.#t.querySelectorAll(".item.unread");for(const t of e)t instanceof HTMLElement&&this.markAsRead(t)}}toggle(){this.#e.classList.contains("open")?this.close():this.open()}recount(){const e=this.#t.querySelectorAll(".item.unread").length;this.#m(e)}get count(){return this.#i}destroy(){this.#o?.removeEventListener("click",this.toggle),this.#e?.querySelector(".close")?.removeEventListener("click",this.close),this.#e?.querySelector(".clear-all")?.removeEventListener("click",this.clear),this.#s?.removeEventListener("click",this.close),this.clear(),this.#e?.remove(),this.#s?.remove(),this.#o?.remove(),this.#i=0,this.#c=new WeakMap}}const o=n;window.TinyNotifyCenter=t.TinyNotifyCenter})();
@@ -1 +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,{TinyPromiseQueue:()=>i});const i=class{#e=[];#t=!1;#i={};#r=new Set;isRunning(){return this.#t}async#s(e){if(e&&"function"==typeof e.task&&"function"==typeof e.resolve&&"function"==typeof e.reject){const{task:t,resolve:i,reject:r,delay:s,id:n}=e;try{if(n&&this.#r.has(n))return r(new Error("The function was canceled on TinyPromiseQueue.")),this.#r.delete(n),this.#t=!1,void this.#n();s&&n&&await new Promise(e=>{const t=setTimeout(()=>{delete this.#i[n],e(null)},s);this.#i[n]=t}),i(await t())}catch(e){r(e)}finally{this.#t=!1,this.#n()}}}async#u(){const e=[];for(;this.#e.length&&"POINT_MARKER"===this.#e[0]?.marker;)e.push(this.#e.shift());if(0===e.length)return this.#t=!1,void this.#n();await Promise.all(e.map(({task:e,resolve:t,reject:i,id:r})=>new Promise(async s=>{if(r&&this.#r.has(r))return this.#r.delete(r),i(new Error("The function was canceled on TinyPromiseQueue.")),void s(!0);await e().then(t).catch(i),s(!0)}))),this.#t=!1,this.#n()}async#n(){if(!this.#t&&0!==this.#e.length)if(this.#t=!0,"string"!=typeof this.#e[0]?.marker||"POINT_MARKER"!==this.#e[0]?.marker){const e=this.#e.shift();this.#s(e)}else this.#u()}getIndexById(e){return this.#e.findIndex(t=>t.id===e)}getQueuedIds(){return this.#e.map((e,t)=>({index:t,id:e.id})).filter(e=>"string"==typeof e.id)}reorderQueue(e,t){if("number"!=typeof e||"number"!=typeof t||e<0||t<0||e>=this.#e.length||t>=this.#e.length)return;const[i]=this.#e.splice(e,1);this.#e.splice(t,0,i)}async enqueuePoint(e,t){if("function"!=typeof e)return Promise.reject(new Error("Task must be a function returning a Promise."));if(void 0!==t&&"string"!=typeof t)throw new Error('The "id" parameter must be a string.');return this.#t?new Promise((i,r)=>{this.#e.push({marker:"POINT_MARKER",task:e,resolve:i,reject:r,id:t}),this.#n()}):e()}enqueue(e,t,i){if("function"!=typeof e)return Promise.reject(new Error("Task must be a function returning a Promise."));if(void 0!==t&&("number"!=typeof t||t<0))return Promise.reject(new Error("Delay must be a positive number or undefined."));if(void 0!==i&&"string"!=typeof i)throw new Error('The "id" parameter must be a string.');return new Promise((r,s)=>{this.#e.push({task:e,resolve:r,reject:s,id:i,delay:t}),this.#n()})}cancelTask(e){if("string"!=typeof e)throw new Error('The "id" parameter must be a string.');let t=!1;e in this.#i&&(clearTimeout(this.#i[e]),delete this.#i[e],t=!0);const i=this.getIndexById(e);if(-1!==i){const[e]=this.#e.splice(i,1);e?.reject?.(new Error("The function was canceled on TinyPromiseQueue.")),t=!0}return t&&this.#r.add(e),t}};window.TinyPromiseQueue=t.TinyPromiseQueue})();
1
+ (()=>{"use strict";const e={d:(t,r)=>{if(Array.isArray(r))for(var i=0;i<r.length;){var s=r[i++],n=r[i++];e.o(t,s)?0===n&&i++:0===n?Object.defineProperty(t,s,{enumerable:!0,value:r[i++]}):Object.defineProperty(t,s,{enumerable:!0,get:n})}else for(var s in r)e.o(r,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:r[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};let t={};e.d(t,{TinyPromiseQueue:()=>r});const r=class{#e=[];#t=!1;#r={};#i=new Set;isRunning(){return this.#t}async#s(e){if(e&&"function"==typeof e.task&&"function"==typeof e.resolve&&"function"==typeof e.reject){const{task:t,resolve:r,reject:i,delay:s,id:n}=e;try{if(n&&this.#i.has(n))return i(new Error("The function was canceled on TinyPromiseQueue.")),this.#i.delete(n),this.#t=!1,void this.#n();s&&n&&await new Promise(e=>{const t=setTimeout(()=>{delete this.#r[n],e(null)},s);this.#r[n]=t}),r(await t())}catch(e){i(e)}finally{this.#t=!1,this.#n()}}}async#u(){const e=[];for(;this.#e.length&&"POINT_MARKER"===this.#e[0]?.marker;)e.push(this.#e.shift());if(0===e.length)return this.#t=!1,void this.#n();await Promise.all(e.map(({task:e,resolve:t,reject:r,id:i})=>new Promise(async s=>{if(i&&this.#i.has(i))return this.#i.delete(i),r(new Error("The function was canceled on TinyPromiseQueue.")),void s(!0);await e().then(t).catch(r),s(!0)}))),this.#t=!1,this.#n()}async#n(){if(!this.#t&&0!==this.#e.length)if(this.#t=!0,"string"!=typeof this.#e[0]?.marker||"POINT_MARKER"!==this.#e[0]?.marker){const e=this.#e.shift();this.#s(e)}else this.#u()}getIndexById(e){return this.#e.findIndex(t=>t.id===e)}getQueuedIds(){return this.#e.map((e,t)=>({index:t,id:e.id})).filter(e=>"string"==typeof e.id)}reorderQueue(e,t){if("number"!=typeof e||"number"!=typeof t||e<0||t<0||e>=this.#e.length||t>=this.#e.length)return;const[r]=this.#e.splice(e,1);this.#e.splice(t,0,r)}async enqueuePoint(e,t){if("function"!=typeof e)return Promise.reject(new Error("Task must be a function returning a Promise."));if(void 0!==t&&"string"!=typeof t)throw new Error('The "id" parameter must be a string.');return this.#t?new Promise((r,i)=>{this.#e.push({marker:"POINT_MARKER",task:e,resolve:r,reject:i,id:t}),this.#n()}):e()}enqueue(e,t,r){if("function"!=typeof e)return Promise.reject(new Error("Task must be a function returning a Promise."));if(void 0!==t&&("number"!=typeof t||t<0))return Promise.reject(new Error("Delay must be a positive number or undefined."));if(void 0!==r&&"string"!=typeof r)throw new Error('The "id" parameter must be a string.');return new Promise((i,s)=>{this.#e.push({task:e,resolve:i,reject:s,id:r,delay:t}),this.#n()})}cancelTask(e){if("string"!=typeof e)throw new Error('The "id" parameter must be a string.');let t=!1;e in this.#r&&(clearTimeout(this.#r[e]),delete this.#r[e],t=!0);const r=this.getIndexById(e);if(-1!==r){const[e]=this.#e.splice(r,1);e?.reject?.(new Error("The function was canceled on TinyPromiseQueue.")),t=!0}return t&&this.#i.add(e),t}};window.TinyPromiseQueue=t.TinyPromiseQueue})();