exprify 1.0.4 → 1.0.6
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/HISTORY.md +49 -0
- package/README.md +100 -180
- package/SECURITY.md +18 -0
- package/bin/cli.mjs +234 -0
- package/dist/exprify.cjs.cjs +3558 -1220
- package/dist/exprify.cjs.cjs.map +1 -1
- package/dist/exprify.esm.js +3558 -1220
- package/dist/exprify.esm.js.map +1 -1
- package/dist/exprify.js +3560 -1222
- package/dist/exprify.js.map +1 -1
- package/dist/exprify.min.js +2 -2
- package/dist/exprify.min.js.map +1 -1
- package/package.json +44 -17
- package/src/core/context.js +35 -27
- package/src/core/exprify.js +880 -0
- package/src/function/executor.js +29 -20
- package/src/function/internal.js +1150 -153
- package/src/function/registry.js +23 -16
- package/src/index.js +1 -1
- package/src/math/bignumber.js +31 -0
- package/src/math/fraction.js +112 -0
- package/src/math/operations.js +38 -24
- package/src/parser/astBuild.js +276 -214
- package/src/parser/evaluator.js +431 -171
- package/src/parser/tokenizer.js +179 -146
- package/src/utils/decimal.js +264 -0
- package/src/utils/globalUnits.js +43 -35
- package/src/utils/matrix.js +14 -14
- package/src/utils/store.js +69 -47
- package/src/variables/store.js +18 -15
- package/src/core/Exprify.js +0 -369
package/dist/exprify.min.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
/*! exprify v1.0.
|
|
2
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Exprify=t()}(this,function(){"use strict";const e=e=>e&&"object"==typeof e&&"DenseMatrix"===e.exprify&&"data"in e&&"size"in e,t=e=>Array.isArray(e)?e.map(t):e,r=e=>{if(Array.isArray(e)&&e.every(Array.isArray))return[e.length,e[0]?.length||0];if(Array.isArray(e))return[e.length];throw new Error("Matrix data must be an array")},n=e=>({exprify:"DenseMatrix",data:t(e),size:r(e)}),o=r=>e(r)?t(r.data):r,i=t=>e(t)?JSON.stringify(t):Array.isArray(t)||t&&"object"==typeof t?JSON.stringify(t,(t,r)=>(e(r),r)):t;function a(e,t={}){const r=t.variables,i=t.functions,s=t.units,l=e=>e&&"object"==typeof e&&"value"in e&&"unit"in e,u=e=>e&&"object"==typeof e&&"re"in e&&"im"in e,c=e=>Array.isArray(e)&&e.length>0&&e.every(Array.isArray),p=e=>{if(e=o(e),c(e))return e.map(e=>[...e]);if(Array.isArray(e))return[e];throw new Error("Expected matrix-compatible value")},m=e=>{if("number"!=typeof e||!Number.isInteger(e)||e<1)throw new Error("Matrix indices must be positive integers");return e-1},f=(e,r)=>{if((n=e)&&"object"==typeof n&&"SliceExpression"===n.type){const n=null==e.start?1:a(e.start,t),o=null==e.end?r:a(e.end,t),i=m(n),s=m(o);if(s<i)return[];const l=[];for(let e=i;e<=s;e++)l.push(e);return l}var n;return[m(a(e,t))]},y=e=>{if(u(e))return e;if("number"==typeof e)return{re:e,im:0};throw new Error("Complex arithmetic only supports numbers")},h=e=>0===e.im?e.re:e;switch(e.type){case"Literal":return e.value;case"ImaginaryLiteral":return{re:0,im:e.value};case"UnitLiteral":return{value:e.value,unit:e.unit};case"Identifier":return r.get(e.name);case"AssignmentExpression":{const i=a(e.right,t);if("Identifier"===e.left.type)return r.set(e.left.name,i),"ArrayExpression"===e.right.type?n(o(i)):i;if("IndexExpression"===e.left.type&&"Identifier"===e.left.object.type){const t=((e,t,r)=>{const n=c(e)?e.map(e=>[...e]):Array.isArray(e)?[e.slice()]:[],o=t[0],i=t[1];if(!o)throw new Error("Matrix assignment requires at least one index");const a=Math.max(n.length,1),s=f(o,a);if(1===t.length){const e=c(r)?r:p(r);if(e.length!==s.length)throw new Error("Assigned row count does not match slice");return s.forEach((t,r)=>{n[t]=[...e[r]]}),{updatedMatrix:n,selectionResult:1===s.length?[n[s[0]]]:s.map(e=>[n[e]])}}const l=Math.max(...n.map(e=>e.length),0,1),u=f(i,l),m=p(r);if(m.length!==s.length)throw new Error("Assigned row count does not match matrix slice");return m.forEach((e,t)=>{if(e.length!==u.length)throw new Error("Assigned column count does not match matrix slice")}),s.forEach((e,t)=>{n[e]||(n[e]=[]),u.forEach((r,o)=>{n[e][r]=m[t][o]})}),{updatedMatrix:n,selectionResult:1===s.length?[u.map(e=>n[s[0]][e])]:s.map(e=>u.map(t=>n[e][t]))}})(r.get(e.left.object.name),e.left.selectors,i);return r.set(e.left.object.name,t.updatedMatrix),t.selectionResult}throw new Error("Invalid assignment target")}case"FunctionAssignmentExpression":{if("="!==e.operator)throw new Error(`Operator ${e.operator} is not supported for function definitions`);const r=(...r)=>{const n=t.withScope(((e,t)=>{const r={};return e.forEach((e,n)=>{r[e]=t[n]}),r})(e.params,r));return a(e.right,n)};return i.register(e.left.name,r),r}case"UnaryExpression":{const r=a(e.argument,t);switch(e.operator){case"-":return u(r)?h({re:-r.re,im:-r.im}):-r;case"!":return!r}throw new Error(`Unknown unary operator ${e.operator}`)}case"BinaryExpression":{let r=a(e.left,t),n=a(e.right,t);if(l(r)||l(n)){if(!s)throw new Error("Unit system not available");return s.compute(e.operator,r,n)}if("*"===e.operator&&(Array.isArray(r)||Array.isArray(n)))return((e,t)=>{const r=p(e),n=p(t);if(r[0].length!==n.length)throw new Error("Matrix dimensions do not allow multiplication");return r.map(e=>n[0].map((t,r)=>e.reduce((e,t,o)=>e+t*n[o][r],0)))})(r,n);if(u(r)||u(n))return((e,t,r)=>{const n=y(t),o=y(r);switch(e){case"+":return h({re:n.re+o.re,im:n.im+o.im});case"-":return h({re:n.re-o.re,im:n.im-o.im});case"*":return h({re:n.re*o.re-n.im*o.im,im:n.re*o.im+n.im*o.re});case"/":{const e=o.re**2+o.im**2;if(0===e)throw new Error("Division by zero");return h({re:(n.re*o.re+n.im*o.im)/e,im:(n.im*o.re-n.re*o.im)/e})}default:throw new Error(`Operator ${e} is not supported for complex numbers`)}})(e.operator,r,n);switch(e.operator){case"+":return r+n;case"-":return r-n;case"*":return r*n;case"/":return r/n;case"%":return r%n;case"^":return r**n;case">":return r>n;case"<":return r<n;case">=":return r>=n;case"<=":return r<=n;case"==":return r===n}throw new Error(`Unknown operator ${e.operator}`)}case"LogicalExpression":{const r=a(e.left,t);if("&&"===e.operator)return r&&a(e.right,t);if("||"===e.operator)return r||a(e.right,t);if("??"===e.operator)return r??a(e.right,t);throw new Error(`Unknown logical operator ${e.operator}`)}case"CallExpression":{const r=e.callee.name;return i.get(r)(...e.arguments.map(e=>a(e,t)))}case"PipelineExpression":{const r=a(e.left,t);if("CallExpression"===e.right.type){const n=e.right.callee.name;return i.get(n)(...[r,...e.right.arguments.map(e=>a(e,t))])}if("Identifier"===e.right.type){return i.get(e.right.name)(r)}throw new Error("Invalid pipeline target")}case"UnitConversion":{const r=a(e.from,t);if(!l(r))throw new Error("Left side must be a unit value");if(!s)throw new Error("Unit system not available");return s.convert(r.value,r.unit,e.to)}case"ArrayExpression":return e.elements.map(e=>a(e,t));case"IndexExpression":return((e,t)=>{const r=p(e);if(1===t.length){const e=f(t[0],r.length).map(e=>{if(e>=r.length)throw new Error("Row index out of range");return[...r[e]]});return 1===e.length?e[0]:e}const n=f(t[0],r.length),o=f(t[1],r[0]?.length||0),i=n.map(e=>{if(e>=r.length)throw new Error("Row index out of range");return o.map(t=>{if(t>=r[e].length)throw new Error("Column index out of range");return r[e][t]})});return 1===n.length&&1===o.length?i[0][0]:1===n.length?i[0]:1===o.length?i.map(e=>[e[0]]):i})(a(e.object,t),e.selectors);case"ObjectExpression":{const r={};for(let n of e.properties)r[n.key]=a(n.value,t);return r}case"MemberExpression":{const r=a(e.object,t);if(e.optional&&null==r)return;return r[e.property.name]}default:throw new Error(`Unknown AST node type: ${e.type}`)}}function s({variables:e,functions:t,units:r,evaluate:n}){if(!e)throw new Error("Variable store missing");if(!t)throw new Error("Function registry missing");if(!r)throw new Error("Units list missing");if(!n)throw new Error("evaluate function missing");return{variables:e,functions:t,units:r,evaluate:n,withScope(o={}){const i={...e.all?.(),...o};return s({functions:t,evaluate:n,units:r,variables:{get:e=>i[e],set:(e,t)=>i[e]=t,all:()=>i}})}}}const l=(e,t)=>typeof e==typeof t&&("number"==typeof e||"bigint"==typeof e),u=Object.freeze({power:function(e,t){if(l(e,t))return e**t;throw new Error("Invalid types for ^")},multiply:function(e,t){if(l(e,t))return e*t;throw new Error("Invalid types for *")},divide:function(e,t){if(l(e,t)){if(0===t)throw new Error("Division by zero");return e/t}throw new Error("Invalid types for /")},add:function(e,t){if(l(e,t))return e+t;if("string"==typeof e&&"string"==typeof t)return e+t;throw new Error("Invalid types for +")},subtract:function(e,t){if(l(e,t))return e-t;throw new Error("Invalid types for -")},modulus:function(e,t){if(l(e,t))return e%t;throw new Error("Invalid types for %")}});const c={length:{m:{value:1,unit:"meter",symbol:"m"},cm:{value:.01,unit:"centimeter",symbol:"cm"},mm:{value:.001,unit:"millimeter",symbol:"mm"},km:{value:1e3,unit:"kilometer",symbol:"km"},um:{value:1e-6,unit:"micrometer",symbol:"um",note:"also called micron"},nm:{value:1e-9,unit:"nanometer",symbol:"nm"},px:{value:264583e-9,unit:"pixel",symbol:"px",note:"96dpi standard"},em:{value:.004233328,unit:"em",symbol:"em",note:"1em = 16px by default"},rem:{value:.004233328,unit:"rem",symbol:"rem",note:"root em = 16px by default"},pt:{value:352778e-9,unit:"point",symbol:"pt",note:"1pt = 1/72 inch"},pc:{value:.00423333,unit:"pica",symbol:"pc",note:"1pc = 12pt"},inch:{value:.0254,unit:"inch",symbol:"in"},ft:{value:.3048,unit:"foot",symbol:"ft"},yd:{value:.9144,unit:"yard",symbol:"yd"},mi:{value:1609.344,unit:"mile",symbol:"mi"},thou:{value:254e-7,unit:"mil",symbol:"thou",note:"thousandth of an inch"},furlong:{value:201.168,unit:"furlong",symbol:"fur",note:"220 yards"},nmi:{value:1852,unit:"nautical mile",symbol:"nmi"},fathom:{value:1.8288,unit:"fathom",symbol:"fathom"},au:{value:1496e8,unit:"astronomical unit",symbol:"AU"},ly:{value:94607e11,unit:"light year",symbol:"ly"},pc:{value:30857e12,unit:"parsec",symbol:"pc"}},weight:{mg:{value:1e-6,unit:"milligram",symbol:"mg"},g:{value:.001,unit:"gram",symbol:"g"},kg:{value:1,unit:"kilogram",symbol:"kg"},t:{value:1e3,unit:"tonne",symbol:"t",note:"metric ton"},lb:{value:.453592,unit:"pound",symbol:"lb"},oz:{value:.0283495,unit:"ounce",symbol:"oz"},stone:{value:6.35029,unit:"stone",symbol:"st",note:"1 stone = 14 lb"}},time:{s:{value:1,unit:"second",symbol:"s"},min:{value:60,unit:"minute",symbol:"min"},h:{value:3600,unit:"hour",symbol:"h"},day:{value:86400,unit:"day",symbol:"d"},week:{value:604800,unit:"week",symbol:"wk"},month:{value:2629800,unit:"month",symbol:"mo",note:"average month = 30.44 days"},year:{value:31557600,unit:"year",symbol:"yr",note:"average year = 365.25 days"}},voltage:{V:{value:1,unit:"volt",symbol:"V"},mV:{value:.001,unit:"millivolt",symbol:"mV"},kV:{value:1e3,unit:"kilovolt",symbol:"kV"},MV:{value:1e6,unit:"megavolt",symbol:"MV"},GV:{value:1e9,unit:"gigavolt",symbol:"GV"},statV:{value:299.792458,unit:"statvolt",symbol:"statV",note:"CGS unit"},abV:{value:1e-8,unit:"abvolt",symbol:"abV",note:"CGS electromagnetic unit"}},frequency:{Hz:{value:1,unit:"hertz",symbol:"Hz",note:"1 cycle per second"},kHz:{value:1e3,unit:"kilohertz",symbol:"kHz"},MHz:{value:1e6,unit:"megahertz",symbol:"MHz"},GHz:{value:1e9,unit:"gigahertz",symbol:"GHz"},THz:{value:1e12,unit:"terahertz",symbol:"THz"}},power:{W:{value:1,unit:"watt",symbol:"W",note:"1 joule per second"},mW:{value:.001,unit:"milliwatt",symbol:"mW"},kW:{value:1e3,unit:"kilowatt",symbol:"kW"},MW:{value:1e6,unit:"megawatt",symbol:"MW"},GW:{value:1e9,unit:"gigawatt",symbol:"GW"},HP:{value:745.7,unit:"horsepower",symbol:"HP",note:"mechanical HP = 745.7 W"},kcal_per_h:{value:1.163,unit:"kilocalorie per hour",symbol:"kcal/h",note:"= 1.163 W"},BTU_per_h:{value:.29307107,unit:"BTU per hour",symbol:"BTU/h",note:"= 0.293 W"}},sound:{dB:{value:1,unit:"decibel",symbol:"dB",note:"logarithmic unit of sound intensity"},dBA:{value:1,unit:"A-weighted decibel",symbol:"dBA",note:"Adjusted for human hearing"},dBC:{value:1,unit:"C-weighted decibel",symbol:"dBC",note:"Flat weighting for high-level sounds"}},temperature:{K:{value:1,unit:"kelvin",symbol:"K"},C:{value:1,unit:"Celsius",symbol:"°C",note:"°C → K: add 273.15"},F:{value:1,unit:"Fahrenheit",symbol:"°F",note:"°F → K: (°F - 32) * 5/9 + 273.15"}},pressure:{Pa:{value:1,unit:"pascal",symbol:"Pa"},kPa:{value:1e3,unit:"kilopascal",symbol:"kPa"},MPa:{value:1e6,unit:"megapascal",symbol:"MPa"},bar:{value:1e5,unit:"bar",symbol:"bar"},atm:{value:101325,unit:"atmosphere",symbol:"atm"},psi:{value:6894.757,unit:"pound per square inch",symbol:"psi"},mmHg:{value:133.322,unit:"millimeter of mercury",symbol:"mmHg"}},energy:{J:{value:1,unit:"joule",symbol:"J"},kJ:{value:1e3,unit:"kilojoule",symbol:"kJ"},cal:{value:4.184,unit:"calorie",symbol:"cal"},kcal:{value:4184,unit:"kilocalorie",symbol:"kcal"},eV:{value:160218e-24,unit:"electronvolt",symbol:"eV"},BTU:{value:1055.06,unit:"BTU",symbol:"BTU"}},force:{N:{value:1,unit:"newton",symbol:"N"},kN:{value:1e3,unit:"kilonewton",symbol:"kN"},lbf:{value:4.44822,unit:"pound-force",symbol:"lbf"},kgf:{value:9.80665,unit:"kilogram-force",symbol:"kgf"},dyne:{value:1e-5,unit:"dyne",symbol:"dyn"}},area:{m2:{value:1,unit:"square meter",symbol:"m²"},cm2:{value:1e-4,unit:"square centimeter",symbol:"cm²"},km2:{value:1e6,unit:"square kilometer",symbol:"km²"},acre:{value:4046.856,unit:"acre",symbol:"acre"},hectare:{value:1e4,unit:"hectare",symbol:"ha"},ft2:{value:.092903,unit:"square foot",symbol:"ft²"},yd2:{value:.836127,unit:"square yard",symbol:"yd²"}},volume:{m3:{value:1,unit:"cubic meter",symbol:"m³"},L:{value:.001,unit:"liter",symbol:"L"},mL:{value:1e-6,unit:"milliliter",symbol:"mL"},gallon:{value:.00378541,unit:"US gallon",symbol:"gal"},pint:{value:473176e-9,unit:"US pint",symbol:"pt"},floz:{value:29574e-9,unit:"US fluid ounce",symbol:"fl oz"}},current:{A:{value:1,unit:"ampere",symbol:"A"},mA:{value:.001,unit:"milliampere",symbol:"mA"},uA:{value:1e-6,unit:"microampere",symbol:"uA"},kA:{value:1e3,unit:"kiloampere",symbol:"kA"}},resistance:{ohm:{value:1,unit:"ohm"},kohm:{value:1e3,unit:"kiloohm"},megaohm:{value:1e6,unit:"megaohm"},S:{value:1,unit:"siemens",symbol:"S",note:"conductance"}},capacitance:{F:{value:1,unit:"farad",symbol:"F"},mF:{value:.001,unit:"millifarad"},uF:{value:1e-6,unit:"microfarad"}},inductance:{H:{value:1,unit:"henry",symbol:"H"},mH:{value:.001,unit:"millihenry",symbol:"mH"},uH:{value:1e-6,unit:"microhenry",symbol:"uH"}},light:{cd:{value:1,unit:"candela",symbol:"cd"},lm:{value:1,unit:"lumen",symbol:"lm"},lx:{value:1,unit:"lux",symbol:"lx"}},data:{bit:{value:1,unit:"bit",symbol:"bit"},B:{value:8,unit:"byte",symbol:"B"},KB:{value:8e3,unit:"kilobyte",symbol:"KB"},MB:{value:8e6,unit:"megabyte",symbol:"MB"},GB:{value:8e9,unit:"gigabyte",symbol:"GB"},TB:{value:8e12,unit:"terabyte",symbol:"TB"}},angle:{deg:{value:1,unit:"degree",symbol:"°"},rad:{value:57.2958,unit:"radian",symbol:"rad",note:"1 rad = 57.2958°"},grad:{value:.9,unit:"grad",symbol:"grad",note:"1 grad = 0.9°"}},radiation:{Gy:{value:1,unit:"gray",symbol:"Gy",note:"Absorbed dose: 1 Gy = 1 J/kg"},mGy:{value:.001,unit:"milligray",symbol:"mGy"},rad:{value:.01,unit:"rad",symbol:"rad",note:"1 rad = 0.01 Gy"},Sv:{value:1,unit:"sievert",symbol:"Sv",note:"Biological effect dose equivalent"},mSv:{value:.001,unit:"millisievert",symbol:"mSv"},rem:{value:.01,unit:"rem",symbol:"rem",note:"1 rem = 0.01 Sv"},Bq:{value:1,unit:"becquerel",symbol:"Bq",note:"1 decay per second"},kBq:{value:1e3,unit:"kilobecquerel",symbol:"kBq"},MBq:{value:1e6,unit:"megabecquerel",symbol:"MBq"},GBq:{value:1e9,unit:"gigabecquerel",symbol:"GBq"},Ci:{value:37e9,unit:"curie",symbol:"Ci",note:"1 Ci = 3.7 x 10¹⁰ decays per second"},mCi:{value:37e6,unit:"millicurie",symbol:"mCi"}}},p=/^[a-zA-Z_$][a-zA-Z0-9_$]*$/;function m(e={}){let t=Object.create(null);for(const r in e)t[r]=e[r];return{set(e,r,{override:n=!0}={}){if("string"!=typeof e||!e)throw new Error("Variable name must be a non-empty string");if(!p.test(e))throw new Error(`Variable Name Error: '${e}' is not a valid variable name`);if(void 0===r)throw new Error(`Variable Value Error: '${e}' cannot be undefined`);if(!n&&e in variablesDB)throw new Error(`Variable '${e}' already exists`);t[e]=r},get:e=>t[e],has:e=>Object.prototype.hasOwnProperty.call(t,e),remove(e){delete t[e]},all:()=>({...t}),clear(){t=Object.create(null)},merge(e={}){for(const r in e)t[r]=e[r]},clone:()=>m(t)}}function f(e){if(e=o(e),!Array.isArray(e)||0===e.length)throw new Error("det() expects a non-empty matrix");if(!e.every(Array.isArray))throw new Error("det() expects a 2D matrix");const t=e.length;if(!e.every(e=>e.length===t))throw new Error("det() expects a square matrix");for(const t of e)for(const e of t)if("number"!=typeof e&&"bigint"!=typeof e)throw new Error("det() matrix values must be numeric")}function y(e){return f(e=o(e)),1===e.length?e[0][0]:2===e.length?e[0][0]*e[1][1]-e[0][1]*e[1][0]:e[0].reduce((t,r,n)=>{const o=e.slice(1).map(e=>e.filter((e,t)=>t!==n));return t+(n%2==0?r:-r)*y(o)},0)}function h(e){const t=o(e);if(!Array.isArray(t))throw new Error("Expected matrix data");return t}function d(e){const t=h(e).map(e=>[...e]);f(t);const r=t.length,o=Array.from({length:r},(e,t)=>t);for(let e=0;e<r;e++){let n=e,i=Math.abs(t[e][e]);for(let o=e+1;o<r;o++){const r=Math.abs(t[o][e]);r>i&&(i=r,n=o)}if(0===i)throw new Error("Matrix is singular");n!==e&&([t[e],t[n]]=[t[n],t[e]],[o[e],o[n]]=[o[n],o[e]]);for(let n=e+1;n<r;n++){t[n][e]/=t[e][e];for(let o=e+1;o<r;o++)t[n][o]-=t[n][e]*t[e][o]}}const i=t.map((e,t)=>e.map((e,r)=>t===r?1:t>r?e:0)),a=t.map((e,t)=>e.map((e,r)=>t<=r?e:0));return{L:n(i),U:n(a),p:o}}function v(e,t){const r=h(e).map(e=>[...e]),o=h(t).map(e=>[...e]);f(r),f(o);const i=r.length;if(o.length!==i)throw new Error("A and Q must have the same dimensions");const a=[],s=[];for(let e=0;e<i;e++)for(let t=0;t<i;t++){const n=new Array(i*i).fill(0);for(let o=0;o<i;o++)n[o*i+t]+=r[e][o],n[e*i+o]+=r[t][o];a.push(n),s.push(-o[e][t])}const l=function(e,t){const r=e.length,n=e.map((e,r)=>[...e,t[r]]);for(let e=0;e<r;e++){let t=e,o=Math.abs(n[e][e]);for(let i=e+1;i<r;i++){const r=Math.abs(n[i][e]);r>o&&(o=r,t=i)}if(0===o)throw new Error("Linear system is singular");t!==e&&([n[e],n[t]]=[n[t],n[e]]);const i=n[e][e];for(let t=e;t<=r;t++)n[e][t]/=i;for(let t=0;t<r;t++){if(t===e)continue;const o=n[t][e];for(let i=e;i<=r;i++)n[t][i]-=o*n[e][i]}}return n.map(e=>e[r])}(a,s),u=[];for(let e=0;e<i;e++)u.push(l.slice(e*i,(e+1)*i));return n(u)}function g(e,t){return e.reduce((e,r,n)=>e+r*t**n,0)}function b(e,t){const r=[...e].reverse(),n=[r[0]];for(let e=1;e<r.length-1;e++)n.push(r[e]+n[e-1]*t);const o=r[r.length-1]+n[n.length-1]*t;return{quotient:n.reverse(),remainder:o}}function w(e){const[t,r,n]=e,o=r**2-4*n*t;if(o<0)throw new Error("Only real roots are supported");const i=Math.sqrt(o);return[(-r+i)/(2*n),(-r-i)/(2*n)]}function E(e,t){return e.reduce((e,r,n)=>e+r*t[n],0)}function x(e){return Math.sqrt(E(e,e))}function A(e,t){return e.map(e=>e*t)}function k(e,t){return e.map((e,r)=>e-t[r])}function $(e,t){const r=function(e){const t=e.replace(/\s+/g,"");return t?t.replace(/-/g,"+-").split("+").filter(Boolean):[]}(e),n=new Map;for(const e of r)if(e.includes(t)){const[r,o]=e.split(t);let i;if(""===r||"+"===r)i=1;else if("-"===r)i=-1;else{const e=r.endsWith("*")?r.slice(0,-1):r;i=Number(e)}if(!Number.isFinite(i))throw new Error("Unsupported algebra term");let a=1;if(o){if(!o.startsWith("^"))throw new Error("Unsupported algebra term");a=Number(o.slice(1))}if(!Number.isInteger(a)||a<0)throw new Error("Only non-negative integer powers are supported");n.set(a,(n.get(a)||0)+i)}else{const t=Number(e);if(!Number.isFinite(t))throw new Error("Unsupported algebra term");n.set(0,(n.get(0)||0)+t)}return n}function M(e,t){const r=[...e.entries()].filter(([,e])=>0!==e).sort((e,t)=>t[0]-e[0]);return r.length?r.map(([e,r],n)=>{const o=r<0,i=Math.abs(r);let a;return a=0===e?`${i}`:1===e?1===i?t:`${i} * ${t}`:1===i?`${t}^${e}`:`${i} * ${t}^${e}`,0===n?o?`-${a}`:a:o?`- ${a}`:`+ ${a}`}).join(" "):"0"}const O={max:(...e)=>{if(!e.length)throw new Error("max() requires arguments");return Math.max(...e)},min:(...e)=>{if(!e.length)throw new Error("min() requires arguments");return Math.min(...e)},abs:e=>Math.abs(e),round:e=>Math.round(e),floor:e=>Math.floor(e),ceil:e=>Math.ceil(e),sqrt:e=>{if(e<0)throw new Error("sqrt() domain error");return Math.sqrt(e)},pow:(e,t)=>e**t,det:e=>y(e),polynomialRoot:(...e)=>function(...e){for(;e.length>1&&0===e[e.length-1];)e.pop();const t=e.length-1;if(t<1)throw new Error("polynomialRoot() expects at least a linear polynomial");if(1===t){const[t,r]=e;return[-t/r]}if(2===t)return w(e);if(3===t){const t=e[0];e[3];const r=[],n=Math.abs(t);for(let e=1;e<=Math.max(1,n);e++)n%e===0&&r.push(e,-e);for(const t of r)if(0===g(e,t))return[t,...w(b(e,t).quotient)]}throw new Error("polynomialRoot() currently supports degree up to 3")}(...e),lsolve:(e,t)=>function(e,t){const{L:r,U:o,p:i}=d(e),a=h(e),s=h(t),l=Array.isArray(s[0])?s.map(e=>e[0]):s;if(a.length!==l.length)throw new Error("Right-hand side dimension mismatch");const u=i.map(e=>l[e]),c=new Array(a.length).fill(0);for(let e=0;e<a.length;e++){c[e]=u[e];for(let t=0;t<e;t++)c[e]-=r.data[e][t]*c[t]}const p=new Array(a.length).fill(0);for(let e=a.length-1;e>=0;e--){p[e]=c[e];for(let t=e+1;t<a.length;t++)p[e]-=o.data[e][t]*p[t];p[e]/=o.data[e][e]}return n(p.map(e=>[e]))}(e,t),lup:e=>d(e),lyap:(e,t)=>v(e,t),qr:e=>function(e){const t=h(e).map(e=>[...e]);if(!t.length||!t.every(e=>e.length===t[0].length))throw new Error("qr() expects a rectangular matrix");const r=t.length,o=t[0].length,i=(a=t)[0].map((e,t)=>a.map(e=>e[t]));var a;const s=[];for(let e=0;e<o;e++){let t=[...i[e]];for(let r=0;r<s.length;r++){const n=E(s[r],i[e]);t=k(t,A(s[r],n))}const r=x(t);if(0===r)throw new Error("qr() requires linearly independent columns");s.push(A(t,1/r))}for(let e=0;s.length<r&&e<r;e++){let t=Array.from({length:r},(t,r)=>r===e?1:0);for(const e of s)t=k(t,A(e,E(e,t)));const n=x(t);n>1e-10&&s.push(A(t,1/n))}const l=Array.from({length:r},(e,t)=>s.map(e=>e[t])),u=Array.from({length:r},()=>Array(o).fill(0));for(let e=0;e<r;e++)for(let t=0;t<o;t++)u[e][t]=E(s[e],i[t]);return{Q:n(l),R:n(u)}}(e),simplify:e=>{if("string"!=typeof e)throw new Error("simplify() expects an expression string");return function(e){const t=e.replace(/\s+/g,"").match(/[a-zA-Z]+/),r=t?.[0]||"x";return M($(e,r),r)}(e)},derivative:(e,t="x")=>{if("string"!=typeof e||"string"!=typeof t)throw new Error("derivative() expects expression and variable strings");return function(e,t){const r=$(e,t),n=new Map;for(const[e,t]of r.entries())0!==e&&n.set(e-1,(n.get(e-1)||0)+t*e);return M(n,t)}(e,t)},sin:e=>Math.sin(e),cos:e=>Math.cos(e),tan:e=>Math.tan(e),asin:e=>Math.asin(e),acos:e=>Math.acos(e),atan:e=>Math.atan(e),log:e=>{if(e<=0)throw new Error("log() domain error");return Math.log(e)},log10:e=>{if(e<=0)throw new Error("log10() domain error");return Math.log10(e)},exp:e=>Math.exp(e),random:()=>Math.random(),and:(e,t)=>Boolean(e&&t),or:(e,t)=>Boolean(e||t),not:e=>!e,"!":e=>!e,eq:(e,t)=>e===t,neq:(e,t)=>e!==t,notEqual:(e,t)=>e!==t,gt:(e,t)=>e>t,greaterThan:(e,t)=>e>t,lt:(e,t)=>e<t,lessThan:(e,t)=>e<t,gte:(e,t)=>e>=t,greaterThanOrEqual:(e,t)=>e>=t,lte:(e,t)=>e<=t,lessThanOrEqual:(e,t)=>e<=t,clamp:(e,t,r)=>{if(t>r)throw new Error("clamp(): min > max");return Math.min(Math.max(e,t),r)},if:(e,t,r)=>e?t:r,typeof:e=>typeof e,length:e=>{if("string"==typeof e||Array.isArray(e))return e.length;throw new Error("length() expects string or array")}};function U(e){let t=0;const r=()=>e[t],n=()=>e[t++],o=(e,n)=>{const o=r();return!!o&&(o.type===e&&((void 0===n||o.value===n)&&(t++,!0)))},i=()=>{let e=null;if("Colon"!==r()?.type&&"Comma"!==r()?.type&&"ArrayEnd"!==r()?.type&&(e=h()),o("Colon")){let t=null;return"Comma"!==r()?.type&&"ArrayEnd"!==r()?.type&&(t=h()),{type:"SliceExpression",start:e,end:t}}return e};function a(){let e=function(){const e=n();if(!e)throw new Error("Unexpected end of input");switch(e.type){case"Number":case"BigInt":case"Boolean":case"String":return{type:"Literal",value:e.value};case"ImaginaryLiteral":return{type:"ImaginaryLiteral",value:e.value};case"NumberWithUnit":return{type:"UnitLiteral",value:e.value,unit:e.unit};case"Identifier":case"Function":return{type:"Identifier",name:e.name};case"Parenthesis":if("("===e.value){const e=h();if(!o("Parenthesis",")"))throw new Error("Expected ')'");return e}case"ArrayStart":{const e=[];let r=[];if(!o("ArrayEnd"))for(;;)if(r.push(h()),!o("Comma")){if(!o("Semicolon")){if(o("ArrayEnd")){e.push(r);break}throw new Error(`Expected ',', ';', or ']' at ${t}`)}e.push(r),r=[]}return e.length?1===e.length?{type:"ArrayExpression",elements:e[0]}:{type:"ArrayExpression",elements:e.map(e=>({type:"ArrayExpression",elements:e}))}:{type:"ArrayExpression",elements:[]}}case"BlockStart":{const e=[];if(!o("BlockEnd")){do{const t=n();if("Identifier"!==t.type&&"String"!==t.type)throw new Error("Invalid object key");if(!o("Colon"))throw new Error("Expected ':' after key");const r=h();e.push({key:t.value,value:r})}while(o("Comma"));if(!o("BlockEnd"))throw new Error(`Expected '}' at ${t}`)}return{type:"ObjectExpression",properties:e}}}throw new Error(`Unexpected token: ${JSON.stringify(e)}`)}();for(;;){if(o("ArrayStart")){const r=[];if(!o("ArrayEnd")){do{r.push(i())}while(o("Comma"));if(!o("ArrayEnd"))throw new Error(`Expected ']' at ${t}`)}e={type:"IndexExpression",object:e,selectors:r};continue}if(o("Dot")){const t=n();if("Identifier"!==t.type)throw new Error("Expected property after '.'");e={type:"MemberExpression",object:e,property:{type:"Identifier",name:t.value},optional:!1};continue}if(o("Operator","?.")){e={type:"MemberExpression",object:e,property:{type:"Identifier",name:n().value},optional:!0};continue}break}return e}function s(){if(o("UnaryOperator")){return{type:"UnaryExpression",operator:e[t-1].value,argument:s()}}return function(){let e=a();for(;"Parenthesis"===r()?.type&&"("===r()?.value;){n();const i=[];if("Parenthesis"!==r()?.type||")"!==r()?.value)do{i.push(h())}while(o("Comma"));if(!o("Parenthesis",")"))throw new Error(`Expected ')' at ${t}`);e={type:"CallExpression",callee:e,arguments:i}}return e}()}function l(){let e=s();if(o("Operator","^")){return{type:"BinaryExpression",operator:"^",left:e,right:l()}}return e}function u(){let r=l();for(;o("Operator","*")||o("Operator","/")||o("Operator","%");){r={type:"BinaryExpression",operator:e[t-1].value,left:r,right:l()}}return r}function c(){let i=function(){let r=u();for(;o("Operator","+")||o("Operator","-");)r={type:"BinaryExpression",operator:e[t-1].value,left:r,right:u()};return r}();const a=r();if("Keyword"===a?.type&&["to","in"].includes(a.value)){n();const e=n();if(!e||"Unit"!==e.type)throw new Error(`Expected unit after '${a.value}'`);return{type:"UnitConversion",from:i,to:e.value}}return i}function p(){let r=c();for(;o("Operator",">")||o("Operator","<")||o("Operator",">=")||o("Operator","<=")||o("Operator","==");){r={type:"BinaryExpression",operator:e[t-1].value,left:r,right:c()}}return r}function m(){let r=p();for(;o("Operator","&&")||o("Operator","||");){r={type:"LogicalExpression",operator:e[t-1].value,left:r,right:p()}}return r}function f(){let e=function(){let e=m();for(;o("Operator","??");)e={type:"LogicalExpression",operator:"??",left:e,right:m()};return e}();if(o("Ternary","?")){const t=h();if(!o("Ternary",":"))throw new Error("Expected ':' in ternary");return{type:"ConditionalExpression",test:e,consequent:t,alternate:h()}}return e}function y(){let r=function(){let e=f();for(;o("Operator","|>");)e={type:"PipelineExpression",left:e,right:f()};return e}();if(o("Operator","=")||o("Operator","+=")||o("Operator","-=")||o("Operator","*=")||o("Operator","/=")){const n=e[t-1].value;if("CallExpression"===r.type){if(!("Identifier"===r.callee?.type&&r.arguments.every(e=>"Identifier"===e.type)))throw new Error("Invalid function definition");const e=y();return{type:"FunctionAssignmentExpression",operator:n,left:{type:"Identifier",name:r.callee.name},params:r.arguments.map(e=>e.name),right:e}}if("Identifier"!==r.type&&"MemberExpression"!==r.type&&"IndexExpression"!==r.type)throw new Error("Invalid assignment target");return{type:"AssignmentExpression",operator:n,left:r,right:y()}}return r}function h(){return y()}const d=h();if(t<e.length)throw new Error(`Unexpected token at end: ${JSON.stringify(r())}`);return d}const C=e=>e&&"object"==typeof e&&"re"in e&&"im"in e,B=e=>"number"!=typeof e||Number.isInteger(e)?String(e):Number(e.toFixed(14)).toString(),I=t=>C(t)?(e=>{if(!C(e))return e;const t=e.re,r=Math.abs(e.im),n=e.im<0?"-":"+";return 0===t?1===e.im?"i":-1===e.im?"-i":`${e.im}i`:`${t} ${n} ${1===r?"i":`${r}i`}`})(t):(e=>e&&"object"==typeof e&&"value"in e&&"unit"in e)(t)?`${t.value} ${t.unit}`:e(t)?i(t):(e=>Array.isArray(e)&&e.length>0&&e.every(Array.isArray))(t)?t.map(e=>e.map(B).join("\t")).join("\n"):Array.isArray(t)?JSON.stringify(t):t&&"object"==typeof t?i(t):t;return class{constructor(){this.math=u,this.units=function(e={}){let t={...e};function r(e){e=e.toLowerCase();for(const r in t)for(const n in t[r]){const o=t[r][n];if(n.toLowerCase()===e||o.unit?.toLowerCase()===e||o.symbol?.toLowerCase()===e)return{type:r,key:n,data:o}}return null}return{getUnits:()=>t,setUnits:e=>{t={...e}},updateType:(e,r)=>{t[e]={...t[e],...r}},addUnit:(e,r,n)=>{t[e]||(t[e]={}),t[e][r]=n},compute(e,t,r){const n=e=>e&&"object"==typeof e&&"value"in e&&"unit"in e,o=(t,r)=>{switch(e){case"+":return t+r;case"-":return t-r;case"*":return t*r;case"/":return t/r;case"%":return t%r;case"^":return Math.pow(t,r)}};if(n(t)&&n(r)){const e=this.findUnit(r.unit),n=this.findUnit(t.unit);if(e.type!==n.type)throw new Error("Cannot operate on different unit types");const i=r.value*(e.data.value/n.data.value);return{value:o(t.value,i),unit:t.unit}}if(n(t)&&!n(r))return{value:o(t.value,r),unit:t.unit};if(!n(t)&&n(r)){return{value:o(t,r.value),unit:r.unit}}return o(t,r)},convert:function(e,n,o){const i=r(n),a=r(o);if(!i)throw new Error(`Unknown unit: ${n}`);if(!a)throw new Error(`Unknown unit: ${o}`);if(i.type!==a.type)throw new Error(`Cannot convert ${n} to ${o} (${a.data.unit||a.key}). ${i.data.unit||i.key} conversion units like ${Object.keys(t[i.type]).join(", ")}`);return{value:e*(i.data.value/a.data.value),unit:a.key}},getAllUnitsFlat:function(){const e=new Set;for(const r in t)for(const n in t[r]){const o=t[r][n],i=n.toLowerCase();if(e.add(i),o.unit){const t=o.unit.toLowerCase();t!==i&&1===t.split(/\s+/).length&&e.add(t)}if(o.symbol){const t=o.symbol.toLowerCase();o.unit&&t===o.unit.toLowerCase()||e.add(t)}}return Array.from(e)},findUnit:r}}(c),this.functions=function(e={}){const t=Object.create(null);for(const r in e)"function"==typeof e[r]&&(t[r]=e[r]);return{getAllFunctionsName:()=>Object.keys(t),register(e,r){if("string"!=typeof e||!e)throw new Error("Formula name must be a non-empty string");if("function"!=typeof r)throw new Error(`Formula "${e}" must be callable`);t[e]=r},get:e=>t[e],has:e=>Object.prototype.hasOwnProperty.call(t,e),remove(e){delete t[e]},all:()=>({...t}),clear(){for(const e in t)delete t[e]},extend(e={}){for(const r in e)"function"==typeof e[r]&&(t[r]=e[r])},clone:()=>createFormulaRegistry(t)}}(O),this.variables=m(),this._cache=new Map,this.variables.set("pi",Math.PI),this.variables.set("e",Math.E),this.addFunction("parse",e=>{if("string"!=typeof e)throw new Error("parse() expects an expression string");return e}),this.addFunction("leafCount",e=>{let t=e;if("string"==typeof e)try{t=this.parse(e).ast}catch{return(e=>{const t=e.replace(/(^|[{,]\s*)[a-zA-Z_][a-zA-Z0-9_]*\s*:/g,"$1").match(/\d+(\.\d+)?(e[+-]?\d+)?n?|[a-zA-Z_][a-zA-Z0-9_]*/gi);return t?t.length:0})(e)}const r=e=>{if(!e||"object"!=typeof e)return 0;switch(e.type){case"Literal":case"ImaginaryLiteral":case"UnitLiteral":case"Identifier":return 1;default:return Object.values(e).reduce((e,t)=>Array.isArray(t)?e+t.reduce((e,t)=>e+r(t),0):e+r(t),0)}};return r(t)}),this.addFunction("matrix",e=>n(e)),this.addFunction("sparse",e=>n(e)),this.addFunction("rationalize",(e,t=!1)=>{if("string"!=typeof e)throw new Error("rationalize() expects an expression string");const r=e.replace(/\s+/g,"").replace(/(\d)([a-zA-Z(])/g,"$1*$2").replace(/([a-zA-Z)])(\d)/g,"$1*$2"),n=e=>JSON.stringify(Object.entries(e).sort(([e],[t])=>e.localeCompare(t))),o=e=>Object.fromEntries(JSON.parse(e)),i=e=>new Map([[n({}),e]]),a=e=>new Map([...e.entries()].filter(([,e])=>0!==e)),s=(e,t,r=1)=>{const n=new Map(e);for(const[e,o]of t.entries())n.set(e,(n.get(e)||0)+r*o);return a(n)},l=(e,t)=>{const r=new Map;for(const[i,a]of e.entries()){const e=o(i);for(const[i,s]of t.entries()){const t=o(i),l={...e};for(const[e,r]of Object.entries(t))l[e]=(l[e]||0)+r;const u=n(l);r.set(u,(r.get(u)||0)+a*s)}}return a(r)},u=(e,t)=>{let r=i(1);for(let n=0;n<t;n++)r=l(r,e);return r},c=(e,t=i(1))=>({num:e,den:t}),p=(e,t,r=1)=>c(s(l(e.num,t.den),l(t.num,e.den),r),l(e.den,t.den)),m=e=>{switch(e.type){case"Literal":return c(i(e.value));case"Identifier":return c((a=e.name,new Map([[n({[a]:1}),1]])));case"UnaryExpression":if("-"===e.operator)return o=m(e.argument),c(s(new Map,o.num,-1),o.den);throw new Error("Unsupported unary operator");case"BinaryExpression":{const n=m(e.left),o=m(e.right);switch(e.operator){case"+":return p(n,o);case"-":return p(n,o,-1);case"*":return r=o,c(l((t=n).num,r.num),l(t.den,r.den));case"/":return((e,t)=>c(l(e.num,t.den),l(e.den,t.num)))(n,o);case"^":if("Literal"!==e.right.type||!Number.isInteger(e.right.value)||e.right.value<0)throw new Error("Unsupported exponent");return c(u(n.num,e.right.value),u(n.den,e.right.value));default:throw new Error("Unsupported operator in rationalize()")}}default:throw new Error("Unsupported expression in rationalize()")}var t,r,o,a},f=e=>{const t=[...e.entries()].filter(([,e])=>0!==e).sort(([e],[t])=>{const r=o(e),n=o(t),i=Object.keys(r).sort()[0]||"",a=Object.keys(n).sort()[0]||"";if(i!==a)return i.localeCompare(a);const s=Object.values(r).reduce((e,t)=>e+t,0);return Object.values(n).reduce((e,t)=>e+t,0)-s});return t.length?t.map(([e,t],r)=>{const n=o(e),i=Math.abs(t);let a=Object.entries(n).map(([e,t])=>1===t?e:`${e} ^ ${t}`).join(" * ");return a?1!==i&&(a=`${i} * ${a}`):a=`${i}`,0===r?t<0?`- ${a}`.replace("- ","-"):a:t<0?`- ${a}`:`+ ${a}`}).join(" "):"0"},y=this.parse(r).ast,h=m(y),d=f(h.num),v=f(h.den),g=new Set;for(const e of[h.num,h.den])for(const t of e.keys())for(const e of Object.keys(o(t)))g.add(e);return t?{numerator:d,denominator:v,coefficients:[],variables:[...g].sort(),expression:`(${d}) / (${v})`}:`(${d}) / (${v})`})}setVariable(e,t){this.variables.set(e,t)}getVariable(e){return this.variables.get(e)}addFunction(e,t){this.functions.register(e,t)}_createContext(){return s({functions:this.functions,variables:this.variables,units:this.units,evaluate:this.evaluate.bind(this)})}tokenize(e){if("string"!=typeof e)throw new Error("Expression must be a string");return function(e,t={}){const r=[];let n="",o="";const i=["+","-","*","/","%","^","=",">","<","!","&","|"],a=["==",">=","<=","&&","||","+=","-=","*=","/=","%=","?.","??","|>"],s=["to","in"],l=t.units?.getAllUnitsFlat?.()||[],u=e=>!e||"Operator"===e.type||"UnaryOperator"===e.type||"Parenthesis"===e.type&&")"!==e.value||"ArrayStart"===e.type||"Semicolon"===e.type||"Comma"===e.type||"Ternary"===e.type,c=(t,o)=>{if(!n)return;if(/^(true|false)$/i.test(n))return r.push({type:"Boolean",value:"true"===n.toLowerCase()}),void(n="");if(s.includes(n))return r.push({type:"Keyword",value:n,pos:o}),void(n="");if(/^\d+n$/.test(n))return r.push({type:"BigInt",value:BigInt(n.slice(0,-1)),pos:o}),void(n="");if(/^0x[0-9a-fA-F]+$/.test(n))return r.push({type:"Number",value:parseInt(n,16),pos:o}),void(n="");if(/^0b[01]+$/.test(n))return r.push({type:"Number",value:parseInt(n,2),pos:o}),void(n="");if(/^[+-]?(\d+(\.\d+)?|\.\d+)(e[+-]?\d+)?$/i.test(n))return r.push({type:"Number",value:parseFloat(n),pos:o}),void(n="");if(/^[+-]?(\d+(\.\d+)?|\.\d+)(e[+-]?\d+)?i$/i.test(n))return r.push({type:"ImaginaryLiteral",value:parseFloat(n.slice(0,-1)),pos:o}),void(n="");if(/^[+-]?i$/i.test(n)){const e="-"===n[0]?-1:1;return r.push({type:"ImaginaryLiteral",value:e,pos:o}),void(n="")}const i=n.match(/^([+-]?\d+(\.\d+)?)([a-zA-Z]+)$/);if(i){const e=parseFloat(i[1]),t=i[3];return r.push({type:l.includes(t)?"NumberWithUnit":"UnknownUnit",value:e,unit:t,pos:o}),void(n="")}if(l.includes(n)){const{prevWord:i}=function(e,t){const r=e.match(/[a-z0-9]+/gi)||[],n=e[t]||null,o=t>0?e[t-1]:null;let i=t;for(;i>0&&/[a-z0-9]/i.test(e[i-1]);)i--;let a=t;for(;a<e.length&&/[a-z0-9]/i.test(e[a]);)a++;const s=e.substring(i,a),l=r.indexOf(s);return{prevWord:l>0?r[l-1]:null,prevChar:o,currentWord:s,currentChar:n,nextWord:-1!==l&&l<r.length-1?r[l+1]:null}}(e,o);if("("!==t&&i&&(!isNaN(parseFloat(i))||"to"===i||"in"===i))return r.push({type:"Unit",value:n,pos:o}),void(n="")}if(/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(n))return"("===t?r.push({type:"Function",name:n,pos:o}):r.push({type:"Identifier",name:n,pos:o}),void(n="");throw new Error(`Invalid token "${n}" at index ${o}`)};for(let t=0;t<e.length;t++){let s=e[t],l=e[t+1];if("/"===s&&"/"===l){for(;t<e.length&&"\n"!==e[t];)t++;continue}if("/"===s&&"*"===l){for(t+=2;t<e.length&&("*"!==e[t]||"/"!==e[t+1]);)t++;t++;continue}if("\"'".includes(s)){o?o===s?(n+=s,r.push({type:"String",value:n.slice(1,-1),pos:t}),n="",o=""):n+=s:(o=s,n+=s);continue}if(o){n+="\\"===s?s+e[++t]:s;continue}const p=s+l;if(a.includes(p))c(s,t),r.push({type:"Operator",value:p,pos:t}),t++;else if("?"!==s){if(":"===s){c(s,t);const e=r[r.length-1];e&&"Ternary"===e.type?r.push({type:"Ternary",value:":"}):r.push({type:"Colon"});continue}if("."===s&&/\d/.test(n)&&/\d/.test(l))n+=s;else if("."!==s){if(i.includes(s)){c(s,t);const e=r[r.length-1];"-"!==s&&"!"!==s||!u(e)?r.push({type:"Operator",value:s,pos:t}):r.push({type:"UnaryOperator",value:s,pos:t});continue}"()".includes(s)?(c(s,t),r.push({type:"Parenthesis",value:s,pos:t})):"["!==s?"]"!==s?"{"!==s?"}"!==s?","!==s?";"!==s?" "!==s?(n+=s,t===e.length-1&&c(null,t)):c(l,t):(c(s,t),r.push({type:"Semicolon",pos:t})):(c(s,t),r.push({type:"Comma",pos:t})):(c(s,t),r.push({type:"BlockEnd",pos:t})):(c(s,t),r.push({type:"BlockStart",pos:t})):(c(s,t),r.push({type:"ArrayEnd",pos:t})):(c(s,t),r.push({type:"ArrayStart",pos:t}))}else c(s,t),r.push({type:"Dot",pos:t})}else r.push({type:"Ternary",value:"?"})}if(o)throw new Error("Unclosed string literal");const p=[];for(let e=0;e<r.length;e++){const t=r[e],n=r[e+1];"Number"!==t?.type||"Unit"!==n?.type?p.push(t):(p.push({type:"NumberWithUnit",value:t.value,unit:n.value,pos:t.pos}),e++)}const m=[];for(let e=0;e<p.length;e++){const t=p[e],r=p[e+1];m.push(t),t&&r&&(["Number","Identifier"].includes(t.type)||"Parenthesis"===t.type&&")"===t.value||"ArrayEnd"===t.type)&&(["Identifier","Function"].includes(r.type)||"Parenthesis"===r.type&&"("===r.value)&&m.push({type:"Operator",value:"*",implicit:!0})}return m}(e,this._createContext())}parse(e){const t=this.tokenize(e);return{tokens:t,ast:U(t)}}evaluate(e){const{ast:t}=this.parse(e);return I(a(t,this._createContext()))}compile(e){if(this._cache.has(e))return this._cache.get(e);const{ast:t}=this.parse(e),r=(e={})=>{const r=this._createContext().withScope(e);return I(a(t,r))};return this._cache.set(e,r),r}clearCache(){this._cache.clear()}}});
|
|
1
|
+
/*! exprify v1.0.6 | * (c) 2026 Nirmal Paul and contributors | GPL-3.0 License*/
|
|
2
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Exprify=t()}(this,function(){"use strict";const e=e=>e&&"object"==typeof e&&"DenseMatrix"===e.exprify&&"data"in e&&"size"in e,t=e=>Array.isArray(e)?e.map(t):e,r=e=>{if(Array.isArray(e)&&e.every(Array.isArray))return[e.length,e[0]?.length||0];if(Array.isArray(e))return[e.length];throw new Error("Matrix data must be an array")},n=e=>({exprify:"DenseMatrix",data:t(e),size:r(e)}),o=r=>e(r)?t(r.data):r,i=t=>e(t)?JSON.stringify(t):Array.isArray(t)||t&&"object"==typeof t?JSON.stringify(t,(t,r)=>(e(r),r)):t;function a(e,t=1){if("number"!=typeof e||"number"!=typeof t)throw new Error("Fraction requires numeric arguments");if(!Number.isInteger(e)||!Number.isInteger(t))throw new Error("Fraction requires integer arguments");if(0===t)throw new Error("Fraction denominator cannot be zero");t<0&&(e=-e,t=-t);const r=((e,t)=>{for(e=Math.abs(e),t=Math.abs(t);t;)[e,t]=[t,e%t];return e})(e,t);return{n:e/r,d:t/r}}function s(e){return e&&"object"==typeof e&&"n"in e&&"d"in e&&!("re"in e)&&!("unit"in e)}class u{static DP=20;#e;#t;#r;constructor(e){if(e instanceof u)return this.#e=e.#e,this.#t=e.#t,void(this.#r=e.#r);if("bigint"==typeof e)return this.#e=e>=0n?1:-1,this.#t=e>=0n?e:-e,void(this.#r=0);if("number"==typeof e){if(!Number.isFinite(e))throw new Error(`Cannot create ExprDecimal from ${e}`);e=String(e)}if("string"!=typeof e)throw new Error("ExprDecimal expects a number, string, bigint, or ExprDecimal");let t=e.trim();if(""===t)throw new Error("Cannot create ExprDecimal from empty string");this.#e=1,"-"===t[0]?(this.#e=-1,t=t.slice(1)):"+"===t[0]&&(t=t.slice(1));let r=0;const n=t.search(/[eE]/);-1!==n&&(r=parseInt(t.slice(n+1),10),t=t.slice(0,n));const o=t.indexOf(".");if(-1===o)this.#t=BigInt(t||"0"),this.#r=0;else{const e=t.slice(0,o)||"0",r=t.slice(o+1),n=e+r;this.#t=BigInt(n||"0"),this.#r=r.length}this.#r-=r,this.#r<0&&(this.#t*=10n**BigInt(-this.#r),this.#r=0),this.#n()}#n(){for(;this.#r>0&&this.#t%10n==0n;)this.#t/=10n,this.#r--;0n===this.#t&&(this.#e=1,this.#r=0)}#o(e){if(this.#r===e.#r)return[this.#t*BigInt(this.#e),e.#t*BigInt(e.#e),this.#r];if(this.#r<e.#r){const t=10n**BigInt(e.#r-this.#r);return[this.#t*t*BigInt(this.#e),e.#t*BigInt(e.#e),e.#r]}const t=10n**BigInt(this.#r-e.#r);return[this.#t*BigInt(this.#e),e.#t*t*BigInt(e.#e),this.#r]}#i(e,t,r){const n=new u(0);return n.#e=e,n.#t=t<0n?-t:t,t<0n&&(n.#e=-e),n.#r=r,n.#n(),n}plus(e){e=e instanceof u?e:new u(e);const[t,r,n]=this.#o(e);return this.#i(1,t+r,n)}minus(e){e=e instanceof u?e:new u(e);const[t,r,n]=this.#o(e);return this.#i(1,t-r,n)}times(e){e=e instanceof u?e:new u(e);const t=this.#t*e.#t,r=this.#r+e.#r;return this.#i(this.#e*e.#e,t,r)}div(e){if(0n===(e=e instanceof u?e:new u(e)).#t)throw new Error("Division by zero");const t=Math.min(u.DP,100),r=10n**BigInt(t+e.#r),n=this.#t*r/e.#t,o=this.#e*e.#e;return 0n===n?new u(0):this.#i(o,n,t)}mod(e){e=e instanceof u?e:new u(e);const t=this.div(e),r=t.#i(t.#e,t.#t-t.#t%10n**BigInt(t.#r>0?1:0),0);return this.minus(r.times(e))}pow(e){if((e=e instanceof u?e:new u(e)).#r>0||1!==e.#e)throw new Error("ExprDecimal pow() supports non-negative integer exponents only");const t=Number(e.#t);if(t>100)throw new Error("ExprDecimal pow() exponent too large");let r=new u(1);for(let e=0;e<t;e++)r=r.times(this);return r}negated(){const e=new u(this);return e.#e=-e.#e,0n===e.#t&&(e.#e=1),e}eq(e){e=e instanceof u?e:new u(e);const[t,r]=this.#o(e);return t===r}gt(e){e=e instanceof u?e:new u(e);const[t,r]=this.#o(e);return t>r}lt(e){e=e instanceof u?e:new u(e);const[t,r]=this.#o(e);return t<r}gte(e){return this.gt(e)||this.eq(e)}lte(e){return this.lt(e)||this.eq(e)}toString(){let e=this.#t.toString();const t=this.#r,r=(e,t)=>{const r=e[0],n=e.slice(1).replace(/0+$/,"");let o=r;return n&&(o+=`.${n}`),o+="e",o+=t>=0?"+":"",o+=t,-1===this.#e?`-${o}`:o};if(0===t)return e.length>15?r(e,e.length-1):-1===this.#e?`-${e}`:e;for(;e.length<=t;)e=`0${e}`;const n=e.length-t,o=e.slice(0,n),i=o.replace(/^0+/,"")||"0",a=e.slice(n);if(i.length>15||"0"===i&&a.replace(/0+$/,"").length>15){const t=e.replace(/^0+/,"")||"0";return r(t,n-(e.length-t.length)-1)}const s=o||"0",u=a.replace(/0+$/,"");return""===u?-1===this.#e?`-${s}`:s:`${-1===this.#e?"-":""}${s}.${u}`}toNumber(){return Number(this.toString())}static isDecimal(e){return e instanceof u}}function l(e){if(u.isDecimal(e))return e;if("number"==typeof e||"string"==typeof e||"bigint"==typeof e)return new u(e);throw new Error("bignumber() expects a number, string, or bigint")}function c(e){return u.isDecimal(e)}function p(e){return u.isDecimal(e)?e.toString():String(e)}function h(t,r={}){const i=r.variables,u=r.functions,p=r.units,f=e=>e&&"object"==typeof e&&"value"in e&&"unit"in e,m=e=>e&&"object"==typeof e&&"re"in e&&"im"in e,g=e=>Array.isArray(e)&&e.length>0&&e.every(Array.isArray),y=t=>g(t)||e(t),d=e=>{if(e=o(e),g(e))return e.map(e=>[...e]);if(Array.isArray(e))return[e];throw new Error("Expected matrix-compatible value")},w=e=>{const r=t&&void 0!==t.pos?` at position ${t.pos}`:"";return new Error(`${e}${r}`)},b=e=>{if("number"!=typeof e||!Number.isInteger(e)||e<1)throw new Error("Matrix indices must be positive integers");return e-1},v=(e,t)=>{if((n=e)&&"object"==typeof n&&"SliceExpression"===n.type){const n=null===e.start||void 0===e.start?1:h(e.start,r),o=null===e.end||void 0===e.end?t:h(e.end,r),i=b(n),a=b(o);if(a<i)return[];const s=[];for(let e=i;e<=a;e++)s.push(e);return s}var n;return[b(h(e,r))]},E=e=>"number"==typeof e||"bigint"==typeof e,x=(e,t)=>{if(E(e)){return d(t).map(t=>t.map(t=>Number(e)*t))}if(E(t)){return d(e).map(e=>e.map(e=>e*Number(t)))}const r=d(e),n=d(t);if(r[0].length!==n.length)throw new Error("Matrix dimensions do not allow multiplication");return r.map(e=>n[0].map((t,r)=>e.reduce((e,t,o)=>e+t*n[o][r],0)))},M=(e,t)=>{const r=d(e);if(r.length!==r[0].length)throw new Error("Matrix power requires a square matrix");if(!Number.isInteger(t)||t<0)throw new Error("Matrix power requires a non-negative integer exponent");if(0===t)return n=r.length,Array.from({length:n},(e,t)=>Array.from({length:n},(e,r)=>t===r?1:0));var n;let o=r;for(let e=1;e<t;e++)o=x(o,r);return o},A=e=>{if(m(e))return e;if("number"==typeof e)return{re:e,im:0};throw new Error("Complex arithmetic only supports numbers")},$=e=>0===e.im?e.re:e,I=(e,t)=>{const r={};return e.forEach((e,n)=>{r[e]=t[n]}),r};switch(t.type){case"Literal":return t.value;case"ImaginaryLiteral":return{re:0,im:t.value};case"UnitLiteral":return{value:t.value,unit:t.unit};case"Identifier":return i.get(t.name);case"AssignmentExpression":{let e;if("="!==t.operator){const n=i.get(t.left.name),o=h(t.right,r);switch(t.operator.slice(0,-1)){case"+":e=n+o;break;case"-":e=n-o;break;case"*":e=n*o;break;case"/":e=n/o;break;case"%":e=n%o;break;default:throw w(`Unknown compound operator ${t.operator}`)}}else e=h(t.right,r);if("Identifier"===t.left.type)return i.set(t.left.name,e),"ArrayExpression"===t.right.type?n(o(e)):e;if("IndexExpression"===t.left.type&&"Identifier"===t.left.object.type){const r=((e,t,r)=>{const n=g(e)?e.map(e=>[...e]):Array.isArray(e)?[e.slice()]:[],o=t[0],i=t[1];if(!o)throw new Error("Matrix assignment requires at least one index");const a=Math.max(n.length,1),s=v(o,a);if(1===t.length){const e=g(r)?r:d(r);if(e.length!==s.length)throw new Error("Assigned row count does not match slice");return s.forEach((t,r)=>{n[t]=[...e[r]]}),{updatedMatrix:n,selectionResult:1===s.length?[n[s[0]]]:s.map(e=>[n[e]])}}const u=Math.max(...n.map(e=>e.length),0,1),l=v(i,u),c=d(r);if(c.length!==s.length)throw new Error("Assigned row count does not match matrix slice");return c.forEach((e,t)=>{if(e.length!==l.length)throw new Error("Assigned column count does not match matrix slice")}),s.forEach((e,t)=>{n[e]||(n[e]=[]),l.forEach((r,o)=>{n[e][r]=c[t][o]})}),{updatedMatrix:n,selectionResult:1===s.length?[l.map(e=>n[s[0]][e])]:s.map(e=>l.map(t=>n[e][t]))}})(i.get(t.left.object.name),t.left.selectors,e);return i.set(t.left.object.name,r.updatedMatrix),r.selectionResult}throw w("Invalid assignment target")}case"FunctionAssignmentExpression":{if("="!==t.operator)throw w(`Operator ${t.operator} is not supported for function definitions`);const e=(...e)=>{const n=r.withScope(I(t.params,e));return h(t.right,n)};return u.register(t.left.name,e),e}case"UnaryExpression":{const e=h(t.argument,r);switch(t.operator){case"-":return c(e)?e.negated():m(e)?$({re:-e.re,im:-e.im}):-e;case"!":return!e}throw w(`Unknown unary operator ${t.operator}`)}case"BinaryExpression":{const e=h(t.left,r),n=h(t.right,r);if(f(e)||f(n)){if(!p)throw new Error("Unit system not available");return p.compute(t.operator,e,n)}if(y(e)||y(n)||"*"===t.operator&&(Array.isArray(e)||Array.isArray(n)))switch(t.operator){case"+":return((e,t)=>{const r=d(e),n=d(t);if(r.length!==n.length||r[0].length!==n[0].length)throw new Error("Matrix dimensions must match for addition");return r.map((e,t)=>e.map((e,r)=>e+n[t][r]))})(e,n);case"-":return((e,t)=>{const r=d(e),n=d(t);if(r.length!==n.length||r[0].length!==n[0].length)throw new Error("Matrix dimensions must match for subtraction");return r.map((e,t)=>e.map((e,r)=>e-n[t][r]))})(e,n);case"*":return x(e,n);case"^":return M(e,n);default:throw w(`Operator ${t.operator} not supported for matrices`)}if(s(e)||s(n)){const r=s(e)?e:a(e,1),o=s(n)?n:a(n,1);switch(t.operator){case"+":return function(e,t){return a(e.n*t.d+t.n*e.d,e.d*t.d)}(r,o);case"-":return function(e,t){return a(e.n*t.d-t.n*e.d,e.d*t.d)}(r,o);case"*":return function(e,t){return a(e.n*t.n,e.d*t.d)}(r,o);case"/":return function(e,t){return a(e.n*t.d,e.d*t.n)}(r,o);case"^":{const e=function(e,t){return!Number.isInteger(t)||t<0?null:a(e.n**t,e.d**t)}(r,n);if(e)return e;throw w("Fraction power requires non-negative integer exponent")}default:throw w(`Operator ${t.operator} not supported for fractions`)}}if(c(e)||c(n)){const r=c(e)?e:l(e),o=c(n)?n:l(n);switch(t.operator){case"+":return r.plus(o);case"-":return r.minus(o);case"*":return r.times(o);case"/":return r.div(o);case"%":return r.mod(o);case"^":return r.pow(o);case">":return r.gt(o);case"<":return r.lt(o);case">=":return r.gte(o);case"<=":return r.lte(o);case"==":return r.eq(o);default:throw w(`Operator ${t.operator} not supported for BigNumber`)}}if(m(e)||m(n))return((e,t,r)=>{const n=A(t),o=A(r);switch(e){case"+":return $({re:n.re+o.re,im:n.im+o.im});case"-":return $({re:n.re-o.re,im:n.im-o.im});case"*":return $({re:n.re*o.re-n.im*o.im,im:n.re*o.im+n.im*o.re});case"/":{const e=o.re**2+o.im**2;if(0===e)throw new Error("Division by zero");return $({re:(n.re*o.re+n.im*o.im)/e,im:(n.im*o.re-n.re*o.im)/e})}default:throw new Error(`Operator ${e} is not supported for complex numbers`)}})(t.operator,e,n);switch(t.operator){case"+":return e+n;case"-":return e-n;case"*":return e*n;case"/":return e/n;case"%":return e%n;case"^":return e**n;case">":return e>n;case"<":return e<n;case">=":return e>=n;case"<=":return e<=n;case"==":return e===n}throw w(`Unknown operator ${t.operator}`)}case"LogicalExpression":{const e=h(t.left,r);if("&&"===t.operator)return e&&h(t.right,r);if("||"===t.operator)return e||h(t.right,r);if("??"===t.operator)return e??h(t.right,r);throw w(`Unknown logical operator ${t.operator}`)}case"RangeExpression":{const e=h(t.start,r),n=h(t.end,r);if("number"!=typeof e||"number"!=typeof n)throw w("Range requires numeric bounds");const o=[];for(let t=Math.floor(e);t<=Math.floor(n);t++)o.push(t);return o}case"ArrowFunctionExpression":return(...e)=>{const n=r.withScope(I(t.params,e));return h(t.body,n)};case"CallExpression":{const e=t.callee.name,n=u.get(e),o=t.arguments.map(e=>{if("SpreadElement"===e.type){const t=h(e.argument,r);if(!Array.isArray(t))throw new Error("Spread operator requires an array");return{spread:!0,values:t}}return{spread:!1,value:h(e,r)}}),i=[];for(const e of o)e.spread?i.push(...e.values):i.push(e.value);return n(...i)}case"PipelineExpression":{const e=h(t.left,r);if("CallExpression"===t.right.type){const n=t.right.callee.name;return u.get(n)(...[e,...t.right.arguments.map(e=>h(e,r))])}if("Identifier"===t.right.type){return u.get(t.right.name)(e)}throw w("Invalid pipeline target")}case"UnitConversion":{const e=h(t.from,r);if(!f(e))throw w("Left side must be a unit value");if(!p)throw w("Unit system not available");return p.convert(e.value,e.unit,t.to)}case"ArrayExpression":return t.elements.map(e=>h(e,r));case"IndexExpression":return((e,t)=>{const r=d(e);if(1===t.length){const e=v(t[0],r.length).map(e=>{if(e>=r.length)throw new Error("Row index out of range");return[...r[e]]});return 1===e.length?e[0]:e}const n=v(t[0],r.length),o=v(t[1],r[0]?.length||0),i=n.map(e=>{if(e>=r.length)throw new Error("Row index out of range");return o.map(t=>{if(t>=r[e].length)throw new Error("Column index out of range");return r[e][t]})});return 1===n.length&&1===o.length?i[0][0]:1===n.length?i[0]:1===o.length?i.map(e=>[e[0]]):i})(h(t.object,r),t.selectors);case"ObjectExpression":{const e={};for(const n of t.properties)e[n.key]=h(n.value,r);return e}case"MemberExpression":{const e=h(t.object,r);if(t.optional&&null==e)return;return e[t.property.name]}default:throw w(`Unknown AST node type: ${t.type}`)}}function f({variables:e,functions:t,units:r,evaluate:n}){if(!e)throw new Error("Variable store missing");if(!t)throw new Error("Function registry missing");if(!r)throw new Error("Units list missing");if(!n)throw new Error("evaluate function missing");return{variables:e,functions:t,units:r,evaluate:n,withScope(o={}){const i={...e.all?.(),...o};return f({functions:t,evaluate:n,units:r,variables:{get:e=>i[e],set:(e,t)=>i[e]=t,all:()=>i}})}}}const m=(e,t)=>typeof e==typeof t&&("number"==typeof e||"bigint"==typeof e),g=Object.freeze({power:function(e,t){if(m(e,t))return e**t;throw new Error("Invalid types for ^")},multiply:function(e,t){if(m(e,t))return e*t;throw new Error("Invalid types for *")},divide:function(e,t){if(m(e,t)){if(0===t)throw new Error("Division by zero");return e/t}throw new Error("Invalid types for /")},add:function(e,t){if(m(e,t))return e+t;if("string"==typeof e&&"string"==typeof t)return e+t;throw new Error("Invalid types for +")},subtract:function(e,t){if(m(e,t))return e-t;throw new Error("Invalid types for -")},modulus:function(e,t){if(m(e,t))return e%t;throw new Error("Invalid types for %")}});const y={length:{m:{value:1,unit:"meter",symbol:"m"},cm:{value:.01,unit:"centimeter",symbol:"cm"},mm:{value:.001,unit:"millimeter",symbol:"mm"},km:{value:1e3,unit:"kilometer",symbol:"km"},um:{value:1e-6,unit:"micrometer",symbol:"um",note:"also called micron"},nm:{value:1e-9,unit:"nanometer",symbol:"nm"},px:{value:264583e-9,unit:"pixel",symbol:"px",note:"96dpi standard"},em:{value:.004233328,unit:"em",symbol:"em",note:"1em = 16px by default"},rem:{value:.004233328,unit:"rem",symbol:"rem",note:"root em = 16px by default"},pt:{value:352778e-9,unit:"point",symbol:"pt",note:"1pt = 1/72 inch"},pica:{value:.00423333,unit:"pica",symbol:"pc",note:"1pc = 12pt"},inch:{value:.0254,unit:"inch",symbol:"in"},ft:{value:.3048,unit:"foot",symbol:"ft"},yd:{value:.9144,unit:"yard",symbol:"yd"},mi:{value:1609.344,unit:"mile",symbol:"mi"},thou:{value:254e-7,unit:"mil",symbol:"thou",note:"thousandth of an inch"},furlong:{value:201.168,unit:"furlong",symbol:"fur",note:"220 yards"},nmi:{value:1852,unit:"nautical mile",symbol:"nmi"},fathom:{value:1.8288,unit:"fathom",symbol:"fathom"},au:{value:1496e8,unit:"astronomical unit",symbol:"AU"},ly:{value:94607e11,unit:"light year",symbol:"ly"},pc:{value:30857e12,unit:"parsec",symbol:"pc"}},weight:{mg:{value:1e-6,unit:"milligram",symbol:"mg"},g:{value:.001,unit:"gram",symbol:"g"},kg:{value:1,unit:"kilogram",symbol:"kg"},t:{value:1e3,unit:"tonne",symbol:"t",note:"metric ton"},lb:{value:.453592,unit:"pound",symbol:"lb"},oz:{value:.0283495,unit:"ounce",symbol:"oz"},stone:{value:6.35029,unit:"stone",symbol:"st",note:"1 stone = 14 lb"}},time:{s:{value:1,unit:"second",symbol:"s"},min:{value:60,unit:"minute",symbol:"min"},h:{value:3600,unit:"hour",symbol:"h"},day:{value:86400,unit:"day",symbol:"d"},week:{value:604800,unit:"week",symbol:"wk"},month:{value:2629800,unit:"month",symbol:"mo",note:"average month = 30.44 days"},year:{value:31557600,unit:"year",symbol:"yr",note:"average year = 365.25 days"}},voltage:{V:{value:1,unit:"volt",symbol:"V"},mV:{value:.001,unit:"millivolt",symbol:"mV"},kV:{value:1e3,unit:"kilovolt",symbol:"kV"},MV:{value:1e6,unit:"megavolt",symbol:"MV"},GV:{value:1e9,unit:"gigavolt",symbol:"GV"},statV:{value:299.792458,unit:"statvolt",symbol:"statV",note:"CGS unit"},abV:{value:1e-8,unit:"abvolt",symbol:"abV",note:"CGS electromagnetic unit"}},frequency:{Hz:{value:1,unit:"hertz",symbol:"Hz",note:"1 cycle per second"},kHz:{value:1e3,unit:"kilohertz",symbol:"kHz"},MHz:{value:1e6,unit:"megahertz",symbol:"MHz"},GHz:{value:1e9,unit:"gigahertz",symbol:"GHz"},THz:{value:1e12,unit:"terahertz",symbol:"THz"}},power:{W:{value:1,unit:"watt",symbol:"W",note:"1 joule per second"},mW:{value:.001,unit:"milliwatt",symbol:"mW"},kW:{value:1e3,unit:"kilowatt",symbol:"kW"},MW:{value:1e6,unit:"megawatt",symbol:"MW"},GW:{value:1e9,unit:"gigawatt",symbol:"GW"},HP:{value:745.7,unit:"horsepower",symbol:"HP",note:"mechanical HP = 745.7 W"},"kcal/h":{value:1.163,unit:"kilocalorie per hour",symbol:"kcal/h",note:"= 1.163 W"},"BTU/h":{value:.29307107,unit:"BTU per hour",symbol:"BTU/h",note:"= 0.293 W"}},sound:{dB:{value:1,unit:"decibel",symbol:"dB",note:"logarithmic unit of sound intensity"},dBA:{value:1,unit:"A-weighted decibel",symbol:"dBA",note:"Adjusted for human hearing"},dBC:{value:1,unit:"C-weighted decibel",symbol:"dBC",note:"Flat weighting for high-level sounds"}},temperature:{K:{value:1,unit:"kelvin",symbol:"K"},C:{value:1,unit:"Celsius",symbol:"°C",note:"°C → K: add 273.15"},F:{value:1,unit:"Fahrenheit",symbol:"°F",note:"°F → K: (°F - 32) * 5/9 + 273.15"}},pressure:{Pa:{value:1,unit:"pascal",symbol:"Pa"},kPa:{value:1e3,unit:"kilopascal",symbol:"kPa"},MPa:{value:1e6,unit:"megapascal",symbol:"MPa"},bar:{value:1e5,unit:"bar",symbol:"bar"},atm:{value:101325,unit:"atmosphere",symbol:"atm"},psi:{value:6894.757,unit:"pound per square inch",symbol:"psi"},mmHg:{value:133.322,unit:"millimeter of mercury",symbol:"mmHg"}},energy:{J:{value:1,unit:"joule",symbol:"J"},kJ:{value:1e3,unit:"kilojoule",symbol:"kJ"},cal:{value:4.184,unit:"calorie",symbol:"cal"},kcal:{value:4184,unit:"kilocalorie",symbol:"kcal"},eV:{value:160218e-24,unit:"electronvolt",symbol:"eV"},BTU:{value:1055.06,unit:"BTU",symbol:"BTU"}},force:{N:{value:1,unit:"newton",symbol:"N"},kN:{value:1e3,unit:"kilonewton",symbol:"kN"},lbf:{value:4.44822,unit:"pound-force",symbol:"lbf"},kgf:{value:9.80665,unit:"kilogram-force",symbol:"kgf"},dyne:{value:1e-5,unit:"dyne",symbol:"dyn"}},area:{m2:{value:1,unit:"square meter",symbol:"m²"},cm2:{value:1e-4,unit:"square centimeter",symbol:"cm²"},km2:{value:1e6,unit:"square kilometer",symbol:"km²"},acre:{value:4046.856,unit:"acre",symbol:"acre"},hectare:{value:1e4,unit:"hectare",symbol:"ha"},ft2:{value:.092903,unit:"square foot",symbol:"ft²"},yd2:{value:.836127,unit:"square yard",symbol:"yd²"}},volume:{m3:{value:1,unit:"cubic meter",symbol:"m³"},L:{value:.001,unit:"liter",symbol:"L"},mL:{value:1e-6,unit:"milliliter",symbol:"mL"},gallon:{value:.00378541,unit:"US gallon",symbol:"gal"},pint:{value:473176e-9,unit:"US pint",symbol:"pt"},floz:{value:29574e-9,unit:"US fluid ounce",symbol:"fl oz"}},current:{A:{value:1,unit:"ampere",symbol:"A"},mA:{value:.001,unit:"milliampere",symbol:"mA"},uA:{value:1e-6,unit:"microampere",symbol:"uA"},kA:{value:1e3,unit:"kiloampere",symbol:"kA"}},resistance:{ohm:{value:1,unit:"ohm"},kohm:{value:1e3,unit:"kiloohm"},megaohm:{value:1e6,unit:"megaohm"},S:{value:1,unit:"siemens",symbol:"S",note:"conductance"}},capacitance:{F:{value:1,unit:"farad",symbol:"F"},mF:{value:.001,unit:"millifarad"},uF:{value:1e-6,unit:"microfarad"}},inductance:{H:{value:1,unit:"henry",symbol:"H"},mH:{value:.001,unit:"millihenry",symbol:"mH"},uH:{value:1e-6,unit:"microhenry",symbol:"uH"}},light:{cd:{value:1,unit:"candela",symbol:"cd"},lm:{value:1,unit:"lumen",symbol:"lm"},lx:{value:1,unit:"lux",symbol:"lx"}},data:{bit:{value:1,unit:"bit",symbol:"bit"},B:{value:8,unit:"byte",symbol:"B"},KB:{value:8e3,unit:"kilobyte",symbol:"KB"},MB:{value:8e6,unit:"megabyte",symbol:"MB"},GB:{value:8e9,unit:"gigabyte",symbol:"GB"},TB:{value:8e12,unit:"terabyte",symbol:"TB"}},angle:{deg:{value:1,unit:"degree",symbol:"°"},rad:{value:57.2958,unit:"radian",symbol:"rad",note:"1 rad = 57.2958°"},grad:{value:.9,unit:"grad",symbol:"grad",note:"1 grad = 0.9°"}},radiation:{Gy:{value:1,unit:"gray",symbol:"Gy",note:"Absorbed dose: 1 Gy = 1 J/kg"},mGy:{value:.001,unit:"milligray",symbol:"mGy"},rad:{value:.01,unit:"rad",symbol:"rad",note:"1 rad = 0.01 Gy"},Sv:{value:1,unit:"sievert",symbol:"Sv",note:"Biological effect dose equivalent"},mSv:{value:.001,unit:"millisievert",symbol:"mSv"},rem:{value:.01,unit:"rem",symbol:"rem",note:"1 rem = 0.01 Sv"},Bq:{value:1,unit:"becquerel",symbol:"Bq",note:"1 decay per second"},kBq:{value:1e3,unit:"kilobecquerel",symbol:"kBq"},MBq:{value:1e6,unit:"megabecquerel",symbol:"MBq"},GBq:{value:1e9,unit:"gigabecquerel",symbol:"GBq"},Ci:{value:37e9,unit:"curie",symbol:"Ci",note:"1 Ci = 3.7 x 10¹⁰ decays per second"},mCi:{value:37e6,unit:"millicurie",symbol:"mCi"}}},d=/^[a-zA-Z_$][a-zA-Z0-9_$]*$/;function w(e={}){let t=Object.create(null);for(const r in e)t[r]=e[r];return{set(e,r,{override:n=!0}={}){if("string"!=typeof e||!e)throw new Error("Variable name must be a non-empty string");if(!d.test(e))throw new Error(`Variable Name Error: '${e}' is not a valid variable name`);if(void 0===r)throw new Error(`Variable Value Error: '${e}' cannot be undefined`);if(!n&&e in t)throw new Error(`Variable '${e}' already exists`);t[e]=r},get:e=>t[e],has:e=>Object.prototype.hasOwnProperty.call(t,e),remove(e){delete t[e]},all:()=>({...t}),clear(){t=Object.create(null)},merge(e={}){for(const r in e)t[r]=e[r]},clone:()=>w(t)}}function b(e={}){const t=Object.create(null);for(const r in e)"function"==typeof e[r]&&(t[r]=e[r]);return{getAllFunctionsName:()=>Object.keys(t),register(e,r){if("string"!=typeof e||!e)throw new Error("Formula name must be a non-empty string");if("function"!=typeof r)throw new Error(`Formula "${e}" must be callable`);t[e]=r},get:e=>t[e],has:e=>Object.prototype.hasOwnProperty.call(t,e),remove(e){delete t[e]},all:()=>({...t}),clear(){for(const e in t)delete t[e]},extend(e={}){for(const r in e)"function"==typeof e[r]&&(t[r]=e[r])},clone:()=>b(t)}}function v(e){if(e=o(e),!Array.isArray(e)||0===e.length)throw new Error("det() expects a non-empty matrix");if(!e.every(Array.isArray))throw new Error("det() expects a 2D matrix");const t=e.length;if(!e.every(e=>e.length===t))throw new Error("det() expects a square matrix");for(const t of e)for(const e of t)if("number"!=typeof e&&"bigint"!=typeof e)throw new Error("det() matrix values must be numeric")}function E(e){return v(e=o(e)),1===e.length?e[0][0]:2===e.length?e[0][0]*e[1][1]-e[0][1]*e[1][0]:e[0].reduce((t,r,n)=>{const o=e.slice(1).map(e=>e.filter((e,t)=>t!==n));return t+(n%2==0?r:-r)*E(o)},0)}function x(e){const t=o(e);if(!Array.isArray(t))throw new Error("Expected matrix data");return t}function M(e){const t=x(e).map(e=>[...e]);v(t);const r=t.length,o=Array.from({length:r},(e,t)=>t);for(let e=0;e<r;e++){let n=e,i=Math.abs(t[e][e]);for(let o=e+1;o<r;o++){const r=Math.abs(t[o][e]);r>i&&(i=r,n=o)}if(0===i)throw new Error("Matrix is singular");n!==e&&([t[e],t[n]]=[t[n],t[e]],[o[e],o[n]]=[o[n],o[e]]);for(let n=e+1;n<r;n++){t[n][e]/=t[e][e];for(let o=e+1;o<r;o++)t[n][o]-=t[n][e]*t[e][o]}}const i=t.map((e,t)=>e.map((e,r)=>t===r?1:t>r?e:0)),a=t.map((e,t)=>e.map((e,r)=>t<=r?e:0));return{L:n(i),U:n(a),p:o}}function A(e,t){const{L:r,U:o,p:i}=M(e),a=x(e),s=x(t),u=Array.isArray(s[0])?s.map(e=>e[0]):s;if(a.length!==u.length)throw new Error("Right-hand side dimension mismatch");const l=i.map(e=>u[e]),c=new Array(a.length).fill(0);for(let e=0;e<a.length;e++){c[e]=l[e];for(let t=0;t<e;t++)c[e]-=r.data[e][t]*c[t]}const p=new Array(a.length).fill(0);for(let e=a.length-1;e>=0;e--){p[e]=c[e];for(let t=e+1;t<a.length;t++)p[e]-=o.data[e][t]*p[t];p[e]/=o.data[e][e]}return n(p.map(e=>[e]))}function $(e,t){const r=x(e).map(e=>[...e]),o=x(t).map(e=>[...e]);v(r),v(o);const i=r.length;if(o.length!==i)throw new Error("A and Q must have the same dimensions");const a=[],s=[];for(let e=0;e<i;e++)for(let t=0;t<i;t++){const n=new Array(i*i).fill(0);for(let o=0;o<i;o++)n[o*i+t]+=r[e][o],n[e*i+o]+=r[t][o];a.push(n),s.push(-o[e][t])}const u=function(e,t){const r=e.length,n=e.map((e,r)=>[...e,t[r]]);for(let e=0;e<r;e++){let t=e,o=Math.abs(n[e][e]);for(let i=e+1;i<r;i++){const r=Math.abs(n[i][e]);r>o&&(o=r,t=i)}if(0===o)throw new Error("Linear system is singular");t!==e&&([n[e],n[t]]=[n[t],n[e]]);const i=n[e][e];for(let t=e;t<=r;t++)n[e][t]/=i;for(let t=0;t<r;t++){if(t===e)continue;const o=n[t][e];for(let i=e;i<=r;i++)n[t][i]-=o*n[e][i]}}return n.map(e=>e[r])}(a,s),l=[];for(let e=0;e<i;e++)l.push(u.slice(e*i,(e+1)*i));return n(l)}function I(e,t){return e.reduce((e,r,n)=>e+r*t**n,0)}function k(e,t){const r=[...e].reverse(),n=[r[0]];for(let e=1;e<r.length-1;e++)n.push(r[e]+n[e-1]*t);const o=r[r.length-1]+n[n.length-1]*t;return{quotient:n.reverse(),remainder:o}}function q(e){const[t,r,n]=e,o=r**2-4*n*t;if(o<0)throw new Error("Only real roots are supported");const i=Math.sqrt(o);return[(-r+i)/(2*n),(-r-i)/(2*n)]}function N(e,t){return e.reduce((e,r,n)=>e+r*t[n],0)}function O(e){return Math.sqrt(N(e,e))}function z(e,t){return e.map(e=>e*t)}function B(e,t){return e.map((e,r)=>e-t[r])}function C(e){return e[0].map((t,r)=>e.map(e=>e[r]))}function U(e,t){const r=function(e){const t=e.replace(/\s+/g,"");return t?t.replace(/-/g,"+-").split("+").filter(Boolean):[]}(e),n=new Map;for(const e of r)if(e.includes(t)){const[r,o]=e.split(t);let i;if(""===r||"+"===r)i=1;else if("-"===r)i=-1;else{const e=r.endsWith("*")?r.slice(0,-1):r;i=Number(e)}if(!Number.isFinite(i))throw new Error("Unsupported algebra term");let a=1;if(o){if(!o.startsWith("^"))throw new Error("Unsupported algebra term");a=Number(o.slice(1))}if(!Number.isInteger(a)||a<0)throw new Error("Only non-negative integer powers are supported");n.set(a,(n.get(a)||0)+i)}else{const t=Number(e);if(!Number.isFinite(t))throw new Error("Unsupported algebra term");n.set(0,(n.get(0)||0)+t)}return n}function j(e,t){const r=[...e.entries()].filter(([,e])=>0!==e).sort((e,t)=>t[0]-e[0]);return r.length?r.map(([e,r],n)=>{const o=r<0,i=Math.abs(r);let a;return a=0===e?`${i}`:1===e?1===i?t:`${i} * ${t}`:1===i?`${t}^${e}`:`${i} * ${t}^${e}`,0===n?o?`-${a}`:a:o?`- ${a}`:`+ ${a}`}).join(" "):"0"}function S(e,t){for(e=Math.abs(e),t=Math.abs(t);t;)[e,t]=[t,e%t];return e}function F(e){if(0===e)throw new Error("gamma(0) is undefined");if(Number.isInteger(e)&&e<0)throw new Error("gamma() undefined for negative integers");if(Number.isInteger(e)&&e>0){let t=1;for(let r=2;r<e;r++)t*=r;return t}const t=[.9999999999998099,676.5203681218851,-1259.1392167224028,771.3234287776531,-176.6150291621406,12.507343278686905,-.13857109526572012,9984369578019572e-21,1.5056327351493116e-7];if(e<.5)return Math.PI/(Math.sin(Math.PI*e)*F(1-e));e-=1;let r=t[0];for(let n=1;n<9;n++)r+=t[n]/(e+n);const n=e+7+.5;return Math.sqrt(2*Math.PI)*n**(e+.5)*Math.exp(-n)*r}function P(e){return Array.from({length:e},(t,r)=>Array.from({length:e},(e,t)=>r===t?1:0))}function _(e){const t=o(e).map(e=>[...e]);let r=0;const i=t.length,a=t[0].length;for(let e=0;e<i&&!(r>=a);e++){let n=e;for(;Math.abs(t[n][r])<1e-12&&(n++,!(n===i&&(n=e,r++,r>=a))););if(r>=a)break;[t[e],t[n]]=[t[n],t[e]];const o=t[e][r];for(let r=0;r<a;r++)t[e][r]/=o;for(let n=0;n<i;n++)if(n!==e){const o=t[n][r];for(let r=0;r<a;r++)t[n][r]-=o*t[e][r]}r++}return n(t)}function L(e){const t=o(e);v(e);const[[r,i],[a,s]]=t,u=r+s,l=u*u-4*(r*s-i*a);if(l<0)throw new Error("Complex eigenvalues not supported");const c=Math.sqrt(l),p=(u+c)/2,h=(u-c)/2,f=e=>Math.abs(i)>1e-12?[1,(e-r)/i]:Math.abs(a)>1e-12?[(e-s)/a,1]:[1,0],m=f(p),g=Math.sqrt(m[0]*m[0]+m[1]*m[1]),y=f(h),d=Math.sqrt(y[0]*y[0]+y[1]*y[1]);return{values:[p,h],vectors:n([[m[0]/g,y[0]/d],[m[1]/g,y[1]/d]])}}const V={fraction:(e,t)=>a(e,t),numer:e=>function(e){if(!s(e))throw new Error("numer() expects a fraction");return e.n}(e),denom:e=>function(e){if(!s(e))throw new Error("denom() expects a fraction");return e.d}(e),isFraction:e=>s(e),bignumber:e=>l(e),isBigNumber:e=>c(e),max:(...e)=>{if(!e.length)throw new Error("max() requires arguments");return Math.max(...e)},min:(...e)=>{if(!e.length)throw new Error("min() requires arguments");return Math.min(...e)},abs:e=>Math.abs(e),round:e=>Math.round(e),floor:e=>Math.floor(e),ceil:e=>Math.ceil(e),sqrt:e=>{if(e<0)throw new Error("sqrt() domain error");return Math.sqrt(e)},pow:(e,t)=>e**t,det:e=>E(e),polynomialRoot:(...e)=>function(...e){for(;e.length>1&&0===e[e.length-1];)e.pop();const t=e.length-1;if(t<1)throw new Error("polynomialRoot() expects at least a linear polynomial");if(1===t){const[t,r]=e;return[-t/r]}if(2===t)return q(e);if(3===t){const t=e[0],r=[],n=Math.abs(t);for(let e=1;e<=Math.max(1,n);e++)n%e===0&&r.push(e,-e);for(const t of r)if(0===I(e,t))return[t,...q(k(e,t).quotient)]}throw new Error("polynomialRoot() currently supports degree up to 3")}(...e),lsolve:(e,t)=>A(e,t),lup:e=>M(e),lyap:(e,t)=>$(e,t),qr:e=>function(e){const t=x(e).map(e=>[...e]);if(!t.length||!t.every(e=>e.length===t[0].length))throw new Error("qr() expects a rectangular matrix");const r=t.length,o=t[0].length,i=C(t),a=[];for(let e=0;e<o;e++){let t=[...i[e]];for(let r=0;r<a.length;r++){const n=N(a[r],i[e]);t=B(t,z(a[r],n))}const r=O(t);if(0===r)throw new Error("qr() requires linearly independent columns");a.push(z(t,1/r))}for(let e=0;a.length<r&&e<r;e++){let t=Array.from({length:r},(t,r)=>r===e?1:0);for(const e of a)t=B(t,z(e,N(e,t)));const n=O(t);n>1e-10&&a.push(z(t,1/n))}const s=Array.from({length:r},(e,t)=>a.map(e=>e[t])),u=Array.from({length:r},()=>Array(o).fill(0));for(let e=0;e<r;e++)for(let t=0;t<o;t++)u[e][t]=N(a[e],i[t]);return{Q:n(s),R:n(u)}}(e),transpose:e=>n(C(o(e))),inverse:e=>function(e){const t=o(e);v(e);const r=t.length;if(2===r){const e=t[0][0]*t[1][1]-t[0][1]*t[1][0];if(0===e)throw new Error("Matrix is singular");return n([[t[1][1]/e,-t[0][1]/e],[-t[1][0]/e,t[0][0]/e]])}const i=Array.from({length:r},()=>Array(r).fill(0));for(let e=0;e<r;e++){const a=Array.from({length:r},(t,r)=>r===e?1:0),s=A(t,n(a.map(e=>[e]))),u=o(s);for(let t=0;t<r;t++)i[t][e]=u[t][0]}return n(i)}(e),trace:e=>{const t=o(e);return v(e),t.reduce((e,t,r)=>e+t[r],0)},rank:e=>o(_(e)).filter(e=>e.some(e=>Math.abs(e)>1e-10)).length,rref:e=>_(e),minor:(e,t,r)=>{const n=o(e);v(e);return E(n.filter((e,r)=>r!==t).map(e=>e.filter((e,t)=>t!==r)))},cofactor:(e,t,r)=>{const n=o(e).filter((e,r)=>r!==t).map(e=>e.filter((e,t)=>t!==r));return((t+r)%2==0?1:-1)*E(n)},cross:(e,t)=>{const r=o(e),n=o(t);if(!Array.isArray(r)||!Array.isArray(n)||3!==r.length||3!==n.length)throw new Error("cross() requires two 3D vectors");return function(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}(r,n)},normalize:e=>{const t=o(e);if(!Array.isArray(t))throw new Error("normalize() expects a vector");const r=O(t);if(0===r)throw new Error("Cannot normalize zero vector");return z(t,1/r)},angle:(e,t)=>{const r=o(e),n=o(t);if(!Array.isArray(r)||!Array.isArray(n))throw new Error("angle() expects vectors");const i=N(r,n),a=O(r)*O(n);if(0===a)throw new Error("Zero vector angle is undefined");return Math.acos(Math.max(-1,Math.min(1,i/a)))},projection:(e,t)=>{const r=o(e),n=o(t);if(!Array.isArray(r)||!Array.isArray(n))throw new Error("projection() expects vectors");const i=N(r,n),a=O(n);if(0===a)throw new Error("Zero vector projection undefined");return i/a},identity:e=>n(P(e)),eye:e=>n(P(e)),zeros:(e,t)=>(void 0===t&&(t=e),n(Array.from({length:e},()=>Array(t).fill(0)))),ones:(e,t)=>(void 0===t&&(t=e),n(Array.from({length:e},()=>Array(t).fill(1)))),diag:e=>{const t=o(e);if(!Array.isArray(t))throw new Error("diag() expects an array");return n(Array.from({length:t.length},(e,r)=>Array.from({length:t.length},(e,n)=>r===n?t[r]:0)))},cholesky:e=>function(e){const t=o(e);v(e);const r=t.length,i=Array.from({length:r},()=>Array(r).fill(0));for(let e=0;e<r;e++){let n=0;for(let t=0;t<e;t++)n+=i[e][t]*i[e][t];const o=t[e][e]-n;if(o<=0)throw new Error("Matrix is not positive definite");i[e][e]=Math.sqrt(o);for(let o=e+1;o<r;o++){n=0;for(let t=0;t<e;t++)n+=i[o][t]*i[e][t];i[o][e]=(t[o][e]-n)/i[e][e]}}return n(i)}(e),eig:e=>L(e),svd:e=>function(e){const t=o(e),r=t.length,i=t[0].length;if(2!==r||2!==i)throw new Error("svd() currently supports 2x2 matrices only");const a=[[t[0][0]*t[0][0]+t[1][0]*t[1][0],t[0][0]*t[0][1]+t[1][0]*t[1][1]],[t[0][1]*t[0][0]+t[1][1]*t[1][0],t[0][1]*t[0][1]+t[1][1]*t[1][1]]],s=L(n(a)),u=[Math.sqrt(Math.max(0,s.values[0])),Math.sqrt(Math.max(0,s.values[1]))],l=o(s.vectors),c=[[(t[0][0]*l[0][0]+t[0][1]*l[1][0])/(u[0]||1),(t[0][0]*l[0][1]+t[0][1]*l[1][1])/(u[1]||1)],[(t[1][0]*l[0][0]+t[1][1]*l[1][0])/(u[0]||1),(t[1][0]*l[0][1]+t[1][1]*l[1][1])/(u[1]||1)]];return{U:n(c),S:n([[u[0],0],[0,u[1]]]),V:n(l)}}(e),simplify:e=>{if("string"!=typeof e)throw new Error("simplify() expects an expression string");return function(e){const t=e.replace(/\s+/g,"").match(/[a-zA-Z]+/),r=t?.[0]||"x";return j(U(e,r),r)}(e)},derivative:(e,t="x")=>{if("string"!=typeof e||"string"!=typeof t)throw new Error("derivative() expects expression and variable strings");return function(e,t){const r=U(e,t),n=new Map;for(const[e,t]of r.entries())0!==e&&n.set(e-1,(n.get(e-1)||0)+t*e);return j(n,t)}(e,t)},sin:e=>Math.sin(e),cos:e=>Math.cos(e),tan:e=>Math.tan(e),sind:e=>Math.sin(e*Math.PI/180),cosd:e=>Math.cos(e*Math.PI/180),tand:e=>Math.tan(e*Math.PI/180),asind:e=>180*Math.asin(e)/Math.PI,acosd:e=>180*Math.acos(e)/Math.PI,atand:e=>180*Math.atan(e)/Math.PI,atand2:(e,t)=>180*Math.atan2(e,t)/Math.PI,asin:e=>Math.asin(e),acos:e=>Math.acos(e),atan:e=>Math.atan(e),log:e=>{if(e<=0)throw new Error("log() domain error");return Math.log(e)},log10:e=>{if(e<=0)throw new Error("log10() domain error");return Math.log10(e)},exp:e=>Math.exp(e),random:()=>Math.random(),and:(e,t)=>Boolean(e&&t),or:(e,t)=>Boolean(e||t),not:e=>!e,"!":e=>!e,eq:(e,t)=>e===t,neq:(e,t)=>e!==t,notEqual:(e,t)=>e!==t,gt:(e,t)=>e>t,greaterThan:(e,t)=>e>t,lt:(e,t)=>e<t,lessThan:(e,t)=>e<t,gte:(e,t)=>e>=t,greaterThanOrEqual:(e,t)=>e>=t,lte:(e,t)=>e<=t,lessThanOrEqual:(e,t)=>e<=t,clamp:(e,t,r)=>{if(t>r)throw new Error("clamp(): min > max");return Math.min(Math.max(e,t),r)},if:(e,t,r)=>e?t:r,typeof:e=>typeof e,length:e=>{if("string"==typeof e||Array.isArray(e))return e.length;throw new Error("length() expects string or array")},sum:(...e)=>{if(!e.length)throw new Error("sum() requires at least one argument");return e.reduce((e,t)=>e+t,0)},prod:(...e)=>{if(!e.length)throw new Error("prod() requires at least one argument");return e.reduce((e,t)=>e*t,1)},mean:(...e)=>{if(!e.length)throw new Error("mean() requires at least one argument");return e.reduce((e,t)=>e+t,0)/e.length},median:(...e)=>{if(!e.length)throw new Error("median() requires at least one argument");const t=[...e].sort((e,t)=>e-t),r=Math.floor(t.length/2);return t.length%2?t[r]:(t[r-1]+t[r])/2},mode:(...e)=>{if(!e.length)throw new Error("mode() requires at least one argument");const t=new Map;e.forEach(e=>t.set(e,(t.get(e)||0)+1));let r=0,n=e[0];for(const[e,o]of t)o>r&&(r=o,n=e);return n},std:(...e)=>{if(e.length<2)throw new Error("std() requires at least two values");const t=e.reduce((e,t)=>e+t,0)/e.length;return Math.sqrt(e.reduce((e,r)=>e+(r-t)**2,0)/(e.length-1))},variance:(...e)=>{if(e.length<2)throw new Error("variance() requires at least two values");const t=e.reduce((e,t)=>e+t,0)/e.length;return e.reduce((e,r)=>e+(r-t)**2,0)/(e.length-1)},range:(...e)=>{if(!e.length)throw new Error("range() requires at least one argument");return Math.max(...e)-Math.min(...e)},gcd:(e,t)=>S(e,t),lcm:(e,t)=>0===e||0===t?0:Math.abs(e/S(e,t)*t),factorial:e=>{if(!Number.isInteger(e)||e<0)throw new Error("factorial() requires a non-negative integer");if(0===e||1===e)return 1;let t=1;for(let r=2;r<=e;r++)t*=r;return t},isPrime:e=>{if(!Number.isInteger(e)||e<2)return!1;if(2===e)return!0;if(e%2==0)return!1;for(let t=3;t*t<=e;t+=2)if(e%t===0)return!1;return!0},primeFactors:e=>{if(!Number.isInteger(e)||e<2)throw new Error("primeFactors() requires an integer >= 2");const t=[];let r=e;for(let e=2;e*e<=r;e++)for(;r%e===0;)t.push(e),r/=e;return r>1&&t.push(r),t},fibonacci:e=>{if(!Number.isInteger(e)||e<0)throw new Error("fibonacci() requires a non-negative integer");if(e<=1)return e;let t=0,r=1;for(let n=2;n<=e;n++){const e=t+r;t=r,r=e}return r},nCr:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t)||e<0||t<0)throw new Error("nCr() requires non-negative integers");if(t>e)return 0;if(0===t||t===e)return 1;t=Math.min(t,e-t);let r=1;for(let n=1;n<=t;n++)r=r*(e-t+n)/n;return r},nPr:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t)||e<0||t<0)throw new Error("nPr() requires non-negative integers");if(t>e)return 0;let r=1;for(let n=0;n<t;n++)r*=e-n;return r},gamma:e=>F(e),sinh:e=>Math.sinh(e),cosh:e=>Math.cosh(e),tanh:e=>Math.tanh(e),asinh:e=>Math.asinh(e),acosh:e=>Math.acosh(e),atanh:e=>Math.atanh(e),sec:e=>{const t=Math.cos(e);if(Math.abs(t)<1e-15)throw new Error("sec() undefined for this input");return 1/t},csc:e=>{const t=Math.sin(e);if(Math.abs(t)<1e-15)throw new Error("csc() undefined for this input");return 1/t},cot:e=>{const t=Math.sin(e);if(Math.abs(t)<1e-15)throw new Error("cot() undefined for this input");return Math.cos(e)/t},trunc:e=>Math.trunc(e),sign:e=>Math.sign(e),frac:e=>e-Math.trunc(e),split:(e,t)=>{if("string"!=typeof e)throw new Error("split() expects a string");return e.split(t)},join:(e,t)=>{if(!Array.isArray(e))throw new Error("join() expects an array");return e.join(t)},upper:e=>{if("string"!=typeof e)throw new Error("upper() expects a string");return e.toUpperCase()},lower:e=>{if("string"!=typeof e)throw new Error("lower() expects a string");return e.toLowerCase()},trim:e=>{if("string"!=typeof e)throw new Error("trim() expects a string");return e.trim()},replace:(e,t,r)=>{if("string"!=typeof e)throw new Error("replace() expects a string");return e.replace(t,r)},substring:(e,t,r)=>{if("string"!=typeof e)throw new Error("substring() expects a string");return e.substring(t,r)},acot:e=>0===e?Math.PI/2:Math.atan(1/e),asec:e=>{if(e<1&&e>-1)throw new Error("asec() domain error");return Math.acos(1/e)},acsc:e=>{if(e<1&&e>-1)throw new Error("acsc() domain error");return Math.asin(1/e)},acoth:e=>{if(Math.abs(e)<=1)throw new Error("acoth() domain error");return Math.atanh(1/e)},asech:e=>{if(e<=0||e>1)throw new Error("asech() domain error");return Math.acosh(1/e)},acsch:e=>{if(0===e)throw new Error("acsch() domain error");return Math.asinh(1/e)},quantile:(e,t)=>{if(!Array.isArray(e)||0===e.length)throw new Error("quantile() expects a non-empty array");if(t<0||t>1)throw new Error("quantile() p must be between 0 and 1");const r=[...e].sort((e,t)=>e-t),n=t*(r.length-1),o=Math.floor(n),i=Math.ceil(n);return o===i?r[o]:r[o]+(n-o)*(r[i]-r[o])},percentile:(e,t)=>{if(t<0||t>100)throw new Error("percentile() p must be between 0 and 100");return V.quantile(e,t/100)},covariance:(e,t)=>{if(!Array.isArray(e)||!Array.isArray(t)||e.length<2||e.length!==t.length)throw new Error("covariance() expects two arrays of equal length >= 2");const r=e.reduce((e,t)=>e+t,0)/e.length,n=t.reduce((e,t)=>e+t,0)/t.length;return e.reduce((e,o,i)=>e+(o-r)*(t[i]-n),0)/(e.length-1)},corr:(e,t)=>{const r=V.covariance(e,t),n=Math.sqrt(V.covariance(e,e)),o=Math.sqrt(V.covariance(t,t));if(0===n||0===o)throw new Error("corr() zero variance");return r/(n*o)},randomInt:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t))throw new Error("randomInt() expects integers");return Math.floor(Math.random()*(t-e+1))+e},randomNormal:(e,t)=>{if(t<=0)throw new Error("randomNormal() std must be > 0");let r=0,n=0;for(;0===r;)r=Math.random();for(;0===n;)n=Math.random();return e+t*Math.sqrt(-2*Math.log(r))*Math.cos(2*Math.PI*n)},erf:e=>{if(0===e)return 0;const t=1/(1+.3275911*Math.abs(e)),r=[.254829592,-.284496736,1.421413741,-1.453152027,1.061405429];let n=r[4]*t+r[3];n=n*t+r[2],n=n*t+r[1],n=n*t+r[0],n*=t;const o=1-n*Math.exp(-e*e);return e>=0?o:-o},lgamma:e=>{if(e<=0)throw new Error("lgamma() domain error (x > 0 required)");if(e<12){let t=e,r=0;for(;t<12;)r-=Math.log(t),t+=1;return r+V.lgamma(t)}const t=1/e,r=(1/12-t*t/360+t*t*t*t/1260)*t;return(e-.5)*Math.log(e)-e+.9189385332046727+r},beta:(e,t)=>{if(e<=0||t<=0)throw new Error("beta() domain error");return Math.exp(V.lgamma(e)+V.lgamma(t)-V.lgamma(e+t))},hypot:(...e)=>Math.hypot(...e),cbrt:e=>Math.cbrt(e),log2:e=>{if(e<=0)throw new Error("log2() domain error");return Math.log2(e)},log1p:e=>{if(e<=-1)throw new Error("log1p() domain error");return Math.log1p(e)},expm1:e=>Math.expm1(e),bitAnd:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t))throw new Error("bitAnd() expects integers");return e&t},bitOr:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t))throw new Error("bitOr() expects integers");return e|t},bitXor:(e,t)=>{if(!Number.isInteger(e)||!Number.isInteger(t))throw new Error("bitXor() expects integers");return e^t},bitNot:e=>{if(!Number.isInteger(e))throw new Error("bitNot() expects an integer");return~e}};function T(e){let t=0;const r=()=>e[t],n=()=>e[t++],o=()=>{const r=t>0?e[t-1]:null;return r&&void 0!==r.pos?r.pos:-1},i=()=>{const e=r();return e&&void 0!==e.pos?e.pos:-1},a=e=>{const t=o();return t>=0&&(e.pos=t),e},s=e=>{const t=i()>=0?i():o();throw new Error(`${e}${t>=0?` at position ${t}`:""}`)},u=(e,n)=>{const o=r();return!!o&&(o.type===e&&((void 0===n||o.value===n)&&(t++,!0)))},l=()=>{let e=null;if("Colon"!==r()?.type&&"Comma"!==r()?.type&&"ArrayEnd"!==r()?.type&&(e=E()),u("Colon",void 0)){let t=null;return"Comma"!==r()?.type&&"ArrayEnd"!==r()?.type&&(t=E()),{type:"SliceExpression",start:e,end:t}}return e};function c(){let e=function(){const e=n();e||s("Unexpected end of input");const t=t=>(void 0!==e.pos&&(t.pos=e.pos),t);switch(e.type){case"Number":case"BigInt":case"Boolean":case"String":return t({type:"Literal",value:e.value});case"ImaginaryLiteral":return t({type:"ImaginaryLiteral",value:e.value});case"NumberWithUnit":return t({type:"UnitLiteral",value:e.value,unit:e.unit});case"Identifier":case"Function":return t({type:"Identifier",name:e.name});case"Parenthesis":if("("===e.value){const e=E();return u("Parenthesis",")")||s("Expected ')'"),e}case"ArrayStart":{const e=[];let r=[];if(!u("ArrayEnd",void 0))for(;;)if(r.push(E()),!u("Comma",void 0))if(u("Semicolon",void 0))e.push(r),r=[];else{if(u("ArrayEnd",void 0)){e.push(r);break}s("Expected ',', ';', or ']'")}return e.length?1===e.length?t({type:"ArrayExpression",elements:e[0]}):t({type:"ArrayExpression",elements:e.map(e=>({type:"ArrayExpression",elements:e}))}):t({type:"ArrayExpression",elements:[]})}case"BlockStart":{const e=[];if(!u("BlockEnd",void 0)){do{const t=n();"Identifier"!==t.type&&"String"!==t.type&&s("Invalid object key"),u("Colon",void 0)||s("Expected ':' after key");const r=E();e.push({key:t.value,value:r})}while(u("Comma",void 0));u("BlockEnd",void 0)||s("Expected '}'")}return t({type:"ObjectExpression",properties:e})}}s(`Unexpected token: ${JSON.stringify(e.value||e.name||e.type)}`)}();for(;;){if(u("ArrayStart",void 0)){const t=[];if(!u("ArrayEnd",void 0)){do{t.push(l())}while(u("Comma",void 0));u("ArrayEnd",void 0)||s("Expected ']'")}e=a({type:"IndexExpression",object:e,selectors:t});continue}if(u("Dot",void 0)){const t=n();"Identifier"!==t.type&&s("Expected property after '.'"),e=a({type:"MemberExpression",object:e,property:{type:"Identifier",name:t.value},optional:!1});continue}if(u("Operator","?.")){const t=n();e=a({type:"MemberExpression",object:e,property:{type:"Identifier",name:t.value},optional:!0});continue}break}return e}function p(){if(u("UnaryOperator",void 0)){const r=e[t-1].value;return a({type:"UnaryExpression",operator:r,argument:p()})}return function(){let e=c();for(;"Parenthesis"===r()?.type&&"("===r()?.value;){n();const t=[];if("Parenthesis"!==r()?.type||")"!==r()?.value)do{if(u("Spread",void 0)){const e=E();t.push({type:"SpreadElement",argument:e})}else t.push(E())}while(u("Comma",void 0));u("Parenthesis",")")||s("Expected ')'"),e=a({type:"CallExpression",callee:e,arguments:t})}return e}()}function h(){const e=p();if(u("Operator","^")){const t=h();return a({type:"BinaryExpression",operator:"^",left:e,right:t})}return e}function f(){let r=h();for(;u("Operator","*")||u("Operator","/")||u("Operator","%");){const n=e[t-1].value,o=h();r=a({type:"BinaryExpression",operator:n,left:r,right:o})}return r}function m(){const o=function(){let r=f();for(;u("Operator","+")||u("Operator","-");){const n=e[t-1].value,o=f();r=a({type:"BinaryExpression",operator:n,left:r,right:o})}return r}(),i=r();if("Keyword"===i?.type&&["to","in"].includes(i.value)){n();const e=n();return e&&"Unit"===e.type||s(`Expected unit after '${i.value}'`),a({type:"UnitConversion",from:o,to:e.value})}return o}function g(){let r=m();for(;u("Operator",">")||u("Operator","<")||u("Operator",">=")||u("Operator","<=")||u("Operator","==");){const n=e[t-1].value,o=m();r=a({type:"BinaryExpression",operator:n,left:r,right:o})}return r}function y(){let r=g();for(;u("Operator","&&")||u("Operator","||");){const n=e[t-1].value,o=g();r=a({type:"LogicalExpression",operator:n,left:r,right:o})}return r}function d(){let e=y();for(;u("Operator","??");){const t=y();e=a({type:"LogicalExpression",operator:"??",left:e,right:t})}return e}function w(){const e=d();if(u("Ternary","?")){const t=E();u("Ternary",":")||s("Expected ':' in ternary");const r=E();return a({type:"ConditionalExpression",test:e,consequent:t,alternate:r})}if(u("Colon",void 0)){const t=d();return a({type:"RangeExpression",start:e,end:t})}return e}function b(){const e=function(){let e=w();for(;u("Operator","|>");){const t=w();e=a({type:"PipelineExpression",left:e,right:t})}return e}();if(u("Operator","->")){let t;"Identifier"===e.type?t=[e.name]:"ArrayExpression"===e.type?t=e.elements.map(e=>("Identifier"!==e.type&&s("Lambda parameter must be an identifier"),e.name)):s("Invalid lambda parameter");const r=b();return a({type:"ArrowFunctionExpression",params:t,body:r})}return e}function v(){const r=b();if(u("Operator","=")||u("Operator","+=")||u("Operator","-=")||u("Operator","*=")||u("Operator","/=")){const n=e[t-1].value;if("CallExpression"===r.type){"Identifier"===r.callee?.type&&r.arguments.every(e=>"Identifier"===e.type)||s("Invalid function definition");const e=v();return a({type:"FunctionAssignmentExpression",operator:n,left:{type:"Identifier",name:r.callee.name},params:r.arguments.map(e=>e.name),right:e})}"Identifier"!==r.type&&"MemberExpression"!==r.type&&"IndexExpression"!==r.type&&s("Invalid assignment target");const o=v();return a({type:"AssignmentExpression",operator:n,left:r,right:o})}return r}function E(){return v()}const x=E();if(t<e.length){const e=r(),t=e&&void 0!==e.pos?` at position ${e.pos}`:"";throw new Error(`Unexpected token "${e?JSON.stringify(e.value||e.name||e.type):"?"}"${t}`)}return x}const Z=e=>e&&"object"==typeof e&&"re"in e&&"im"in e,H=e=>c(e)?p(e):"number"!=typeof e||Number.isInteger(e)?String(e):Number(e.toFixed(14)).toString(),R=t=>{return s(t)?s(r=t)?1===r.d?String(r.n):`${r.n}/${r.d}`:String(r):c(t)?p(t):Z(t)?(e=>{if(!Z(e))return e;const t=e.re,r=Math.abs(e.im),n=e.im<0?"-":"+";return 0===t?1===e.im?"i":-1===e.im?"-i":`${e.im}i`:`${t} ${n} ${1===r?"i":`${r}i`}`})(t):(e=>e&&"object"==typeof e&&"value"in e&&"unit"in e)(t)?`${t.value} ${t.unit}`:e(t)?i(t):(e=>Array.isArray(e)&&e.length>0&&e.every(Array.isArray))(t)?t.map(e=>e.map(H).join("\t")).join("\n"):Array.isArray(t)?JSON.stringify(t):t&&"object"==typeof t?i(t):t;var r};class W{constructor(e){this._expr=e,this._rawResult=void 0}evaluate(e,t={}){return this._rawResult=this._expr._evaluateRaw(e,{...t,ans:this._rawResult}),this}setVariable(e,t){return this._expr.setVariable(e,t),this}compile(e){return this._expr.compile(e)}done(){return R(this._rawResult)}}return class{constructor(){this.math=g,this.units=function(e={}){let t={...e};function r(e){e=e.toLowerCase();for(const r in t)for(const n in t[r]){const o=t[r][n];if(n.toLowerCase()===e||o.unit?.toLowerCase()===e||o.symbol?.toLowerCase()===e)return{type:r,key:n,data:o}}return null}return{getUnits:()=>t,setUnits:e=>{t={...e}},updateType:(e,r)=>{t[e]={...t[e],...r}},addUnit:(e,r,n)=>{t[e]||(t[e]={}),t[e][r]=n},compute(e,t,r){const n=e=>e&&"object"==typeof e&&"value"in e&&"unit"in e,o=(t,r)=>{switch(e){case"+":return t+r;case"-":return t-r;case"*":return t*r;case"/":return t/r;case"%":return t%r;case"^":return Math.pow(t,r)}};if(n(t)&&n(r)){const e=this.findUnit(r.unit),n=this.findUnit(t.unit);if(!e||!n||e.type!==n.type)throw new Error("Cannot operate on different unit types");const i=r.value*(e.data.value/n.data.value);return{value:o(t.value,i),unit:t.unit}}if(n(t)&&!n(r))return{value:o(t.value,r),unit:t.unit};if(!n(t)&&n(r)){return{value:o(t,r.value),unit:r.unit}}return o(t,r)},convert:function(e,n,o){const i=r(n),a=r(o);if(!i)throw new Error(`Unknown unit: ${n}`);if(!a)throw new Error(`Unknown unit: ${o}`);if(i.type!==a.type)throw new Error(`Cannot convert ${n} to ${o} (${a.data.unit||a.key}). ${i.data.unit||i.key} conversion units like ${Object.keys(t[i.type]).join(", ")}`);return{value:e*(i.data.value/a.data.value),unit:a.key}},getAllUnitsFlat:function(){const e=new Set;for(const r in t)for(const n in t[r]){const o=t[r][n],i=n.toLowerCase();if(e.add(i),o.unit){const t=o.unit.toLowerCase();t!==i&&1===t.split(/\s+/).length&&e.add(t)}if(o.symbol){const t=o.symbol.toLowerCase();o.unit&&t===o.unit.toLowerCase()||e.add(t)}}return Array.from(e)},findUnit:r}}(y),this.functions=b(V),this.variables=w(),this._cache=new Map,this.variables.set("pi",Math.PI),this.variables.set("e",Math.E),this.variables.set("PHI",(1+Math.sqrt(5))/2),this.variables.set("TAU",2*Math.PI),this.variables.set("INFINITY",1/0),this.variables.set("NaN",NaN),this.addFunction("parse",e=>{if("string"!=typeof e)throw new Error("parse() expects an expression string");return e}),this.addFunction("leafCount",e=>{let t=e;if("string"==typeof e)try{t=this.parse(e).ast}catch{return(e=>{const t=e.replace(/(^|[{,]\s*)[a-zA-Z_][a-zA-Z0-9_]*\s*:/g,"$1").match(/\d+(\.\d+)?(e[+-]?\d+)?n?|[a-zA-Z_][a-zA-Z0-9_]*/gi);return t?t.length:0})(e)}const r=e=>{if(!e||"object"!=typeof e)return 0;switch(e.type){case"Literal":case"ImaginaryLiteral":case"UnitLiteral":case"Identifier":return 1;default:return Object.values(e).reduce((e,t)=>Array.isArray(t)?e+t.reduce((e,t)=>e+r(t),0):e+r(t),0)}};return r(t)}),this.addFunction("matrix",e=>n(e)),this.addFunction("sparse",e=>n(e)),this.addFunction("rationalize",(e,t=!1)=>{if("string"!=typeof e)throw new Error("rationalize() expects an expression string");const r=e.replace(/\s+/g,"").replace(/(\d)([a-zA-Z(])/g,"$1*$2").replace(/([a-zA-Z)])(\d)/g,"$1*$2"),n=e=>JSON.stringify(Object.entries(e).sort(([e],[t])=>e.localeCompare(t))),o=e=>Object.fromEntries(JSON.parse(e)),i=e=>new Map([[n({}),e]]),a=e=>new Map([...e.entries()].filter(([,e])=>0!==e)),s=(e,t,r=1)=>{const n=new Map(e);for(const[e,o]of t.entries())n.set(e,(n.get(e)||0)+r*o);return a(n)},u=(e,t)=>{const r=new Map;for(const[i,a]of e.entries()){const e=o(i);for(const[i,s]of t.entries()){const t=o(i),u={...e};for(const[e,r]of Object.entries(t))u[e]=(u[e]||0)+r;const l=n(u);r.set(l,(r.get(l)||0)+a*s)}}return a(r)},l=(e,t)=>{let r=i(1);for(let n=0;n<t;n++)r=u(r,e);return r},c=(e,t=i(1))=>({num:e,den:t}),p=(e,t,r=1)=>c(s(u(e.num,t.den),u(t.num,e.den),r),u(e.den,t.den)),h=e=>{switch(e.type){case"Literal":return c(i(e.value));case"Identifier":return c((a=e.name,new Map([[n({[a]:1}),1]])));case"UnaryExpression":if("-"===e.operator)return o=h(e.argument),c(s(new Map,o.num,-1),o.den);throw new Error("Unsupported unary operator");case"BinaryExpression":{const n=h(e.left),o=h(e.right);switch(e.operator){case"+":return p(n,o);case"-":return p(n,o,-1);case"*":return r=o,c(u((t=n).num,r.num),u(t.den,r.den));case"/":return((e,t)=>c(u(e.num,t.den),u(e.den,t.num)))(n,o);case"^":if("Literal"!==e.right.type||!Number.isInteger(e.right.value)||e.right.value<0)throw new Error("Unsupported exponent");return c(l(n.num,e.right.value),l(n.den,e.right.value));default:throw new Error("Unsupported operator in rationalize()")}}default:throw new Error("Unsupported expression in rationalize()")}var t,r,o,a},f=e=>{const t=[...e.entries()].filter(([,e])=>0!==e).sort(([e],[t])=>{const r=o(e),n=o(t),i=Object.keys(r).sort()[0]||"",a=Object.keys(n).sort()[0]||"";if(i!==a)return i.localeCompare(a);const s=Object.values(r).reduce((e,t)=>e+t,0);return Object.values(n).reduce((e,t)=>e+t,0)-s});return t.length?t.map(([e,t],r)=>{const n=o(e),i=Math.abs(t);let a=Object.entries(n).map(([e,t])=>1===t?e:`${e} ^ ${t}`).join(" * ");return a?1!==i&&(a=`${i} * ${a}`):a=`${i}`,0===r?t<0?`- ${a}`.replace("- ","-"):a:t<0?`- ${a}`:`+ ${a}`}).join(" "):"0"},m=this.parse(r).ast,g=h(m),y=f(g.num),d=f(g.den),w=new Set;for(const e of[g.num,g.den])for(const t of e.keys())for(const e of Object.keys(o(t)))w.add(e);return t?{numerator:y,denominator:d,coefficients:[],variables:[...w].sort(),expression:`(${y}) / (${d})`}:`(${y}) / (${d})`}),this.addFunction("map",(e,t)=>{if(!Array.isArray(e))throw new Error("map() expects an array");const r="string"==typeof t?this.functions.get(t):t;if("function"!=typeof r)throw new Error("map() requires a function or function name");return e.map(e=>r(e))}),this.addFunction("filter",(e,t)=>{if(!Array.isArray(e))throw new Error("filter() expects an array");const r="string"==typeof t?this.functions.get(t):t;if("function"!=typeof r)throw new Error("filter() requires a function or function name");return e.filter(e=>r(e))}),this.addFunction("integral",(e,t,r)=>{if("string"!=typeof e)throw new Error("integral() expects an expression string");const n=this.compile(e),o=(r-t)/100;let i=n({x:t})+n({x:r});for(let e=1;e<100;e++){const r=n({x:t+e*o});i+=e%2==0?2*r:4*r}return o/3*i}),this.addFunction("sigma",(e,t,r,n)=>{if("string"!=typeof n)throw new Error("sigma() expects an expression string");const o=this.compile(n);let i=0;for(let n=t;n<=r;n++)i+=o({[e]:n});return i}),this.addFunction("pi",(e,t,r,n)=>{if("string"!=typeof n)throw new Error("pi() expects an expression string");const o=this.compile(n);let i=1;for(let n=t;n<=r;n++)i*=o({[e]:n});return i}),this.addFunction("substitute",(e,t,r)=>{if("string"!=typeof e)throw new Error("substitute() expects an expression string");return this.compile(e)({[t]:r})}),this.addFunction("limit",(e,t,r,n)=>{if("string"!=typeof e)throw new Error("limit() expects an expression string");const o=this.compile(e),i=[.1,.01,.001,1e-4,1e-5,1e-6,1e-7,1e-8,1e-9,1e-10];let a=NaN;for(const e of i){let i;i="right"===n?r+e:"left"===n?r-e:r+e;const s=o({[t]:i});isFinite(s)&&(a=s)}return a}),this.addFunction("expand",e=>{if("string"!=typeof e)throw new Error("expand() expects an expression string");const t=e.match(/[a-zA-Z_][a-zA-Z0-9_]*/);if(!t)throw new Error("expand() could not identify variable");const r=t[0],n=e.replace(/\s+/g,"").replace(/\\/g,"\\\\").replace(/"/g,'\\"'),o=e=>{return this.evaluate(`substitute("${t=n,t.replace(/(\d)([a-zA-Z_])/g,"$1*$2")}", "${r}", ${e})`);var t},i=[];for(let e=0;e<=10;e++)i.push(o(e));let a=0,s=[...i];for(let e=0;e<=10;e++){Math.abs(s[0])>1e-10&&(a=e);const t=[];for(let e=0;e<s.length-1;e++)t.push(s[e+1]-s[e]);if(s=t,s.every(e=>Math.abs(e)<1e-10))break}const u=a+1,l=Array.from({length:u},(e,t)=>{const r=Array.from({length:u},(e,r)=>t**r);return r.push(i[t]),r});for(let e=0;e<u;e++){let t=e;for(;t<u&&Math.abs(l[t][e])<1e-12;)t++;if(t===u)continue;[l[e],l[t]]=[l[t],l[e]];const r=l[e][e];for(let t=e;t<=u;t++)l[e][t]/=r;for(let t=0;t<u;t++)if(t!==e){const r=l[t][e];for(let n=e;n<=u;n++)l[t][n]-=r*l[e][n]}}const c=l.map(e=>Math.abs(e[u])<1e-10?0:e[u]),p=[];for(let e=a;e>=0;e--){const t=c[e];if(Math.abs(t)<1e-10)continue;const n=0===p.length?t<0?"-":"":t<0?" - ":" + ",o=Math.abs(t),i=0===e?`${o}`:1===o?"":`${o}`,a=0===e?"":1===e?r:`${r}^${e}`;p.push(`${n}${i}${a}`)}return p.join("")||"0"}),this.addFunction("factor",e=>{if("string"!=typeof e)throw new Error("factor() expects an expression string");const t=e.replace(/\s+/g,""),r=t.match(/[a-zA-Z_][a-zA-Z0-9_]*/);if(!r)throw new Error("factor() could not identify variable");const n=r[0],o=t.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/(\d)([a-zA-Z_])/g,"$1*$2");const i=[];for(let e=0;e<=6;e++)i.push(this.evaluate(`substitute("${o}", "${n}", ${e})`));let a=i.slice(),s=0;for(let e=0;e<=6;e++){if(a.every(e=>Math.abs(e)<1e-10)){s=Math.max(0,e-1);break}if(e<6){const e=[];for(let t=0;t<a.length-1;t++)e.push(a[t+1]-a[t]);a=e}}if(0===s)return`(${e})`;const u=s+1,l=Array.from({length:u},(e,t)=>{const r=Array.from({length:u},(e,r)=>t**r);return r.push(i[t]),r});for(let e=0;e<u;e++){let t=e;for(;t<u&&Math.abs(l[t][e])<1e-12;)t++;if(t===u)continue;[l[e],l[t]]=[l[t],l[e]];const r=l[e][e];for(let t=e;t<=u;t++)l[e][t]/=r;for(let t=0;t<u;t++)if(t!==e){const r=l[t][e];for(let n=e;n<=u;n++)l[t][n]-=r*l[e][n]}}const c=l.map(e=>Math.abs(e[u])<1e-10?0:e[u]);if(s>=1&&s<=3){const e=this.functions.get("polynomialRoot")(...c),t=Array.isArray(e)?e:[e],r=[...new Set(t.map(e=>Number.isInteger(e)?e:Math.round(1e10*e)/1e10))].sort((e,t)=>e-t);if(r.length===s){const e=c[s];return`${Math.abs(e-1)>1e-10?Math.abs(e+1)<1e-10?"-":`${e}`:""}${r.map(e=>Math.abs(e)<1e-10?n:e>0?`(${n} - ${e})`:`(${n} + ${Math.abs(e)})`).join("")}`}}return`(${e})`}),this.addFunction("solve",(e,t)=>{if("string"!=typeof e)throw new Error("solve() expects an equation string");const r=e.split("=");if(2!==r.length)throw new Error("solve() expects an equation with =");const n=`(${r[0].trim()}) - (${r[1].trim()})`.replace(/\s+/g,""),o=n.match(/[a-zA-Z_][a-zA-Z0-9_]*/),i=t||(o?o[0]:"x"),a=n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/(\d)([a-zA-Z_])/g,"$1*$2");const s=[];for(let e=0;e<=6;e++)s.push(this.evaluate(`substitute("${a}", "${i}", ${e})`));let u=s.slice(),l=0;for(let e=0;e<=6;e++){if(u.every(e=>Math.abs(e)<1e-10)){l=Math.max(0,e-1);break}if(e<6){const e=[];for(let t=0;t<u.length-1;t++)e.push(u[t+1]-u[t]);u=e}}if(0===l)throw new Error("No solution found");const c=l+1,p=Array.from({length:c},(e,t)=>{const r=Array.from({length:c},(e,r)=>t**r);return r.push(s[t]),r});for(let e=0;e<c;e++){let t=e;for(;t<c&&Math.abs(p[t][e])<1e-12;)t++;if(t===c)continue;[p[e],p[t]]=[p[t],p[e]];const r=p[e][e];for(let t=e;t<=c;t++)p[e][t]/=r;for(let t=0;t<c;t++)if(t!==e){const r=p[t][e];for(let n=e;n<=c;n++)p[t][n]-=r*p[e][n]}}const h=p.map(e=>Math.abs(e[c])<1e-10?0:e[c]);if(l>=1&&l<=3){const e=this.functions.get("polynomialRoot")(...h);return(Array.isArray(e)?e:[e]).sort((e,t)=>e-t)}throw new Error("solve() currently supports degree up to 3")})}setVariable(e,t){this.variables.set(e,t)}getVariable(e){return this.variables.get(e)}addFunction(e,t){this.functions.register(e,t)}_createContext(){return f({functions:this.functions,variables:this.variables,units:this.units,evaluate:this.evaluate.bind(this)})}tokenize(e){if("string"!=typeof e)throw new Error("Expression must be a string");return function(e,t={}){const r=[];let n="",o="";const i=["+","-","*","/","%","^","=",">","<","!","&","|"],a=["==",">=","<=","&&","||","+=","-=","*=","/=","%=","?.","??","|>","->"],s=["to","in"],u=t.units?.getAllUnitsFlat?.()||[],l=e=>!e||"Operator"===e.type||"UnaryOperator"===e.type||"Parenthesis"===e.type&&")"!==e.value||"ArrayStart"===e.type||"Semicolon"===e.type||"Comma"===e.type||"Ternary"===e.type,c=(t,o)=>{if(!n)return;if(/^(true|false)$/i.test(n))return r.push({type:"Boolean",value:"true"===n.toLowerCase()}),void(n="");if(s.includes(n))return r.push({type:"Keyword",value:n,pos:o}),void(n="");if(/^\d+n$/.test(n))return r.push({type:"BigInt",value:BigInt(n.slice(0,-1)),pos:o}),void(n="");if(/^0x[0-9a-fA-F]+$/.test(n))return r.push({type:"Number",value:parseInt(n,16),pos:o}),void(n="");if(/^0b[01]+$/.test(n))return r.push({type:"Number",value:parseInt(n,2),pos:o}),void(n="");if(/^[+-]?(\d+(\.\d+)?|\.\d+)(e[+-]?\d+)?$/i.test(n))return r.push({type:"Number",value:parseFloat(n),pos:o}),void(n="");if(/^[+-]?(\d+(\.\d+)?|\.\d+)(e[+-]?\d+)?i$/i.test(n))return r.push({type:"ImaginaryLiteral",value:parseFloat(n.slice(0,-1)),pos:o}),void(n="");if(/^[+-]?i$/i.test(n)){const e="-"===n[0]?-1:1;return r.push({type:"ImaginaryLiteral",value:e,pos:o}),void(n="")}const i=n.match(/^([+-]?\d+(\.\d+)?)([a-zA-Z]+)$/);if(i){const e=parseFloat(i[1]),t=i[3];return r.push({type:u.includes(t)?"NumberWithUnit":"UnknownUnit",value:e,unit:t,pos:o}),void(n="")}if(u.includes(n)){const{prevWord:i}=function(e,t){const r=e.match(/[a-z0-9]+/gi)||[],n=e[t]||null,o=t>0?e[t-1]:null;let i=t;for(;i>0&&/[a-z0-9]/i.test(e[i-1]);)i--;let a=t;for(;a<e.length&&/[a-z0-9]/i.test(e[a]);)a++;const s=e.substring(i,a),u=r.indexOf(s);return{prevWord:u>0?r[u-1]:null,prevChar:o,currentWord:s,currentChar:n,nextWord:-1!==u&&u<r.length-1?r[u+1]:null}}(e,o);if("("!==t&&i&&(!isNaN(parseFloat(i))||"to"===i||"in"===i))return r.push({type:"Unit",value:n,pos:o}),void(n="")}if(/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(n))return"("===t?r.push({type:"Function",name:n,pos:o}):r.push({type:"Identifier",name:n,pos:o}),void(n="");throw new Error(`Invalid token "${n}" at index ${o}`)};for(let t=0;t<e.length;t++){const s=e[t],u=e[t+1];if("/"===s&&"/"===u){for(;t<e.length&&"\n"!==e[t];)t++;continue}if("/"===s&&"*"===u){for(t+=2;t<e.length&&("*"!==e[t]||"/"!==e[t+1]);)t++;t++;continue}if("\"'".includes(s)){o?o===s?(n+=s,r.push({type:"String",value:n.slice(1,-1),pos:t}),n="",o=""):n+=s:(o=s,n+=s);continue}if(o){n+="\\"===s?s+e[++t]:s;continue}const p=s+u;if(a.includes(p))c(s,t),r.push({type:"Operator",value:p,pos:t}),t++;else if("?"!==s){if(":"===s){c(s,t);const e=r[r.length-1];e&&"Ternary"===e.type?r.push({type:"Ternary",value:":"}):r.push({type:"Colon"});continue}if("."!==s||"."!==u||"."!==e[t+2])if("."===s&&/\d/.test(n)&&/\d/.test(u))n+=s;else if("."!==s){if(i.includes(s)){c(s,t);const e=r[r.length-1];"-"!==s&&"!"!==s||!l(e)?r.push({type:"Operator",value:s,pos:t}):r.push({type:"UnaryOperator",value:s,pos:t});continue}"()".includes(s)?(c(s,t),r.push({type:"Parenthesis",value:s,pos:t})):"["!==s?"]"!==s?"{"!==s?"}"!==s?","!==s?";"!==s?" "!==s?(n+=s,t===e.length-1&&c(null,t)):c(u,t):(c(s,t),r.push({type:"Semicolon",pos:t})):(c(s,t),r.push({type:"Comma",pos:t})):(c(s,t),r.push({type:"BlockEnd",pos:t})):(c(s,t),r.push({type:"BlockStart",pos:t})):(c(s,t),r.push({type:"ArrayEnd",pos:t})):(c(s,t),r.push({type:"ArrayStart",pos:t}))}else c(s,t),r.push({type:"Dot",pos:t});else c(s,t),r.push({type:"Spread",pos:t}),t+=2}else r.push({type:"Ternary",value:"?"})}if(o)throw new Error("Unclosed string literal");const p=[];for(let e=0;e<r.length;e++){const t=r[e],n=r[e+1];"Number"!==t?.type||"Unit"!==n?.type?p.push(t):(p.push({type:"NumberWithUnit",value:t.value,unit:n.value,pos:t.pos}),e++)}const h=[];for(let e=0;e<p.length;e++){const t=p[e],r=p[e+1];h.push(t),t&&r&&(["Number","Identifier"].includes(t.type)||"Parenthesis"===t.type&&")"===t.value||"ArrayEnd"===t.type)&&(["Identifier","Function"].includes(r.type)||"Parenthesis"===r.type&&"("===r.value)&&h.push({type:"Operator",value:"*",implicit:!0})}return h}(e,this._createContext())}parse(e){const t=this.tokenize(e);return{tokens:t,ast:T(t)}}evaluate(e,t={}){return R(this._evaluateRaw(e,t))}_evaluateRaw(e,t={}){const{ast:r}=this.parse(e),n=this._createContext();return h(r,Object.keys(t).length>0?n.withScope(t):n)}compile(e){if(this._cache.has(e))return this._cache.get(e);const{ast:t}=this.parse(e),r=(e={})=>{const r=this._createContext().withScope(e);return R(h(t,r))};return this._cache.set(e,r),r}clearCache(){this._cache.clear()}exportState(){return{variables:this.variables.all(),functions:this.functions.getAllFunctionsName(),units:this.units.getUnits()}}importState(e){if(e.variables&&this.variables.merge(e.variables),e.units&&this.units.setUnits(e.units),e.functions)for(const t of e.functions)this.functions.has(t);return this}chain(){return new W(this)}}});
|
|
3
3
|
|