primux 1.0.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.
- package/LICENSE +21 -0
- package/README.md +94 -0
- package/package.json +13 -0
- package/primux.esm.min.js +1 -0
- package/primux.min.cjs.js +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 JishithMP-Dev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Primux
|
|
2
|
+
|
|
3
|
+
**Primux** is a lightweight, modern, and well-structured JavaScript utility library that extends JavaScript’s standard capabilities.
|
|
4
|
+
It provides reusable helper functions for **functions, arrays, objects, strings, numbers, DOM, browser APIs, and more** — all in one clean package.
|
|
5
|
+
|
|
6
|
+
Primux works in **both Browser and Node.js environments**, with proper ESM and CommonJS support.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- Modern **ESM** and **CommonJS** support
|
|
13
|
+
- Works in **Browser** and **Node.js**
|
|
14
|
+
- Modular utility collection (use only what you need)
|
|
15
|
+
- Safe environment checks (DOM APIs won’t crash Node)
|
|
16
|
+
- Canvas, DOM, and Web API helpers included
|
|
17
|
+
- Zero dependencies
|
|
18
|
+
- Well-tested and predictable behavior
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Using npm
|
|
26
|
+
npm install primux
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Node.js
|
|
32
|
+
|
|
33
|
+
**CommonJS:**
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
const _p = require("primux");
|
|
37
|
+
|
|
38
|
+
console.log(_p.uppercaseWords("hello world")); // "Hello World"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**ESM:**
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
import _p from "primux";
|
|
45
|
+
import { uppercaseWords } from "primux";
|
|
46
|
+
console.log(uppercaseWords("hello world")); // "Hello World"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<!-- Browser Usage (CDN) -->
|
|
51
|
+
|
|
52
|
+
<!-- Minified version -->
|
|
53
|
+
<script src="https://cdn.jsdelivr.net/gh/JishithMP-Dev/primux@v1.0.0/primux.min.js"></script>
|
|
54
|
+
|
|
55
|
+
<!-- Full version -->
|
|
56
|
+
<script src="https://cdn.jsdelivr.net/gh/JishithMP-Dev/primux@v1.0.0/primux.js"></script>
|
|
57
|
+
|
|
58
|
+
<!-- ESM versions -->
|
|
59
|
+
<script type="module" src="https://cdn.jsdelivr.net/gh/JishithMP-Dev/primux@v1.0.0/primux.esm.js"></script>
|
|
60
|
+
<script type="module" src="https://cdn.jsdelivr.net/gh/JishithMP-Dev/primux@v1.0.0/primux.esm.min.js"></script>
|
|
61
|
+
|
|
62
|
+
<!-- Usage in Browser with global _p -->
|
|
63
|
+
<script>
|
|
64
|
+
// _p is available globally if using non-ESM script
|
|
65
|
+
console.log(_p.uppercaseWords("hello world")); // "Hello World"
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<!-- Usage in Browser with ESM imports -->
|
|
69
|
+
<script type="module">
|
|
70
|
+
// Default import
|
|
71
|
+
import _p from "https://cdn.jsdelivr.net/gh/JishithMP-Dev/primux@v1.0.0/primux.esm.min.js";
|
|
72
|
+
console.log(_p.uppercaseWords("hello world")); // "Hello World"
|
|
73
|
+
|
|
74
|
+
// Named import
|
|
75
|
+
import { uppercaseWords } from "https://cdn.jsdelivr.net/gh/JishithMP-Dev/primux@v1.0.0/primux.esm.min.js";
|
|
76
|
+
console.log(uppercaseWords("hello world")); // "Hello World"
|
|
77
|
+
</script>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Documentation
|
|
81
|
+
|
|
82
|
+
You can read the full Primux documentation and see all available utilities at:
|
|
83
|
+
[https://primux-dev.web.app](https://primux-dev.web.app)
|
|
84
|
+
|
|
85
|
+
You can also download the local files (primux.js, primux.min.js, primux.esm.js, primux.esm.min.js) directly from the website for offline use.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Conclusion
|
|
90
|
+
|
|
91
|
+
Primux is a lightweight and comprehensive JavaScript utility library designed to make your development faster and more efficient.
|
|
92
|
+
It works seamlessly in **Node.js** and **Browser environments**, provides **ESM and CommonJS support**, and includes a wide range of helpers for **arrays, strings, objects, numbers, DOM, and Web APIs**.
|
|
93
|
+
|
|
94
|
+
With zero dependencies and predictable behavior, Primux is ready to be integrated into any project — whether for small scripts or large applications.
|
package/package.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "primux",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "**Primux** is a lightweight, modern, and well-structured JavaScript utility library that extends JavaScript’s standard capabilities. It provides reusable helper functions for **functions, arrays, objects, strings, numbers, DOM, browser APIs, and more** — all in one clean package.",
|
|
5
|
+
"main": "primux.esm.min.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"type": "commonjs"
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function createType(typeName,message,validator){let value;function validate(v){if(!validator(v))throw new TypeError(message)}return function(initialValue){return arguments.length>0&&(validate(initialValue),value=initialValue),{get:()=>value,set(newValue){validate(newValue),value=newValue},clear(){value=void 0},type:()=>typeName}}}function resolveStorage(type,fn){if("local"===type)return localStorage;if("session"===type)return sessionStorage;throw new Error(`Primux/${fn}: type must be "local" or "session". Default is "local".`)}function typeOf(v){return null===v?"null":Number.isNaN(v)?"NaN":Array.isArray(v)?"array":"undefined"!=typeof window&&"undefined"!=typeof Element&&v instanceof Element?"dom":v instanceof RegExp?"RegExp":typeof v}function guard(fn,values,schema){const params=Object.keys(schema).join(", ");for(const key in schema){const rule=schema[key],value=values[key],optional=rule.endsWith("?"),expected=optional?rule.slice(0,-1):rule;if(void 0===value){if(optional)continue;throw new TypeError(`Primux/${fn}(${params}): parameter "${key}" is required`)}if("any"===expected)continue;const actual=typeOf(value);if(!expected.split("|").includes(actual))throw new TypeError(`Primux/${fn}(${params}): parameter "${key}" expected ${expected}, received ${actual}`)}}function ensureDOM(fnName){if("undefined"==typeof document)throw new Error(`Primux/${fnName}(): DOM is not available in this environment!`)}function stableHash(value){if(null===value)return"null";if("object"!=typeof value)return typeof value+":"+String(value);if(Array.isArray(value))return"array:["+value.map(stableHash).join(",")+"]";return"object:{"+Object.keys(value).sort().map(k=>`${k}:${stableHash(value[k])}`).join(",")+"}"}function decimalPlaces(num){const match=String(num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);if(!match)return 0;const decimals=match[1]?match[1].length:0,exponent=match[2]?parseInt(match[2],10):0;return Math.max(0,decimals-exponent)}function normalizeToArray(input,fnName){if(null==input)throw new TypeError(`Primux/${fnName}: expected input, got ${input}`);if(input instanceof HTMLElement)return[input];if(NodeList.prototype.isPrototypeOf(input)||HTMLCollection.prototype.isPrototypeOf(input)){if(0===input.length)throw new RangeError(`Primux/${fnName}: element collection must not be empty`);return Array.from(input)}if(Array.isArray(input)){if(0===input.length)throw new RangeError(`Primux/${fnName}: array must not be empty`);return input.flat(1/0)}if("string"==typeof input){const trimmed=input.trim();if(""===trimmed)throw new RangeError(`Primux/${fnName}: string must not be empty`);return[trimmed]}throw new TypeError(`Primux/${fnName}: expected HTMLElement, NodeList, HTMLCollection, array, or string`)}function checkChar(c,fn){if("string"!=typeof c||1!==c.length)throw new TypeError(`Primux/${fn}(str, char): expected a single-character string`)}function getDuration(duration){return"number"==typeof duration?duration:300}function deepEqual(a,b){return stableHash(a)===stableHash(b)}function guardNegativeNumber(length,fn){if(length<0)throw new RangeError(`Primux/${fn}: value must not be negative`)}function uppercaseWords(str){return guard("uppercaseWords",{str:str},{str:"string"}),str?str.trim().split(/\s+/).map(w=>w[0].toUpperCase()+w.slice(1)).join(" "):""}function lowercaseWords(str){return guard("lowercaseWords",{str:str},{str:"string"}),str?str.trim().split(/\s+/).map(w=>w[0].toLowerCase()+w.slice(1)).join(" "):""}function truncate(str,length,ellipsis="..."){return guard("truncate",{str:str,length:length,ellipsis:ellipsis},{str:"string",length:"number",ellipsis:"string?"}),str&&length?(guardNegativeNumber(length,"truncate(str, length, ellipsis?)"),str.length<=length?str:str.slice(0,length)+ellipsis):""}function uppercaseChar(char){return guard("uppercaseChar",{char:char},{char:"string"}),char?(checkChar(char,"uppercaseChar(char)"),char.toUpperCase()):""}function lowercaseFirstChar(str){if(guard("lowercaseFirstChar",{str:str},{str:"string"}),!str)return"";const chars=Array.from(str);return chars[0]=chars[0].toLowerCase(),chars.join("")}function uppercaseFirstChar(str){if(guard("uppercaseFirstChar",{str:str},{str:"string"}),!str)return"";const chars=Array.from(str);return chars[0]=chars[0].toUpperCase(),chars.join("")}function lowercaseChar(char){return guard("lowercaseChar",{char:char},{char:"string"}),char?(checkChar(char,"lowercaseChar(char)"),char.toLowerCase()):""}function slugify(str){return guard("slugify",{str:str},{str:"string"}),str?str.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,""):""}function stripHtml(html){if(guard("stripHtml",{html:html},{html:"string"}),"undefined"!=typeof document){const div=createElement("div",{html:html});return div.querySelectorAll("script, style").forEach(el=>el.remove()),div.textContent||""}return html?html.replace(/<script[\s\S]*?>[\s\S]*?<\/script>/gi,"").replace(/<style[\s\S]*?>[\s\S]*?<\/style>/gi,"").replace(/<[^>]+>/g,""):""}function escapeHtml(html){return guard("escapeHtml",{html:html},{html:"string"}),html?html.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):""}function countOccurrences(str,s){if(guard("countOccurrences",{str:str,s:s},{str:"string",s:"string"}),!s||!str)return 0;let count=0,pos=0;for(;-1!==(pos=str.indexOf(s,pos));)count++,pos+=s.length;return count}function reverseString(str){return guard("reverseString",{str:str},{str:"string"}),str?Array.from(str).reverse().join(""):""}function padCenter(str,length,pad=" "){if(guard("padCenter",{str:str,length:length,pad:pad},{str:"string",length:"number",pad:"string?"}),guardNegativeNumber(length,"padCenter(str, length, pad?)"),!pad)throw new TypeError("Primux/padCenter: pad must be non-empty");const strLen=str.length;if(strLen>=length)return str;const totalPad=length-strLen,left=Math.floor(totalPad/2),right=totalPad-left,makePad=n=>pad.repeat(Math.ceil(n/pad.length)).slice(0,n);return makePad(left)+str+makePad(right)}function removeAccent(str){return guard("removeAccent",{str:str},{str:"string"}),str?str.normalize("NFD").replace(/[\u0300-\u036f]/g,""):""}function isPalindrome(str){guard("isPalindrome",{str:str},{str:"string"});const cleaned=str?str.toLowerCase().replace(/[^\p{L}\p{N}]/gu,""):"";return cleaned===Array.from(cleaned).reverse().join("")}function first(array){return guard("first",{array:array},{array:"array"}),0===array.length?void 0:array[0]}function last(array){return guard("last",{array:array},{array:"array"}),0===array.length?void 0:array[array.length-1]}function atSafe(array,index){guard("atSafe",{array:array,index:index},{array:"array",index:"number"});const len=array.length,i=index<0?len+index:index;return i<0||i>=len?{value:void 0,exists:!1}:{value:array[i],exists:!0}}function sum(array){guard("sum",{array:array},{array:"array"});let total=0;for(let i=0;i<array.length;i++){const v=array[i];"number"==typeof v&&Number.isFinite(v)&&(total+=v)}return total}function average(array){guard("average",{array:array},{array:"array"});let total=0,count=0;for(let i=0;i<array.length;i++){const v=array[i];"number"==typeof v&&Number.isFinite(v)&&(total+=v,count++)}return 0===count?void 0:total/count}function min(array){let min;guard("min",{array:array},{array:"array"});for(let i=0;i<array.length;i++){const v=array[i];"number"==typeof v&&Number.isFinite(v)&&(void 0===min||v<min)&&(min=v)}return min}function max(array){let max;guard("max",{array:array},{array:"array"});for(let i=0;i<array.length;i++){const v=array[i];"number"==typeof v&&Number.isFinite(v)&&(void 0===max||v>max)&&(max=v)}return max}function range(array){let max,min;guard("range",{array:array},{array:"array"});for(let i=0;i<array.length;i++){const v=array[i];"number"==typeof v&&Number.isFinite(v)&&((void 0===max||v>max)&&(max=v),(void 0===min||v<min)&&(min=v))}return void 0===max||void 0===min?void 0:max-min}function median(array){guard("median",{array:array},{array:"array"});const nums=array.filter(v=>"number"==typeof v&&Number.isFinite(v));if(0===nums.length)return;nums.sort((a,b)=>a-b);const mid=Math.floor(nums.length/2);return nums.length%2==0?(nums[mid-1]+nums[mid])/2:nums[mid]}function unique(array){guard("unique",{array:array},{array:"array"});const seen=new Map,result=[];for(const v of array){const key=stableHash(v);seen.has(key)||(seen.set(key,!0),result.push(v))}return result}function duplicates(array){guard("duplicates",{array:array},{array:"array"});const count=new Map,originals=new Map,result=[];for(const v of array){const key=stableHash(v);count.has(key)?count.set(key,count.get(key)+1):(originals.set(key,v),count.set(key,1))}for(const[key,c]of count.entries())c>1&&result.push(originals.get(key));return result}function count(array,value){if(guard("count",{array:array,value:value},{array:"array",value:"any?"}),void 0!==value){const key=stableHash(value);let total=0;for(const v of array)stableHash(v)===key&&total++;return total}const result=new Map;for(const v of array){const key=stableHash(v);result.set(key,(result.get(key)||0)+1)}return result}function containsAll(array,other){guard("containsAll",{array:array,other:other},{array:"array",other:"array"});const map=new Map;for(const v of array)map.set(stableHash(v),!0);for(const v of other)if(!map.has(stableHash(v)))return!1;return!0}function intersection(array,other,options={}){guard("intersection",{array:array,other:other,options:options},{array:"array",other:"array",options:"object?"});const{unique:unique=!1}=options,map=new Map,result=[],seen=new Set;for(const v of other)map.set(stableHash(v),!0);for(const v of array){const h=stableHash(v);map.has(h)&&(unique?seen.has(h)||(result.push(v),seen.add(h)):result.push(v))}return result}function union(array,other){guard("union",{array:array,other:other},{array:"array",other:"array"});const result=[],seen=new Map;for(const v of[...array,...other]){const key=stableHash(v);seen.has(key)||(seen.set(key,!0),result.push(v))}return result}function remove(array,value){if(guard("remove",{array:array},{array:"array"}),arguments.length<2)throw new TypeError('Primux/remove(array, value): parameter "value" is required');return array.filter(v=>!deepEqual(v,value))}function swap(array,fIndex,sIndex){if(guard("swap",{array:array,fIndex:fIndex,sIndex:sIndex},{array:"array",fIndex:"number",sIndex:"number"}),fIndex<0||fIndex>=array.length||sIndex<0||sIndex>=array.length)throw new RangeError("swap(array, i, j): index out of bounds");const newArr=[...array],temp=newArr[fIndex];return newArr[fIndex]=newArr[sIndex],newArr[sIndex]=temp,newArr}function clear(array){guard("clear",{array:array},{array:"array"}),array.splice(0,array.length)}function chunk(array,size){guard("chunk",{array:array,size:size},{array:"array",size:"number"});const result=[];if(size<=0)throw new RangeError("Primux/chunk: size must be greater than 0");for(let i=0;i<array.length;i+=size)result.push(array.slice(i,i+size));return result}function zip(...arrays){arrays.forEach(a=>guard("zip",{a:a},{a:"array"}));const result=[],minLength=Math.min(...arrays.map(a=>a.length));for(let i=0;i<minLength;i++)result.push(arrays.map(a=>a[i]));return result}function flattenDeep(array){guard("flattenDeep",{array:array},{array:"array"});const result=[],stack=[...array];for(;stack.length;){const value=stack.pop();Array.isArray(value)?stack.push(...value):result.push(value)}return result.reverse()}function flattenTo(array,depth=1){guard("flattenTo",{array:array,depth:depth},{array:"array",depth:"number?"}),depth<0&&(depth=0);const result=[],deep=(arr,currentDepth)=>{arr.forEach(item=>{Array.isArray(item)&¤tDepth<depth?deep(item,currentDepth+1):result.push(item)})};return deep(array,0),result}function sortAsc(array,comparator){return guard("sortAsc",{array:array,comparator:comparator},{array:"array",comparator:"function?"}),"function"==typeof comparator?[...array].sort(comparator):[...array].sort((a,b)=>{const toNumber=v=>"boolean"==typeof v?v?1:0:v;return"number"==typeof a&&"number"==typeof b?a-b:"string"==typeof a&&"string"==typeof b?a.localeCompare(b):toNumber(a)-toNumber(b)})}function sortDesc(array,comparator){return guard("sortDesc",{array:array,comparator:comparator},{array:"array",comparator:"function?"}),"function"==typeof comparator?[...array].sort((a,b)=>comparator(b,a)):[...array].sort((a,b)=>{const toNumber=v=>"boolean"==typeof v?v?1:0:v;return"number"==typeof a&&"number"==typeof b?b-a:"string"==typeof a&&"string"==typeof b?b.localeCompare(a):toNumber(b)-toNumber(a)})}function shuffle(array){guard("shuffle",{array:array},{array:"array"});const result=[...array];for(let i=result.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[result[i],result[j]]=[result[j],result[i]]}return result}function sample(array,count=1){if(guard("sample",{array:array,count:count},{array:"array",count:"number?"}),0===array.length)return;if(count>array.length)throw new RangeError("Primux/sample: count exceeds array length");return shuffle(array).slice(0,count)}function compact(array){return guard("compact",{array:array},{array:"array"}),array.filter(v=>Boolean(v))}function isEmpty(collection){return guard("isEmpty",{collection:collection},{collection:"array|object"}),Array.isArray(collection)?0===collection.length:0===Object.keys(collection).length}function isNotEmpty(collection){return!isEmpty(collection)}function deepClone(value,seen=new WeakMap){if(null===value||"object"!=typeof value)return value;if(seen.has(value))return seen.get(value);if(value instanceof Date)return new Date(value);if(value instanceof RegExp)return new RegExp(value.source,value.flags);if(value instanceof Map){const result=new Map;return seen.set(value,result),value.forEach((v,k)=>{result.set(deepClone(k,seen),deepClone(v,seen))}),result}if(value instanceof Set){const result=new Set;return seen.set(value,result),value.forEach(v=>result.add(deepClone(v,seen))),result}if(Array.isArray(value)){const result=[];return seen.set(value,result),value.forEach((v,i)=>result[i]=deepClone(v,seen)),result}const result=Object.create(Object.getPrototypeOf(value));seen.set(value,result);for(const key of Reflect.ownKeys(value)){const desc=Object.getOwnPropertyDescriptor(value,key);"value"in desc&&(desc.value=deepClone(desc.value,seen)),Object.defineProperty(result,key,desc)}return result}function random(p1,p2,precision=0){if(Array.isArray(p1)){if(guard("random",{p1:p1},{p1:"array"}),0===p1.length)return;return p1[Math.floor(Math.random()*p1.length)]}guard("random",{p1:p1,p2:p2,precision:precision},{p1:"number",p2:"number",precision:"number?"});let min=p1,max=p2;if(min>max&&([min,max]=[max,min]),precision>0){const rand=Math.random()*(max-min)+min;return Number(rand.toFixed(precision))}return Math.floor(Math.random()*(max-min+1))+min}function keysArray(obj){return guard("keysArray",{obj:obj},{obj:"object"}),Reflect.ownKeys(obj)}function valuesArray(obj){return guard("valuesArray",{obj:obj},{obj:"object"}),Reflect.ownKeys(obj).map(k=>obj[k])}function entriesArray(obj){return guard("entriesArray",{obj:obj},{obj:"object"}),Reflect.ownKeys(obj).map(k=>[k,obj[k]])}function keysLength(obj){return guard("keysLength",{obj:obj},{obj:"object"}),Reflect.ownKeys(obj).length}function has(obj,key){return guard("has",{obj:obj,key:key},{obj:"object",key:"string|symbol"}),Object.prototype.hasOwnProperty.call(obj,key)}function deepMerge(target,source,seen=new WeakMap){if(guard("deepMerge",{target:target,source:source},{target:"object?",source:"object"}),null===source||"object"!=typeof source)return source;if(null===target||"object"!=typeof target)return deepClone(source);let innerMap=seen.get(target);if(innerMap&&innerMap.has(source))return innerMap.get(source);const result=Array.isArray(source)?[]:Object.create(Object.getPrototypeOf(source));innerMap||(innerMap=new WeakMap,seen.set(target,innerMap)),innerMap.set(source,result);for(const key of Reflect.ownKeys(target))result[key]=target[key];for(const key of Reflect.ownKeys(source)){const sVal=source[key],tVal=result[key];result[key]=sVal&&"object"==typeof sVal?deepMerge(tVal,sVal,seen):sVal}return result}function mergeAll(...objects){if(guard("mergeAll",{objects:objects},{objects:"array"}),!objects.length)return{};const seen=new WeakMap;let result={};for(const obj of objects)result=deepMerge(result,obj,seen);return result}function pick(obj,keysArr){guard("pick",{obj:obj,keysArr:keysArr},{obj:"object",keysArr:"array"});const result={};for(const key of keysArr){if("string"!=typeof key&&"symbol"!=typeof key)throw new TypeError("pick(): keys must be string or symbol");has(obj,key)&&(result[key]=obj[key])}return result}function omit(obj,keysArr){guard("omit",{obj:obj,keysArr:keysArr},{obj:"object",keysArr:"array"});const result=deepClone(obj);for(const key of keysArr){if("string"!=typeof key&&"symbol"!=typeof key)throw new TypeError("omit(): keys must be string or symbol");delete result[key]}return result}function mapValues(obj,callback){guard("mapValues",{obj:obj,callback:callback},{obj:"object",callback:"function"});const result={};for(const key of Reflect.ownKeys(obj))result[key]=callback(obj[key],key,obj);return result}function mapKeys(obj,callback){guard("mapKeys",{obj:obj,callback:callback},{obj:"object",callback:"function"});const result={};for(const key of Reflect.ownKeys(obj)){const newKey=callback(key,obj[key],obj);if("string"!=typeof newKey&&"symbol"!=typeof newKey)throw new TypeError("mapKeys(): callback must return string or symbol");result[newKey]=obj[key]}return result}function mapEntries(obj,callback){guard("mapEntries",{obj:obj,callback:callback},{obj:"object",callback:"function"});const result={};for(const key of Reflect.ownKeys(obj)){const[newKey,newValue]=callback(key,obj[key],obj);if("string"!=typeof newKey&&"symbol"!=typeof newKey)throw new TypeError("mapEntries(): newKey must be string or symbol");result[newKey]=newValue}return result}function filterObj(obj,callback){guard("filterObj",{obj:obj,callback:callback},{obj:"object",callback:"function"});const result={};for(const key of Reflect.ownKeys(obj))callback(obj[key],key,obj)&&(result[key]=obj[key]);return result}function deepFreeze(obj,seen=new WeakSet){if(null===obj||"object"!=typeof obj||seen.has(obj))return obj;seen.add(obj),Object.freeze(obj);for(const key of Reflect.ownKeys(obj))deepFreeze(obj[key],seen);return obj}function keyBy(arr,cb){guard("keyBy",{arr:arr,cb:cb},{arr:"array",cb:"function"});const result={};for(const item of arr){const key=cb(item);if("string"!=typeof key&&"symbol"!=typeof key&&"number"!=typeof key)throw new TypeError("keyBy(): key must be string or symbol or number");result[key]=item}return result}function invert(obj){guard("invert",{obj:obj},{obj:"object"});const result={};for(const key of Reflect.ownKeys(obj)){const value=obj[key];result["symbol"==typeof value?value:String(value)]=key}return result}function once(fn){guard("once",{fn:fn},{fn:"function"});let result,called=!1;return function(...args){return called||(called=!0,result=fn.apply(this,args)),result}}function noop(){}function identity(value){return value}function debounce(fn,delay,options={}){let timerId;guard("debounce",{fn:fn,delay:delay,options:options},{fn:"function",delay:"number",options:"object?"});let lastCall=0;const{leading:leading=!1,trailing:trailing=!0}=options;return function(...args){const context=this,now=Date.now();leading&&now-lastCall>delay&&(fn.apply(context,args),lastCall=now),clearTimeout(timerId),trailing&&(timerId=setTimeout(()=>{(!leading||now-lastCall>=delay)&&(fn.apply(context,args),lastCall=Date.now())},delay))}}function throttle(fn,delay){guard("throttle",{fn:fn,delay:delay},{fn:"function",delay:"number"});let lastTime=0;return function(...args){const now=Date.now();now-lastTime>=delay&&(lastTime=now,fn.apply(this,args))}}function memoize(fn,resolver){guard("memoize",{fn:fn,resolver:resolver},{fn:"function",resolver:"function?"});const cache=new Map;return function(...args){const key=resolver?resolver(...args):JSON.stringify(args);if(cache.has(key))return cache.get(key);const result=fn.apply(this,args);return cache.set(key,result),result}}function retry(fn,times){if(guard("retry",{fn:fn,times:times},{fn:"function",times:"number"}),times<0)throw new RangeError("Primux/retry(fn, times): times should be a non-negative number");let attempts=0;for(;attempts<times;)try{return fn()}catch(err){if(attempts++,attempts>=times)throw err}}async function retryAsync(fn,times){if(guard("retryAsync",{fn:fn,times:times},{fn:"function",times:"number"}),times<0)throw new RangeError("Primux/retryAsync(fn, times): times should be a non-negative number");let attempts=0;for(;attempts<times;)try{return await fn()}catch(err){if(attempts++,attempts>=times)throw err}}function time(fn,label){guard("time",{fn:fn,label:label},{fn:"function",label:"string?"});const start=performance.now();fn();const duration=performance.now()-start+"ms";return label?`${label} : ${duration}`:duration}function sleep(ms){return guard("sleep",{ms:ms},{ms:"number"}),new Promise(resolve=>setTimeout(resolve,ms))}function timeout(fn,ms){return guard("timeout",{fn:fn,ms:ms},{fn:"function",ms:"number"}),(...args)=>Promise.race([Promise.resolve(fn(...args)),new Promise((_,reject)=>setTimeout(()=>reject(new Error(`timeout after ${ms}ms`)),ms))])}function pipe(...fns){if(0===fns.length)throw new Error("pipe(): parameter should not be empty");return fns.forEach(fn=>guard("pipe",{fn:fn},{fn:"function"})),(...args)=>fns.reduce((acc,fn)=>Array.isArray(acc)?fn(...acc):fn(acc),args)}function compose(...fns){if(0===fns.length)throw new Error("compose(): parameter should not be empty");fns.forEach(fn=>guard("compose",{fn:fn},{fn:"function"}));const reversed=[...fns].reverse();return(...args)=>reversed.reduce((acc,fn)=>Array.isArray(acc)?fn(...acc):fn(acc),args)}function before(fn,times){guard("before",{fn:fn,times:times},{fn:"function",times:"number"});let lastResult,count=0;return function(...args){return count<times&&(lastResult=fn.apply(this,args),count++),lastResult}}function after(fn,times){guard("after",{fn:fn,times:times},{fn:"function",times:"number"});let count=0;return function(...args){if(count++,count>=times)return fn.apply(this,args)}}async function series(fns,initialValue){guard("series",{fns:fns,initialValue:initialValue},{fns:"array",initialValue:"any?"});let result=initialValue;for(const fn of fns)guard("series",{fn:fn},{fn:"function"}),result=await fn(result);return result}async function parallel(fns){return guard("parallel",{fns:fns},{fns:"array"}),Promise.all(fns.map(fn=>(guard("parallel",{fn:fn},{fn:"function"}),fn())))}function tryCatch(fn,fallback){return guard("tryCatch",{fn:fn,fallback:fallback},{fn:"function",fallback:"function?"}),function(...args){try{const result=fn(...args);return result instanceof Promise?result.then(res=>res).catch(err=>err):result}catch(err){return err}finally{"function"==typeof fallback&&fallback()}}}function lazy(fn){return guard("lazy",{fn:fn},{fn:"function"}),function(...args){return fn(...args)}}const tap=(fn=console.log)=>value=>(guard("tap",{fn:fn},{fn:"function"}),"function"==typeof fn&&fn(value),value),asyncTap=(fn=console.log)=>async value=>(guard("asyncTap",{fn:fn},{fn:"function"}),"function"==typeof fn&&await fn(value),value);async function retryUntil(fn,condition,{maxAttempts:maxAttempts=5,delay:delay=500}={}){if(guard("retryUntil",{fn:fn,condition:condition},{fn:"function",condition:"function"}),!Number.isFinite(maxAttempts)||maxAttempts<0)throw new RangeError("Primux/retryUntil(fn, condition, options): maxAttempts should be a finite non-negative number");if(!Number.isFinite(delay)||delay<0)throw new RangeError("Primux/retryUntil(fn, condition, options): delay should be a finite non-negative number");let result,attempt=0;for(;attempt<maxAttempts;){if(attempt++,result=await fn(),condition(result))return result;delay&&await new Promise(res=>setTimeout(res,delay))}throw new Error(`retryUntil: condition not met after ${maxAttempts} attempts`)}function safeDivide(a,b,defaultValue=0){if(guard("safeDivide",{a:a,b:b,defaultValue:defaultValue},{a:"number",b:"number",defaultValue:"number?"}),0===b)return defaultValue;const result=a/b;return isNaN(result)?defaultValue:result}function safeAdd(a,b){guard("safeAdd",{a:a,b:b},{a:"number",b:"number"});const factor=10**Math.max(decimalPlaces(a),decimalPlaces(b));return(Math.round(a*factor)+Math.round(b*factor))/factor}function safeJSONParse(str,fallback=null){if("string"!=typeof str||!str.trim())return fallback;try{return JSON.parse(str)??fallback}catch{return fallback}}function safeSub(a,b){guard("safeSub",{a:a,b:b},{a:"number",b:"number"});const factor=10**Math.max(decimalPlaces(a),decimalPlaces(b));return(Math.round(a*factor)-Math.round(b*factor))/factor}function safeMultiply(a,b){guard("safeMultiply",{a:a,b:b},{a:"number",b:"number"});const dp=decimalPlaces(a)+decimalPlaces(b);return Math.round(a*b*10**dp)/10**dp}function clamp(value,min,max){return guard("clamp",{value:value,min:min,max:max},{value:"number",min:"number",max:"number"}),value<min?min:value>max?max:value}function round(value,decimals=0){guard("round",{value:value,decimals:decimals},{value:"number",decimals:"number?"});const factor=Math.pow(10,decimals);return Math.round(value*factor)/factor}function between(value,min,max,inclusive=!0){return guard("between",{value:value,min:min,max:max,inclusive:inclusive},{value:"number",min:"number",max:"number",inclusive:"boolean?"}),min>max&&([min,max]=[max,min]),inclusive?value>=min&&value<=max:value>min&&value<max}function toFixedNumber(value,decimal){if(guard("toFixedNumber",{value:value,decimal:decimal},{value:"number",decimal:"number"}),!Number.isInteger(decimal)||decimal<0)throw new Error("toFixedNumber(): decimal must be non-negative integer");return Number(value.toFixed(decimal))}function percent(value,total,precision=0){if(guard("percent",{value:value,total:total,precision:precision},{value:"number",total:"number",precision:"number?"}),!Number.isInteger(precision)||precision<0)throw new Error("percent(): precision must be non-negative integer");return 0===total?0:Number((value/total*100).toFixed(precision))}function almostEqual(a,b,epsilon=1e-10){if(guard("almostEqual",{a:a,b:b,epsilon:epsilon},{a:"number",b:"number",epsilon:"number?"}),epsilon<0)throw new Error("almostEqual(): epsilon must be non-negative");return Math.abs(a-b)<epsilon}function isEven(...values){if(0===values.length)throw new Error("isEven(): at least one parameter required");return values.forEach(v=>guard("isEven",{v:v},{v:"number"})),values.every(v=>v%2==0)}function isOdd(...values){if(0===values.length)throw new Error("isOdd(): at least one parameter required");return values.forEach(v=>guard("isOdd",{v:v},{v:"number"})),values.every(v=>v%2!=0)}function factorial(n){if(guard("factorial",{n:n},{n:"number"}),!Number.isInteger(n)||n<0)throw new Error("factorial(): parameter must be non-negative integer");if(n<=1)return 1;let result=1;for(let i=2;i<=n;i++)result*=i;return result}function isPrime(n){if(guard("isPrime",{n:n},{n:"number"}),!Number.isInteger(n)||n<2)return!1;for(let i=2;i<=Math.sqrt(n);i++)if(n%i===0)return!1;return!0}function gcd(a,b){for(guard("gcd",{a:a,b:b},{a:"number",b:"number"}),a=Math.abs(a),b=Math.abs(b);0!==b;)[a,b]=[b,a%b];return a}function lcm(a,b){return guard("lcm",{a:a,b:b},{a:"number",b:"number"}),0===a||0===b?0:Math.abs(a*b)/gcd(a,b)}function degreesToRadians(deg){return guard("degreesToRadians",{deg:deg},{deg:"number"}),deg*(Math.PI/180)}function radiansToDegrees(rad){return guard("radiansToDegrees",{rad:rad},{rad:"number"}),rad*(180/Math.PI)}function toOrdinal(n){guard("toOrdinal",{n:n},{n:"number"});const suffixes=["th","st","nd","rd"],v=Math.abs(n)%100;return n+(suffixes[(v-20)%10]||suffixes[v]||suffixes[0])}function randomIntArray(min,max,length,precision=0){if(guard("randomIntArray",{min:min,max:max,length:length,precision:precision},{min:"number",max:"number",length:"number",precision:"number?"}),!Number.isInteger(length)||length<0)throw new Error("randomIntArray(): length must be non-negative integer");if(!Number.isInteger(precision)||precision<0)throw new TypeError("randomIntArray(): precision must be non-negative integer");min>max&&([min,max]=[max,min]);const array=[];for(let i=0;i<length;i++){const rand=Math.random()*(max-min)+min;array.push(precision>0?Number(rand.toFixed(precision)):Math.floor(rand))}return array}function isPositive(n){return guard("isPositive",{n:n},{n:"number"}),n>0}function isNegative(n){return guard("isNegative",{n:n},{n:"number"}),n<0}function randomUniqueIntArray(min,max,length,precision=0){if(guard("randomUniqueArray",{min:min,max:max,length:length,precision:precision},{min:"number",max:"number",length:"number",precision:"number?"}),!Number.isInteger(length)||length<0)throw new TypeError("length must be a non-negative integer");if(!Number.isInteger(precision)||precision<0)throw new Error("randomUniqueArray(): precision must be non-negative integer");min>max&&([min,max]=[max,min]);const factor=10**precision,scaledMin=Math.ceil(min*factor),scaledMax=Math.floor(max*factor);if(length>scaledMax-scaledMin+1)throw new Error("randomUniqueArray(): length exceeds unique range");const range=[];for(let i=scaledMin;i<=scaledMax;i++)range.push(i);const result=[];for(;result.length<length;){const idx=Math.floor(Math.random()*range.length),value=range.splice(idx,1)[0];result.push(Number((value/factor).toFixed(precision)))}return result}function isTrue(value){return guard("isTrue",{value:value},{value:"any"}),!!value}function isFalse(value){return guard("isFalse",{value:value},{value:"any"}),!value}function allTrue(...values){if(0===values.length)throw new Error("Primux/allTrue: at least one parameter required");return values.every(v=>!!v)}function allFalse(...values){if(0===values.length)throw new Error("Primux/allFalse: at least one parameter required");return values.every(v=>!v)}function anyTrue(...values){if(0===values.length)throw new Error("Primux/anyTrue: at least one parameter required");return values.some(v=>!!v)}function anyFalse(...values){if(0===values.length)throw new Error("Primux/anyFalse: at least one parameter required");return values.some(v=>!v)}function xor(a,b){return guard("xor",{a:a,b:b},{a:"any",b:"any"}),!!a!=!!b}function and(...values){if(0===values.length)throw new Error("Primux/and: at least one parameter required");return values.every(v=>!!v)}function or(...values){if(0===values.length)throw new Error("Primux/or: at least one parameter required");return values.some(v=>!!v)}function not(value){return guard("not",{value:value},{value:"any"}),!value}function coerce(value){return guard("coerce",{value:value},{value:"any"}),!!value}function ifTruthy(value,callback){if(guard("ifTruthy",{value:value,callback:callback},{value:"any",callback:"function"}),value)return callback(value)}function ifFalsy(value,callback){if(guard("ifFalsy",{value:value,callback:callback},{value:"any",callback:"function"}),!value)return callback(value)}function isNaN(value){return guard("isNaN",{value:value},{value:"any"}),"number"==typeof value&&Number.isNaN(value)}function defaultIfNaN(value,defaultValue=void 0){return guard("defaultIfNaN",{value:value,defaultValue:defaultValue},{value:"any",defaultValue:"any"}),isNaN(value)?defaultValue:value}function isNull(value){return guard("isNull",{value:value},{value:"any"}),null===value}function isUndefined(value){if(arguments.length<1)throw new TypeError('Primux/isUndefined(value): parameter "value" is required');return void 0===value}function isNil(value){if(arguments.length<1)throw new TypeError('Primux/isNil(value): parameter "value" is required');return null==value}function defaultIfNull(value,defaultValue){return guard("defaultIfNull",{value:value,defaultValue:defaultValue},{value:"any",defaultValue:"any"}),null===value?defaultValue:value}function defaultIfNil(value,defaultValue){if(arguments.length<2)throw new TypeError('Primux/defaultIfNil(value, defaultValue): parameter "value" and "defaultValue" is required');return null==value?defaultValue:value}function defaultIfUndefined(value,defaultValue){if(arguments.length<2)throw new TypeError('Primux/defaultIfUndefined(value, defaultValue): parameter "value" and "defaultValue" is required');return void 0===value?defaultValue:value}function coalesce(...values){if(0===values.length)throw new Error("Primux/coalesce: at least one parameter required");return values.find(v=>null!=v)}function isObject(value){return guard("isObject",{value:value},{value:"any"}),null!==value&&"object"==typeof value&&Object.getPrototypeOf(value)===Object.prototype}function isArray(value){return guard("isArray",{value:value},{value:"any"}),Array.isArray(value)}function isCollection(value){return guard("isCollection",{value:value},{value:"any"}),null!==value&&(!!Array.isArray(value)||(value instanceof Map||value instanceof Set||value instanceof WeakMap||value instanceof WeakSet||Object.getPrototypeOf(value)===Object.prototype))}function checkType(value,expectedType){if("string"!=typeof expectedType)throw new TypeError("Primux/checkType(): expectedType must be a string");switch(expectedType){case"number":return"number"==typeof value&&!Number.isNaN(value);case"int":return Number.isInteger(value);case"string":return"string"==typeof value;case"boolean":case"bool":return"boolean"==typeof value;case"float":return"number"==typeof value&&!Number.isNaN(value)&&!Number.isInteger(value);case"array":return Array.isArray(value);case"object":return null!==value&&"object"==typeof value&&!Array.isArray(value);case"null":return null===value;case"undefined":return void 0===value;case"symbol":return"symbol"==typeof value;case"element":return value instanceof Element;default:throw new Error(`checkType(): unknown type "${expectedType}"`)}}function int(){return createType("number","int(): only accepts integer numbers",v=>Number.isSafeInteger(v))(...arguments)}function float(){return createType("float","float(): only accepts floating point numbers",v=>"number"==typeof v&&!Number.isNaN(v))(...arguments)}function string(){return createType("string","string(): only accepts string",v=>"string"==typeof v)(...arguments)}function bool(){return createType("boolean","bool(): only accepts boolean",v=>"boolean"==typeof v)(...arguments)}function array(){return createType("array","array(): only accepts arrays",v=>Array.isArray(v))(...arguments)}function object(){return createType("object","object(): only accepts plain objects",v=>null!==v&&"object"==typeof v&&Object.getPrototypeOf(v)===Object.prototype)(...arguments)}function sym(){return createType("symbol","sym(): only accepts symbol",v=>"symbol"==typeof v)(...arguments)}function isEmail(str){return guard("isEmail",{str:str},{str:"string"}),/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str)}function isURL(str){return guard("isURL",{str:str},{str:"string"}),/^(https?:\/\/)?([\w\-])+\.{1}([a-zA-Z]{2,63})([\/\w\-.?=&]*)*\/?$/.test(str)}function isPhone(str){return guard("isPhone",{str:str},{str:"string"}),/^\+?[\d\s\-()]{7,15}$/.test(str)}function isHexColor(str){return guard("isHexColor",{str:str},{str:"string"}),/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(str)}function isAlpha(str){return guard("isAlpha",{str:str},{str:"string"}),/^[A-Za-z]+$/.test(str)}function isAlphaNumeric(str){return guard("isAlphaNumeric",{str:str},{str:"string"}),/^[A-Za-z0-9]+$/.test(str)}function isNumeric(str){return guard("isNumeric",{str:str},{str:"string"}),/^\d+$/.test(str)}function matchAll(str,pattern){return guard("matchAll",{str:str,pattern:pattern},{str:"string",pattern:"RegExp"}),[...str.matchAll(pattern)].map(m=>m[0])}function replaceAll(str,pattern,replacement){guard("replaceAll",{str:str,pattern:pattern,replacement:replacement},{str:"string",pattern:"RegExp|string",replacement:"string"});const regex=pattern instanceof RegExp?new RegExp(pattern.source,"g"):new RegExp(pattern,"g");return str.replace(regex,replacement)}function testPattern(str,pattern){return guard("testPattern",{str:str,pattern:pattern},{str:"string",pattern:"RegExp"}),pattern.test(str)}function $id(s){return ensureDOM("$id"),guard("$id",{s:s},{s:"string"}),document.getElementById(s)}function $qs(s){return ensureDOM("$qs"),guard("$qs",{s:s},{s:"string"}),document.querySelector(s)}function $qsa(s){return ensureDOM("$qsa"),guard("$qsa",{s:s},{s:"string"}),document.querySelectorAll(s)}function $class(s){return ensureDOM("$class"),guard("$class",{s:s},{s:"string"}),document.getElementsByClassName(s)||null}function $tag(s){return ensureDOM("$tag"),guard("$tag",{s:s},{s:"string"}),document.getElementsByTagName(s)||null}function $name(s){return ensureDOM("$name"),guard("$name",{s:s},{s:"string"}),document.getElementsByName(s)||null}function siblings(el){return ensureDOM("siblings"),guard("siblings",{el:el},{el:"dom"}),el.parentNode?Array.from(el.parentNode.children).filter(child=>child!==el):[]}function setHTML(el,html){ensureDOM("setHTML"),guard("setHTML",{el:el,html:html},{el:"dom",html:"string"}),el.innerHTML=html}function createElement(tagName,options={}){guard("createElement",{tagName:tagName,options:options},{tagName:"string",options:"object?"});const el=document.createElement(tagName);if(options.class)if(Array.isArray(options.class))el.classList.add(...options.class);else{if("string"!=typeof options.class)throw new TypeError("createElement: 'class' must be string or array of strings");el.classList.add(options.class)}if(options.attrs){if(!isObject(options.attrs))throw new TypeError("createElement: 'attrs' must be an object");Object.entries(options.attrs).forEach(([key,value])=>el.setAttribute(key,value))}if(options.text&&(el.textContent=String(options.text)),options.html&&(el.innerHTML=String(options.html)),options.children){(Array.isArray(options.children)?options.children:[options.children]).forEach(child=>{guard("createElement/children",{child:child},{child:"dom"}),el.appendChild(child)})}return el}function empty(el){ensureDOM("empty"),guard("empty",{el:el},{el:"dom"}),el.innerHTML=""}function wrap(target,wrapper){return ensureDOM("wrap"),guard("wrap",{target:target,wrapper:wrapper},{target:"dom",wrapper:"dom"}),target.parentNode&&target.parentNode.insertBefore(wrapper,target),wrapper.appendChild(target),wrapper}function unwrap(wrapper){ensureDOM("unwrap"),guard("unwrap",{wrapper:wrapper},{wrapper:"dom"});const parent=wrapper.parentNode;if(!parent)return;Array.from(wrapper.childNodes).forEach(child=>parent.insertBefore(child,wrapper)),wrapper.remove()}function addClass(el,...classes){ensureDOM("addClass");const elements=el instanceof HTMLElement?[el]:el instanceof NodeList||Array.isArray(el)?Array.from(el):[];if(0===elements.length)throw new TypeError("Primux/addClass: el should be HTMLElement, NodeList or array of HTMLElements");const allClasses=classes.flat(1/0);return allClasses.forEach(c=>guard("addClass",{c:c},{c:"string"})),elements.forEach(element=>element.classList.add(...allClasses)),el}function removeClass(el,...classes){ensureDOM("removeClass");const elements=el instanceof HTMLElement?[el]:el instanceof NodeList||Array.isArray(el)?Array.from(el):[];if(0===elements.length)throw new TypeError("Primux/removeClass: el should be HTMLElement, NodeList or array of HTMLElements");const allClasses=classes.flat(1/0);return allClasses.forEach(c=>{if("string"!=typeof c)throw new TypeError("Primux/removeClass: class must be string")}),elements.forEach(element=>element.classList.remove(...allClasses)),el}function hasClass(el,...classes){ensureDOM("hasClass");const allClasses=classes.flat(1/0);if(!allClasses.every(c=>"string"==typeof c))throw new TypeError("Primux/hasClass: all classes must be strings");return allClasses.every(c=>el.classList.contains(c))}function data(el,key,value){ensureDOM("data"),guard("data",{el:el,key:key},{el:"dom",key:"string",key:"any"});const attrName=`data-${key.replace(/[A-Z]/g,m=>"-"+m.toLowerCase())}`;return void 0===value?el.getAttribute(attrName):null===value?el.removeAttribute(attrName):void el.setAttribute(attrName,value)}function on(elements,events,handler,option={}){ensureDOM("on"),guard("on",{handler:handler,option:option},{handler:"function",option:"object?"});const{once:once=!1}=option;guard("on",{once:once},{once:"boolean"});const elArr=normalizeToArray(elements,"on(elements, events, handler, options?)"),eventArr=normalizeToArray(events,"on(elements, events, handler, options?)");for(const el of elArr){guard("on",{el:el},{el:"dom"});for(const event of eventArr)guard("on",{event:event},{event:"string"}),el.addEventListener(event,handler,{once:once})}}function off(elements,events,handler){ensureDOM("off"),guard("off",{handler:handler},{handler:"function"});const elArr=normalizeToArray(elements,"off(elements, events, handler)"),eventArr=normalizeToArray(events,"off(elements, events, handler)");for(const el of elArr){guard("off",{el:el},{el:"dom"});for(const event of eventArr)guard("off",{event:event},{event:"string"}),el.removeEventListener(event,handler)}}function delegate(root,event,selector,handler){ensureDOM("delegate"),guard("delegate",{root:root,event:event,selector:selector,handler:handler},{root:"dom",event:"string",selector:"string",handler:"function"}),root.addEventListener(event,e=>{const target=e.target.closest(selector);target&&root.contains(target)&&handler.call(target,e)})}function trigger(elements,events,options={}){if(ensureDOM("trigger"),null===options||"object"!=typeof options)throw new TypeError("trigger(): options must be an object");const elArr=normalizeToArray(elements,"trigger(elements, events, options?)"),eventArr=normalizeToArray(events,"trigger(elements, events, options?)");for(const el of elArr){guard("trigger",{el:el},{el:"dom"});for(const eventName of eventArr){guard("trigger",{eventName:eventName},{eventName:"string"});const{detail:detail=null,bubbles:bubbles=!0,cancelable:cancelable=!0}=options;el.dispatchEvent(new CustomEvent(eventName,{detail:detail,bubbles:bubbles,cancelable:cancelable}))}}}function triggerPairs(pairs){for(const[el,event]of pairs)trigger(el,event)}function css(elements,prop,value){ensureDOM("css");const elArr=normalizeToArray(elements,"css(elements, prop, value)");for(const el of elArr){if(guard("css",{el:el},{el:"dom"}),"string"==typeof prop&&void 0===value)return getComputedStyle(el).getPropertyValue(prop);if("string"!=typeof prop){if(!isObject(prop))throw new TypeError("css(): invalid parameter");for(const key in prop)el.style[key]=prop[key]}else el.style[prop]=value}}function getStyle(el,property){return ensureDOM("getStyle"),guard("getStyle",{el:el,property:property},{el:"dom",property:"string"}),getComputedStyle(el).getPropertyValue(property)}function hide(...elements){ensureDOM("hide");const elArr=normalizeToArray(elements.flat(),"hide(elements)");for(const el of elArr)guard("hide",{el:el},{el:"dom"}),"none"!==el.style.display&&(el.dataset._display=getComputedStyle(el).getPropertyValue("display")),el.style.display="none"}function show(...elements){ensureDOM("show");const elArr=normalizeToArray(elements.flat(),"show(elements)");for(const el of elArr)guard("show",{el:el},{el:"dom"}),el.style.display=el.dataset._display??"",delete el.dataset._display}function toggleDisplay(...elements){ensureDOM("toggleDisplay");const elArr=normalizeToArray(elements.flat(),"toggleDisplay(elements)");for(const el of elArr){guard("toggleDisplay",{el:el},{el:"dom"});"none"===getComputedStyle(el).getPropertyValue("display")?(el.style.display=el.dataset._display??"",delete el.dataset._display):(el.dataset._display=getComputedStyle(el).getPropertyValue("display"),el.style.display="none")}}function addAnimation(...elements){ensureDOM("addAnimation");const className=elements.pop();guard("addAnimation",{className:className},{className:"string"});const elArr=normalizeToArray(elements.flat(),"addAnimation (elements)");for(const el of elArr)guard("addAnimation",{el:el},{el:"dom"}),el.classList.add(className)}function removeAnimation(...elements){ensureDOM("removeAnimation");const className=elements.pop();guard("removeAnimation",{className:className},{className:"string"});const elArr=normalizeToArray(elements.flat(),"removeAnimation(elements)");for(const el of elArr)guard("removeAnimation",{el:el},{el:"dom"}),el.classList.remove(className)}function offset(el){ensureDOM("offset"),guard("offset",{el:el},{el:"dom"});const rect=el.getBoundingClientRect();return{top:rect.top+window.scrollY,left:rect.left+window.scrollX}}function position(el){return ensureDOM("position"),guard("position",{el:el},{el:"dom"}),{top:el.offsetTop,left:el.offsetLeft}}function width(el){return ensureDOM("width"),guard("width",{el:el},{el:"dom"}),parseFloat(getComputedStyle(el).width)}function height(el){return ensureDOM("height"),guard("height",{el:el},{el:"dom"}),parseFloat(getComputedStyle(el).height)}function innerWidth(el){return ensureDOM("innerWidth"),guard("innerWidth",{el:el},{el:"dom"}),el.clientWidth}function innerHeight(el){return ensureDOM("innerHeight"),guard("innerHeight",{el:el},{el:"dom"}),el.clientHeight}function outerWidth(el,includeMargin=!1){ensureDOM("outerWidth"),guard("outerWidth",{el:el},{el:"dom"});let w=el.offsetWidth;if(includeMargin){const s=getComputedStyle(el);w+=parseFloat(s.marginLeft)+parseFloat(s.marginRight)}return w}function outerHeight(el,includeMargin=!1){ensureDOM("outerHeight"),guard("outerHeight",{el:el},{el:"dom"});let h=el.offsetHeight;if(includeMargin){const s=getComputedStyle(el);h+=parseFloat(s.marginTop)+parseFloat(s.marginBottom)}return h}function scrollTop(el=window){return ensureDOM("scrollTop"),el!==window&&guard("scrollTop",{el:el},{el:"dom"}),el===window?window.scrollY:el.scrollTop}function scrollLeft(el=window){return ensureDOM("scrollLeft"),el!==window&&guard("scrollLeft",{el:el},{el:"dom"}),el===window?window.scrollX:el.scrollLeft}function rect(el){ensureDOM("rect"),guard("rect",{el:el},{el:"dom"});const r=el.getBoundingClientRect();return{top:r.top,left:r.left,right:r.right,bottom:r.bottom,width:r.width,height:r.height}}function isInViewport(el,options={}){guard("isInViewport",{el:el,options:options},{el:"dom",options:"object?"});const{partial:partial=!0,offset:offset=0}=options,r=el.getBoundingClientRect(),vw=window.innerWidth,vh=window.innerHeight,top=r.top+offset,left=r.left+offset,right=r.right-offset,bottom=r.bottom-offset;return partial?bottom>-.5&&right>-.5&&top<vh+.5&&left<vw+.5:top>=-.5&&left>=-.5&&bottom<=vh+.5&&right<=vw+.5}function val(el){return ensureDOM("val"),guard("val",{el:el},{el:"dom"}),"value"in el?el.value:null}function setVal(elements,value){ensureDOM("setVal");const elArr=normalizeToArray(elements,"setVal(elements, value)");for(const el of elArr){if(guard("setVal",{el:el},{el:"dom"}),!("value"in el))throw new Error("setVal(): element does not support value");el.value=null==value?"":String(value)}}function isVisible(el,checkOpacity=!1){ensureDOM("isVisible"),guard("isVisible",{el:el,checkOpacity:checkOpacity},{el:"dom",checkOpacity:"boolean?"});const style=getComputedStyle(el);if("none"===style.display||"hidden"===style.visibility)return!1;if(checkOpacity&&0===parseFloat(style.opacity))return!1;const r=el.getBoundingClientRect();return r.width>0&&r.height>0}function isHidden(el,checkOpacity=!1){ensureDOM("isHidden"),guard("isHidden",{el:el,checkOpacity:checkOpacity},{el:"dom",checkOpacity:"boolean?"});const style=getComputedStyle(el);if("none"===style.display||"hidden"===style.visibility)return!0;if(checkOpacity&&0===parseFloat(style.opacity))return!0;const r=el.getBoundingClientRect();return 0===r.width||0===r.height}function fadeIn(el,duration=300){ensureDOM("fadeIn"),guard("fadeIn",{el:el,duration:duration},{el:"dom",duration:"number?"}),duration=getDuration(duration),el.style.opacity=0,el.style.display="","none"===getComputedStyle(el).display&&(el.style.display="block");let start=null;requestAnimationFrame(function animate(ts){start||(start=ts);const progress=Math.min((ts-start)/duration,1);el.style.opacity=progress,progress<1&&requestAnimationFrame(animate)})}function fadeOut(el,duration=300){ensureDOM("fadeOut"),guard("fadeOut",{el:el,duration:duration},{el:"dom",duration:"number?"}),duration=getDuration(duration);const initial=parseFloat(getComputedStyle(el).opacity)||1;let start=null;requestAnimationFrame(function animate(ts){start||(start=ts);const progress=Math.min((ts-start)/duration,1);el.style.opacity=initial*(1-progress),progress<1?requestAnimationFrame(animate):(el.style.display="none",el.style.opacity="")})}function slideDown(el,duration=300){ensureDOM("slideDown"),guard("slideDown",{el:el,duration:duration},{el:"dom",duration:"number?"}),duration=getDuration(duration),el.style.display="","none"===getComputedStyle(el).display&&(el.style.display="block");const height=el.scrollHeight;el.style.overflow="hidden",el.style.height="0px";let start=null;requestAnimationFrame(function animate(ts){start||(start=ts);const progress=Math.min((ts-start)/duration,1);el.style.height=height*progress+"px",progress<1?requestAnimationFrame(animate):(el.style.height="",el.style.overflow="")})}function slideUp(el,duration=300){ensureDOM("slideUp"),guard("slideUp",{el:el,duration:duration},{el:"dom",duration:"number?"}),duration=getDuration(duration);const height=el.scrollHeight;el.style.height=height+"px",el.style.overflow="hidden";let start=null;requestAnimationFrame(function animate(ts){start||(start=ts);const progress=Math.min((ts-start)/duration,1);el.style.height=height*(1-progress)+"px",progress<1?requestAnimationFrame(animate):(el.style.display="none",el.style.height="",el.style.overflow="")})}async function copyToClipboard(text){guard("copyToClipboard",{text:text},{text:"string"});try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(text),!0;const textarea=document.createElement("textarea");textarea.value=text,textarea.style.position="fixed",textarea.style.opacity="0",document.body.appendChild(textarea),textarea.focus(),textarea.select();const success=document.execCommand("copy");return document.body.removeChild(textarea),success}catch{return!1}}function scrollTo(target,options={}){ensureDOM("scrollTo");const{behavior:behavior="smooth",offset:offset=0,container:container=window}=options;if(!(container===window||container instanceof Element))throw new TypeError("scrollTo(): container must be window or DOM element");let top=0;if("number"==typeof target)top=target+offset;else{if(!(target instanceof Element))throw new TypeError("scrollTo(): target must be number or DOM element");{guard("scrollTo",{target:target},{target:"dom"});const rect=target.getBoundingClientRect();if(container===window)top=rect.top+window.pageYOffset+offset;else{if(!(container instanceof Element))throw new TypeError("scrollTo(): container must be window or DOM element");top=rect.top-container.getBoundingClientRect().top+container.scrollTop+offset}}}container===window?window.scrollTo({top:top,behavior:behavior}):container.scrollTo({top:top,behavior:behavior})}function firstChild(el){return ensureDOM("firstChild"),guard("firstChild",{el:el},{el:"dom"}),el.firstElementChild}function lastChild(el){return ensureDOM("lastChild"),guard("lastChild",{el:el},{el:"dom"}),el.lastElementChild}function setData(key,data,type="local"){guard("setData",{key:key,data:data,type:type},{key:"string",data:"object|string",type:"string?"});const storage=resolveStorage(type,"setData(key, data, type?)"),isPlainObject=isObject(data);storage.setItem(key,isPlainObject?JSON.stringify(data):data)}function getData(key,type="local"){guard("getData",{key:key,type:type},{key:"string",type:"string?"});const value=resolveStorage(type,"getData(key, type?)").getItem(key);if(null===value)return null;try{return JSON.parse(value)}catch{return value}}function removeData(key,type="local"){guard("removeData",{key:key,type:type},{key:"string",type:"string?"});resolveStorage(type,"removeData(key, type?)").removeItem(key)}function clearAllData(type="local"){guard("clearAllData",{type:type},{type:"string?"});resolveStorage(type,"clearAllData(type?)").clear()}function isTouchDevice(){return"ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0}function isTouchPhone(){return isTouchDevice()&&matchMedia("(pointer: coarse)").matches&&matchMedia("(hover: none)").matches}function isMouseDevice(){return matchMedia("(pointer: fine)").matches}function isHybridDevice(){return isTouchDevice()&&matchMedia("(pointer: fine)").matches}function supportsHover(){return matchMedia("(hover: hover)").matches}function supportsCoarsePointer(){return matchMedia("(pointer: coarse)").matches}function prefersReducedMotion(){return matchMedia("(prefers-reduced-motion: reduce)").matches}function prefersDarkMode(){return matchMedia("(prefers-color-scheme: dark)").matches}function prefersLightMode(){return matchMedia("(prefers-color-scheme: light)").matches}function times(n,fn){if(guard("times",{n:n,fn:fn},{n:"number",fn:"function"}),n<0)throw new TypeError("times(): n must be a positive number");for(let i=0;i<n;i++)fn(i)}function loopUntil(fn,condition){let result;guard("loopUntil",{fn:fn,condition:condition},{fn:"function",condition:"function"});do{result=fn()}while(!condition(result))}function canShare(){return"undefined"!=typeof navigator&&!!navigator.share}function share(data){return guard("share",{data:data},{data:"object"}),canShare()?navigator.share(data):Promise.reject("Share API not supported")}function canVibrate(){return"undefined"!=typeof navigator&&"vibrate"in navigator}function vibrate(pattern=200){return guard("vibrate",{pattern:pattern},{pattern:"number"}),!!canVibrate()&&navigator.vibrate(pattern)}function canAccessBattery(){return"undefined"!=typeof navigator&&"getBattery"in navigator}async function getBatteryInfo(){if(!canAccessBattery())return null;const battery=await navigator.getBattery();return{level:Math.round(100*battery.level),charging:battery.charging,chargingTime:battery.chargingTime===1/0?null:Math.round(battery.chargingTime/60),dischargingTime:battery.dischargingTime===1/0?null:Math.round(battery.dischargingTime/60)}}function canNotify(){return"undefined"!=typeof window&&"Notification"in window}function requestNotificationPermission(){return canNotify()?Notification.requestPermission():Promise.resolve("denied")}async function notify(title,options={},swPath=null){if(guard("notify",{title:title,options:options},{title:"string",options:"object?"}),!("Notification"in window))return null;if("granted"!==Notification.permission){if("granted"!==await Notification.requestPermission())return null}if("serviceWorker"in navigator){if(swPath){await navigator.serviceWorker.getRegistration()||await navigator.serviceWorker.register(swPath)}return(await navigator.serviceWorker.ready).showNotification(title,options)}return new Notification(title,options)}function canUseBluetooth(){return"undefined"!=typeof navigator&&"bluetooth"in navigator}function requestBluetoothDevice(options){if(guard("requestBluetoothDevice",{options:options},{options:"object"}),!canUseBluetooth())return Promise.reject(new Error("Bluetooth API not supported"));const hasFilters=Array.isArray(options.filters),hasAcceptAll=!0===options.acceptAllDevices;return hasFilters||hasAcceptAll?hasFilters&&hasAcceptAll?Promise.reject(new Error("Cannot use both 'filters' and 'acceptAllDevices'.")):navigator.bluetooth.requestDevice(options):Promise.reject(new Error("Either 'filters' or 'acceptAllDevices: true' is required."))}function getNetworkInfo(){const conn=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return conn?{effectiveType:conn.effectiveType,downlink:conn.downlink,rtt:conn.rtt,saveData:conn.saveData}:null}function canUseMediaDevices(){return"undefined"!=typeof navigator&&!(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia)}function canGeolocate(){return"undefined"!=typeof navigator&&"geolocation"in navigator}function queryPermission(name){return guard("queryPermission",{name:name},{name:"string"}),navigator.permissions?navigator.permissions.query({name:name}):Promise.resolve(null)}function isProbablyOnline(){return navigator.onLine||performance.getEntriesByType("resource").length>0}function ensureCanvas(canvas){return guard("ensureCanvas",{canvas:canvas},{canvas:"dom"}),canvas instanceof HTMLCanvasElement}function getCtx(canvas){if(guard("getCtx",{canvas:canvas},{canvas:"dom"}),!ensureCanvas(canvas))return null;const ctx=canvas.getContext("2d");return ctx||console.warn("getCtx: 2D context not supported"),ctx}function fixDPI(canvas,ctx){if(guard("fixDPI",{canvas:canvas,ctx:ctx},{canvas:"dom",ctx:"object"}),!ctx)return;const dpi=window.devicePixelRatio||1;canvas.width=canvas.clientWidth*dpi,canvas.height=canvas.clientHeight*dpi,ctx.scale(dpi,dpi)}function resizeCanvas(canvas,width,height){guard("resizeCanvas",{canvas:canvas,width:width,height:height},{canvas:"dom",width:"number?",height:"number?"});const w=width??canvas.clientWidth,h=height??canvas.clientHeight;return canvas.width=w,canvas.height=h,{width:w,height:h}}function withCtx(ctx,fn){let result;guard("withCtx",{ctx:ctx,fn:fn},{ctx:"object",fn:"function"}),ctx.save();try{result=fn()}finally{ctx.restore()}return result}function clearCanvas(ctx,width,height){guard("clearCanvas",{ctx:ctx,width:width,height:height},{ctx:"object",width:"number?",height:"number?"});const w=width??ctx.canvas.width,h=height??ctx.canvas.height;ctx.clearRect(0,0,w,h)}function setStyle(ctx,style={}){guard("setStyle",{ctx:ctx,style:style},{ctx:"object",style:"object?"});const{fill:fill,stroke:stroke,lineWidth:lineWidth,font:font,alpha:alpha}=style;fill&&(ctx.fillStyle=fill),stroke&&(ctx.strokeStyle=stroke),lineWidth&&(ctx.lineWidth=lineWidth),font&&(ctx.font=font),void 0!==alpha&&(ctx.globalAlpha=alpha)}function drawRect(ctx,{x:x,y:y,w:w,h:h,fill:fill,stroke:stroke,lineWidth:lineWidth=1}){guard("drawRect",{ctx:ctx,x:x,y:y,w:w,h:h,fill:fill,stroke:stroke,lineWidth:lineWidth},{ctx:"object",x:"number",y:"number",w:"number",h:"number",fill:"string?",stroke:"string?",lineWidth:"number?"}),withCtx(ctx,()=>{fill&&ctx.fillRect(x,y,w,h),stroke&&(ctx.lineWidth=lineWidth,ctx.strokeRect(x,y,w,h))})}function drawCircle(ctx,{x:x,y:y,r:r,fill:fill,stroke:stroke,lineWidth:lineWidth=1}){guard("drawCircle",{ctx:ctx,x:x,y:y,r:r,fill:fill,stroke:stroke,lineWidth:lineWidth},{ctx:"object",x:"number",y:"number",r:"number",fill:"string?",stroke:"string?",lineWidth:"number?"}),withCtx(ctx,()=>{ctx.beginPath(),ctx.arc(x,y,r,0,2*Math.PI),fill&&ctx.fill(),stroke&&(ctx.lineWidth=lineWidth,ctx.stroke())})}function drawLine(ctx,{x1:x1,y1:y1,x2:x2,y2:y2,stroke:stroke="#000",width:width=1}){guard("drawLine",{ctx:ctx,x1:x1,y1:y1,x2:x2,y2:y2,stroke:stroke,width:width},{ctx:"object",x1:"number",y1:"number",x2:"number",y2:"number",stroke:"string?",width:"number?"}),withCtx(ctx,()=>{ctx.strokeStyle=stroke,ctx.lineWidth=width,ctx.beginPath(),ctx.moveTo(x1,y1),ctx.lineTo(x2,y2),ctx.stroke()})}function drawPath(ctx,points,opts={}){if(guard("drawPath",{ctx:ctx,points:points,opts:opts},{ctx:"object",points:"array",opts:"object?"}),!points.length)return;const{stroke:stroke,fill:fill,lineWidth:lineWidth=1,close:close=!1}=opts;withCtx(ctx,()=>{ctx.beginPath(),ctx.moveTo(points[0].x,points[0].y),points.slice(1).forEach(p=>ctx.lineTo(p.x,p.y)),close&&ctx.closePath(),fill&&(ctx.fillStyle=fill,ctx.fill()),stroke&&(ctx.strokeStyle=!0===stroke?"#000":stroke,ctx.lineWidth=lineWidth,ctx.stroke())})}function drawText(ctx,{text:t,x:x,y:y,size:size=16,font:font="sans-serif",color:color="#000",align:align="left"}){guard("drawText",{ctx:ctx,t:t,x:x,y:y,size:size,font:font,color:color,align:align},{ctx:"object",t:"string",x:"number",y:"number"}),withCtx(ctx,()=>{ctx.fillStyle=color,ctx.textAlign=align,ctx.font=`${size}px ${font}`,ctx.fillText(t,x,y)})}function measureText(ctx,textValue){return guard("measureText",{ctx:ctx,textValue:textValue},{ctx:"object",textValue:"string"}),ctx.measureText(textValue)?.width??0}function getMousePos(canvas,evt){guard("getMousePos",{canvas:canvas,evt:evt},{canvas:"dom",evt:"object"});const rect=canvas.getBoundingClientRect();return{x:evt.clientX-rect.left,y:evt.clientY-rect.top}}function getTouchPos(canvas,touch){guard("getTouchPos",{canvas:canvas,touch:touch},{canvas:"dom",touch:"object"});const rect=canvas.getBoundingClientRect();return{x:touch.clientX-rect.left,y:touch.clientY-rect.top}}function destroyCanvas(canvas){guard("destroyCanvas",{canvas:canvas},{canvas:"dom"});const ctx=canvas.getContext("2d");ctx&&clearCanvas(ctx),canvas.width=0,canvas.height=0}const _p=Object.freeze({once:once,noop:noop,identity:identity,debounce:debounce,throttle:throttle,memoize:memoize,retry:retry,retryAsync:retryAsync,time:time,sleep:sleep,timeout:timeout,pipe:pipe,compose:compose,before:before,after:after,series:series,parallel:parallel,tryCatch:tryCatch,lazy:lazy,tap:tap,asyncTap:asyncTap,retryUntil:retryUntil,ensureCanvas:ensureCanvas,getCtx:getCtx,fixDPI:fixDPI,resizeCanvas:resizeCanvas,withCtx:withCtx,setStyle:setStyle,drawRect:drawRect,drawCircle:drawCircle,drawLine:drawLine,drawPath:drawPath,drawText:drawText,measureText:measureText,getMousePos:getMousePos,getTouchPos:getTouchPos,clearCanvas:clearCanvas,destroyCanvas:destroyCanvas,canShare:canShare,share:share,canVibrate:canVibrate,vibrate:vibrate,canAccessBattery:canAccessBattery,getBatteryInfo:getBatteryInfo,canNotify:canNotify,requestNotificationPermission:requestNotificationPermission,notify:notify,canUseBluetooth:canUseBluetooth,requestBluetoothDevice:requestBluetoothDevice,getNetworkInfo:getNetworkInfo,canUseMediaDevices:canUseMediaDevices,canGeolocate:canGeolocate,queryPermission:queryPermission,isProbablyOnline:isProbablyOnline,safeJSONParse:safeJSONParse,times:times,loopUntil:loopUntil,isTouchDevice:isTouchDevice,isTouchPhone:isTouchPhone,isMouseDevice:isMouseDevice,isHybridDevice:isHybridDevice,supportsHover:supportsHover,supportsCoarsePointer:supportsCoarsePointer,prefersReducedMotion:prefersReducedMotion,prefersDarkMode:prefersDarkMode,prefersLightMode:prefersLightMode,setData:setData,getData:getData,removeData:removeData,clearAllData:clearAllData,$id:$id,$qs:$qs,$qsa:$qsa,$class:$class,$tag:$tag,$name:$name,siblings:siblings,setHTML:setHTML,createElement:createElement,empty:empty,wrap:wrap,unwrap:unwrap,addClass:addClass,removeClass:removeClass,hasClass:hasClass,data:data,on:on,off:off,delegate:delegate,trigger:trigger,triggerPairs:triggerPairs,css:css,getStyle:getStyle,hide:hide,show:show,toggleDisplay:toggleDisplay,addAnimation:addAnimation,removeAnimation:removeAnimation,offset:offset,position:position,width:width,height:height,innerWidth:innerWidth,innerHeight:innerHeight,outerWidth:outerWidth,outerHeight:outerHeight,scrollTop:scrollTop,scrollLeft:scrollLeft,rect:rect,isInViewport:isInViewport,val:val,setVal:setVal,isVisible:isVisible,isHidden:isHidden,fadeIn:fadeIn,fadeOut:fadeOut,slideDown:slideDown,slideUp:slideUp,copyToClipboard:copyToClipboard,scrollTo:scrollTo,firstChild:firstChild,lastChild:lastChild,isEmail:isEmail,isURL:isURL,isPhone:isPhone,isHexColor:isHexColor,isAlpha:isAlpha,isAlphaNumeric:isAlphaNumeric,isNumeric:isNumeric,matchAll:matchAll,replaceAll:replaceAll,testPattern:testPattern,clamp:clamp,safeDivide:safeDivide,safeAdd:safeAdd,safeSub:safeSub,safeMultiply:safeMultiply,round:round,random:random,between:between,toFixedNumber:toFixedNumber,percent:percent,almostEqual:almostEqual,isEven:isEven,isOdd:isOdd,factorial:factorial,isPrime:isPrime,gcd:gcd,lcm:lcm,degreesToRadians:degreesToRadians,radiansToDegrees:radiansToDegrees,toOrdinal:toOrdinal,randomIntArray:randomIntArray,randomUniqueIntArray:randomUniqueIntArray,isPositive:isPositive,isNegative:isNegative,isObject:isObject,isArray:isArray,isCollection:isCollection,checkType:checkType,int:int,string:string,bool:bool,object:object,array:array,float:float,sym:sym,isNaN:isNaN,defaultIfNaN:defaultIfNaN,isNull:isNull,isUndefined:isUndefined,isNil:isNil,defaultIfNull:defaultIfNull,defaultIfNil:defaultIfNil,defaultIfUndefined:defaultIfUndefined,coalesce:coalesce,isTrue:isTrue,isFalse:isFalse,allTrue:allTrue,allFalse:allFalse,anyTrue:anyTrue,anyFalse:anyFalse,xor:xor,and:and,or:or,not:not,coerce:coerce,ifTruthy:ifTruthy,ifFalsy:ifFalsy,isEmpty:isEmpty,isNotEmpty:isNotEmpty,first:first,last:last,atSafe:atSafe,sum:sum,average:average,min:min,max:max,range:range,median:median,unique:unique,duplicates:duplicates,count:count,containsAll:containsAll,intersection:intersection,union:union,remove:remove,swap:swap,clear:clear,chunk:chunk,zip:zip,flattenDeep:flattenDeep,flattenTo:flattenTo,sortAsc:sortAsc,sortDesc:sortDesc,shuffle:shuffle,sample:sample,compact:compact,keysArray:keysArray,valuesArray:valuesArray,entriesArray:entriesArray,keysLength:keysLength,has:has,deepClone:deepClone,deepMerge:deepMerge,mergeAll:mergeAll,pick:pick,omit:omit,mapValues:mapValues,mapKeys:mapKeys,mapEntries:mapEntries,filterObj:filterObj,deepFreeze:deepFreeze,keyBy:keyBy,invert:invert,uppercaseWords:uppercaseWords,lowercaseWords:lowercaseWords,truncate:truncate,uppercaseChar:uppercaseChar,lowercaseChar:lowercaseChar,uppercaseFirstChar:uppercaseFirstChar,lowercaseFirstChar:lowercaseFirstChar,slugify:slugify,stripHtml:stripHtml,escapeHtml:escapeHtml,countOccurrences:countOccurrences,reverseString:reverseString,padCenter:padCenter,removeAccent:removeAccent,isPalindrome:isPalindrome});export{once,noop,identity,debounce,throttle,memoize,retry,retryAsync,time,sleep,timeout,pipe,compose,before,after,series,parallel,tryCatch,lazy,tap,asyncTap,retryUntil,ensureCanvas,getCtx,fixDPI,resizeCanvas,withCtx,setStyle,drawRect,drawCircle,drawLine,drawPath,drawText,measureText,getMousePos,getTouchPos,clearCanvas,destroyCanvas,canShare,share,canVibrate,vibrate,canAccessBattery,getBatteryInfo,canNotify,requestNotificationPermission,notify,canUseBluetooth,requestBluetoothDevice,getNetworkInfo,canUseMediaDevices,canGeolocate,queryPermission,isProbablyOnline,safeJSONParse,times,loopUntil,isTouchDevice,isTouchPhone,isMouseDevice,isHybridDevice,supportsHover,supportsCoarsePointer,prefersReducedMotion,prefersDarkMode,prefersLightMode,setData,getData,removeData,clearAllData,$id,$qs,$qsa,$class,$tag,$name,siblings,setHTML,createElement,empty,wrap,unwrap,addClass,removeClass,hasClass,data,on,off,delegate,trigger,triggerPairs,css,getStyle,hide,show,toggleDisplay,addAnimation,removeAnimation,offset,position,width,height,innerWidth,innerHeight,outerWidth,outerHeight,scrollTop,scrollLeft,rect,isInViewport,val,setVal,isVisible,isHidden,fadeIn,fadeOut,slideDown,slideUp,copyToClipboard,scrollTo,firstChild,lastChild,isEmail,isURL,isPhone,isHexColor,isAlpha,isAlphaNumeric,isNumeric,matchAll,replaceAll,testPattern,clamp,safeDivide,safeAdd,safeSub,safeMultiply,round,random,between,toFixedNumber,percent,almostEqual,isEven,isOdd,factorial,isPrime,gcd,lcm,degreesToRadians,radiansToDegrees,toOrdinal,randomIntArray,randomUniqueIntArray,isPositive,isNegative,isObject,isArray,isCollection,checkType,int,string,bool,object,array,float,sym,isNaN,defaultIfNaN,isNull,isUndefined,isNil,defaultIfNull,defaultIfNil,defaultIfUndefined,coalesce,isTrue,isFalse,allTrue,allFalse,anyTrue,anyFalse,xor,and,or,not,coerce,ifTruthy,ifFalsy,isEmpty,isNotEmpty,first,last,atSafe,sum,average,min,max,range,median,unique,duplicates,count,containsAll,intersection,union,remove,swap,clear,chunk,zip,flattenDeep,flattenTo,sortAsc,sortDesc,shuffle,sample,compact,keysArray,valuesArray,entriesArray,keysLength,has,deepClone,deepMerge,mergeAll,pick,omit,mapValues,mapKeys,mapEntries,filterObj,deepFreeze,keyBy,invert,uppercaseWords,lowercaseWords,truncate,uppercaseChar,lowercaseChar,uppercaseFirstChar,lowercaseFirstChar,slugify,stripHtml,escapeHtml,countOccurrences,reverseString,padCenter,removeAccent,isPalindrome};export default _p;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function createType(typeName,message,validator){let value;function validate(v){if(!validator(v))throw new TypeError(message)}return function(initialValue){return arguments.length>0&&(validate(initialValue),value=initialValue),{get:()=>value,set(newValue){validate(newValue),value=newValue},clear(){value=void 0},type:()=>typeName}}}function resolveStorage(type,fn){if("local"===type)return localStorage;if("session"===type)return sessionStorage;throw new Error(`Primux/${fn}: type must be "local" or "session". Default is "local".`)}function typeOf(v){return null===v?"null":Number.isNaN(v)?"NaN":Array.isArray(v)?"array":"undefined"!=typeof window&&"undefined"!=typeof Element&&v instanceof Element?"dom":v instanceof RegExp?"RegExp":typeof v}function guard(fn,values,schema){const params=Object.keys(schema).join(", ");for(const key in schema){const rule=schema[key],value=values[key],optional=rule.endsWith("?"),expected=optional?rule.slice(0,-1):rule;if(void 0===value){if(optional)continue;throw new TypeError(`Primux/${fn}(${params}): parameter "${key}" is required`)}if("any"===expected)continue;const actual=typeOf(value);if(!expected.split("|").includes(actual))throw new TypeError(`Primux/${fn}(${params}): parameter "${key}" expected ${expected}, received ${actual}`)}}function ensureDOM(fnName){if("undefined"==typeof document)throw new Error(`Primux/${fnName}(): DOM is not available in this environment!`)}function stableHash(value){if(null===value)return"null";if("object"!=typeof value)return typeof value+":"+String(value);if(Array.isArray(value))return"array:["+value.map(stableHash).join(",")+"]";return"object:{"+Object.keys(value).sort().map(k=>`${k}:${stableHash(value[k])}`).join(",")+"}"}function decimalPlaces(num){const match=String(num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);if(!match)return 0;const decimals=match[1]?match[1].length:0,exponent=match[2]?parseInt(match[2],10):0;return Math.max(0,decimals-exponent)}function normalizeToArray(input,fnName){if(null==input)throw new TypeError(`Primux/${fnName}: expected input, got ${input}`);if(input instanceof HTMLElement)return[input];if(NodeList.prototype.isPrototypeOf(input)||HTMLCollection.prototype.isPrototypeOf(input)){if(0===input.length)throw new RangeError(`Primux/${fnName}: element collection must not be empty`);return Array.from(input)}if(Array.isArray(input)){if(0===input.length)throw new RangeError(`Primux/${fnName}: array must not be empty`);return input.flat(1/0)}if("string"==typeof input){const trimmed=input.trim();if(""===trimmed)throw new RangeError(`Primux/${fnName}: string must not be empty`);return[trimmed]}throw new TypeError(`Primux/${fnName}: expected HTMLElement, NodeList, HTMLCollection, array, or string`)}function checkChar(c,fn){if("string"!=typeof c||1!==c.length)throw new TypeError(`Primux/${fn}(str, char): expected a single-character string`)}function getDuration(duration){return"number"==typeof duration?duration:300}function deepEqual(a,b){return stableHash(a)===stableHash(b)}function guardNegativeNumber(length,fn){if(length<0)throw new RangeError(`Primux/${fn}: value must not be negative`)}const _p=function(){function shuffle(array){guard("shuffle",{array:array},{array:"array"});const result=[...array];for(let i=result.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[result[i],result[j]]=[result[j],result[i]]}return result}function isEmpty(collection){return guard("isEmpty",{collection:collection},{collection:"array|object"}),Array.isArray(collection)?0===collection.length:0===Object.keys(collection).length}function deepClone(value,seen=new WeakMap){if(null===value||"object"!=typeof value)return value;if(seen.has(value))return seen.get(value);if(value instanceof Date)return new Date(value);if(value instanceof RegExp)return new RegExp(value.source,value.flags);if(value instanceof Map){const result=new Map;return seen.set(value,result),value.forEach((v,k)=>{result.set(deepClone(k,seen),deepClone(v,seen))}),result}if(value instanceof Set){const result=new Set;return seen.set(value,result),value.forEach(v=>result.add(deepClone(v,seen))),result}if(Array.isArray(value)){const result=[];return seen.set(value,result),value.forEach((v,i)=>result[i]=deepClone(v,seen)),result}const result=Object.create(Object.getPrototypeOf(value));seen.set(value,result);for(const key of Reflect.ownKeys(value)){const desc=Object.getOwnPropertyDescriptor(value,key);"value"in desc&&(desc.value=deepClone(desc.value,seen)),Object.defineProperty(result,key,desc)}return result}function has(obj,key){return guard("has",{obj:obj,key:key},{obj:"object",key:"string|symbol"}),Object.prototype.hasOwnProperty.call(obj,key)}function deepMerge(target,source,seen=new WeakMap){if(guard("deepMerge",{target:target,source:source},{target:"object?",source:"object"}),null===source||"object"!=typeof source)return source;if(null===target||"object"!=typeof target)return deepClone(source);let innerMap=seen.get(target);if(innerMap&&innerMap.has(source))return innerMap.get(source);const result=Array.isArray(source)?[]:Object.create(Object.getPrototypeOf(source));innerMap||(innerMap=new WeakMap,seen.set(target,innerMap)),innerMap.set(source,result);for(const key of Reflect.ownKeys(target))result[key]=target[key];for(const key of Reflect.ownKeys(source)){const sVal=source[key],tVal=result[key];result[key]=sVal&&"object"==typeof sVal?deepMerge(tVal,sVal,seen):sVal}return result}function gcd(a,b){for(guard("gcd",{a:a,b:b},{a:"number",b:"number"}),a=Math.abs(a),b=Math.abs(b);0!==b;)[a,b]=[b,a%b];return a}function isNaN(value){return guard("isNaN",{value:value},{value:"any"}),"number"==typeof value&&Number.isNaN(value)}function isObject(value){return guard("isObject",{value:value},{value:"any"}),null!==value&&"object"==typeof value&&Object.getPrototypeOf(value)===Object.prototype}function createElement(tagName,options={}){guard("createElement",{tagName:tagName,options:options},{tagName:"string",options:"object?"});const el=document.createElement(tagName);if(options.class)if(Array.isArray(options.class))el.classList.add(...options.class);else{if("string"!=typeof options.class)throw new TypeError("createElement: 'class' must be string or array of strings");el.classList.add(options.class)}if(options.attrs){if(!isObject(options.attrs))throw new TypeError("createElement: 'attrs' must be an object");Object.entries(options.attrs).forEach(([key,value])=>el.setAttribute(key,value))}if(options.text&&(el.textContent=String(options.text)),options.html&&(el.innerHTML=String(options.html)),options.children){(Array.isArray(options.children)?options.children:[options.children]).forEach(child=>{guard("createElement/children",{child:child},{child:"dom"}),el.appendChild(child)})}return el}function trigger(elements,events,options={}){if(ensureDOM("trigger"),null===options||"object"!=typeof options)throw new TypeError("trigger(): options must be an object");const elArr=normalizeToArray(elements,"trigger(elements, events, options?)"),eventArr=normalizeToArray(events,"trigger(elements, events, options?)");for(const el of elArr){guard("trigger",{el:el},{el:"dom"});for(const eventName of eventArr){guard("trigger",{eventName:eventName},{eventName:"string"});const{detail:detail=null,bubbles:bubbles=!0,cancelable:cancelable=!0}=options;el.dispatchEvent(new CustomEvent(eventName,{detail:detail,bubbles:bubbles,cancelable:cancelable}))}}}function isTouchDevice(){return"ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0}function canShare(){return"undefined"!=typeof navigator&&!!navigator.share}function canVibrate(){return"undefined"!=typeof navigator&&"vibrate"in navigator}function canAccessBattery(){return"undefined"!=typeof navigator&&"getBattery"in navigator}function canNotify(){return"undefined"!=typeof window&&"Notification"in window}function canUseBluetooth(){return"undefined"!=typeof navigator&&"bluetooth"in navigator}function ensureCanvas(canvas){return guard("ensureCanvas",{canvas:canvas},{canvas:"dom"}),canvas instanceof HTMLCanvasElement}function withCtx(ctx,fn){let result;guard("withCtx",{ctx:ctx,fn:fn},{ctx:"object",fn:"function"}),ctx.save();try{result=fn()}finally{ctx.restore()}return result}function clearCanvas(ctx,width,height){guard("clearCanvas",{ctx:ctx,width:width,height:height},{ctx:"object",width:"number?",height:"number?"});const w=width??ctx.canvas.width,h=height??ctx.canvas.height;ctx.clearRect(0,0,w,h)}return Object.freeze({once:function once(fn){guard("once",{fn:fn},{fn:"function"});let result,called=!1;return function(...args){return called||(called=!0,result=fn.apply(this,args)),result}},noop:function noop(){},identity:function identity(value){return value},debounce:function debounce(fn,delay,options={}){let timerId;guard("debounce",{fn:fn,delay:delay,options:options},{fn:"function",delay:"number",options:"object?"});let lastCall=0;const{leading:leading=!1,trailing:trailing=!0}=options;return function(...args){const context=this,now=Date.now();leading&&now-lastCall>delay&&(fn.apply(context,args),lastCall=now),clearTimeout(timerId),trailing&&(timerId=setTimeout(()=>{(!leading||now-lastCall>=delay)&&(fn.apply(context,args),lastCall=Date.now())},delay))}},throttle:function throttle(fn,delay){guard("throttle",{fn:fn,delay:delay},{fn:"function",delay:"number"});let lastTime=0;return function(...args){const now=Date.now();now-lastTime>=delay&&(lastTime=now,fn.apply(this,args))}},memoize:function memoize(fn,resolver){guard("memoize",{fn:fn,resolver:resolver},{fn:"function",resolver:"function?"});const cache=new Map;return function(...args){const key=resolver?resolver(...args):JSON.stringify(args);if(cache.has(key))return cache.get(key);const result=fn.apply(this,args);return cache.set(key,result),result}},retry:function retry(fn,times){if(guard("retry",{fn:fn,times:times},{fn:"function",times:"number"}),times<0)throw new RangeError("Primux/retry(fn, times): times should be a non-negative number");let attempts=0;for(;attempts<times;)try{return fn()}catch(err){if(attempts++,attempts>=times)throw err}},retryAsync:async function retryAsync(fn,times){if(guard("retryAsync",{fn:fn,times:times},{fn:"function",times:"number"}),times<0)throw new RangeError("Primux/retryAsync(fn, times): times should be a non-negative number");let attempts=0;for(;attempts<times;)try{return await fn()}catch(err){if(attempts++,attempts>=times)throw err}},time:function time(fn,label){guard("time",{fn:fn,label:label},{fn:"function",label:"string?"});const start=performance.now();fn();const duration=performance.now()-start+"ms";return label?`${label} : ${duration}`:duration},sleep:function sleep(ms){return guard("sleep",{ms:ms},{ms:"number"}),new Promise(resolve=>setTimeout(resolve,ms))},timeout:function timeout(fn,ms){return guard("timeout",{fn:fn,ms:ms},{fn:"function",ms:"number"}),(...args)=>Promise.race([Promise.resolve(fn(...args)),new Promise((_,reject)=>setTimeout(()=>reject(new Error(`timeout after ${ms}ms`)),ms))])},pipe:function pipe(...fns){if(0===fns.length)throw new Error("pipe(): parameter should not be empty");return fns.forEach(fn=>guard("pipe",{fn:fn},{fn:"function"})),(...args)=>fns.reduce((acc,fn)=>Array.isArray(acc)?fn(...acc):fn(acc),args)},compose:function compose(...fns){if(0===fns.length)throw new Error("compose(): parameter should not be empty");fns.forEach(fn=>guard("compose",{fn:fn},{fn:"function"}));const reversed=[...fns].reverse();return(...args)=>reversed.reduce((acc,fn)=>Array.isArray(acc)?fn(...acc):fn(acc),args)},before:function before(fn,times){guard("before",{fn:fn,times:times},{fn:"function",times:"number"});let lastResult,count=0;return function(...args){return count<times&&(lastResult=fn.apply(this,args),count++),lastResult}},after:function after(fn,times){guard("after",{fn:fn,times:times},{fn:"function",times:"number"});let count=0;return function(...args){if(count++,count>=times)return fn.apply(this,args)}},series:async function series(fns,initialValue){guard("series",{fns:fns,initialValue:initialValue},{fns:"array",initialValue:"any?"});let result=initialValue;for(const fn of fns)guard("series",{fn:fn},{fn:"function"}),result=await fn(result);return result},parallel:async function parallel(fns){return guard("parallel",{fns:fns},{fns:"array"}),Promise.all(fns.map(fn=>(guard("parallel",{fn:fn},{fn:"function"}),fn())))},tryCatch:function tryCatch(fn,fallback){return guard("tryCatch",{fn:fn,fallback:fallback},{fn:"function",fallback:"function?"}),function(...args){try{const result=fn(...args);return result instanceof Promise?result.then(res=>res).catch(err=>err):result}catch(err){return err}finally{"function"==typeof fallback&&fallback()}}},lazy:function lazy(fn){return guard("lazy",{fn:fn},{fn:"function"}),function(...args){return fn(...args)}},tap:(fn=console.log)=>value=>(guard("tap",{fn:fn},{fn:"function"}),"function"==typeof fn&&fn(value),value),asyncTap:(fn=console.log)=>async value=>(guard("asyncTap",{fn:fn},{fn:"function"}),"function"==typeof fn&&await fn(value),value),retryUntil:async function retryUntil(fn,condition,{maxAttempts:maxAttempts=5,delay:delay=500}={}){if(guard("retryUntil",{fn:fn,condition:condition},{fn:"function",condition:"function"}),!Number.isFinite(maxAttempts)||maxAttempts<0)throw new RangeError("Primux/retryUntil(fn, condition, options): maxAttempts should be a finite non-negative number");if(!Number.isFinite(delay)||delay<0)throw new RangeError("Primux/retryUntil(fn, condition, options): delay should be a finite non-negative number");let result,attempt=0;for(;attempt<maxAttempts;){if(attempt++,result=await fn(),condition(result))return result;delay&&await new Promise(res=>setTimeout(res,delay))}throw new Error(`retryUntil: condition not met after ${maxAttempts} attempts`)},ensureCanvas:ensureCanvas,getCtx:function getCtx(canvas){if(guard("getCtx",{canvas:canvas},{canvas:"dom"}),!ensureCanvas(canvas))return null;const ctx=canvas.getContext("2d");return ctx||console.warn("getCtx: 2D context not supported"),ctx},fixDPI:function fixDPI(canvas,ctx){if(guard("fixDPI",{canvas:canvas,ctx:ctx},{canvas:"dom",ctx:"object"}),!ctx)return;const dpi=window.devicePixelRatio||1;canvas.width=canvas.clientWidth*dpi,canvas.height=canvas.clientHeight*dpi,ctx.scale(dpi,dpi)},resizeCanvas:function resizeCanvas(canvas,width,height){guard("resizeCanvas",{canvas:canvas,width:width,height:height},{canvas:"dom",width:"number?",height:"number?"});const w=width??canvas.clientWidth,h=height??canvas.clientHeight;return canvas.width=w,canvas.height=h,{width:w,height:h}},withCtx:withCtx,setStyle:function setStyle(ctx,style={}){guard("setStyle",{ctx:ctx,style:style},{ctx:"object",style:"object?"});const{fill:fill,stroke:stroke,lineWidth:lineWidth,font:font,alpha:alpha}=style;fill&&(ctx.fillStyle=fill),stroke&&(ctx.strokeStyle=stroke),lineWidth&&(ctx.lineWidth=lineWidth),font&&(ctx.font=font),void 0!==alpha&&(ctx.globalAlpha=alpha)},drawRect:function drawRect(ctx,{x:x,y:y,w:w,h:h,fill:fill,stroke:stroke,lineWidth:lineWidth=1}){guard("drawRect",{ctx:ctx,x:x,y:y,w:w,h:h,fill:fill,stroke:stroke,lineWidth:lineWidth},{ctx:"object",x:"number",y:"number",w:"number",h:"number",fill:"string?",stroke:"string?",lineWidth:"number?"}),withCtx(ctx,()=>{fill&&ctx.fillRect(x,y,w,h),stroke&&(ctx.lineWidth=lineWidth,ctx.strokeRect(x,y,w,h))})},drawCircle:function drawCircle(ctx,{x:x,y:y,r:r,fill:fill,stroke:stroke,lineWidth:lineWidth=1}){guard("drawCircle",{ctx:ctx,x:x,y:y,r:r,fill:fill,stroke:stroke,lineWidth:lineWidth},{ctx:"object",x:"number",y:"number",r:"number",fill:"string?",stroke:"string?",lineWidth:"number?"}),withCtx(ctx,()=>{ctx.beginPath(),ctx.arc(x,y,r,0,2*Math.PI),fill&&ctx.fill(),stroke&&(ctx.lineWidth=lineWidth,ctx.stroke())})},drawLine:function drawLine(ctx,{x1:x1,y1:y1,x2:x2,y2:y2,stroke:stroke="#000",width:width=1}){guard("drawLine",{ctx:ctx,x1:x1,y1:y1,x2:x2,y2:y2,stroke:stroke,width:width},{ctx:"object",x1:"number",y1:"number",x2:"number",y2:"number",stroke:"string?",width:"number?"}),withCtx(ctx,()=>{ctx.strokeStyle=stroke,ctx.lineWidth=width,ctx.beginPath(),ctx.moveTo(x1,y1),ctx.lineTo(x2,y2),ctx.stroke()})},drawPath:function drawPath(ctx,points,opts={}){if(guard("drawPath",{ctx:ctx,points:points,opts:opts},{ctx:"object",points:"array",opts:"object?"}),!points.length)return;const{stroke:stroke,fill:fill,lineWidth:lineWidth=1,close:close=!1}=opts;withCtx(ctx,()=>{ctx.beginPath(),ctx.moveTo(points[0].x,points[0].y),points.slice(1).forEach(p=>ctx.lineTo(p.x,p.y)),close&&ctx.closePath(),fill&&(ctx.fillStyle=fill,ctx.fill()),stroke&&(ctx.strokeStyle=!0===stroke?"#000":stroke,ctx.lineWidth=lineWidth,ctx.stroke())})},drawText:function drawText(ctx,{text:t,x:x,y:y,size:size=16,font:font="sans-serif",color:color="#000",align:align="left"}){guard("drawText",{ctx:ctx,t:t,x:x,y:y,size:size,font:font,color:color,align:align},{ctx:"object",t:"string",x:"number",y:"number"}),withCtx(ctx,()=>{ctx.fillStyle=color,ctx.textAlign=align,ctx.font=`${size}px ${font}`,ctx.fillText(t,x,y)})},measureText:function measureText(ctx,textValue){return guard("measureText",{ctx:ctx,textValue:textValue},{ctx:"object",textValue:"string"}),ctx.measureText(textValue)?.width??0},getMousePos:function getMousePos(canvas,evt){guard("getMousePos",{canvas:canvas,evt:evt},{canvas:"dom",evt:"object"});const rect=canvas.getBoundingClientRect();return{x:evt.clientX-rect.left,y:evt.clientY-rect.top}},getTouchPos:function getTouchPos(canvas,touch){guard("getTouchPos",{canvas:canvas,touch:touch},{canvas:"dom",touch:"object"});const rect=canvas.getBoundingClientRect();return{x:touch.clientX-rect.left,y:touch.clientY-rect.top}},clearCanvas:clearCanvas,destroyCanvas:function destroyCanvas(canvas){guard("destroyCanvas",{canvas:canvas},{canvas:"dom"});const ctx=canvas.getContext("2d");ctx&&clearCanvas(ctx),canvas.width=0,canvas.height=0},canShare:canShare,share:function share(data){return guard("share",{data:data},{data:"object"}),canShare()?navigator.share(data):Promise.reject("Share API not supported")},canVibrate:canVibrate,vibrate:function vibrate(pattern=200){return guard("vibrate",{pattern:pattern},{pattern:"number"}),!!canVibrate()&&navigator.vibrate(pattern)},canAccessBattery:canAccessBattery,getBatteryInfo:async function getBatteryInfo(){if(!canAccessBattery())return null;const battery=await navigator.getBattery();return{level:Math.round(100*battery.level),charging:battery.charging,chargingTime:battery.chargingTime===1/0?null:Math.round(battery.chargingTime/60),dischargingTime:battery.dischargingTime===1/0?null:Math.round(battery.dischargingTime/60)}},canNotify:canNotify,requestNotificationPermission:function requestNotificationPermission(){return canNotify()?Notification.requestPermission():Promise.resolve("denied")},notify:async function notify(title,options={},swPath=null){if(guard("notify",{title:title,options:options},{title:"string",options:"object?"}),!("Notification"in window))return null;if("granted"!==Notification.permission){if("granted"!==await Notification.requestPermission())return null}if("serviceWorker"in navigator){if(swPath){await navigator.serviceWorker.getRegistration()||await navigator.serviceWorker.register(swPath)}return(await navigator.serviceWorker.ready).showNotification(title,options)}return new Notification(title,options)},canUseBluetooth:canUseBluetooth,requestBluetoothDevice:function requestBluetoothDevice(options){if(guard("requestBluetoothDevice",{options:options},{options:"object"}),!canUseBluetooth())return Promise.reject(new Error("Bluetooth API not supported"));const hasFilters=Array.isArray(options.filters),hasAcceptAll=!0===options.acceptAllDevices;return hasFilters||hasAcceptAll?hasFilters&&hasAcceptAll?Promise.reject(new Error("Cannot use both 'filters' and 'acceptAllDevices'.")):navigator.bluetooth.requestDevice(options):Promise.reject(new Error("Either 'filters' or 'acceptAllDevices: true' is required."))},getNetworkInfo:function getNetworkInfo(){const conn=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return conn?{effectiveType:conn.effectiveType,downlink:conn.downlink,rtt:conn.rtt,saveData:conn.saveData}:null},canUseMediaDevices:function canUseMediaDevices(){return"undefined"!=typeof navigator&&!(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia)},canGeolocate:function canGeolocate(){return"undefined"!=typeof navigator&&"geolocation"in navigator},queryPermission:function queryPermission(name){return guard("queryPermission",{name:name},{name:"string"}),navigator.permissions?navigator.permissions.query({name:name}):Promise.resolve(null)},isProbablyOnline:function isProbablyOnline(){return navigator.onLine||performance.getEntriesByType("resource").length>0},safeJSONParse:function safeJSONParse(str,fallback=null){if("string"!=typeof str||!str.trim())return fallback;try{return JSON.parse(str)??fallback}catch{return fallback}},times:function times(n,fn){if(guard("times",{n:n,fn:fn},{n:"number",fn:"function"}),n<0)throw new TypeError("times(): n must be a positive number");for(let i=0;i<n;i++)fn(i)},loopUntil:function loopUntil(fn,condition){let result;guard("loopUntil",{fn:fn,condition:condition},{fn:"function",condition:"function"});do{result=fn()}while(!condition(result))},isTouchDevice:isTouchDevice,isTouchPhone:function isTouchPhone(){return isTouchDevice()&&matchMedia("(pointer: coarse)").matches&&matchMedia("(hover: none)").matches},isMouseDevice:function isMouseDevice(){return matchMedia("(pointer: fine)").matches},isHybridDevice:function isHybridDevice(){return isTouchDevice()&&matchMedia("(pointer: fine)").matches},supportsHover:function supportsHover(){return matchMedia("(hover: hover)").matches},supportsCoarsePointer:function supportsCoarsePointer(){return matchMedia("(pointer: coarse)").matches},prefersReducedMotion:function prefersReducedMotion(){return matchMedia("(prefers-reduced-motion: reduce)").matches},prefersDarkMode:function prefersDarkMode(){return matchMedia("(prefers-color-scheme: dark)").matches},prefersLightMode:function prefersLightMode(){return matchMedia("(prefers-color-scheme: light)").matches},setData:function setData(key,data,type="local"){guard("setData",{key:key,data:data,type:type},{key:"string",data:"object|string",type:"string?"});const storage=resolveStorage(type,"setData(key, data, type?)"),isPlainObject=isObject(data);storage.setItem(key,isPlainObject?JSON.stringify(data):data)},getData:function getData(key,type="local"){guard("getData",{key:key,type:type},{key:"string",type:"string?"});const value=resolveStorage(type,"getData(key, type?)").getItem(key);if(null===value)return null;try{return JSON.parse(value)}catch{return value}},removeData:function removeData(key,type="local"){guard("removeData",{key:key,type:type},{key:"string",type:"string?"}),resolveStorage(type,"removeData(key, type?)").removeItem(key)},clearAllData:function clearAllData(type="local"){guard("clearAllData",{type:type},{type:"string?"}),resolveStorage(type,"clearAllData(type?)").clear()},$id:function $id(s){return ensureDOM("$id"),guard("$id",{s:s},{s:"string"}),document.getElementById(s)},$qs:function $qs(s){return ensureDOM("$qs"),guard("$qs",{s:s},{s:"string"}),document.querySelector(s)},$qsa:function $qsa(s){return ensureDOM("$qsa"),guard("$qsa",{s:s},{s:"string"}),document.querySelectorAll(s)},$class:function $class(s){return ensureDOM("$class"),guard("$class",{s:s},{s:"string"}),document.getElementsByClassName(s)||null},$tag:function $tag(s){return ensureDOM("$tag"),guard("$tag",{s:s},{s:"string"}),document.getElementsByTagName(s)||null},$name:function $name(s){return ensureDOM("$name"),guard("$name",{s:s},{s:"string"}),document.getElementsByName(s)||null},siblings:function siblings(el){return ensureDOM("siblings"),guard("siblings",{el:el},{el:"dom"}),el.parentNode?Array.from(el.parentNode.children).filter(child=>child!==el):[]},setHTML:function setHTML(el,html){ensureDOM("setHTML"),guard("setHTML",{el:el,html:html},{el:"dom",html:"string"}),el.innerHTML=html},createElement:createElement,empty:function empty(el){ensureDOM("empty"),guard("empty",{el:el},{el:"dom"}),el.innerHTML=""},wrap:function wrap(target,wrapper){return ensureDOM("wrap"),guard("wrap",{target:target,wrapper:wrapper},{target:"dom",wrapper:"dom"}),target.parentNode&&target.parentNode.insertBefore(wrapper,target),wrapper.appendChild(target),wrapper},unwrap:function unwrap(wrapper){ensureDOM("unwrap"),guard("unwrap",{wrapper:wrapper},{wrapper:"dom"});const parent=wrapper.parentNode;if(!parent)return;Array.from(wrapper.childNodes).forEach(child=>parent.insertBefore(child,wrapper)),wrapper.remove()},addClass:function addClass(el,...classes){ensureDOM("addClass");const elements=el instanceof HTMLElement?[el]:el instanceof NodeList||Array.isArray(el)?Array.from(el):[];if(0===elements.length)throw new TypeError("Primux/addClass: el should be HTMLElement, NodeList or array of HTMLElements");const allClasses=classes.flat(1/0);return allClasses.forEach(c=>guard("addClass",{c:c},{c:"string"})),elements.forEach(element=>element.classList.add(...allClasses)),el},removeClass:function removeClass(el,...classes){ensureDOM("removeClass");const elements=el instanceof HTMLElement?[el]:el instanceof NodeList||Array.isArray(el)?Array.from(el):[];if(0===elements.length)throw new TypeError("Primux/removeClass: el should be HTMLElement, NodeList or array of HTMLElements");const allClasses=classes.flat(1/0);return allClasses.forEach(c=>{if("string"!=typeof c)throw new TypeError("Primux/removeClass: class must be string")}),elements.forEach(element=>element.classList.remove(...allClasses)),el},hasClass:function hasClass(el,...classes){ensureDOM("hasClass");const allClasses=classes.flat(1/0);if(!allClasses.every(c=>"string"==typeof c))throw new TypeError("Primux/hasClass: all classes must be strings");return allClasses.every(c=>el.classList.contains(c))},data:function data(el,key,value){ensureDOM("data"),guard("data",{el:el,key:key},{el:"dom",key:"string",key:"any"});const attrName=`data-${key.replace(/[A-Z]/g,m=>"-"+m.toLowerCase())}`;return void 0===value?el.getAttribute(attrName):null===value?el.removeAttribute(attrName):void el.setAttribute(attrName,value)},on:function on(elements,events,handler,option={}){ensureDOM("on"),guard("on",{handler:handler,option:option},{handler:"function",option:"object?"});const{once:once=!1}=option;guard("on",{once:once},{once:"boolean"});const elArr=normalizeToArray(elements,"on(elements, events, handler, options?)"),eventArr=normalizeToArray(events,"on(elements, events, handler, options?)");for(const el of elArr){guard("on",{el:el},{el:"dom"});for(const event of eventArr)guard("on",{event:event},{event:"string"}),el.addEventListener(event,handler,{once:once})}},off:function off(elements,events,handler){ensureDOM("off"),guard("off",{handler:handler},{handler:"function"});const elArr=normalizeToArray(elements,"off(elements, events, handler)"),eventArr=normalizeToArray(events,"off(elements, events, handler)");for(const el of elArr){guard("off",{el:el},{el:"dom"});for(const event of eventArr)guard("off",{event:event},{event:"string"}),el.removeEventListener(event,handler)}},delegate:function delegate(root,event,selector,handler){ensureDOM("delegate"),guard("delegate",{root:root,event:event,selector:selector,handler:handler},{root:"dom",event:"string",selector:"string",handler:"function"}),root.addEventListener(event,e=>{const target=e.target.closest(selector);target&&root.contains(target)&&handler.call(target,e)})},trigger:trigger,triggerPairs:function triggerPairs(pairs){for(const[el,event]of pairs)trigger(el,event)},css:function css(elements,prop,value){ensureDOM("css");const elArr=normalizeToArray(elements,"css(elements, prop, value)");for(const el of elArr){if(guard("css",{el:el},{el:"dom"}),"string"==typeof prop&&void 0===value)return getComputedStyle(el).getPropertyValue(prop);if("string"!=typeof prop){if(!isObject(prop))throw new TypeError("css(): invalid parameter");for(const key in prop)el.style[key]=prop[key]}else el.style[prop]=value}},getStyle:function getStyle(el,property){return ensureDOM("getStyle"),guard("getStyle",{el:el,property:property},{el:"dom",property:"string"}),getComputedStyle(el).getPropertyValue(property)},hide:function hide(...elements){ensureDOM("hide");const elArr=normalizeToArray(elements.flat(),"hide(elements)");for(const el of elArr)guard("hide",{el:el},{el:"dom"}),"none"!==el.style.display&&(el.dataset._display=getComputedStyle(el).getPropertyValue("display")),el.style.display="none"},show:function show(...elements){ensureDOM("show");const elArr=normalizeToArray(elements.flat(),"show(elements)");for(const el of elArr)guard("show",{el:el},{el:"dom"}),el.style.display=el.dataset._display??"",delete el.dataset._display},toggleDisplay:function toggleDisplay(...elements){ensureDOM("toggleDisplay");const elArr=normalizeToArray(elements.flat(),"toggleDisplay(elements)");for(const el of elArr){guard("toggleDisplay",{el:el},{el:"dom"});"none"===getComputedStyle(el).getPropertyValue("display")?(el.style.display=el.dataset._display??"",delete el.dataset._display):(el.dataset._display=getComputedStyle(el).getPropertyValue("display"),el.style.display="none")}},addAnimation:function addAnimation(...elements){ensureDOM("addAnimation");const className=elements.pop();guard("addAnimation",{className:className},{className:"string"});const elArr=normalizeToArray(elements.flat(),"addAnimation (elements)");for(const el of elArr)guard("addAnimation",{el:el},{el:"dom"}),el.classList.add(className)},removeAnimation:function removeAnimation(...elements){ensureDOM("removeAnimation");const className=elements.pop();guard("removeAnimation",{className:className},{className:"string"});const elArr=normalizeToArray(elements.flat(),"removeAnimation(elements)");for(const el of elArr)guard("removeAnimation",{el:el},{el:"dom"}),el.classList.remove(className)},offset:function offset(el){ensureDOM("offset"),guard("offset",{el:el},{el:"dom"});const rect=el.getBoundingClientRect();return{top:rect.top+window.scrollY,left:rect.left+window.scrollX}},position:function position(el){return ensureDOM("position"),guard("position",{el:el},{el:"dom"}),{top:el.offsetTop,left:el.offsetLeft}},width:function width(el){return ensureDOM("width"),guard("width",{el:el},{el:"dom"}),parseFloat(getComputedStyle(el).width)},height:function height(el){return ensureDOM("height"),guard("height",{el:el},{el:"dom"}),parseFloat(getComputedStyle(el).height)},innerWidth:function innerWidth(el){return ensureDOM("innerWidth"),guard("innerWidth",{el:el},{el:"dom"}),el.clientWidth},innerHeight:function innerHeight(el){return ensureDOM("innerHeight"),guard("innerHeight",{el:el},{el:"dom"}),el.clientHeight},outerWidth:function outerWidth(el,includeMargin=!1){ensureDOM("outerWidth"),guard("outerWidth",{el:el},{el:"dom"});let w=el.offsetWidth;if(includeMargin){const s=getComputedStyle(el);w+=parseFloat(s.marginLeft)+parseFloat(s.marginRight)}return w},outerHeight:function outerHeight(el,includeMargin=!1){ensureDOM("outerHeight"),guard("outerHeight",{el:el},{el:"dom"});let h=el.offsetHeight;if(includeMargin){const s=getComputedStyle(el);h+=parseFloat(s.marginTop)+parseFloat(s.marginBottom)}return h},scrollTop:function scrollTop(el=window){return ensureDOM("scrollTop"),el!==window&&guard("scrollTop",{el:el},{el:"dom"}),el===window?window.scrollY:el.scrollTop},scrollLeft:function scrollLeft(el=window){return ensureDOM("scrollLeft"),el!==window&&guard("scrollLeft",{el:el},{el:"dom"}),el===window?window.scrollX:el.scrollLeft},rect:function rect(el){ensureDOM("rect"),guard("rect",{el:el},{el:"dom"});const r=el.getBoundingClientRect();return{top:r.top,left:r.left,right:r.right,bottom:r.bottom,width:r.width,height:r.height}},isInViewport:function isInViewport(el,options={}){guard("isInViewport",{el:el,options:options},{el:"dom",options:"object?"});const{partial:partial=!0,offset:offset=0}=options,r=el.getBoundingClientRect(),vw=window.innerWidth,vh=window.innerHeight,top=r.top+offset,left=r.left+offset,right=r.right-offset,bottom=r.bottom-offset;return partial?bottom>-.5&&right>-.5&&top<vh+.5&&left<vw+.5:top>=-.5&&left>=-.5&&bottom<=vh+.5&&right<=vw+.5},val:function val(el){return ensureDOM("val"),guard("val",{el:el},{el:"dom"}),"value"in el?el.value:null},setVal:function setVal(elements,value){ensureDOM("setVal");const elArr=normalizeToArray(elements,"setVal(elements, value)");for(const el of elArr){if(guard("setVal",{el:el},{el:"dom"}),!("value"in el))throw new Error("setVal(): element does not support value");el.value=null==value?"":String(value)}},isVisible:function isVisible(el,checkOpacity=!1){ensureDOM("isVisible"),guard("isVisible",{el:el,checkOpacity:checkOpacity},{el:"dom",checkOpacity:"boolean?"});const style=getComputedStyle(el);if("none"===style.display||"hidden"===style.visibility)return!1;if(checkOpacity&&0===parseFloat(style.opacity))return!1;const r=el.getBoundingClientRect();return r.width>0&&r.height>0},isHidden:function isHidden(el,checkOpacity=!1){ensureDOM("isHidden"),guard("isHidden",{el:el,checkOpacity:checkOpacity},{el:"dom",checkOpacity:"boolean?"});const style=getComputedStyle(el);if("none"===style.display||"hidden"===style.visibility)return!0;if(checkOpacity&&0===parseFloat(style.opacity))return!0;const r=el.getBoundingClientRect();return 0===r.width||0===r.height},fadeIn:function fadeIn(el,duration=300){ensureDOM("fadeIn"),guard("fadeIn",{el:el,duration:duration},{el:"dom",duration:"number?"}),duration=getDuration(duration),el.style.opacity=0,el.style.display="","none"===getComputedStyle(el).display&&(el.style.display="block");let start=null;requestAnimationFrame(function animate(ts){start||(start=ts);const progress=Math.min((ts-start)/duration,1);el.style.opacity=progress,progress<1&&requestAnimationFrame(animate)})},fadeOut:function fadeOut(el,duration=300){ensureDOM("fadeOut"),guard("fadeOut",{el:el,duration:duration},{el:"dom",duration:"number?"}),duration=getDuration(duration);const initial=parseFloat(getComputedStyle(el).opacity)||1;let start=null;requestAnimationFrame(function animate(ts){start||(start=ts);const progress=Math.min((ts-start)/duration,1);el.style.opacity=initial*(1-progress),progress<1?requestAnimationFrame(animate):(el.style.display="none",el.style.opacity="")})},slideDown:function slideDown(el,duration=300){ensureDOM("slideDown"),guard("slideDown",{el:el,duration:duration},{el:"dom",duration:"number?"}),duration=getDuration(duration),el.style.display="","none"===getComputedStyle(el).display&&(el.style.display="block");const height=el.scrollHeight;el.style.overflow="hidden",el.style.height="0px";let start=null;requestAnimationFrame(function animate(ts){start||(start=ts);const progress=Math.min((ts-start)/duration,1);el.style.height=height*progress+"px",progress<1?requestAnimationFrame(animate):(el.style.height="",el.style.overflow="")})},slideUp:function slideUp(el,duration=300){ensureDOM("slideUp"),guard("slideUp",{el:el,duration:duration},{el:"dom",duration:"number?"}),duration=getDuration(duration);const height=el.scrollHeight;el.style.height=height+"px",el.style.overflow="hidden";let start=null;requestAnimationFrame(function animate(ts){start||(start=ts);const progress=Math.min((ts-start)/duration,1);el.style.height=height*(1-progress)+"px",progress<1?requestAnimationFrame(animate):(el.style.display="none",el.style.height="",el.style.overflow="")})},copyToClipboard:async function copyToClipboard(text){guard("copyToClipboard",{text:text},{text:"string"});try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(text),!0;const textarea=document.createElement("textarea");textarea.value=text,textarea.style.position="fixed",textarea.style.opacity="0",document.body.appendChild(textarea),textarea.focus(),textarea.select();const success=document.execCommand("copy");return document.body.removeChild(textarea),success}catch{return!1}},scrollTo:function scrollTo(target,options={}){ensureDOM("scrollTo");const{behavior:behavior="smooth",offset:offset=0,container:container=window}=options;if(!(container===window||container instanceof Element))throw new TypeError("scrollTo(): container must be window or DOM element");let top=0;if("number"==typeof target)top=target+offset;else{if(!(target instanceof Element))throw new TypeError("scrollTo(): target must be number or DOM element");{guard("scrollTo",{target:target},{target:"dom"});const rect=target.getBoundingClientRect();if(container===window)top=rect.top+window.pageYOffset+offset;else{if(!(container instanceof Element))throw new TypeError("scrollTo(): container must be window or DOM element");top=rect.top-container.getBoundingClientRect().top+container.scrollTop+offset}}}container===window?window.scrollTo({top:top,behavior:behavior}):container.scrollTo({top:top,behavior:behavior})},firstChild:function firstChild(el){return ensureDOM("firstChild"),guard("firstChild",{el:el},{el:"dom"}),el.firstElementChild},lastChild:function lastChild(el){return ensureDOM("lastChild"),guard("lastChild",{el:el},{el:"dom"}),el.lastElementChild},isEmail:function isEmail(str){return guard("isEmail",{str:str},{str:"string"}),/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str)},isURL:function isURL(str){return guard("isURL",{str:str},{str:"string"}),/^(https?:\/\/)?([\w\-])+\.{1}([a-zA-Z]{2,63})([\/\w\-.?=&]*)*\/?$/.test(str)},isPhone:function isPhone(str){return guard("isPhone",{str:str},{str:"string"}),/^\+?[\d\s\-()]{7,15}$/.test(str)},isHexColor:function isHexColor(str){return guard("isHexColor",{str:str},{str:"string"}),/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(str)},isAlpha:function isAlpha(str){return guard("isAlpha",{str:str},{str:"string"}),/^[A-Za-z]+$/.test(str)},isAlphaNumeric:function isAlphaNumeric(str){return guard("isAlphaNumeric",{str:str},{str:"string"}),/^[A-Za-z0-9]+$/.test(str)},isNumeric:function isNumeric(str){return guard("isNumeric",{str:str},{str:"string"}),/^\d+$/.test(str)},matchAll:function matchAll(str,pattern){return guard("matchAll",{str:str,pattern:pattern},{str:"string",pattern:"RegExp"}),[...str.matchAll(pattern)].map(m=>m[0])},replaceAll:function replaceAll(str,pattern,replacement){guard("replaceAll",{str:str,pattern:pattern,replacement:replacement},{str:"string",pattern:"RegExp|string",replacement:"string"});const regex=pattern instanceof RegExp?new RegExp(pattern.source,"g"):new RegExp(pattern,"g");return str.replace(regex,replacement)},testPattern:function testPattern(str,pattern){return guard("testPattern",{str:str,pattern:pattern},{str:"string",pattern:"RegExp"}),pattern.test(str)},clamp:function clamp(value,min,max){return guard("clamp",{value:value,min:min,max:max},{value:"number",min:"number",max:"number"}),value<min?min:value>max?max:value},safeDivide:function safeDivide(a,b,defaultValue=0){if(guard("safeDivide",{a:a,b:b,defaultValue:defaultValue},{a:"number",b:"number",defaultValue:"number?"}),0===b)return defaultValue;const result=a/b;return isNaN(result)?defaultValue:result},safeAdd:function safeAdd(a,b){guard("safeAdd",{a:a,b:b},{a:"number",b:"number"});const factor=10**Math.max(decimalPlaces(a),decimalPlaces(b));return(Math.round(a*factor)+Math.round(b*factor))/factor},safeSub:function safeSub(a,b){guard("safeSub",{a:a,b:b},{a:"number",b:"number"});const factor=10**Math.max(decimalPlaces(a),decimalPlaces(b));return(Math.round(a*factor)-Math.round(b*factor))/factor},safeMultiply:function safeMultiply(a,b){guard("safeMultiply",{a:a,b:b},{a:"number",b:"number"});const dp=decimalPlaces(a)+decimalPlaces(b);return Math.round(a*b*10**dp)/10**dp},round:function round(value,decimals=0){guard("round",{value:value,decimals:decimals},{value:"number",decimals:"number?"});const factor=Math.pow(10,decimals);return Math.round(value*factor)/factor},random:function random(p1,p2,precision=0){if(Array.isArray(p1)){if(guard("random",{p1:p1},{p1:"array"}),0===p1.length)return;return p1[Math.floor(Math.random()*p1.length)]}guard("random",{p1:p1,p2:p2,precision:precision},{p1:"number",p2:"number",precision:"number?"});let min=p1,max=p2;if(min>max&&([min,max]=[max,min]),precision>0){const rand=Math.random()*(max-min)+min;return Number(rand.toFixed(precision))}return Math.floor(Math.random()*(max-min+1))+min},between:function between(value,min,max,inclusive=!0){return guard("between",{value:value,min:min,max:max,inclusive:inclusive},{value:"number",min:"number",max:"number",inclusive:"boolean?"}),min>max&&([min,max]=[max,min]),inclusive?value>=min&&value<=max:value>min&&value<max},toFixedNumber:function toFixedNumber(value,decimal){if(guard("toFixedNumber",{value:value,decimal:decimal},{value:"number",decimal:"number"}),!Number.isInteger(decimal)||decimal<0)throw new Error("toFixedNumber(): decimal must be non-negative integer");return Number(value.toFixed(decimal))},percent:function percent(value,total,precision=0){if(guard("percent",{value:value,total:total,precision:precision},{value:"number",total:"number",precision:"number?"}),!Number.isInteger(precision)||precision<0)throw new Error("percent(): precision must be non-negative integer");return 0===total?0:Number((value/total*100).toFixed(precision))},almostEqual:function almostEqual(a,b,epsilon=1e-10){if(guard("almostEqual",{a:a,b:b,epsilon:epsilon},{a:"number",b:"number",epsilon:"number?"}),epsilon<0)throw new Error("almostEqual(): epsilon must be non-negative");return Math.abs(a-b)<epsilon},isEven:function isEven(...values){if(0===values.length)throw new Error("isEven(): at least one parameter required");return values.forEach(v=>guard("isEven",{v:v},{v:"number"})),values.every(v=>v%2==0)},isOdd:function isOdd(...values){if(0===values.length)throw new Error("isOdd(): at least one parameter required");return values.forEach(v=>guard("isOdd",{v:v},{v:"number"})),values.every(v=>v%2!=0)},factorial:function factorial(n){if(guard("factorial",{n:n},{n:"number"}),!Number.isInteger(n)||n<0)throw new Error("factorial(): parameter must be non-negative integer");if(n<=1)return 1;let result=1;for(let i=2;i<=n;i++)result*=i;return result},isPrime:function isPrime(n){if(guard("isPrime",{n:n},{n:"number"}),!Number.isInteger(n)||n<2)return!1;for(let i=2;i<=Math.sqrt(n);i++)if(n%i===0)return!1;return!0},gcd:gcd,lcm:function lcm(a,b){return guard("lcm",{a:a,b:b},{a:"number",b:"number"}),0===a||0===b?0:Math.abs(a*b)/gcd(a,b)},degreesToRadians:function degreesToRadians(deg){return guard("degreesToRadians",{deg:deg},{deg:"number"}),deg*(Math.PI/180)},radiansToDegrees:function radiansToDegrees(rad){return guard("radiansToDegrees",{rad:rad},{rad:"number"}),rad*(180/Math.PI)},toOrdinal:function toOrdinal(n){guard("toOrdinal",{n:n},{n:"number"});const suffixes=["th","st","nd","rd"],v=Math.abs(n)%100;return n+(suffixes[(v-20)%10]||suffixes[v]||suffixes[0])},randomIntArray:function randomIntArray(min,max,length,precision=0){if(guard("randomIntArray",{min:min,max:max,length:length,precision:precision},{min:"number",max:"number",length:"number",precision:"number?"}),!Number.isInteger(length)||length<0)throw new Error("randomIntArray(): length must be non-negative integer");if(!Number.isInteger(precision)||precision<0)throw new TypeError("randomIntArray(): precision must be non-negative integer");min>max&&([min,max]=[max,min]);const array=[];for(let i=0;i<length;i++){const rand=Math.random()*(max-min)+min;array.push(precision>0?Number(rand.toFixed(precision)):Math.floor(rand))}return array},randomUniqueIntArray:function randomUniqueIntArray(min,max,length,precision=0){if(guard("randomUniqueArray",{min:min,max:max,length:length,precision:precision},{min:"number",max:"number",length:"number",precision:"number?"}),!Number.isInteger(length)||length<0)throw new TypeError("length must be a non-negative integer");if(!Number.isInteger(precision)||precision<0)throw new Error("randomUniqueArray(): precision must be non-negative integer");min>max&&([min,max]=[max,min]);const factor=10**precision,scaledMin=Math.ceil(min*factor),scaledMax=Math.floor(max*factor);if(length>scaledMax-scaledMin+1)throw new Error("randomUniqueArray(): length exceeds unique range");const range=[];for(let i=scaledMin;i<=scaledMax;i++)range.push(i);const result=[];for(;result.length<length;){const idx=Math.floor(Math.random()*range.length),value=range.splice(idx,1)[0];result.push(Number((value/factor).toFixed(precision)))}return result},isPositive:function isPositive(n){return guard("isPositive",{n:n},{n:"number"}),n>0},isNegative:function isNegative(n){return guard("isNegative",{n:n},{n:"number"}),n<0},isObject:isObject,isArray:function isArray(value){return guard("isArray",{value:value},{value:"any"}),Array.isArray(value)},isCollection:function isCollection(value){return guard("isCollection",{value:value},{value:"any"}),null!==value&&(!!Array.isArray(value)||(value instanceof Map||value instanceof Set||value instanceof WeakMap||value instanceof WeakSet||Object.getPrototypeOf(value)===Object.prototype))},checkType:function checkType(value,expectedType){if("string"!=typeof expectedType)throw new TypeError("Primux/checkType(): expectedType must be a string");switch(expectedType){case"number":return"number"==typeof value&&!Number.isNaN(value);case"int":return Number.isInteger(value);case"string":return"string"==typeof value;case"boolean":case"bool":return"boolean"==typeof value;case"float":return"number"==typeof value&&!Number.isNaN(value)&&!Number.isInteger(value);case"array":return Array.isArray(value);case"object":return null!==value&&"object"==typeof value&&!Array.isArray(value);case"null":return null===value;case"undefined":return void 0===value;case"symbol":return"symbol"==typeof value;case"element":return value instanceof Element;default:throw new Error(`checkType(): unknown type "${expectedType}"`)}},int:function int(){return createType("number","int(): only accepts integer numbers",v=>Number.isSafeInteger(v))(...arguments)},string:function string(){return createType("string","string(): only accepts string",v=>"string"==typeof v)(...arguments)},bool:function bool(){return createType("boolean","bool(): only accepts boolean",v=>"boolean"==typeof v)(...arguments)},object:function object(){return createType("object","object(): only accepts plain objects",v=>null!==v&&"object"==typeof v&&Object.getPrototypeOf(v)===Object.prototype)(...arguments)},array:function array(){return createType("array","array(): only accepts arrays",v=>Array.isArray(v))(...arguments)},float:function float(){return createType("float","float(): only accepts floating point numbers",v=>"number"==typeof v&&!Number.isNaN(v))(...arguments)},sym:function sym(){return createType("symbol","sym(): only accepts symbol",v=>"symbol"==typeof v)(...arguments)},isNaN:isNaN,defaultIfNaN:function defaultIfNaN(value,defaultValue=void 0){return guard("defaultIfNaN",{value:value,defaultValue:defaultValue},{value:"any",defaultValue:"any"}),isNaN(value)?defaultValue:value},isNull:function isNull(value){return guard("isNull",{value:value},{value:"any"}),null===value},isUndefined:function isUndefined(value){if(arguments.length<1)throw new TypeError('Primux/isUndefined(value): parameter "value" is required');return void 0===value},isNil:function isNil(value){if(arguments.length<1)throw new TypeError('Primux/isNil(value): parameter "value" is required');return null==value},defaultIfNull:function defaultIfNull(value,defaultValue){return guard("defaultIfNull",{value:value,defaultValue:defaultValue},{value:"any",defaultValue:"any"}),null===value?defaultValue:value},defaultIfNil:function defaultIfNil(value,defaultValue){if(arguments.length<2)throw new TypeError('Primux/defaultIfNil(value, defaultValue): parameter "value" and "defaultValue" is required');return null==value?defaultValue:value},defaultIfUndefined:function defaultIfUndefined(value,defaultValue){if(arguments.length<2)throw new TypeError('Primux/defaultIfUndefined(value, defaultValue): parameter "value" and "defaultValue" is required');return void 0===value?defaultValue:value},coalesce:function coalesce(...values){if(0===values.length)throw new Error("Primux/coalesce: at least one parameter required");return values.find(v=>null!=v)},isTrue:function isTrue(value){return guard("isTrue",{value:value},{value:"any"}),!!value},isFalse:function isFalse(value){return guard("isFalse",{value:value},{value:"any"}),!value},allTrue:function allTrue(...values){if(0===values.length)throw new Error("Primux/allTrue: at least one parameter required");return values.every(v=>!!v)},allFalse:function allFalse(...values){if(0===values.length)throw new Error("Primux/allFalse: at least one parameter required");return values.every(v=>!v)},anyTrue:function anyTrue(...values){if(0===values.length)throw new Error("Primux/anyTrue: at least one parameter required");return values.some(v=>!!v)},anyFalse:function anyFalse(...values){if(0===values.length)throw new Error("Primux/anyFalse: at least one parameter required");return values.some(v=>!v)},xor:function xor(a,b){return guard("xor",{a:a,b:b},{a:"any",b:"any"}),!!a!=!!b},and:function and(...values){if(0===values.length)throw new Error("Primux/and: at least one parameter required");return values.every(v=>!!v)},or:function or(...values){if(0===values.length)throw new Error("Primux/or: at least one parameter required");return values.some(v=>!!v)},not:function not(value){return guard("not",{value:value},{value:"any"}),!value},coerce:function coerce(value){return guard("coerce",{value:value},{value:"any"}),!!value},ifTruthy:function ifTruthy(value,callback){if(guard("ifTruthy",{value:value,callback:callback},{value:"any",callback:"function"}),value)return callback(value)},ifFalsy:function ifFalsy(value,callback){if(guard("ifFalsy",{value:value,callback:callback},{value:"any",callback:"function"}),!value)return callback(value)},isEmpty:isEmpty,isNotEmpty:function isNotEmpty(collection){return!isEmpty(collection)},first:function first(array){return guard("first",{array:array},{array:"array"}),0===array.length?void 0:array[0]},last:function last(array){return guard("last",{array:array},{array:"array"}),0===array.length?void 0:array[array.length-1]},atSafe:function atSafe(array,index){guard("atSafe",{array:array,index:index},{array:"array",index:"number"});const len=array.length,i=index<0?len+index:index;return i<0||i>=len?{value:void 0,exists:!1}:{value:array[i],exists:!0}},sum:function sum(array){guard("sum",{array:array},{array:"array"});let total=0;for(let i=0;i<array.length;i++){const v=array[i];"number"==typeof v&&Number.isFinite(v)&&(total+=v)}return total},average:function average(array){guard("average",{array:array},{array:"array"});let total=0,count=0;for(let i=0;i<array.length;i++){const v=array[i];"number"==typeof v&&Number.isFinite(v)&&(total+=v,count++)}return 0===count?void 0:total/count},min:function min(array){let min;guard("min",{array:array},{array:"array"});for(let i=0;i<array.length;i++){const v=array[i];"number"==typeof v&&Number.isFinite(v)&&(void 0===min||v<min)&&(min=v)}return min},max:function max(array){let max;guard("max",{array:array},{array:"array"});for(let i=0;i<array.length;i++){const v=array[i];"number"==typeof v&&Number.isFinite(v)&&(void 0===max||v>max)&&(max=v)}return max},range:function range(array){let max,min;guard("range",{array:array},{array:"array"});for(let i=0;i<array.length;i++){const v=array[i];"number"==typeof v&&Number.isFinite(v)&&((void 0===max||v>max)&&(max=v),(void 0===min||v<min)&&(min=v))}return void 0===max||void 0===min?void 0:max-min},median:function median(array){guard("median",{array:array},{array:"array"});const nums=array.filter(v=>"number"==typeof v&&Number.isFinite(v));if(0===nums.length)return;nums.sort((a,b)=>a-b);const mid=Math.floor(nums.length/2);return nums.length%2==0?(nums[mid-1]+nums[mid])/2:nums[mid]},unique:function unique(array){guard("unique",{array:array},{array:"array"});const seen=new Map,result=[];for(const v of array){const key=stableHash(v);seen.has(key)||(seen.set(key,!0),result.push(v))}return result},duplicates:function duplicates(array){guard("duplicates",{array:array},{array:"array"});const count=new Map,originals=new Map,result=[];for(const v of array){const key=stableHash(v);count.has(key)?count.set(key,count.get(key)+1):(originals.set(key,v),count.set(key,1))}for(const[key,c]of count.entries())c>1&&result.push(originals.get(key));return result},count:function count(array,value){if(guard("count",{array:array,value:value},{array:"array",value:"any?"}),void 0!==value){const key=stableHash(value);let total=0;for(const v of array)stableHash(v)===key&&total++;return total}const result=new Map;for(const v of array){const key=stableHash(v);result.set(key,(result.get(key)||0)+1)}return result},containsAll:function containsAll(array,other){guard("containsAll",{array:array,other:other},{array:"array",other:"array"});const map=new Map;for(const v of array)map.set(stableHash(v),!0);for(const v of other)if(!map.has(stableHash(v)))return!1;return!0},intersection:function intersection(array,other,options={}){guard("intersection",{array:array,other:other,options:options},{array:"array",other:"array",options:"object?"});const{unique:unique=!1}=options,map=new Map,result=[],seen=new Set;for(const v of other)map.set(stableHash(v),!0);for(const v of array){const h=stableHash(v);map.has(h)&&(unique?seen.has(h)||(result.push(v),seen.add(h)):result.push(v))}return result},union:function union(array,other){guard("union",{array:array,other:other},{array:"array",other:"array"});const result=[],seen=new Map;for(const v of[...array,...other]){const key=stableHash(v);seen.has(key)||(seen.set(key,!0),result.push(v))}return result},remove:function remove(array,value){if(guard("remove",{array:array},{array:"array"}),arguments.length<2)throw new TypeError('Primux/remove(array, value): parameter "value" is required');return array.filter(v=>!deepEqual(v,value))},swap:function swap(array,fIndex,sIndex){if(guard("swap",{array:array,fIndex:fIndex,sIndex:sIndex},{array:"array",fIndex:"number",sIndex:"number"}),fIndex<0||fIndex>=array.length||sIndex<0||sIndex>=array.length)throw new RangeError("swap(array, i, j): index out of bounds");const newArr=[...array],temp=newArr[fIndex];return newArr[fIndex]=newArr[sIndex],newArr[sIndex]=temp,newArr},clear:function clear(array){guard("clear",{array:array},{array:"array"}),array.splice(0,array.length)},chunk:function chunk(array,size){guard("chunk",{array:array,size:size},{array:"array",size:"number"});const result=[];if(size<=0)throw new RangeError("Primux/chunk: size must be greater than 0");for(let i=0;i<array.length;i+=size)result.push(array.slice(i,i+size));return result},zip:function zip(...arrays){arrays.forEach(a=>guard("zip",{a:a},{a:"array"}));const result=[],minLength=Math.min(...arrays.map(a=>a.length));for(let i=0;i<minLength;i++)result.push(arrays.map(a=>a[i]));return result},flattenDeep:function flattenDeep(array){guard("flattenDeep",{array:array},{array:"array"});const result=[],stack=[...array];for(;stack.length;){const value=stack.pop();Array.isArray(value)?stack.push(...value):result.push(value)}return result.reverse()},flattenTo:function flattenTo(array,depth=1){guard("flattenTo",{array:array,depth:depth},{array:"array",depth:"number?"}),depth<0&&(depth=0);const result=[],deep=(arr,currentDepth)=>{arr.forEach(item=>{Array.isArray(item)&¤tDepth<depth?deep(item,currentDepth+1):result.push(item)})};return deep(array,0),result},sortAsc:function sortAsc(array,comparator){return guard("sortAsc",{array:array,comparator:comparator},{array:"array",comparator:"function?"}),"function"==typeof comparator?[...array].sort(comparator):[...array].sort((a,b)=>{const toNumber=v=>"boolean"==typeof v?v?1:0:v;return"number"==typeof a&&"number"==typeof b?a-b:"string"==typeof a&&"string"==typeof b?a.localeCompare(b):toNumber(a)-toNumber(b)})},sortDesc:function sortDesc(array,comparator){return guard("sortDesc",{array:array,comparator:comparator},{array:"array",comparator:"function?"}),"function"==typeof comparator?[...array].sort((a,b)=>comparator(b,a)):[...array].sort((a,b)=>{const toNumber=v=>"boolean"==typeof v?v?1:0:v;return"number"==typeof a&&"number"==typeof b?b-a:"string"==typeof a&&"string"==typeof b?b.localeCompare(a):toNumber(b)-toNumber(a)})},shuffle:shuffle,sample:function sample(array,count=1){if(guard("sample",{array:array,count:count},{array:"array",count:"number?"}),0===array.length)return;if(count>array.length)throw new RangeError("Primux/sample: count exceeds array length");return shuffle(array).slice(0,count)},compact:function compact(array){return guard("compact",{array:array},{array:"array"}),array.filter(v=>Boolean(v))},keysArray:function keysArray(obj){return guard("keysArray",{obj:obj},{obj:"object"}),Reflect.ownKeys(obj)},valuesArray:function valuesArray(obj){return guard("valuesArray",{obj:obj},{obj:"object"}),Reflect.ownKeys(obj).map(k=>obj[k])},entriesArray:function entriesArray(obj){return guard("entriesArray",{obj:obj},{obj:"object"}),Reflect.ownKeys(obj).map(k=>[k,obj[k]])},keysLength:function keysLength(obj){return guard("keysLength",{obj:obj},{obj:"object"}),Reflect.ownKeys(obj).length},has:has,deepClone:deepClone,deepMerge:deepMerge,mergeAll:function mergeAll(...objects){if(guard("mergeAll",{objects:objects},{objects:"array"}),!objects.length)return{};const seen=new WeakMap;let result={};for(const obj of objects)result=deepMerge(result,obj,seen);return result},pick:function pick(obj,keysArr){guard("pick",{obj:obj,keysArr:keysArr},{obj:"object",keysArr:"array"});const result={};for(const key of keysArr){if("string"!=typeof key&&"symbol"!=typeof key)throw new TypeError("pick(): keys must be string or symbol");has(obj,key)&&(result[key]=obj[key])}return result},omit:function omit(obj,keysArr){guard("omit",{obj:obj,keysArr:keysArr},{obj:"object",keysArr:"array"});const result=deepClone(obj);for(const key of keysArr){if("string"!=typeof key&&"symbol"!=typeof key)throw new TypeError("omit(): keys must be string or symbol");delete result[key]}return result},mapValues:function mapValues(obj,callback){guard("mapValues",{obj:obj,callback:callback},{obj:"object",callback:"function"});const result={};for(const key of Reflect.ownKeys(obj))result[key]=callback(obj[key],key,obj);return result},mapKeys:function mapKeys(obj,callback){guard("mapKeys",{obj:obj,callback:callback},{obj:"object",callback:"function"});const result={};for(const key of Reflect.ownKeys(obj)){const newKey=callback(key,obj[key],obj);if("string"!=typeof newKey&&"symbol"!=typeof newKey)throw new TypeError("mapKeys(): callback must return string or symbol");result[newKey]=obj[key]}return result},mapEntries:function mapEntries(obj,callback){guard("mapEntries",{obj:obj,callback:callback},{obj:"object",callback:"function"});const result={};for(const key of Reflect.ownKeys(obj)){const[newKey,newValue]=callback(key,obj[key],obj);if("string"!=typeof newKey&&"symbol"!=typeof newKey)throw new TypeError("mapEntries(): newKey must be string or symbol");result[newKey]=newValue}return result},filterObj:function filterObj(obj,callback){guard("filterObj",{obj:obj,callback:callback},{obj:"object",callback:"function"});const result={};for(const key of Reflect.ownKeys(obj))callback(obj[key],key,obj)&&(result[key]=obj[key]);return result},deepFreeze:function deepFreeze(obj,seen=new WeakSet){if(null===obj||"object"!=typeof obj||seen.has(obj))return obj;seen.add(obj),Object.freeze(obj);for(const key of Reflect.ownKeys(obj))deepFreeze(obj[key],seen);return obj},keyBy:function keyBy(arr,cb){guard("keyBy",{arr:arr,cb:cb},{arr:"array",cb:"function"});const result={};for(const item of arr){const key=cb(item);if("string"!=typeof key&&"symbol"!=typeof key&&"number"!=typeof key)throw new TypeError("keyBy(): key must be string or symbol or number");result[key]=item}return result},invert:function invert(obj){guard("invert",{obj:obj},{obj:"object"});const result={};for(const key of Reflect.ownKeys(obj)){const value=obj[key];result["symbol"==typeof value?value:String(value)]=key}return result},uppercaseWords:function uppercaseWords(str){return guard("uppercaseWords",{str:str},{str:"string"}),str?str.trim().split(/\s+/).map(w=>w[0].toUpperCase()+w.slice(1)).join(" "):""},lowercaseWords:function lowercaseWords(str){return guard("lowercaseWords",{str:str},{str:"string"}),str?str.trim().split(/\s+/).map(w=>w[0].toLowerCase()+w.slice(1)).join(" "):""},truncate:function truncate(str,length,ellipsis="..."){return guard("truncate",{str:str,length:length,ellipsis:ellipsis},{str:"string",length:"number",ellipsis:"string?"}),str&&length?(guardNegativeNumber(length,"truncate(str, length, ellipsis?)"),str.length<=length?str:str.slice(0,length)+ellipsis):""},uppercaseChar:function uppercaseChar(char){return guard("uppercaseChar",{char:char},{char:"string"}),char?(checkChar(char,"uppercaseChar(char)"),char.toUpperCase()):""},lowercaseChar:function lowercaseChar(char){return guard("lowercaseChar",{char:char},{char:"string"}),char?(checkChar(char,"lowercaseChar(char)"),char.toLowerCase()):""},uppercaseFirstChar:function uppercaseFirstChar(str){if(guard("uppercaseFirstChar",{str:str},{str:"string"}),!str)return"";const chars=Array.from(str);return chars[0]=chars[0].toUpperCase(),chars.join("")},lowercaseFirstChar:function lowercaseFirstChar(str){if(guard("lowercaseFirstChar",{str:str},{str:"string"}),!str)return"";const chars=Array.from(str);return chars[0]=chars[0].toLowerCase(),chars.join("")},slugify:function slugify(str){return guard("slugify",{str:str},{str:"string"}),str?str.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,""):""},stripHtml:function stripHtml(html){if(guard("stripHtml",{html:html},{html:"string"}),"undefined"!=typeof document){const div=createElement("div",{html:html});return div.querySelectorAll("script, style").forEach(el=>el.remove()),div.textContent||""}return html?html.replace(/<script[\s\S]*?>[\s\S]*?<\/script>/gi,"").replace(/<style[\s\S]*?>[\s\S]*?<\/style>/gi,"").replace(/<[^>]+>/g,""):""},escapeHtml:function escapeHtml(html){return guard("escapeHtml",{html:html},{html:"string"}),html?html.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):""},countOccurrences:function countOccurrences(str,s){if(guard("countOccurrences",{str:str,s:s},{str:"string",s:"string"}),!s||!str)return 0;let count=0,pos=0;for(;-1!==(pos=str.indexOf(s,pos));)count++,pos+=s.length;return count},reverseString:function reverseString(str){return guard("reverseString",{str:str},{str:"string"}),str?Array.from(str).reverse().join(""):""},padCenter:function padCenter(str,length,pad=" "){if(guard("padCenter",{str:str,length:length,pad:pad},{str:"string",length:"number",pad:"string?"}),guardNegativeNumber(length,"padCenter(str, length, pad?)"),!pad)throw new TypeError("Primux/padCenter: pad must be non-empty");const strLen=str.length;if(strLen>=length)return str;const totalPad=length-strLen,left=Math.floor(totalPad/2),right=totalPad-left,makePad=n=>pad.repeat(Math.ceil(n/pad.length)).slice(0,n);return makePad(left)+str+makePad(right)},removeAccent:function removeAccent(str){return guard("removeAccent",{str:str},{str:"string"}),str?str.normalize("NFD").replace(/[\u0300-\u036f]/g,""):""},isPalindrome:function isPalindrome(str){guard("isPalindrome",{str:str},{str:"string"});const cleaned=str?str.toLowerCase().replace(/[^\p{L}\p{N}]/gu,""):"";return cleaned===Array.from(cleaned).reverse().join("")}})}();!function(root,factory){"function"==typeof define&&define.amd?define([],factory):"object"==typeof module&&module.exports?module.exports=factory():root._p=factory()}("undefined"!=typeof globalThis?globalThis:this,function(){return _p});
|