ziko
Version:
A versatile JavaScript library offering a rich set of Hyperscript Based UI components, advanced mathematical utilities, interactivity ,animations, client side routing and more ...
1,562 lines (1,484 loc) • 174 kB
JavaScript
/*
Project: ziko.js
Author: Zakaria Elalaoui
Date : Thu Oct 09 2025 16:04:28 GMT+0100 (UTC+01:00)
Git-Repo : https://github.com/zakarialaoui10/ziko.js
Git-Wiki : https://github.com/zakarialaoui10/ziko.js/wiki
Released under MIT License
*/
'use strict';
const { PI: PI$2, E } = Math;
const EPSILON=Number.EPSILON;
const {PI: PI$1, cos: cos$3, sin: sin$3, tan: tan$1, acos: acos$2, asin: asin$1, atan: atan$1, cosh: cosh$2, sinh: sinh$2, tanh: tanh$1, acosh: acosh$1, asinh: asinh$1, atanh: atanh$1, log: log$1} = Math;
let Fixed={
cos: cos$3,
sin: sin$3,
tan: tan$1,
sinc: x => sin$3(PI$1*x)/(PI$1*x),
sec: x => 1/cos$3(x),
csc: x => 1/sin$3(x),
cot: x => 1/tan$1(x),
acos: acos$2,
asin: asin$1,
atan: atan$1,
acot: x => PI$1/2-atan$1(x),
cosh: cosh$2,
sinh: sinh$2,
tanh: tanh$1,
coth: n => (1/2*log$1((1+n)/(1-n))),
acosh: acosh$1,
asinh: asinh$1,
atanh: atanh$1,
};
Fixed = new Proxy(Fixed, {
get(target, prop) {
if(prop in target){
return x => + target[prop](x).toFixed(15);
}
return undefined;
}
});
class ZikoMath {}
// To generalise
const mapfun$1=(fun,...X)=>{
const Y=X.map(x=>{
if(x===null) return fun(null);
if(["number","string","boolean","bigint","undefined"].includes(typeof x)) return fun(x);
if(x instanceof Array) return x.map(n=>mapfun$1(fun,n));
if(ArrayBuffer.isView(x)) return x.map(n=>fun(n));
if(x instanceof Set) return new Set(mapfun$1(fun,...[...x]));
if(x instanceof Map) return new Map([...x].map(n=>[n[0],mapfun$1(fun,n[1])]));
if(x instanceof Matrix){
return new Matrix(x.rows,x.cols, mapfun$1(x.arr.flat(1)))
}
if(x instanceof Complex){
const [a,b,z,phi]=[x.a,x.b,x.z,x.phi];
switch(fun){
case Math.log: return complex(ln(z),phi); // Done
case Math.exp: return complex(e(a)*cos$2(b),e(a)*sin$2(b)); // Done
case Math.abs: return z; // Done
case Math.sqrt: return complex(sqrt$2(z)*cos$2(phi/2),sqrt$2(z)*sin$2(phi/2)); // Done
case Fixed.cos: return complex(cos$2(a)*cosh$1(b),-(sin$2(a)*sinh$1(b)));
case Fixed.sin: return complex(sin$2(a)*cosh$1(b),cos$2(a)*sinh$1(b));
case Fixed.tan:{
const DEN = cos$2(2*a)+cosh$1(2*b);
return complex(sin$2(2*a)/DEN,sinh$1(2*b)/DEN);
}
case Fixed.cosh:return complex(cosh$1(a)*cos$2(b),sinh$1(a)*sin$2(b));
case Fixed.sinh:return complex(sinh$1(a)*cos$2(b),cosh$1(a)*sin$2(b));
case Fixed.tanh:{
const DEN=cosh$1(2*a)+cos$2(2*b);
return complex(sinh$1(2*a)/DEN,sin$2(2*b)/DEN)
}
default : return fun(x)
}
}
else if(x instanceof Object){
return Object.fromEntries(Object.entries(x).map(n=>n=[n[0],mapfun$1(fun,n[1])]))
}
});
return Y.length==1?Y[0]:Y;
};
const _add=(a,b)=>{
if(typeof(a)==="number"){
if (typeof b == "number") return a + b;
else if (b instanceof Complex)return complex(a + b.a, b.b);
else if (b instanceof Matrix) return Matrix.nums(b.rows, b.cols, a).add(b);
else if (b instanceof Array)return b.map(n=>add(n,a));
}
else if(a instanceof Complex||a instanceof Matrix){
if(b instanceof Array)return b.map(n=>a.clone.add(n));
return a.clone.add(b);
}
else if(a instanceof Array){
if(b instanceof Array){
if(a.length === b.length)return a.map((n,i)=>add(n,b[i]))
}
else {
return a.map(n=>add(n,b));
}
}
};
const _sub=(a,b)=>{
if(typeof(a)==="number"){
if (typeof b == "number") return a - b;
else if (b instanceof Complex)return complex(a - b.a, -b.b);
else if (b instanceof Matrix) return Matrix.nums(b.rows, b.cols, a).sub(b);
else if (b instanceof Array)return b.map(n=>sub(n,a));
}
else if(a instanceof Complex||a instanceof Matrix){
if(b instanceof Array)return b.map(n=>a.clone.sub(n));
return a.clone.sub(b);
}
else if(a instanceof Array){
if(b instanceof Array){
if(b instanceof Array){
if(a.length === b.length)return a.map((n,i)=>sub(n,b[i]))
}
}
else {
return a.map(n=>sub(n,b));
}
}
};
const _mul=(a,b)=>{
if(typeof(a)==="number"){
if (typeof b == "number") return a * b;
else if (b instanceof Complex)return complex(a * b.a,a * b.b);
else if (b instanceof Matrix) return Matrix.nums(b.rows, b.cols, a).mul(b);
else if (b instanceof Array)return b.map(n=>mul(a,n));
}
else if(a instanceof Complex||a instanceof Matrix){
if(b instanceof Array)return b.map(n=>a.clone.mul(n));
return a.clone.mul(b);
}
else if(a instanceof Array){
if(b instanceof Array){
if(b instanceof Array){
if(a.length === b.length)return a.map((n,i)=>mul(n,b[i]))
}
}
else {
return a.map(n=>mul(n,b));
}
}
};
const _div=(a,b)=>{
if(typeof(a)==="number"){
if (typeof b == "number") return a / b;
else if (b instanceof Complex)return complex(a / b.a,a / b.b);
else if (b instanceof Matrix) return Matrix.nums(b.rows, b.cols, a).div(b);
else if (b instanceof Array)return b.map(n=>div(a,n));
}
else if(a instanceof Complex||a instanceof Matrix){
if(b instanceof Array)return b.map(n=>a.clone.div(n));
return a.clone.div(b);
}
else if(a instanceof Array){
if(b instanceof Array){
if(b instanceof Array){
if(a.length === b.length)return a.map((n,i)=>div(n,b[i]))
}
}
else {
return a.map(n=>div(n,b));
}
}
};
const _modulo=(a,b)=>{
if(typeof(a)==="number"){
if (typeof b == "number") return a % b;
else if (b instanceof Complex)return complex(a % b.a,a % b.b);
else if (b instanceof Matrix) return Matrix.nums(b.rows, b.cols, a).modulo(b);
else if (b instanceof Array)return b.map(n=>div(a,n));
}
else if(a instanceof Complex||a instanceof Matrix){
if(b instanceof Array)return b.map(n=>a.clone.div(n));
return a.clone.div(b);
}
else if(a instanceof Array){
if(b instanceof Array);
else {
return a.map(n=>add(n,b));
}
}
};
const add=(a,...b)=>{
var res=a;
for(let i=0;i<b.length;i++)res=_add(res,b[i]);
return res;
};
const sub=(a,...b)=>{
var res=a;
for(let i=0;i<b.length;i++)res=_sub(res,b[i]);
return res;
};
const mul=(a,...b)=>{
var res=a;
for(let i=0;i<b.length;i++)res=_mul(res,b[i]);
return res;
};
const div=(a,...b)=>{
var res=a;
for(let i=0;i<b.length;i++)res=_div(res,b[i]);
return res;
};
const modulo=(a,...b)=>{
var res=a;
for(let i=0;i<b.length;i++)res=_modulo(res,b[i]);
return res;
};
const zeros=(n)=>new Array(n).fill(0);
const ones=(n)=>new Array(n).fill(1);
const nums=(num,n)=>new Array(n).fill(num);
const norm=(value, min, max)=>{
if (typeof value === "number") return min !== max ? (value - min) / (max - min) : 0;
else if (value instanceof Matrix) return new Matrix(value.rows, value.cols, norm(value.arr.flat(1), min, max));
else if (value instanceof Complex) return new Complex(norm(value.a, min, max), norm(value.b, min, max));
else if (value instanceof Array) {
if (value.every((n) => typeof (n === "number"))) {
return value.map((n) => norm(n, min, max));
} else {
let y = new Array(value.length);
for (let i = 0; i < value.length; i++) {
y[i] = norm(value[i]);
}
}
}
};
const lerp=(value, min, max)=>{
if (typeof value === "number") return (max - min) * value + min;
else if (value instanceof Matrix) return new Matrix(value.rows, value.cols, lerp(value.arr.flat(1), min, max));
else if (value instanceof Complex) return new Complex(lerp(value.a, min, max), lerp(value.b, min, max));
else if (value instanceof Array) {
if (value.every((n) => typeof (n === "number"))) {
return value.map((n) => lerp(n, min, max));
} else {
let y = new Array(value.length);
for (let i = 0; i < value.length; i++) {
y[i] = lerp(value[i]);
}
}
}
};
const map$1=(value, a, b, c, d)=>{
if (typeof value === "number") return lerp(norm(value, a, b), c, d);
else if (value instanceof Matrix) return new Matrix(value.rows, value.cols, map$1(value.arr.flat(1), a, b, c, d));
else if (value instanceof Complex) return new Complex(map$1(value.a, b, c, d), map$1(value.b, a, b, c, d));
else if (value instanceof Array) {
if (value.every((n) => typeof (n === "number"))) {
return value.map((n) => map$1(n, a, b, c, d));
} else {
let y = new Array(value.length);
for (let i = 0; i < value.length; i++) {
y[i] = map$1(value[i], a, b, c, d);
}
}
}
};
const clamp=(x, a , b)=>{
const [min_value,max_value]=[min(a,b),max(a,b)];
if (typeof x === "number") return min(max(x, min_value), max_value);
else if (x instanceof Matrix) return new Matrix(x.rows, x.cols, clamp(x.arr.flat(1), min_value, max_value));
else if (x instanceof Complex) return new Complex(clamp(x.a, min_value, max_value), clamp(x.b, min_value, max_value));
else if (x instanceof Array) {
if (x.every((n) => typeof (n === "number"))) {
return x.map((n) => clamp(n, min_value, max_value));
} else {
let y = new Array(x.length);
for (let i = 0; i < x.length; i++) {
y[i] = clamp(x[i], min_value, max_value);
}
}
}
};
const arange=(a, b, step , include = false)=>{
let tab = [];
if(a<b){
for (let i = a; include?i<=b:i<b; i += step) tab.push((i * 10) / 10);
}
else {
for(let i = a; include?i>=b:i>b; i -= step) tab.push((i * 10) / 10);
}
return tab;
};
const linspace=(a,b,n=abs(b-a)+1,endpoint=true)=>{
if(Math.floor(n)!==n)return;
if([a,b].every(n=>typeof n==="number")){
const [max,min]=[a,b].sort((a,b)=>b-a);
var Y = [];
let step ;
endpoint ? step = (max - min) / (n - 1) : step = (max - min) / n;
for (var i = 0; i < n; i++) {
a<b?Y.push(min+step*i):Y.push(max-step*i);
}
return Y
}
if([a,b].some(n=>n instanceof Complex)){
const z1=complex(a);
const z2=complex(b);
n=n||Math.abs(z1.a-z2.a)+1;
const X=linspace(z1.a,z2.a,n,endpoint);
const Y=linspace(z1.b,z2.b,n,endpoint);
let Z=new Array(n).fill(null);
Z=Z.map((n,i)=>complex(X[i],Y[i]));
return Z;
}
};
const logspace=(a,b,n=b-a+1,base=E,endpoint=true)=>{
return linspace(a,b,n,endpoint).map(n=>pow$1(base,n))
};
const geomspace=(a,b,n=abs(b-a)+1,endpoint=true)=>{
if(Math.floor(n)!==n)return;
if([a,b].every(n=>typeof n==="number")){
const [max,min]=[a,b].sort((a,b)=>b-a);
let base;
endpoint ? base = sqrtn(max/min,n-1) : base = sqrtn(max/min,n) ;
const Y = [min];
for (let i = 1; i < n; i++) {
Y.push(Y[i-1]*base);
}
return a<b?Y:Y.reverse()
}
if([a,b].some(n=>n instanceof Complex)){
const z1=complex(a);
const z2=complex(b);
n=n||Math.abs(z1.a-z2.a)+1;
let base;
endpoint ? base = sqrtn(z2.div(z1),n-1) : base = sqrtn(z2.div(z1),n) ;
const Y = [z1];
for (let i = 1; i < n; i++) {
Y.push(mul(Y[i-1],base));
}
return Y;
}
};
/** @module Math */
/**
* Converts degrees to radians.
* @param {...number} deg - Degrees to convert.
* @returns {number|number[]} Returns an array of radians corresponding to the input degrees.
*/
const deg2rad = (...deg) => mapfun(x => x * Math.PI / 180, ...deg);
/**
* Converts radians to degrees.
* @param {...number} rad - Radians to convert.
* @returns {number|number[]} Returns an array of degrees corresponding to the input radians.
*/
const rad2deg = (...rad) => mapfun(x => x / Math.PI * 180, ...rad);
// Mixed calcul
const sum=(...x)=>{
if(x.every(n=>typeof n==="number")){
let s = x[0];
for (let i = 1; i < x.length; i++) s += x[i];
return s;
}
const Y=[];
for(let i=0;i<x.length;i++){
if(x[i] instanceof Array)Y.push(sum(...x[i]));
else if(x[i] instanceof Object){
Y.push(sum(...Object.values(x[i])));
}
}
return Y.length===1?Y[0]:Y;
};
const prod=(...x)=>{
if(x.every(n=>typeof n==="number")){
let p = x[0];
for (let i = 1; i < x.length; i++) p *= x[i];
return p;
}
const Y=[];
for(let i=0;i<x.length;i++){
if(x[i] instanceof Array)Y.push(prod(...x[i]));
else if(x[i] instanceof Object){
Y.push(prod(...Object.values(x[i])));
}
}
return Y.length===1?Y[0]:Y;
};
const min=(...num)=>{
if(num.every(n=>typeof n==="number"))return Math.min(...num);
const Y=[];
for(let i=0;i<num.length;i++){
if(num[i] instanceof Array)Y.push(min(...num[i]));
else if(num[i] instanceof Object){
Y.push(
Object.fromEntries(
[Object.entries(num[i]).sort((a,b)=>a[1]-b[1])[0]]
)
);
}
}
return Y.length===1?Y[0]:Y;
};
const max=(...num)=>{
if(num.every(n=>typeof n==="number"))return Math.max(...num);
const Y=[];
for(let i=0;i<num.length;i++){
if(num[i] instanceof Array)Y.push(min(...num[i]));
else if(num[i] instanceof Object){
Y.push(
Object.fromEntries(
[Object.entries(num[i]).sort((a,b)=>b[1]-a[1])[0]]
)
);
}
}
return Y.length===1?Y[0]:Y;
};
const accum=(...num)=>{
if(num.every(n=>typeof n==="number")){
let acc = num.reduce((x, y) => [...x, x[x.length - 1] + y], [0]);
acc.shift();
return acc;
}
const Y=[];
for(let i=0;i<num.length;i++){
if(num[i] instanceof Array)Y.push(accum(...num[i]));
else if(num[i] instanceof Object){
Y.push(null
// Object.fromEntries(
// [Object.entries(num[i]).sort((a,b)=>b[1]-a[1])[0]]
// )
);
}
}
return Y.length===1?Y[0]:Y;
};
//moy
//med
//variance
//std
//mode
//acccum
//min2max
//max2min
//percentile
/** @module Math */
/**
* Checks if a value is within the specified range.
* @function
* @param {number} x - The value to check.
* @param {number} a - The start of the range.
* @param {number} b - The end of the range.
* @returns {boolean} Returns true if the value is within the range [a, b], otherwise false.
*/
const inRange = (x, a, b) => {
const [min, max] = [Math.min(a, b), Math.max(a, b)];
return x >= min && x <= max;
};
/**
* Checks if two numbers are approximately equal within a given error margin.
* @param {number} a - The first number.
* @param {number} b - The second number.
* @param {number} [Err=0.0001] - The maximum acceptable difference between the two numbers.
* @returns {boolean} Returns true if the two numbers are approximately equal within the specified error margin, otherwise false.
*/
const isApproximatlyEqual = (a, b, Err = 0.0001) => {
return Math.abs(a - b) <= Err;
};
/** @module Math */
/**
* Computes the cartesian product of two arrays.
* @param {Array} a - The first array.
* @param {Array} b - The second array.
* @returns {Array} Returns an array representing the cartesian product of the input arrays.
*/
const cartesianProduct = (a, b) => a.reduce((p, x) => [...p, ...b.map((y) => [x, y])], []);
/**
* Computes the greatest common divisor (GCD) of two numbers.
* @param {number} n1 - The first number.
* @param {number} n2 - The second number.
* @returns {number} Returns the greatest common divisor of the two input numbers.
*/
const pgcd = (n1, n2) => {
let i,
pgcd = 1;
if (n1 == floor(n1) && n2 == floor(n2)) {
for (i = 2; i <= n1 && i <= n2; ++i) {
if (n1 % i == 0 && n2 % i == 0) pgcd = i;
}
return pgcd;
} else console.log("error");
};
/**
* Computes the least common multiple (LCM) of two numbers.
* @param {number} n1 - The first number.
* @param {number} n2 - The second number.
* @returns {number} Returns the least common multiple of the two input numbers.
*/
const ppcm = (n1, n2) => {
let ppcm;
if (n1 == floor(n1) && n2 == floor(n2)) {
ppcm = n1 > n2 ? n1 : n2;
while (true) {
if (ppcm % n1 == 0 && ppcm % n2 == 0) break;
++ppcm;
}
return ppcm;
} else console.log("error");
};
const Utils={
add,
sub,
mul,
div,
modulo,
zeros,
ones,
nums,
norm,
lerp,
map: map$1,
clamp,
arange,
linspace,
logspace,
geomspace,
sum,
prod,
accum,
cartesianProduct,
ppcm,
pgcd,
deg2rad,
rad2deg,
inRange,
isApproximatlyEqual
};
const powerSet=originalSet=>{
const subSets = [];
const NUMBER_OF_COMBINATIONS = 2 ** originalSet.length;
for (let i = 0; i < NUMBER_OF_COMBINATIONS; i += 1) {
const subSet = [];
for (let j = 0; j < originalSet.length; j += 1) {
if (i & (1 << j)) {
subSet.push(originalSet[j]);
}
}
subSets.push(subSet);
}
return subSets;
};
// const subSet = (...arr) => {
// let list = arange(0, 2 ** arr.length, 1);
// let bin = list.map((n) => n.toString(2).padStart(arr.length, '0')).map((n) => n.split("").map((n) => +n));
// let sub = bin.map((n) => n.map((m, i) => (m === 1 ? arr[i] : null))).map((n) => n.filter((x) => x !== null));
// return sub;
// };
const subSet = null;
const Base={
_mode:Number,
_map:function(func,number,toBase){
if (number instanceof Matrix)
return new Matrix(
number.rows,
number.cols,
number.arr.flat(1).map(n=>func(n,toBase))
);
else if (number instanceof Complex) return new Complex(func(number.a,toBase),func(number.b,toBase));
else if (number instanceof Array) return number.map((n) =>func(n,toBase));
},
dec2base(dec,base){
base<=10?this._mode=Number:this._mode=String;
//this._mode=String
if (typeof dec === "number") return this._mode((dec >>> 0).toString(base));
return this._map(this.dec2base,dec,base)
},
dec2bin(dec){
return this.dec2base(dec,2);
},
dec2oct(dec){
return this.dec2base(dec,8);
},
dec2hex(dec){
return this.dec2base(dec,16);
},
bin2base(bin, base) {
return this.dec2base(this.bin2dec(bin),base)
},
bin2dec(bin){
return this._mode("0b"+bin);
},
bin2oct(bin){
return this.bin2base(bin,8);
},
bin2hex(bin){
return this.bin2base(bin,16);
},
oct2dec(oct){
return this._mode("0o"+oct);
},
oct2bin(oct){
return this.dec2bin(this.oct2dec(oct))
},
oct2hex(oct){
return this.dec2hex(this.oct2dec(oct))
},
oct2base(oct, base) {
return this.dec2base(this.oct2dec(oct),base)
},
hex2dec(hex){
return this._mode("0x"+hex);
},
hex2bin(hex){
return this.dec2bin(this.hex2dec(hex))
},
hex2oct(hex){
return this.dec2oct(this.hex2dec(hex))
},
hex2base(hex, base) {
return this.dec2base(this.hex2dec(hex),base)
},
IEEE32toDec(Bin){
let IEEE32=Bin.split(" ").join("").padEnd(32,"0");
let s=IEEE32[0];
let e=2**(+("0b"+IEEE32.slice(1,9))-127);
let m=IEEE32.slice(9,32).split("").map(n=>+n);
let M=m.map((n,i)=>n*(2**(-i-1))).reduce((a,b)=>a+b,0);
let dec=(-1)**s*(1+M)*e;
return dec
},
IEEE64toDec(Bin){
let IEEE64=Bin.split(" ").join("").padEnd(64,"0");
let s=IEEE64[0];
let e=2**(+("0b"+IEEE64.slice(1,12))-1023);
let m=IEEE64.slice(13,64).split("").map(n=>+n);
let M=m.map((n,i)=>n*(2**(-i-1))).reduce((a,b)=>a+b,0);
let dec=(-1)**s*(1+M)*e;
return dec;
}
};
const Logic$1={
_mode:Number,
_map:function(func,a,b){
if (a instanceof Matrix)
return new Matrix(
a.rows,
a.cols,
a.arr.flat(1).map((n) => func(n, b))
);
else if (a instanceof Complex) return new Complex(func(a.a, b), func(a.b, b));
else if (a instanceof Array) return a.map((n) => func(n, b));
},
not:function(input){
if(["number","boolean"].includes(typeof input)) return Logic$1._mode(!input);
else return this._map(this.not,input)
},
and:function(a, ...b){
if(["number","boolean"].includes(typeof a))return Logic$1._mode(b.reduce((n, m) => (n &= m), a));
else return this._map(this.and,a,b)
},
or:function(a, ...b) {
if(["number","boolean"].includes(typeof a)) return Logic$1._mode(b.reduce((n, m) => (n |= m), a));
else return this._map(this.or,a,b);
},
nand:function(a, ...b) {
return this.not(this.and(a, b));
},
nor:function(a, ...b) {
return this.not(this.or(a, b));
},
xor:function(a,...b){
let arr=[a,...b];
if(["number","boolean"].includes(typeof a))return this._mode(arr.reduce((length,cur)=>{
if(+cur===1)length+=1;
return length;
},0)===1);
else return this._map(this.xor,a,b);
},
xnor:function(a,...b){
return Logic$1.not(Logic$1.xor(a,b))
}
};
class Permutation {
static withDiscount(arr, l = arr.length) {
if (l === 1) return arr.map((n) => [n]);
const permutations = [];
let smallerPermutations;
smallerPermutations = this.withDiscount(arr, l - 1);
arr.forEach((currentOption) => {
smallerPermutations.forEach((smallerPermutation) => {
permutations.push([currentOption].concat(smallerPermutation));
});
});
return permutations;
}
static withoutDiscount(arr) {
const l = arr.length;
if (l === 1) return arr.map((n) => [n]);
const permutations = [];
const smallerPermutations = this.withoutDiscount(arr.slice(1));
const firstOption = arr[0];
for (let i = 0; i < smallerPermutations.length; i++) {
const smallerPermutation = smallerPermutations[i];
for (let j = 0; j <= smallerPermutation.length; j++) {
const permutationPrefix = smallerPermutation.slice(0, j);
const permutationSuffix = smallerPermutation.slice(j);
permutations.push(permutationPrefix.concat([firstOption], permutationSuffix));
}
}
return permutations;
}
}
class Combinaison {
static withDiscount(comboOptions, comboLength) {
if (comboLength === 1) {
return comboOptions.map((comboOption) => [comboOption]);
}
const combos = [];
comboOptions.forEach((currentOption, optionIndex) => {
const smallerCombos = this.withDiscount(comboOptions.slice(optionIndex), comboLength - 1);
smallerCombos.forEach((smallerCombo) => {
combos.push([currentOption].concat(smallerCombo));
});
});
return combos;
}
static withoutDiscount(comboOptions, comboLength) {
if (comboLength === 1) {
return comboOptions.map((comboOption) => [comboOption]);
}
const combos = [];
comboOptions.forEach((currentOption, optionIndex) => {
const smallerCombos = this.withoutDiscount(comboOptions.slice(optionIndex + 1), comboLength - 1);
smallerCombos.forEach((smallerCombo) => {
combos.push([currentOption].concat(smallerCombo));
});
});
return combos;
}
}
const combinaison=(comboOptions, comboLength, discount=false)=>Combinaison[discount?"withDiscount":"withoutDiscount"](comboOptions, comboLength);
class Random {
static float(a = 1, b) {
return b ? Math.random() * (b - a) + a : a * Math.random();
}
static int(a, b) {
return Math.floor(this.float(a, b));
}
static char(upperCase){
upperCase=upperCase??this.bool();
const Char=String.fromCharCode(this.int(97,120));
return upperCase?Char.toUpperCase():Char;
}
static bool(){
return [false,true][Math.floor(Math.random()*2)];
}
static string(length,upperCase){
return length instanceof Array?
new Array(this.int(...length)).fill(0).map(() => this.char(upperCase)).join(""):
new Array(length).fill(0).map(() => this.char(upperCase)).join("");
}
static bin() {
return this.int(2);
}
static oct() {
return this.int(8);
}
static dec() {
return this.int(8);
}
static hex() {
return this.int(16);
}
static choice(choices = [1, 2, 3], p = new Array(choices.length).fill(1 / choices.length)) {
let newchoice = new Array(100);
p=Utils.accum(...p).map(n=>n*100);
newchoice.fill(choices[0], 0, p[0]);
for (let i = 1; i < choices.length; i++) newchoice.fill(choices[i], p[i - 1], p[i]);
return newchoice[this.int(newchoice.length - 1)];
}
static shuffleArr(arr){
return arr.sort(()=>0.5-Math.random())
}
static shuffleMatrix(M){
const {rows,cols,arr}=M;
return matrix(rows,cols,arr.flat().sort(()=>0.5-Math.random()))
}
static floats(n, a, b) {
return new Array(n).fill(0).map(() => this.float(a, b));
}
static ints(n, a, b) {
return new Array(n).fill(0).map(() => this.int(a, b));
}
static bools(n){
return new Array(n).fill(0).map(() => this.bool());
}
static bins(n) {
return new Array(n).fill(0).map(() => this.int(2));
}
static octs(n) {
return new Array(n).fill(0).map(() => this.int(8));
}
static decs(n) {
return new Array(n).fill(0).map(() => this.int(10));
}
static hexs(n) {
return new Array(n).fill(0).map(() => this.int(16));
}
static choices(n, choices, p) {
return new Array(n).fill(0).map(() => this.choice(choices, p));
}
static perm(...arr) {
// permutation
return arr.permS[this.int(arr.length)];
}
static color() {
return "#" + Base.dec2hex(this.float(16777216)).padStart(6,0);
}
static colors(n) {
return new Array(n).fill(null).map(()=>this.color());
}
static complex(a = [0,1], b = [0,1]) {
return a instanceof Array?
new Complex(
this.float(a[0], a[1]),
this.float(b[0], b[1])
):
new Complex(
...this.floats(2,a,b)
)
}
static complexInt(a = [0,1], b = [0,1]) {
return new Complex(
this.int(a[0], a[1]),
this.int(b[0], b[1])
);
}
static complexBin() {
return new Complex(...this.bins(2));
}
static complexOct() {
return new Complex(...this.octs(2));
}
static complexDec() {
return new Complex(...this.decs(10));
}
static complexHex() {
return new Complex(...this.octs(2));
}
static complexes(n, a = 0, b = 1) {
return new Array(n).fill(0).map(() => this.complex(a, b));
}
static complexesInt(n, a = 0, b = 1) {
return new Array(n).fill(0).map(() => this.complexInt(a, b));
}
static complexesBin(n) {
return new Array(n).fill(0).map(() => this.complexBin());
}
static complexesOct(n) {
return new Array(n).fill(0).map(() => this.complexOct());
}
static complexesDec(n) {
return new Array(n).fill(0).map(() => this.complexDec());
}
static complexesHex(n) {
return new Array(n).fill(0).map(() => this.complexHex());
}
static matrix(r,c,min,max){
return matrix(r,c,this.floats(r*c,min,max))
}
static matrixInt(r,c,min,max){
return matrix(r,c,this.ints(r*c,min,max))
}
static matrixBin(r,c){
return matrix(r,c,this.bins(r*c))
}
static matrixOct(r,c){
return matrix(r,c,this.octs(r*c))
}
static matrixDec(r,c){
return matrix(r,c,this.decs(r*c))
}
static matrixHex(r,c){
return matrix(r,c,this.hex(r*c))
}
static matrixColor(r,c){
return matrix(r,c,this.colors(r*c))
}
static matrixComplex(r,c,a,b){
return matrix(r,c,this.complexes(r*c,a,b))
}
static matrixComplexInt(r,c,a,b){
return matrix(r,c,this.complexesInt(r*c,a,b))
}
static matrixComplexBin(r,c){
return matrix(r,c,this.complexesBin(r*c))
}
static matrixComplexOct(r,c){
return matrix(r,c,this.complexesBin(r*c))
}
static matrixComplexDec(r,c){
return matrix(r,c,this.complexesBin(r*c))
}
static matrixComplexHex(r,c){
return matrix(r,c,this.complexesBin(r*c))
}
}
const preload=(url)=>{
const xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.send();
if (xhr.status === 200) {
return xhr.responseText;
} else {
throw new Error(`Failed to fetch data from ${url}. Status: ${xhr.status}`);
}
};
async function fetchdom(url='https://github.com/zakarialaoui10'){
const data=await fetch(url);
const html=await data.text();
const dom= new DOMParser().parseFromString(html,'text/xml');
return dom.documentElement
}
function fetchdomSync(url='https://github.com/zakarialaoui10'){
const data=preload(url);
const dom= new DOMParser().parseFromString(data,'text/xml');
return dom.documentElement;
}
globalThis.fetchdom=fetchdom;
globalThis.fetchdomSync=fetchdomSync;
const csv2arr = (csv, delimiter = ",")=>csv.trim().trimEnd().split("\n").map(n=>n.split(delimiter));
const csv2matrix = (csv, delimiter = ",")=>new Matrix(csv2arr(csv,delimiter));
const csv2object = (csv, delimiter = ",") => {
const [header, ...rows] = csv2arr(csv,delimiter);
const result = rows.map(row => {
const obj = {};
header.forEach((key, index) => {
obj[key] = row[index];
});
return obj;
});
return result;
};
const csv2json = (csv, delimiter = ",") => JSON.stringify(csv2object(csv,delimiter));
const csv2sql=(csv, Table)=>{
const lines = csv.trim().trimEnd().split('\n').filter(n=>n);
const columns = lines[0].split(',');
let sqlQuery = `INSERT INTO ${Table} (${columns.join(', ')}) Values `;
let sqlValues = [];
for (let i = 1; i < lines.length; i++) {
const values = lines[i].split(',');
sqlValues.push(`(${values})`);
}
return sqlQuery+sqlValues.join(",\n");
};
const _objects2arr=data=>data instanceof Array?[Object.keys(data[0]),...data.map(n=>Object.values(n))]:[Object.keys(data)];
const _objects2csv=(data,delimiter)=>_objects2arr(data).map(n=>n.join(delimiter)).join("\n");
const json2arr=json=>json instanceof Object?_objects2arr(json):_objects2arr(JSON.parse(json));
const json2csv=(json,delimiter=",")=>json instanceof Object?_objects2csv(json,delimiter):_objects2csv(JSON.parse(json),delimiter);
const json2csvFile=(json,delimiter)=>{
const str=json2csv(json,delimiter);
const blob=new Blob([str], { type: 'text/csv;charset=utf-8;' });
return {
str,
blob,
url:URL.createObjectURL(blob)
}
};
const _processObject=(obj, indent)=>{
const yml = [];
if (Array.isArray(obj)) {
obj.forEach(item => {
if (typeof item === 'object' && item !== null) {
yml.push(`${indent}-`);
const nestedLines = _processObject(item, `${indent} `);
yml.push(...nestedLines);
} else yml.push(`${indent}- ${item}`);
});
} else {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
if (typeof value === 'object' && value !== null) {
yml.push(`${indent}${key}:`);
const nestedLines = _processObject(value, `${indent} `);
yml.push(...nestedLines);
} else {
yml.push(`${indent}${key}: ${value}`);
}
}
}
}
return yml;
};
const _object2yml=(object,indent="")=>_processObject(object,indent).join('\n');
const json2yml=(json,indent)=>json instanceof Object?_object2yml(json,indent):_object2yml(JSON.parse(json),indent);
const json2ymlFile=(json,indent)=>{
const str=json2yml(json,indent);
const blob=new Blob([str], { type: 'text/yml;charset=utf-8;' });
return {
str,
blob,
url:URL.createObjectURL(blob)
}
};
const json2xml=(json, indent = 1)=>{
let xml = '';
for (const key in json) {
if (json.hasOwnProperty(key)) {
const value = json[key];
xml += '\n' + ' '.repeat(indent) + `<${key}>`;
(typeof value === 'object') ? xml += json2xml(value, indent + 2) : xml += `${value}`;
xml += `</${key}>`;
}
}
return xml.trim();
};
const json2xmlFile=(json,indent)=>{
const str=json2xml(json,indent);
const blob=new Blob([str], { type: 'text/xml;charset=utf-8;' });
return {
str,
blob,
url:URL.createObjectURL(blob)
}
};
class UINode {
constructor(node){
this.cache = {
node
};
}
isZikoUINode(){
return true
}
get node(){
return this.cache.node;
}
}
// globalThis.node = (node) => new UINode(node);
function parseQueryParams$1(queryString) {
const params = {};
queryString.replace(/[A-Z0-9]+?=([\w|:|\/\.]*)/gi, (match) => {
const [key, value] = match.split('=');
params[key] = value;
});
return params;
}
function defineParamsGetter$1(target ){
Object.defineProperties(target, {
'QueryParams': {
get: function() {
return parseQueryParams$1(globalThis.location.search.substring(1));
},
configurable: false,
enumerable: true
},
'HashParams': {
get: function() {
const hash = globalThis.location.hash.substring(1);
return hash.split("#");
},
configurable: false,
enumerable: true
}
});
}
class UIStore extends Array {
constructor(...args) {
super(...args);
}
getItemById(id) {
return this.find(n => n.element.id === id);
}
getItemsByTagName(tag) {
return this.filter(n => n.element.tagName.toLowerCase() === tag.toLowerCase());
}
getElementsByClassName(className) {
return this.filter(n => n.element.classList?.contains(className));
}
querySelector(selector) {
const el = globalThis?.document?.querySelector(selector);
if (!el) return null;
return this.find(ui => ui.element === el) || null;
}
querySelectorAll(selector) {
const els = globalThis?.document?.querySelectorAll(selector);
return Array.from(els)
.map(el => this.find(ui => ui.element === el))
.filter(Boolean);
}
}
// create the singleton
const __UI__ = new UIStore();
const __Config__ = {
default:{
target:null,
render:true,
math:{
mode:"deg"
}
},
setDefault:function(pairs){
const keys=Object.keys(pairs);
const values=Object.values(pairs);
for(let i=0; i<keys.length; i++) this.default[keys[i]]=values[i];
},
init:()=>{
// document.documentElement.setAttribute("data-engine","zikojs")
},
renderingMode :"spa",
isSSC : false,
};
const __HYDRATION__ = {
store : new Map(),
index : 0,
register: function(component){
this.store.set(this.index++, component);
}
};
const __CACHE__ = {
ui_index : 0,
get_ui_index:function(){
return this.ui_index ++
},
register_ui: function(UIElement){
}
};
const __State__ = {
store : new Map(),
index : undefined?.data?.__Ziko__?.__State__?.index ?? 0,
register: function(state){
console.log({
// hmr : import.meta.hot?.data.__Ziko__.__State__.index,
index : this.index
});
this.store.set(this.index++, state);
}
};
function __init__global__(){
if ( !globalThis?.__Ziko__ ){
globalThis.__Ziko__ = {
__UI__,
__HYDRATION__,
__State__,
__Config__,
__CACHE__,
};
defineParamsGetter$1(__Ziko__);
}
}
__init__global__();
class UIElementCore extends UINode{
constructor(){
super();
}
init(element, name, type, render, isInteractive = [true, false][Math.floor(2*Math.random())]){
this.target = globalThis.__Ziko__.__Config__.default.target||globalThis?.document?.body;
if(typeof element === "string") {
switch(type){
case "html" : {
element = globalThis?.document?.createElement(element);
// console.log('1')
} break;
case "svg" : {
element = globalThis?.document?.createElementNS("http://www.w3.org/2000/svg", element);
// console.log('2')
} break;
default : throw Error("Not supported")
}
}
else this.target = element?.parentElement;
Object.assign(this.cache, {
name,
isInteractive,
parent:null,
isBody:false,
isRoot:false,
isHidden: false,
isFrozzen:false,
legacyParent : null,
attributes: {},
filters: {},
temp:{}
});
this.events = {
ptr:null,
mouse:null,
wheel:null,
key:null,
drag:null,
drop:null,
click:null,
clipboard:null,
focus:null,
swipe:null,
custom:null,
};
this.observer={
resize:null,
intersection:null
};
if(element) Object.assign(this.cache,{element});
// useDefaultStyle && this.style({
// position: "relative",
// boxSizing:"border-box",
// margin:0,
// padding:0,
// width : "auto",
// height : "auto"
// });
this.items = new UIStore();
globalThis.__Ziko__.__UI__[this.cache.name]?globalThis.__Ziko__.__UI__[this.cache.name]?.push(this):globalThis.__Ziko__.__UI__[this.cache.name]=[this];
element && render && this?.render?.();
if(
// globalThis.__Ziko__.__Config__.renderingMode !== "spa"
// &&
// !globalThis.__Ziko__.__Config__.isSSC
// &&
this.isInteractive()){
// this.setAttr("ziko-hydration-index", globalThis.__Ziko__.__HYDRATION__.index);
// this.element.setAttribute('ziko-hydration-index', globalThis.__Ziko__.__HYDRATION__.index)
globalThis.__Ziko__.__HYDRATION__.register(() => this);
}
globalThis.__Ziko__.__UI__.push(this);
}
get element(){
return this.cache.element;
}
[Symbol.iterator]() {
return this.items[Symbol.iterator]();
}
maintain() {
for (let i = 0; i < this.items.length; i++) {
Object.defineProperty(this, i, {
value: this.items[i],
writable: true,
configurable: true,
enumerable: false
});
}
}
isInteractive(){
return this.cache.isInteractive;
}
isUIElement(){
return true;
}
// get st(){
// return this.cache.style;
// }
// get attr(){
// return this.cache.attributes;
// }
// get evt(){
// return this.events;
// }
// get html(){
// return this.element.innerHTML;
// }
// get text(){
// return this.element.textContent;
// }
// get isBody(){
// return this.element === globalThis?.document.body;
// }
// get parent(){
// return this.cache.parent;
// }
// get width(){
// return this.element.getBoundingClientRect().width;
// }
// get height(){
// return this.element.getBoundingClientRect().height;
// }
// get top(){
// return this.element.getBoundingClientRect().top;
// }
// get right(){
// return this.element.getBoundingClientRect().right;
// }
// get bottom(){
// return this.element.getBoundingClientRect().bottom;
// }
// get left(){
// return this.element.getBoundingClientRect().left;
// }
// clone(render=false) {
// // UI.__proto__=this.__proto__;
// // if(this.items.length){
// // const items = [...this.items].map(n=>n.clone());
// // UI.append(...items);
// // }
// // else UI.element=this.element.cloneNode(true);
// // return UI.render(render);
// }
// freeze(freeze){
// this.cache.isFrozzen=freeze;
// return this;
// }
// setTarget(tg) {
// if(this.isBody) return ;
// if (tg?.isUIElement) tg = tg.element;
// this.unrender();
// this.target = tg;
// this.render();
// return this;
// }
// describe(label){
// if(label)this.setAttr("aria-label",label)
// }
// get children() {
// return [...this.element.children];
// }
// get cloneElement() {
// return this.element.cloneNode(true);
// }
// setClasses(...value) {
// this.setAttr("class", value.join(" "));
// return this;
// }
// get classes(){
// const classes=this.element.getAttribute("class");
// return classes===null?[]:classes.split(" ");
// }
// addClass() {
// /*this.setAttr("class", value);
// return this;*/
// }
// setId(id) {
// this.setAttr("id", id);
// return this;
// }
// get id() {
// return this.element.getAttribute("id");
// }
// onSwipe(width_threshold, height_threshold,...callbacks){
// if(!this.events.swipe)this.events.swipe = useSwipeEvent(this, width_threshold, height_threshold);
// this.events.swipe.onSwipe(...callbacks);
// return this;
// }
// To Fix
// onKeysDown({keys=[],callback}={}){
// if(!this.events.key)this.events.key = useKeyEvent(this);
// this.events.key.handleSuccessifKeys({keys,callback});
// return this;
// }
// onSelect(...callbacks){
// if(!this.events.clipboard)this.events.clipboard = useClipboardEvent(this);
// this.events.clipboard.onSelect(...callbacks);
// return this;
// }
// on(event_name,...callbacks){
// if(!this.events.custom)this.events.custom = useCustomEvent(this);
// this.events.custom.on(event_name,...callbacks);
// return this;
// }
// emit(event_name,detail={}){
// if(!this.events.custom)this.events.custom = useCustomEvent(this);
// this.events.custom.emit(event_name,detail);
// return this;
// }
// watchAttr(callback){
// if(!this.observer.attr)this.observer.attr = watchAttr(this,callback);
// return this;
// }
// watchChildren(callback){
// if(!this.observer.children)this.observer.children = watchChildren(this,callback);
// return this;
// }
// watchSize(callback){
// if(!this.observer.resize)this.observer.resize = watchSize(this,callback);
// this.observer.resize.start();
// return this;
// }
// watchIntersection(callback,config){
// if(!this.observer.intersection)this.observer.intersection = watchIntersection(this,callback,config);
// this.observer.intersection.start();
// return this;
// }
}
function register_to_class(target, ...mixins){
mixins.forEach(n => _register_to_class_(target, n));
}
function _register_to_class_(target, mixin) {
const descriptors = Object.getOwnPropertyDescriptors(mixin);
for (const key of Reflect.ownKeys(descriptors)) {
const desc = descriptors[key];
if ('get' in desc || 'set' in desc || typeof desc.value !== 'function') {
Object.defineProperty(Object.getPrototypeOf(target), key, desc);
} else if (typeof desc.value === 'function') {
if (!Object.getPrototypeOf(target).hasOwnProperty(key)) {
Object.defineProperty(Object.getPrototypeOf(target), key, desc);
}
}
}
}
if(!globalThis.__Ziko__) __init__global__();
// HMR persistence
if (undefined?.data) {
undefined.data.__Ziko__ = undefined.data?.__Ziko__ || globalThis?.__Ziko__;
globalThis.__Ziko__ = undefined.data.__Ziko__;
// import.meta.hot.accept(n=>console.log(n));
// console.log(import.meta.hot.data.__Ziko__.__State__.store)
}
function useState(initialValue) {
// console.log(import.meta.hot.data.__Ziko__.__State__.store.get(0))
const {store, index} = __Ziko__.__State__;
__Ziko__.__State__.register({
value : initialValue,
subscribers : new Set(),
paused : false
});
const current = store.get(index);
function getValue() {
return {
value: current.value,
isStateGetter: () => true,
_subscribe: (fn) => current.subscribers.add(fn),
};
}
function setValue(newValue) {
if (current.paused) return;
if (typeof newValue === "function") newValue = newValue(current.value);
if (newValue !== current.value) {
current.value = newValue;
current.subscribers.forEach(fn => fn(current.value));
}
}
const controller = {
pause: () => { current.paused = true; },
resume: () => { current.paused = false; },
clear: () => { current.subscribers.clear(); },
force: (newValue) => {
if (typeof newValue === "function") newValue = newValue(current.value);
current.value = newValue;
current.subscribers.forEach(fn => fn(current.value));
},
getSubscribers: () => new Set(current.subscribers),
};
return [getValue, setValue, controller];
}
const isStateGetter = (arg) => {
return typeof arg === 'function' && arg?.()?.isStateGetter?.();
};
const camel2hyphencase$1 = (text = '') => text.replace(/[A-Z]/g, match => '-' + match.toLowerCase());
const is_camelcase$1 = (text = '') =>{
if (text.length === 0) return false;
const camelCasePattern = /^[a-z][a-zA-Z0-9]*$/;
return camelCasePattern.test(text);
};
class ZikoUIText extends UINode {
constructor(...value) {
super("span", "text", false, ...value);
this.element = globalThis?.document?.createTextNode(...value);
}
isText(){
return true
}
}
const text = (...str) => new ZikoUIText(...str);
async function __addItem__(adder, pusher, ...ele) {
if (this.cache.isFrozzen) {
console.warn("You can't append new item to frozzen element");
return this;
}
for (let i = 0; i < ele.length; i++) {
if (["number", "string"].includes(typeof ele[i])) ele[i] = text(ele[i]);
// Fix Items Latter
if (ele[i] instanceof Function) {
const getter = ele[i]();
if (getter.isStateGetter) {
ele[i] = text(getter.value);
getter._subscribe(
(newValue) => (ele[i].element.textContent = newValue),
ele[i]
);
// this.element.appendChild(textNode);
}
}
if (typeof globalThis?.Node === "function" && ele[i] instanceof globalThis?.Node) ele[i] = new this.constructor(ele[i]);
if (ele[i]?.isZikoUINode) {
ele[i].cache.parent = this;
this.element?.[adder](ele[i].element);
ele[i].target = this.element;
this.items[pusher](ele[i]);
}
else if(ele[i] instanceof Promise){
const UIEle = await ele[i];
UIEle.cache.parent = this;
this.element?.[adder](UIEle.element);
UIEle.target = this.e