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,571 lines (1,490 loc) • 172 kB
JavaScript
/*
Project: ziko.js
Author: Zakaria Elalaoui
Date : Fri Dec 05 2025 11:33:57 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, 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 : x=> {
if(x.isComplex?.()) return new x.constructor(
cos$3(x.a)*cosh$2(x.b),
-(sin$3(x.a)*sinh$2(x.b))
);
return cos$3(x)
},
sin : x=>{
if(x?.isComplex) return new x.constructor(
sin$3(x.a)*cosh$2(x.b),
cos$3(x.a)*sinh$2(x.b)
);
return sin$3(x)
},
tan : x=>{
if(x?.isComplex){
const DEN = cos$3(2*x.a)+cosh$2(2*x.b);
return new x.constructor(
sin$3(2*x.a)/DEN,
sinh$2(2*x.b)/DEN
);
}
return tan$1(x)
},
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: x=>{
if(x?.isComplex) return
return sin$3(x)
},
asin: x=>{
if(x?.isComplex) return
return sin$3(x)
},
atan: x=>{
if(x?.isComplex) return
return sin$3(x)
},
acot: x => PI$1/2-atan$1(x),
cosh: x=>{
if(x?.isComplex) return new x.constructor(
cosh$2(x.a)*cos$3(x.b),
sinh$2(x.a)*sin$3(x.b)
);
return cosh$2(x)
},
sinh: x=>{
if(x?.isComplex) return new x.constructor(
sinh$2(x.a)*cos$3(x.b),
cosh$2(x.a)*sin$3(x.b)
);
return sinh$2(x)
},
tanh: x=>{
if(x?.isComplex){
const DEN=cosh$2(2*a)+cos$3(2*b);
return new x.constructor(
sinh$2(2*a)/DEN,
sin$3(2*b)/DEN
)
}
return tanh$1(x)
},
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;
// }
// })
const mapfun$1=(fun,...X)=>{
const Y=X.map(x=>{
if(
x===null||
["number","string","boolean","bigint","undefined"].includes(typeof x)||
x?.__mapfun__
) 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.isMatrix?.()) return new x.constructor(x.rows, x.cols, mapfun$1(x.arr.flat(1)))
// if(x.isComplex?.()){
// const [a,b,z,phi]=[x.a,x.b,x.z,x.phi];
// switch(fun){
// // Moved to Fixed to avoid Circular Dep
// // case Math.log: return new x.constructor(ln(z),phi); // Done
// // case Math.exp: return new x.constructor(e(a)*cos(b),e(a)*sin(b)); // Done
// // case Math.abs: return z; // Done
// // case Math.sqrt: return new x.constructor(sqrt(z)*cos(phi/2),sqrt(z)*sin(phi/2)); // Done
// // case Fixed.cos: return new x.constructor(cos(a)*cosh(b),-(sin(a)*sinh(b)));
// // case Fixed.sin: return new x.constructor(sin(a)*cosh(b),cos(a)*sinh(b));
// // case Fixed.tan:{
// // const DEN = cos(2*a)+cosh(2*b);
// // return new x.constructor(sin(2*a)/DEN,sinh(2*b)/DEN);
// // }
// // case Fixed.cosh:return new x.constructor(cosh(a)*cos(b),sinh(a)*sin(b));
// // case Fixed.sinh:return new x.constructor(sinh(a)*cos(b),cosh(a)*sin(b));
// // case Fixed.tanh:{
// // const DEN=cosh(2*a)+cos(2*b);
// // return new x.constructor(sinh(2*a)/DEN,sin(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 fun(Object) || Object.fromEntries(Object.entries(x).map(n=>n=[n[0],mapfun(fun,n[1])]))
}
});
return Y.length==1? Y[0]: Y;
};
// 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
const abs=(...x)=>mapfun$1(Math.abs,...x);
const sqrt$2=(...x)=>mapfun$1(Math.sqrt,...x);
const pow$1=(x,n)=>{
if(typeof x === "number"){
if(typeof n === "number")return Math.pow(x,n);
else if(n?.isComplex?.())return n.constructor.fromExpo(x**n.a,n.b*ln(x))
else return mapfun$1(a=>pow$1(x,a),...n);
}
else if(x.isComplex?.()){
if(typeof n === "number")return x.constructor.fromExpo(x.z**n,x.phi*n);
else if(n.isComplex?.())return x.constructor.fromExpo(
x.z**n.a*e(-x.phi*n.b),
ln(x.z)*n.b+n.a*x.phi
)
else return mapfun$1(a=>pow$1(x,a),...n);
}
else if(x instanceof Array){
if(typeof n === "number") return mapfun$1(a=>pow$1(a,n),...x);
else if(n instanceof Array){
const Y=[];
for(let i=0;i<x.length;i++){
Y.push(mapfun$1(a=>pow$1(x[i],a),...n));
}
return Y;
}
}
};
const sqrtn=(x,n)=>{
if(typeof x === "number"){
if(typeof n === "number")return Math.pow(x,1/n);
else return mapfun$1(a=>sqrtn(x,a),...n);
}
else if(x.isComplex?.()){
if(typeof n === "number")return x.constructor.fromExpo(sqrtn(x.z,n),x.phi/n);
else return mapfun$1(a=>sqrtn(x,a),...n);
}
else if(x instanceof Array){
if(typeof n === "number") return mapfun$1(a=>sqrtn(a,n),...x);
else if(n instanceof Array){
const Y=[];
for(let i=0;i<x.length;i++){
Y.push(mapfun$1(a=>sqrtn(x[i],a),...n));
}
return Y;
}
}
};
const e=(...x) => mapfun$1(Math.exp,...x);
const ln=(...x) => mapfun$1(Math.log,...x);
const cos$2=(...x) => mapfun$1(Fixed.cos,...x);
const sin$2=(...x) => mapfun$1(Fixed.sin,...x);
const tan=(...x) => mapfun$1(Fixed.tan,...x);
const sec=(...x) => mapfun$1(Fixed.sec,...x);
const sinc=(...x) => mapfun$1(Fixed.sinc,...x);
const csc=(...x) => mapfun$1(Fixed.csc,...x);
const cot=(...x) => mapfun$1(Fixed.cot,...x);
const acos$1=(...x) => mapfun$1(Fixed.acos,...x);
const asin=(...x) => mapfun$1(Fixed.asin,...x);
const atan=(...x) => mapfun$1(Fixed.atan,...x);
const acot=(...x) => mapfun$1(Fixed.acot,...x);
const cosh$1=(...x) => mapfun$1(Fixed.cosh,...x);
const sinh$1=(...x) => mapfun$1(Fixed.sinh,...x);
const tanh=(...x) => mapfun$1(Fixed.tanh,...x);
const coth=(...x) => mapfun$1(Fixed.coth,...x);
const acosh=(...x) => mapfun$1(Fixed.acosh,...x);
const asinh=(...x) => mapfun$1(Fixed.asinh,...x);
const atanh=(...x) => mapfun$1(Fixed.atanh,...x);
const ceil=(...x) => mapfun$1(Math.ceil,...x);
const floor=(...x) => mapfun$1(Math.floor,...x);
const round=(...x) => mapfun$1(Math.round,...x);
const atan2=(x,y,rad=true)=>{
if(typeof x === "number"){
if(typeof y === "number")return rad?Math.atan2(x,y):Math.atan2(x,y)*180/Math.PI;
else return mapfun$1(a=>atan2(x,a,rad),...y);
}
// else if(x.isComplex?.()){
// if(typeof n === "number")return x.constructor.fromExpo(x.z**n,x.phi*n);
// else return mapfun(a=>pow(x,a),...n);
// }
else if(x instanceof Array){
if(typeof y === "number") return mapfun$1(a=>atan2(a,y,rad),...x);
else if(y instanceof Array){
const Y=[];
for(let i=0;i<x.length;i++){
Y.push(mapfun$1(a=>pow$1(x[i],a),...y));
}
return Y;
}
}
};
const fact=(...x)=>mapfun$1(n=> {
let i,
y = 1;
if (n == 0) y = 1;
else if (n > 0) for (i = 1; i <= n; i++) y *= i;
else y = NaN;
return y;
},...x);
const sign=(...x)=>mapfun$1(Math.sign,...x);
const sig=(...x)=>mapfun$1(n=>1/(1+e(-n)),...x);
const hypot=(...x)=>{
if(x.every(n=>typeof n === "number"))return Math.hypot(...x);
if(x.every(n=>n instanceof Array))return mapfun$1(
Math.hypot,
...x
)
};
const _add=(a,b)=>{
if(typeof(a)==="number"){
if (typeof b == "number") return a + b;
else if (b.isComplex?.())return new b.constructor(a + b.a, b.b);
else if (b.isMatrix?.()) return b.constructor.nums(b.rows, b.cols, a).add(b);
else if (b instanceof Array)return b.map(n=>add(n,a));
}
else if(a.isComplex?.()||a.isMatrix?.()){
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.isComplex?.())return new b.constructor(a - b.a, -b.b);
else if (b.isMatrix?.()) return b.constructor.nums(b.rows, b.cols, a).sub(b);
else if (b instanceof Array)return b.map(n=>sub(n,a));
}
else if(a.isComplex?.()||a.isMatrix?.()){
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.isComplex?.())return new b.constructor(a * b.a,a * b.b);
else if (b.isMatrix?.()) return b.constructor.nums(b.rows, b.cols, a).mul(b);
else if (b instanceof Array)return b.map(n=>mul(a,n));
}
else if(a.isComplex?.()||a.isMatrix?.()){
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.isComplex?.())return new b.constructor(a / b.a,a / b.b);
else if (b.isMatrix?.()) return b.constructor.nums(b.rows, b.cols, a).div(b);
else if (b instanceof Array)return b.map(n=>div(a,n));
}
else if(a.isComplex?.()||a.isMatrix?.()){
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.isComplex?.())return new b.constructor(a % b.a,a % b.b);
else if (b.isMatrix?.()) return b.constructor.nums(b.rows, b.cols, a).modulo(b);
else if (b instanceof Array)return b.map(n=>div(a,n));
}
else if(a.isComplex?.()||a.isMatrix?.()){
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.isMatrix?.()) return new value.constructor(value.rows, value.cols, norm(value.arr.flat(1), min, max));
else if (value.isComplex?.()) return new value.constructor(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.isMatrix?.()) return new value.constructor(value.rows, value.cols, lerp(value.arr.flat(1), min, max));
else if (value.isComplex?.()) return new value.constructor(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=(x, a, b, c, d)=>{
if (typeof x === "number") return lerp(norm(x, a, b), c, d);
else if (x.isMatrix?.()) return new x.constructor(x.rows, x.cols, map$1(x.arr.flat(1), a, b, c, d));
else if (x.isComplex?.()) return new x.constructor(map$1(x.a, b, c, d), map$1(x.b, a, b, c, d));
else if (x instanceof Array) {
if (x.every((n) => typeof (n === "number"))) {
return x.map((n) => map$1(n, a, b, c, d));
} else {
let y = new Array(x.length);
for (let i = 0; i < x.length; i++) {
y[i] = map$1(x[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.isMatrix?.()) return new x.constructor(x.rows, x.cols, clamp(x.arr.flat(1), min_value, max_value));
else if (x.isComplex?.()) return new x.constructor(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.isComplex?.())){
const z1 = new n.constructor(a);
const z2 = new n.constructor(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)=> new n.constructor(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.isComplex?.())){
const z1 = new n.constructor(a);
const z2 = new n.constructor(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);
/** @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
};
class Complex{
constructor(a = 0, b = 0) {
if(a instanceof Complex){
this.a=a.a;
this.b=a.b;
}
else if(typeof(a)==="object"){
if(("a" in a && "b" in a)){
this.a=a.a;
this.b=a.b;
}
else if(("a" in a && "z" in a)){
this.a=a.a;
this.b=sqrt$2((a.z**2)-(a.a**2));
}
else if(("a" in a && "phi" in a)){
this.a=a.a;
this.b=a.a*tan(a.phi);
}
else if(("b" in a && "z" in a)){
this.b=a.b;
this.a=sqrt$2((a.z**2)-(a.b**2));
}
else if(("b" in a && "phi" in a)){
this.b=b;
this.a=a.b/tan(a.phi);
}
else if(("z" in a && "phi" in a)){
this.a=a.z*cos$2(a.phi);
this.a=a.z*sin$2(a.phi);
}
}
else if(typeof(a)==="number"&&typeof(b)==="number"){
this.a = +a.toFixed(32);
this.b = +b.toFixed(32);
}
}
get __mapfun__(){
return true
}
isComplex(){
return true
}
toString(){
let str = "";
if (this.a !== 0)
this.b >= 0
? (str = `${this.a}+${this.b}*i`)
: (str = `${this.a}-${Math.abs(this.b)}*i`);
else
this.b >= 0
? (str = `${this.b}*i`)
: (str = `-${Math.abs(this.b)}*i`);
return str;
}
get clone() {
return new Complex(this.a, this.b);
}
get z(){
return hypot(this.a,this.b);
}
get phi(){
return atan2(this.b , this.a);
}
static Zero() {
return new Complex(0, 0);
}
get conj() {
return new Complex(this.a, -this.b);
}
get inv() {
return new Complex(this.a / (pow$1(this.a, 2) + pow$1(this.b, 2)), -this.b / (pow$1(this.a, 2) + pow$1(this.b, 2)));
}
add(...z) {
for (let i = 0; i < z.length; i++) {
if (typeof z[i] === "number") z[i] = new Complex(z[i], 0);
}
let re = z.map((n) => n.a);
let im = z.map((n) => n.b);
this.a+=+sum(...re).toFixed(15);
this.b+=+sum(...im).toFixed(15);
return this;
}
sub(...z) {
for (let i = 0; i < z.length; i++) {
if (typeof z[i] === "number") z[i] = new Complex(z[i], 0);
}
let re = z.map((n) => n.a);
let im = z.map((n) => n.b);
this.a-=+sum(...re).toFixed(15);
this.b-=+sum(...im).toFixed(15);
return this;
}
mul(...z){
for (let i = 0; i < z.length; i++) {
if (typeof z[i] === "number") z[i] = new Complex(z[i], 0);
}
let Z=+prod(this.z,...z.map(n=>n.z)).toFixed(15);
let phi=+sum(this.phi,...z.map(n=>n.phi)).toFixed(15);
this.a=+(Z*cos$2(phi).toFixed(15)).toFixed(14);
this.b=+(Z*sin$2(phi).toFixed(15)).toFixed(14);
return this;
}
div(...z) {
for (let i = 0; i < z.length; i++) {
if (typeof z[i] === "number") z[i] = new Complex(z[i], 0);
}
let Z=+(this.z/prod(...z.map(n=>n.z))).toFixed(15);
let phi=+(this.phi-sum(...z.map(n=>n.phi))).toFixed(15);
this.a=+(Z*cos$2(phi).toFixed(15)).toFixed(15);
this.b=+(Z*sin$2(phi).toFixed(15)).toFixed(15);
return this;
}
pow(n) {
if (floor(n) === n && n > 0) {
let z=+(this.z**n).toFixed(15);
let phi=+(this.phi*n).toFixed(15);
this.a=+(z*cos$2(phi).toFixed(15)).toFixed(15);
this.b=+(z*sin$2(phi).toFixed(15)).toFixed(15);
}
return this;
}
static fromExpo(z, phi) {
return new Complex(
+(z * cos$2(phi)).toFixed(13),
+(z * sin$2(phi)).toFixed(13)
);
}
get expo() {
return [this.z, this.phi];
}
static add(c,...z) {
return c.clone.add(...z);
}
static sub(c,...z) {
return c.clone.sub(...z);
}
static mul(c,...z) {
return c.clone.mul(...z);
}
static div(c,...z) {
return c.clone.div(...z);
}
static pow(z,n){
return z.clone.pow(n);
}
static xpowZ(x){
return complex((x**this.a)*cos$2(this.b*ln(x)),(x**this.a)*sin$2(this.b*ln(x)));
}
sqrtn(n=2){
return complex(sqrtn(this.z,n)*cos$2(this.phi/n),sqrtn(this.z,n)*sin$2(this.phi/n));
}
get sqrt(){
return this.sqrtn(2);
}
get log(){
return complex(this.z,this.phi);
}
get cos(){
return complex(cos$2(this.a)*cosh$1(this.b),sin$2(this.a)*sinh$1(this.b))
}
get sin(){
return complex(sin$2(this.a)*cosh$1(this.b),cos$2(this.a)*sinh$1(this.b))
}
get tan(){
const de=cos$2(this.a*2)+cosh$1(this.b*2);
return complex(sin$2(2*this.a)/de,sinh$1(2*this.b)/de);
}
}
const complex=(a,b)=>{
if((a instanceof Array||ArrayBuffer.isView(a)) && (b instanceof Array||ArrayBuffer.isView(a)))return a.map((n,i)=>complex(a[i],b[i]));
if(a.isMatrix?.() && b.isMatrix?.()){
if((a.shape[0]!==b.shape[0])||(a.shape[1]!==b.shape[1]))return Error(0)
const arr=a.arr.map((n,i)=>complex(a.arr[i],b.arr[i]));
return new a.constructor(a.rows,a.cols,...arr)
}
return new Complex(a,b)
};
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') {
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const html = await response.text();
const dom = new DOMParser().parseFromString(html, 'text/html');
return dom.documentElement;
} catch (err) {
console.error('Failed to fetch DOM:', err);
throw err;
}
}
function fetchdomSync(url='https://github.com/zakarialaoui10') {
try {
const data = preload(url);
const dom = new DOMParser().parseFromString(data, 'text/html');
return dom.documentElement;
} catch (err) {
console.error('Failed to fetch DOM synchronously:', err);
throw err;
}
}
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);
}
clear(){
this.length = 0;
return this;
}
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);
},
reset(){
this.index = 0;
this.store.clear();
}
};
const __CACHE__ = {
ui_index : 0,
get_ui_index:function(){
return this.ui_index ++
},
register_ui: function(UIElement){
}
};
class UseIPC {
#channel;
#eventData;
#handlers;
#uuid;
#subscribers;
#currentRooms;
constructor(name = "") {
this.#channel = new BroadcastChannel(name);
this.#eventData = new Map();
this.#handlers = new Map(); // Map<event, Array<{fn, rooms}>>
this.#uuid = "ziko-channel:" + (Math.random()*10e16); // To Be Replaced by UUID
this.#subscribers = new Set([this.#uuid]);
this.#currentRooms = new Set();
this.#channel.addEventListener("message", (e) => {
const { last_sent_event, userId, eventData, rooms } = e.data;
if (userId === this.#uuid) return; // ignore own messages
// broadcast if no rooms, else check intersection
if (rooms && rooms.length && !rooms.some(r => this.#currentRooms.has(r))) return;
this.#subscribers.add(userId);
this.#eventData = new Map(eventData);
const handlersList = this.#handlers.get(last_sent_event);
if (!handlersList) return;
handlersList.forEach(({ fn, rooms: handlerRooms }) => {
// trigger if listener has no room filter, or intersects subscriber rooms
if (!handlerRooms || handlerRooms.length === 0 ||
!rooms || rooms.some(r => handlerRooms.includes(r))) {
fn(this.#eventData.get(last_sent_event));
}
});
});
}
emit(event, data, rooms) {
this.#eventData.set(event, data);
if(typeof rooms === 'string') rooms = [rooms];
this.#channel.postMessage({
eventData: Array.from(this.#eventData.entries()),
last_sent_event: event,
userId: this.#uuid,
rooms: rooms && rooms.length ? rooms : undefined
});
return this;
}
on(event, handler = console.log, rooms) {
if (!this.#handlers.has(event)) this.#handlers.set(event, []);
if(typeof rooms === 'string') rooms = [rooms];
this.#handlers.get(event).push({ fn: handler, rooms });
return this;
}
off(event, handler) {
if (!this.#handlers.has(event)) return this;
this.#handlers.set(
event,
this.#handlers.get(event).filter(h => h.fn !== handler)
);
return this;
}
once(event, handler, rooms) {
const wrapper = (data) => {
handler(data);
this.off(event, wrapper);
};
this.on(event, wrapper, rooms);
return this;
}
join(...rooms) {
rooms.forEach(r => this.#currentRooms.add(r));
return this;
}
leave(...rooms) {
if (!rooms.length) this.#currentRooms.clear();
else rooms.forEach(r => this.#currentRooms.delete(r));
return this;
}
close() {
this.#channel.close();
return this;
}
}
const useIPC = (name) => new UseIPC(name);
class UseStorage {
constructor(storage, globalKey, initialValue, use_channel = true) {
this.cache = {
storage,
globalKey,
channel: use_channel ? useIPC(`Ziko:useStorage-${globalKey}`) : null,
oldItemKeys: new Set()
};
this.#init(initialValue, use_channel);
}
get items() {
const raw = this.cache.storage.getItem(this.cache.globalKey);
if (!raw) return {};
try {
return JSON.parse(raw);
} catch {
return {};
}
}
#maintain() {
const items = this.items;
this.cache.oldItemKeys.forEach(k => delete this[k]);
for (const key in items) {
this[key] = items[key];
this.cache.oldItemKeys.add(key);
}
}
#init(initialValue, use_channel) {
if (use_channel && this.cache.channel) this.cache.channel.on("Ziko-Storage-Updated", () => this.#maintain());
if (!initialValue) {
this.#maintain();
return;
}
if (this.cache.storage.getItem(this.cache.globalKey)) {
const existing = this.items;
Object.keys(existing).forEach(k => this.cache.oldItemKeys.add(k));
this.#maintain();
}
else this.set(initialValue);
}
set(data) {
this.cache.storage.setItem(this.cache.globalKey, JSON.stringify(data));
if (this.cache.channel) this.cache.channel.emit("Ziko-Storage-Updated", data);
this.#maintain();
return this;
}
add(data) {
this.set({
...this.items,
...data
});
return this;
}
remove(...keys) {
const items = { ...this.items };
keys.forEach(key => {
delete items[key];
delete this[key];
this.cache.oldItemKeys.delete(key);
});
this.set(items);
return this;
}
get(key) {
return this.items[key];
}
clear() {
this.cache.storage.removeItem(this.cache.globalKey);
this.cache.oldItemKeys.forEach(k => delete this[k]);
this.cache.oldItemKeys.clear();
this.#maintain();
return this;
}
onStorageUpdated(callback) {
if (this.cache.channel) {
this.cache.channel.on("Ziko-Storage-Updated", callback);
}
return this;
}
}
// factory functions
const useLocaleStorage = (key, initialValue, use_channel = true) =>
new UseStorage(localStorage, key, initialValue, use_channel);
const useSessionStorage = (key, initialValue, use_channel = true) =>
new UseStorage(sessionStorage, key, initialValue, use_channel);
var __State__ = {
store : new Map(),
index : 0,
session_storage : null,
register: function(state){
if(!undefined.SSR && undefined.DEV){
if(!this.session) this.session_storage = useSessionStorage('ziko-state', {});
const savedValue = this.session_storage.get(this.index);
if(!savedValue) this.session_storage.add({[this.index] : state.value});
else state.value = savedValue;
}
this.store.set(this.index++, state);
},
update: function(index, value){
if(!undefined.SSR && undefined.DEV){
this.session_storage.add({[index] : value});
}
},
};
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){
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 : false,
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?.();
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;
}
}
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);
}
}
}
}
// export function mount(target = this.target) {
// if(this.isBody) return ;
// if(target?.isUIElement)target=target.element;
// this.target=target;
// this.target?.appendChild(this.element);
// return this;
// }
// export function unmount(){
// if(this.cache.parent)this.cache.parent.remove(this);
// else if(this.target?.children?.length && [...this.target?.children].includes(this.element)) this.target.removeChild(this.element);
// return this;
// }
// export function mountAfter(target = this.target, t = 1) {
// setTimeout(() => this.mount(), t);
// return this;
// }
// export function unmountAfter(t = 1) {
// setTimeout(() => this.unmount(), t);
// return this;
// }
function mount(target = this.target, delay = 0) {
if (delay > 0) {
setTimeout(() => this.mount(target, 0), delay);
return this;
}
if (this.isBody) return this;
if (target?.isUIElement) target = target.element;
this.target = target;
this.target?.appendChild(this.element);
return this;
}
function unmount(delay = 0) {
if (delay > 0) {
setTimeout(() => this.unmount(0), delay);
return this;
}
if (this.cache.parent) {
this.cache.parent.remove(this);
} else if (
this.target?.children?.length &&
[...this.target.children].includes(this.element)
) {
this.target.removeChild(this.element);
}
return this;
}
var LifecycleMethods = /*#__PURE__*/Object.freeze({
__proto__: null,
mount: mount,
unmount: unmount
});
if(!globalThis.__Ziko__) __init__global__();
function useState(initialValue) {
const {store, index} = __Ziko__.__State__;
__Ziko__.__State__.register({
value : initialValue,
subscribers : new Set(),
paused : false
});
let 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));
__Ziko__.__State__.update(index, newValue);
}
}
const controller = {
pause: () => { current.paused = true; },
resume: () => { current.paused = false; },
clear: () => { current.subscribers.clear(); },
force: (newValue) => {
if (typeof newValue === "function") newValue