From 2a18a9e6e001b9ca4ad710eeb15513fbc0d24b9c Mon Sep 17 00:00:00 2001 From: nikoscham Date: Wed, 21 May 2025 08:19:21 +0300 Subject: [PATCH 1/6] Add branching and workflow guidelines to CONTRIBUTING.md; update README for clarity in example usage --- CONTRIBUTING.md | 9 +++++++++ README.md | 21 +++++++-------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7b1d13..47d724f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,6 +27,15 @@ Thank you for your interest in contributing! FEAScript is in early development, where the server will be available at `http://127.0.0.1:8000/`. Static file server npm packages like [serve](https://github.com/vercel/serve#readme) and [Vite](https://vite.dev/) can also be used. +## Branching & Workflow + +To contribute a new feature or fix: + +- Do not commit directly to `main` or `dev`. +- Instead, start your work in a feature branch based on the `dev` branch. + +**If you are not a member of the repository (e.g., an external contributor), you must first [fork the repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo).** Make your changes in your fork, then submit a Pull Request from your fork's feature branch into the`dev` branch. + ## File Structure Guidelines All files in the FEAScript-core codebase should follow this structure: diff --git a/README.md b/README.md index a9744d3..040bbd8 100644 --- a/README.md +++ b/README.md @@ -13,17 +13,13 @@ FEAScript is entirely implemented in pure JavaScript and requires only a simple ### Example Usage ```javascript -// Import required modules +// Import FEAScript library import { FEAScriptModel, plotSolution } from "https://core.feascript.com/src/index.js"; -// Create a new FEAScript model +// Create and configure model const model = new FEAScriptModel(); - -// Configure the solver model.setSolverConfig("solverType"); // e.g., "solidHeatTransfer" for a stationary solid heat transfer case - -// Define mesh configuration (assuming a rectangular domain for 2D) -model.setMeshConfig({ +model.setMeshConfig({ // Define mesh configuration (assuming a rectangular domain for 2D) meshDimension: "1D" | "2D", // Mesh dimension elementOrder: "linear" | "quadratic", // Element order numElementsX: number, // Number of elements in x-direction @@ -32,16 +28,13 @@ model.setMeshConfig({ maxY: number, // Domain length in y-direction (for 2D) }); -// Define boundary conditions -model.addBoundaryCondition("boundaryIndex", ["conditionType", ...parameters]); - -// Set solver method -model.setSolverMethod("solverMethod"); // e.g., "lusolve" for LU decomposition +// Apply boundary conditions +model.addBoundaryCondition("boundaryIndex", ["conditionType", /* parameters */]); -// Solve the problem +// Solve const { solutionVector, nodesCoordinates } = model.solve(); -// Visualize results +// Plot results plotSolution( solutionVector, nodesCoordinates, From b494dd5b8e8e27fd51127d3c3c9224eff0529157 Mon Sep 17 00:00:00 2001 From: sridhar <2019309038@student.annauniv.edu> Date: Thu, 22 May 2025 15:26:58 +0530 Subject: [PATCH 2/6] Made the initial build for npm (#25) * Made the initial build for npm * fix: update package.json with correct license, description and module type - Change license from AGPLv3 to MIT to match actual project license - Replace HTML image tag with proper text description - Update type to "module" to align with ES module syntax * Prepare package for npm publishing and bump version to 0.1.1 * Update package.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update rollup.config.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update rollup.config.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: update test script to use jest and add jest as a devDependency * fix: remove (still) unused wasm plugin from rollup configuration * fix: remove unused rollup-plugin-wasm from devDependencies * fix: revert test script to no tests configured and remove jest from devDependencies * Add plotly.js as a peer and dev dependency; update Rollup config for external globals * fix: remove unused rollup-plugin-typescript2 from configuration * Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: update import paths in README for consistency with distribution bundle * fix: correct parameter syntax in addBoundaryCondition example --------- Co-authored-by: Sridhar.Mani Co-authored-by: Nikos Chamakos Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .gitignore | 3 + .npmignore | 4 + README.md | 55 +- dist/feascript.cjs.js | 8 + dist/feascript.cjs.js.map | 1 + dist/feascript.esm.js | 7 + dist/feascript.esm.js.map | 1 + dist/feascript.umd.js | 8 + dist/feascript.umd.js.map | 1 + feascript-0.1.1.tgz | Bin 0 -> 141436 bytes package-lock.json | 4525 +++++++++++++++++++++++++++++++++++++ package.json | 60 + rollup.config.js | 39 + src/index.js | 1 + tsconfig.json | 25 + 15 files changed, 4734 insertions(+), 4 deletions(-) create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 dist/feascript.cjs.js create mode 100644 dist/feascript.cjs.js.map create mode 100644 dist/feascript.esm.js create mode 100644 dist/feascript.esm.js.map create mode 100644 dist/feascript.umd.js create mode 100644 dist/feascript.umd.js.map create mode 100644 feascript-0.1.1.tgz create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 rollup.config.js create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9c7c58b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/node_modules +node_modules +node_modules/ \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..1742c61 --- /dev/null +++ b/.npmignore @@ -0,0 +1,4 @@ +examples/ +test/ +.gitignore +package-lock.json \ No newline at end of file diff --git a/README.md b/README.md index 040bbd8..9c05e59 100644 --- a/README.md +++ b/README.md @@ -6,20 +6,67 @@ > 🚧 **FEAScript is currently under heavy development.** Functionality and interfaces may change rapidly as new features and enhancements are introduced. 🚧 -## Getting Started +## Installation -FEAScript is entirely implemented in pure JavaScript and requires only a simple HTML page to operate. All simulations are executed locally in your browser, without the need for any cloud services. +FEAScript is entirely implemented in pure JavaScript and requires only a simple HTML page to operate. All simulations are executed locally in your browser, without the need for any cloud services. You can use FEAScript in your projects through one of the following methods: + +### Option 1: NPM Installation + +```bash +# Install FEAScript and its peer dependencies +npm install feascript mathjs plotly.js +``` + +Then import it in your JavaScript/TypeScript file: + +```javascript +// ES Modules +import { FEAScriptModel, plotSolution } from "feascript"; + +// CommonJS +const { FEAScriptModel, plotSolution } = require("feascript"); +``` + +**Important:** FEAScript is built as an ES module. If you're starting a new project, make sure to configure it to use ES modules by running: + +```bash +# Create package.json with type=module for ES modules support +echo '{"type":"module"}' > package.json +``` + +If you already have a package.json file, manually add `"type": "module"` to enable ES modules in your project. + +### Option 2: Direct Import from CDN + +Add this line to your HTML or JavaScript module: + +```javascript +import { FEAScriptModel, plotSolution } from "https://core.feascript.com/dist/feascript.umd.js"; +``` + +### Option 3: Download and Use Locally + +1. Download the latest release from [GitHub Releases](https://github.com/FEAScript/FEAScript-core/releases) +2. Include it in your project: + +```html + +``` ### Example Usage ```javascript // Import FEAScript library -import { FEAScriptModel, plotSolution } from "https://core.feascript.com/src/index.js"; +import { FEAScriptModel, plotSolution } from "https://core.feascript.com/dist/feascript.umd.js"; // Create and configure model const model = new FEAScriptModel(); model.setSolverConfig("solverType"); // e.g., "solidHeatTransfer" for a stationary solid heat transfer case -model.setMeshConfig({ // Define mesh configuration (assuming a rectangular domain for 2D) +model.setMeshConfig({ + // Define mesh configuration (assuming a rectangular domain for 2D) meshDimension: "1D" | "2D", // Mesh dimension elementOrder: "linear" | "quadratic", // Element order numElementsX: number, // Number of elements in x-direction diff --git a/dist/feascript.cjs.js b/dist/feascript.cjs.js new file mode 100644 index 0000000..6084723 --- /dev/null +++ b/dist/feascript.cjs.js @@ -0,0 +1,8 @@ +"use strict";Object.defineProperty(exports,"__esModule",{value:!0});class e{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getGaussPointsAndWeights(){let e=[],t=[];return"linear"===this.elementOrder?(e[0]=.5,t[0]=1):"quadratic"===this.elementOrder&&(e[0]=(1-Math.sqrt(.6))/2,e[1]=.5,e[2]=(1+Math.sqrt(.6))/2,t[0]=5/18,t[1]=8/18,t[2]=5/18),{gaussPoints:e,gaussWeights:t}}}let t="basic";function n(e){"debug"===t&&console.log("%c[DEBUG] "+e,"color: #2196F3; font-weight: bold;")}function s(e){console.log("%c[INFO] "+e,"color: #4CAF50; font-weight: bold;")}function o(e){console.log("%c[ERROR] "+e,"color: #F44336; font-weight: bold;")}class i{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getBasisFunctions(e,t=null){let n=[],s=[],i=[];if("1D"===this.meshDimension)"linear"===this.elementOrder?(n[0]=1-e,n[1]=e,s[0]=-1,s[1]=1):"quadratic"===this.elementOrder&&(n[0]=1-3*e+2*e**2,n[1]=4*e-4*e**2,n[2]=2*e**2-e,s[0]=4*e-3,s[1]=4-8*e,s[2]=4*e-1);else if("2D"===this.meshDimension){if(null===t)return void o("Eta coordinate is required for 2D elements");if("linear"===this.elementOrder){function r(e){return 1-e}n[0]=r(e)*r(t),n[1]=r(e)*t,n[2]=e*r(t),n[3]=e*t,s[0]=-1*r(t),s[1]=-1*t,s[2]=1*r(t),s[3]=1*t,i[0]=-1*r(e),i[1]=1*r(e),i[2]=-1*e,i[3]=1*e}else if("quadratic"===this.elementOrder){function a(e){return 2*e**2-3*e+1}function l(e){return-4*e**2+4*e}function d(e){return 2*e**2-e}function h(e){return 4*e-3}function m(e){return-8*e+4}function u(e){return 4*e-1}n[0]=a(e)*a(t),n[1]=a(e)*l(t),n[2]=a(e)*d(t),n[3]=l(e)*a(t),n[4]=l(e)*l(t),n[5]=l(e)*d(t),n[6]=d(e)*a(t),n[7]=d(e)*l(t),n[8]=d(e)*d(t),s[0]=h(e)*a(t),s[1]=h(e)*l(t),s[2]=h(e)*d(t),s[3]=m(e)*a(t),s[4]=m(e)*l(t),s[5]=m(e)*d(t),s[6]=u(e)*a(t),s[7]=u(e)*l(t),s[8]=u(e)*d(t),i[0]=a(e)*h(t),i[1]=a(e)*m(t),i[2]=a(e)*u(t),i[3]=l(e)*h(t),i[4]=l(e)*m(t),i[5]=l(e)*u(t),i[6]=d(e)*h(t),i[7]=d(e)*m(t),i[8]=d(e)*u(t)}}return{basisFunction:n,basisFunctionDerivKsi:s,basisFunctionDerivEta:i}}}class r{constructor({numElementsX:e=null,maxX:t=null,numElementsY:n=null,maxY:s=null,meshDimension:o=null,elementOrder:i="linear",parsedMesh:r=null}){this.numElementsX=e,this.numElementsY=n,this.maxX=t,this.maxY=s,this.meshDimension=o,this.elementOrder=i,this.parsedMesh=r}generateMesh(){if(this.parsedMesh){if(this.parsedMesh.nodalNumbering&&"object"==typeof this.parsedMesh.nodalNumbering&&!Array.isArray(this.parsedMesh.nodalNumbering)){const e=this.parsedMesh.nodalNumbering.quadElements||[];if(this.parsedMesh.nodalNumbering.triangleElements,n("Initial parsed mesh nodal numbering from GMSH format: "+JSON.stringify(this.parsedMesh.nodalNumbering)),this.parsedMesh.elementTypes[3]||this.parsedMesh.elementTypes[10]){const t=[];for(let n=0;n0&&void 0===this.parsedMesh.boundaryElements[0]){const e=[];for(let t=1;t{if(1===e.dimension){const t=this.parsedMesh.boundaryNodePairs[e.tag]||[];t.length>0&&(this.parsedMesh.boundaryElements[e.tag]||(this.parsedMesh.boundaryElements[e.tag]=[]),t.forEach((t=>{const s=t[0],i=t[1];n(`Processing boundary node pair: [${s}, ${i}] for boundary ${e.tag} (${e.name||"unnamed"})`);let r=!1;for(let t=0;t0&&void 0===this.parsedMesh.boundaryElements[0])){const e=[];for(let t=1;t{if("constantTemp"===this.boundaryConditions[s][0]){const o=this.boundaryConditions[s][1];n(`Boundary ${s}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[s].forEach((([s,i])=>{if("linear"===this.elementOrder){({0:[0],1:[1]})[i].forEach((i=>{const r=this.nop[s][i]-1;n(` - Applied fixed temperature to node ${r+1} (element ${s+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[s][i]-1;n(` - Applied fixed temperature to node ${r+1} (element ${s+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{if("constantTemp"===this.boundaryConditions[s][0]){const o=this.boundaryConditions[s][1];n(`Boundary ${s}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[s].forEach((([s,i])=>{if("linear"===this.elementOrder){({0:[0,2],1:[0,1],2:[1,3],3:[2,3]})[i].forEach((i=>{const r=this.nop[s][i]-1;n(` - Applied fixed temperature to node ${r+1} (element ${s+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[s][i]-1;n(` - Applied fixed temperature to node ${r+1} (element ${s+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const t=this.boundaryConditions[e];"convection"===t[0]&&(d[e]=t[1],h[e]=t[2])})),"1D"===this.meshDimension?Object.keys(this.boundaryConditions).forEach((s=>{if("convection"===this.boundaryConditions[s][0]){const o=d[s],i=h[s];n(`Boundary ${s}: Applying convection with heat transfer coefficient h=${o} W/(m²·K) and external temperature T∞=${i} K`),this.boundaryElements[s].forEach((([s,r])=>{let a;"linear"===this.elementOrder?a=0===r?0:1:"quadratic"===this.elementOrder&&(a=0===r?0:2);const l=this.nop[s][a]-1;n(` - Applied convection boundary condition to node ${l+1} (element ${s+1}, local node ${a+1})`),e[l]+=-o*i,t[l][l]+=o}))}})):"2D"===this.meshDimension&&Object.keys(this.boundaryConditions).forEach((s=>{if("convection"===this.boundaryConditions[s][0]){const m=d[s],u=h[s];n(`Boundary ${s}: Applying convection with heat transfer coefficient h=${m} W/(m²·K) and external temperature T∞=${u} K`),this.boundaryElements[s].forEach((([s,d])=>{if("linear"===this.elementOrder){let h,c,f,p,y;0===d?(h=o[0],c=0,f=0,p=3,y=2):1===d?(h=0,c=o[0],f=0,p=2,y=1):2===d?(h=o[0],c=1,f=1,p=4,y=2):3===d&&(h=1,c=o[0],f=2,p=4,y=1);let g=l.getBasisFunctions(h,c),b=g.basisFunction,E=g.basisFunctionDerivKsi,M=g.basisFunctionDerivEta,$=0,v=0,w=0,C=0;const N=this.nop[s].length;for(let e=0;e"object"==typeof e&&null!==e||"function"==typeof e,f=new Map([["proxy",{canHandle:e=>c(e)&&e[l],serialize(e){const{port1:t,port2:n}=new MessageChannel;return p(e,t),[n,[n]]},deserialize:e=>(e.start(),g(e))}],["throw",{canHandle:e=>c(e)&&u in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function p(e,t=globalThis,n=["*"]){t.addEventListener("message",(function s(o){if(!o||!o.data)return;if(!function(e,t){for(const n of e){if(t===n||"*"===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}return!1}(n,o.origin))return void console.warn(`Invalid origin '${o.origin}' for comlink proxy`);const{id:i,type:r,path:a}=Object.assign({path:[]},o.data),d=(o.data.argumentList||[]).map(S);let h;try{const t=a.slice(0,-1).reduce(((e,t)=>e[t]),e),n=a.reduce(((e,t)=>e[t]),e);switch(r){case"GET":h=n;break;case"SET":t[a.slice(-1)[0]]=S(o.data.value),h=!0;break;case"APPLY":h=n.apply(t,d);break;case"CONSTRUCT":h=function(e){return Object.assign(e,{[l]:!0})}(new n(...d));break;case"ENDPOINT":{const{port1:t,port2:n}=new MessageChannel;p(e,n),h=function(e,t){return C.set(e,t),e}(t,[t])}break;case"RELEASE":h=void 0;break;default:return}}catch(e){h={value:e,[u]:0}}Promise.resolve(h).catch((e=>({value:e,[u]:0}))).then((n=>{const[o,a]=N(n);t.postMessage(Object.assign(Object.assign({},o),{id:i}),a),"RELEASE"===r&&(t.removeEventListener("message",s),y(t),m in e&&"function"==typeof e[m]&&e[m]())})).catch((e=>{const[n,s]=N({value:new TypeError("Unserializable return value"),[u]:0});t.postMessage(Object.assign(Object.assign({},n),{id:i}),s)}))})),t.start&&t.start()}function y(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function g(e,t){const n=new Map;return e.addEventListener("message",(function(e){const{data:t}=e;if(!t||!t.id)return;const s=n.get(t.id);if(s)try{s(t)}finally{n.delete(t.id)}})),v(e,n,[],t)}function b(e){if(e)throw new Error("Proxy has been released and is not useable")}function E(e){return x(e,new Map,{type:"RELEASE"}).then((()=>{y(e)}))}const M=new WeakMap,$="FinalizationRegistry"in globalThis&&new FinalizationRegistry((e=>{const t=(M.get(e)||0)-1;M.set(e,t),0===t&&E(e)}));function v(e,t,n=[],s=function(){}){let o=!1;const i=new Proxy(s,{get(s,r){if(b(o),r===h)return()=>{!function(e){$&&$.unregister(e)}(i),E(e),t.clear(),o=!0};if("then"===r){if(0===n.length)return{then:()=>i};const s=x(e,t,{type:"GET",path:n.map((e=>e.toString()))}).then(S);return s.then.bind(s)}return v(e,t,[...n,r])},set(s,i,r){b(o);const[a,l]=N(r);return x(e,t,{type:"SET",path:[...n,i].map((e=>e.toString())),value:a},l).then(S)},apply(s,i,r){b(o);const a=n[n.length-1];if(a===d)return x(e,t,{type:"ENDPOINT"}).then(S);if("bind"===a)return v(e,t,n.slice(0,-1));const[l,h]=w(r);return x(e,t,{type:"APPLY",path:n.map((e=>e.toString())),argumentList:l},h).then(S)},construct(s,i){b(o);const[r,a]=w(i);return x(e,t,{type:"CONSTRUCT",path:n.map((e=>e.toString())),argumentList:r},a).then(S)}});return function(e,t){const n=(M.get(t)||0)+1;M.set(t,n),$&&$.register(e,t,e)}(i,e),i}function w(e){const t=e.map(N);return[t.map((e=>e[0])),(n=t.map((e=>e[1])),Array.prototype.concat.apply([],n))];var n}const C=new WeakMap;function N(e){for(const[t,n]of f)if(n.canHandle(e)){const[s,o]=n.serialize(e);return[{type:"HANDLER",name:t,value:s},o]}return[{type:"RAW",value:e},C.get(e)||[]]}function S(e){switch(e.type){case"HANDLER":return f.get(e.name).deserialize(e.value);case"RAW":return e.value}}function x(e,t,n,s){return new Promise((o=>{const i=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");t.set(i,o),e.start&&e.start(),e.postMessage(Object.assign({id:i},n),s)}))}exports.FEAScriptModel=class{constructor(){this.solverConfig=null,this.meshConfig={},this.boundaryConditions={},this.solverMethod="lusolve",s("FEAScriptModel instance created")}setSolverConfig(e){this.solverConfig=e,n(`Solver config set to: ${e}`)}setMeshConfig(e){this.meshConfig=e,n(`Mesh config set with dimensions: ${e.meshDimension}`)}addBoundaryCondition(e,t){this.boundaryConditions[e]=t,n(`Boundary condition added for boundary: ${e}, type: ${t[0]}`)}setSolverMethod(e){this.solverMethod=e,n(`Solver method set to: ${e}`)}solve(){if(!this.solverConfig||!this.meshConfig||!this.boundaryConditions){const e="Solver config, mesh config, and boundary conditions must be set before solving.";throw console.error(e),new Error(e)}let t=[],o=[],l=[],d={};if(s("Beginning matrix assembly..."),console.time("assemblyMatrices"),"solidHeatTransferScript"===this.solverConfig&&(s(`Using solver: ${this.solverConfig}`),({jacobianMatrix:t,residualVector:o,nodesCoordinates:d}=function(t,o){s("Starting solid heat transfer matrix assembly...");const{meshDimension:l,numElementsX:d,numElementsY:h,maxX:m,maxY:u,elementOrder:c,parsedMesh:f}=t;n("Generating mesh...");const p=new r({numElementsX:d,numElementsY:h,maxX:m,maxY:u,meshDimension:l,elementOrder:c,parsedMesh:f}).generateMesh();let y,g,b=p.nodesXCoordinates,E=p.nodesYCoordinates,M=p.totalNodesX,$=p.totalNodesY,v=p.nodalNumbering,w=p.boundaryElements;null!=f?(y=v.length,g=b.length,n(`Using parsed mesh with ${y} elements and ${g} nodes`)):(y=d*("2D"===l?h:1),g=M*("2D"===l?$:1),n(`Using mesh generated from geometry with ${y} elements and ${g} nodes`));let C,N,S,x,D,O,A,F=[],T=[],k=[],X=[],P=[],R=[],Y=[],W=[],I=[],j=[];for(let e=0;e{console.error("FEAScriptWorker: Worker error:",e)};const e=g(this.worker);this.feaWorker=await new e,this.isReady=!0}catch(e){throw console.error("Failed to initialize worker",e),e}}async _ensureReady(){return this.isReady?Promise.resolve():new Promise(((e,t)=>{let n=0;const s=()=>{n++,this.isReady?e():n>=50?t(new Error("Timeout waiting for worker to be ready")):setTimeout(s,1e3)};s()}))}async setSolverConfig(e){return await this._ensureReady(),s(`FEAScriptWorker: Setting solver config to: ${e}`),this.feaWorker.setSolverConfig(e)}async setMeshConfig(e){return await this._ensureReady(),s("FEAScriptWorker: Setting mesh config"),this.feaWorker.setMeshConfig(e)}async addBoundaryCondition(e,t){return await this._ensureReady(),s(`FEAScriptWorker: Adding boundary condition for boundary: ${e}`),this.feaWorker.addBoundaryCondition(e,t)}async setSolverMethod(e){return await this._ensureReady(),s(`FEAScriptWorker: Setting solver method to: ${e}`),this.feaWorker.setSolverMethod(e)}async solve(){await this._ensureReady(),s("FEAScriptWorker: Requesting solution from worker...");const e=performance.now(),t=await this.feaWorker.solve();return s(`FEAScriptWorker: Solution completed in ${((performance.now()-e)/1e3).toFixed(2)}s`),t}async getModelInfo(){return await this._ensureReady(),this.feaWorker.getModelInfo()}async ping(){return await this._ensureReady(),this.feaWorker.ping()}terminate(){this.worker&&(this.worker.terminate(),this.worker=null,this.feaWorker=null,this.isReady=!1)}},exports.VERSION="0.1.1",exports.importGmshQuadTri=async e=>{let t={nodesXCoordinates:[],nodesYCoordinates:[],nodalNumbering:{quadElements:[],triangleElements:[]},boundaryElements:[],boundaryConditions:[],boundaryNodePairs:{},gmshV:0,ascii:!1,fltBytes:"8",totalNodesX:0,totalNodesY:0,physicalPropMap:[],elementTypes:{}},s=(await e.text()).split("\n").map((e=>e.trim())).filter((e=>""!==e&&" "!==e)),o="",i=0,r=0,a=0,l=0,d={numNodes:0},h=0,m=[],u=0,c=0,f=0,p={dim:0,tag:0,elementType:0,numElements:0},y=0,g={};for(;i""!==e));if("meshFormat"===o)t.gmshV=parseFloat(n[0]),t.ascii="0"===n[1],t.fltBytes=n[2];else if("physicalNames"===o){if(n.length>=3){if(!/^\d+$/.test(n[0])){i++;continue}const e=parseInt(n[0],10),s=parseInt(n[1],10);let o=n.slice(2).join(" ");o=o.replace(/^"|"$/g,""),t.physicalPropMap.push({tag:s,dimension:e,name:o})}}else if("nodes"===o){if(0===r){r=parseInt(n[0],10),a=parseInt(n[1],10),t.nodesXCoordinates=new Array(a).fill(0),t.nodesYCoordinates=new Array(a).fill(0),i++;continue}if(lparseInt(e,10)));if(1===p.elementType||8===p.elementType){const n=p.tag;g[n]||(g[n]=[]),g[n].push(e),t.boundaryNodePairs[n]||(t.boundaryNodePairs[n]=[]),t.boundaryNodePairs[n].push(e)}else 2===p.elementType?t.nodalNumbering.triangleElements.push(e):(3===p.elementType||10===p.elementType)&&t.nodalNumbering.quadElements.push(e);y++,y===p.numElements&&(f++,p={numElements:0})}}i++}return t.physicalPropMap.forEach((e=>{if(1===e.dimension){const n=g[e.tag]||[];n.length>0&&t.boundaryConditions.push({name:e.name,tag:e.tag,nodes:n})}})),n(`Parsed boundary node pairs by physical tag: ${JSON.stringify(t.boundaryNodePairs)}. These pairs will be used to identify boundary elements in the mesh.`),t},exports.logSystem=function(e){"basic"!==e&&"debug"!==e?(console.log("%c[WARN] Invalid log level: "+e+". Using basic instead.","color: #FFC107; font-weight: bold;"),t="basic"):(t=e,s(`Log level set to: ${e}`))},exports.plotSolution=function(e,t,n,s,o,i,r="structured"){const{nodesXCoordinates:a,nodesYCoordinates:l}=t;if("1D"===s&&"line"===o){let t;t=e.length>0&&Array.isArray(e[0])?e.map((e=>e[0])):e;let s=Array.from(a),o={x:s,y:t,mode:"lines",type:"scatter",line:{color:"rgb(219, 64, 82)",width:2},name:"Solution"},r=Math.min(window.innerWidth,700),l=Math.max(...s),d=r/l,h={title:`line plot - ${n}`,width:Math.max(d*l,400),height:350,xaxis:{title:"x"},yaxis:{title:"Solution"},margin:{l:70,r:40,t:50,b:50}};Plotly.newPlot(i,[o],h,{responsive:!0})}else if("2D"===s&&"contour"===o){const t="structured"===r,s=new Set(a).size,d=new Set(l).size;let h=Array.isArray(e[0])?e.map((e=>e[0])):e,m=Math.min(window.innerWidth,700),u=Math.max(...a),c=Math.max(...l)/u,f=Math.min(m,600),p={title:`${o} plot - ${n}`,width:f,height:f*c*.8,xaxis:{title:"x"},yaxis:{title:"y"},margin:{l:50,r:50,t:50,b:50},hovermode:"closest"};if(t){const t=s,n=d;math.reshape(Array.from(a),[t,n]);let o=math.reshape(Array.from(l),[t,n]),r=math.reshape(Array.from(e),[t,n]),h=math.transpose(r),m=[];for(let e=0;e | |\n // 0 --- 1 0 --- 2\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[3]; // 3 -> 1\n feaScriptNodes[2] = gmshNodes[1]; // 1 -> 2\n feaScriptNodes[3] = gmshNodes[2]; // 2 -> 3\n } else if (gmshNodes.length === 9) {\n // Mapping for quadratic quad elements (9 nodes)\n // GMSH: FEAScript:\n // 3--6--2 2--5--8\n // | | | |\n // 7 8 5 --> 1 4 7\n // | | | |\n // 0--4--1 0--3--6\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[7]; // 7 -> 1\n feaScriptNodes[2] = gmshNodes[3]; // 3 -> 2\n feaScriptNodes[3] = gmshNodes[4]; // 4 -> 3\n feaScriptNodes[4] = gmshNodes[8]; // 8 -> 4\n feaScriptNodes[5] = gmshNodes[6]; // 6 -> 5\n feaScriptNodes[6] = gmshNodes[1]; // 1 -> 6\n feaScriptNodes[7] = gmshNodes[5]; // 5 -> 7\n feaScriptNodes[8] = gmshNodes[2]; // 2 -> 8\n }\n\n mappedNodalNumbering.push(feaScriptNodes);\n }\n\n this.parsedMesh.nodalNumbering = mappedNodalNumbering;\n } else if (this.parsedMesh.elementTypes[2]) {\n }\n\n debugLog(\n \"Nodal numbering after mapping from GMSH to FEAScript format: \" +\n JSON.stringify(this.parsedMesh.nodalNumbering)\n );\n\n // Process boundary elements if they exist and if physical property mapping exists\n if (this.parsedMesh.physicalPropMap && this.parsedMesh.boundaryElements) {\n // Check if boundary elements need to be processed\n if (\n Array.isArray(this.parsedMesh.boundaryElements) &&\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n // Create a new array without the empty first element\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n\n // If boundary node pairs exist but boundary elements haven't been processed\n if (this.parsedMesh.boundaryNodePairs && !this.parsedMesh.boundaryElementsProcessed) {\n // Reset boundary elements array\n this.parsedMesh.boundaryElements = [];\n\n // Process each physical property from the Gmsh file\n this.parsedMesh.physicalPropMap.forEach((prop) => {\n // Only process 1D physical entities (boundary lines)\n if (prop.dimension === 1) {\n // Get all node pairs for this boundary\n const boundaryNodePairs = this.parsedMesh.boundaryNodePairs[prop.tag] || [];\n\n if (boundaryNodePairs.length > 0) {\n // Initialize array for this boundary tag\n if (!this.parsedMesh.boundaryElements[prop.tag]) {\n this.parsedMesh.boundaryElements[prop.tag] = [];\n }\n\n // For each boundary line segment (defined by a pair of nodes)\n boundaryNodePairs.forEach((nodesPair) => {\n const node1 = nodesPair[0]; // First node in the pair\n const node2 = nodesPair[1]; // Second node in the pair\n\n debugLog(\n `Processing boundary node pair: [${node1}, ${node2}] for boundary ${prop.tag} (${\n prop.name || \"unnamed\"\n })`\n );\n\n // Search through all elements to find which one contains both nodes\n let foundElement = false;\n\n // Loop through all elements in the mesh\n for (let elemIdx = 0; elemIdx < this.parsedMesh.nodalNumbering.length; elemIdx++) {\n const elemNodes = this.parsedMesh.nodalNumbering[elemIdx];\n\n // For linear quadrilateral linear elements (4 nodes)\n if (elemNodes.length === 4) {\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript linear quadrilateral numbering:\n // 1 --- 3\n // | |\n // 0 --- 2\n\n if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0)\n ) {\n side = 0; // Bottom side\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0)\n ) {\n side = 1; // Left side\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 1 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 1)\n ) {\n side = 2; // Top side\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 2)\n ) {\n side = 3; // Right side\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n } else if (elemNodes.length === 9) {\n // For quadratic quadrilateral elements (9 nodes)\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript quadratic quadrilateral numbering:\n // 2--5--8\n // | |\n // 1 4 7\n // | |\n // 0--3--6\n\n if (\n (node1Index === 0 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 0) ||\n (node1Index === 3 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 3)\n ) {\n side = 0; // Bottom side (nodes 0, 3, 6)\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0) ||\n (node1Index === 1 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 1)\n ) {\n side = 1; // Left side (nodes 0, 1, 2)\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 5) ||\n (node1Index === 5 && node2Index === 2) ||\n (node1Index === 5 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 5)\n ) {\n side = 2; // Top side (nodes 2, 5, 8)\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 6 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 7) ||\n (node1Index === 7 && node2Index === 6) ||\n (node1Index === 7 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 7)\n ) {\n side = 3; // Right side (nodes 6, 7, 8)\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n }\n }\n\n if (!foundElement) {\n errorLog(\n `Could not find element containing boundary nodes ${node1} and ${node2}. Boundary may be incomplete.`\n );\n }\n });\n }\n }\n });\n\n // Mark as processed\n this.parsedMesh.boundaryElementsProcessed = true;\n\n // Fix boundary elements array - remove undefined entries\n if (\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n }\n }\n }\n }\n\n debugLog(\"Processed boundary elements by tag: \" + JSON.stringify(this.parsedMesh.boundaryElements));\n\n return this.parsedMesh;\n } else {\n // Validate required geometry parameters based on mesh dimension\n if (this.meshDimension === \"1D\") {\n if (this.numElementsX === null || this.maxX === null) {\n errorLog(\"numElementsX and maxX are required parameters when generating a 1D mesh from geometry\");\n }\n } else if (this.meshDimension === \"2D\") {\n if (\n this.numElementsX === null ||\n this.maxX === null ||\n this.numElementsY === null ||\n this.maxY === null\n ) {\n errorLog(\n \"numElementsX, maxX, numElementsY, and maxY are required parameters when generating a 2D mesh from geometry\"\n );\n }\n }\n\n // Generate mesh based on dimension\n return this.generateMeshFromGeometry();\n }\n }\n\n /**\n * Function to generate a structured mesh based on the geometry configuration\n * @returns {object} An object containing the coordinates of nodes,\n * total number of nodes, nodal numbering (NOP) array, and boundary elements\n */\n generateMeshFromGeometry() {\n let nodesXCoordinates = [];\n let nodesYCoordinates = [];\n const xStart = 0;\n const yStart = 0;\n let totalNodesX, totalNodesY, deltaX, deltaY;\n\n if (this.meshDimension === \"1D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX;\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX / 2;\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n null, // numElementsY (not used in 1D)\n totalNodesX,\n null, // totalNodesY (not used in 1D)\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n\n // Return x coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n totalNodesX,\n nodalNumbering,\n boundaryElements,\n };\n } else if (this.meshDimension === \"2D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n totalNodesY = this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + nodeIndexY * deltaY;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + nodeIndexX * deltaX;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + nodeIndexY * deltaY;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n totalNodesY = 2 * this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + (nodeIndexY * deltaY) / 2;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + (nodeIndexX * deltaX) / 2;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + (nodeIndexY * deltaY) / 2;\n }\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n this.numElementsY,\n totalNodesX,\n totalNodesY,\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n debugLog(\"Generated node Y coordinates: \" + JSON.stringify(nodesYCoordinates));\n\n // Return x and y coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n nodesYCoordinates,\n totalNodesX,\n totalNodesY,\n nodalNumbering,\n boundaryElements,\n };\n }\n }\n\n /**\n * Function to find the elements that belong to each boundary of a domain\n * @returns {array} An array containing arrays of elements and their adjacent boundary side for each boundary\n * Each element in the array is of the form [elementIndex, side], where 'side' indicates which side\n * of the reference element is in contact with the physical boundary:\n *\n * For 1D domains (line segments):\n * 0 - Left node of reference element (maps to physical left endpoint)\n * 1 - Right node of reference element (maps to physical right endpoint)\n *\n * For 2D domains (rectangular):\n * 0 - Bottom side of reference element (maps to physical bottom boundary)\n * 1 - Left side of reference element (maps to physical left boundary)\n * 2 - Top side of reference element (maps to physical top boundary)\n * 3 - Right side of reference element (maps to physical right boundary)\n */\n findBoundaryElements() {\n const boundaryElements = [];\n const maxSides = this.meshDimension === \"1D\" ? 2 : 4; // Number of element sides based on mesh dimension\n for (let sideIndex = 0; sideIndex < maxSides; sideIndex++) {\n boundaryElements.push([]);\n }\n\n if (this.meshDimension === \"1D\") {\n // Left boundary (element 0, side 0)\n boundaryElements[0].push([0, 0]);\n\n // Right boundary (last element, side 1)\n boundaryElements[1].push([this.numElementsX - 1, 1]);\n } else if (this.meshDimension === \"2D\") {\n for (let elementIndexX = 0; elementIndexX < this.numElementsX; elementIndexX++) {\n for (let elementIndexY = 0; elementIndexY < this.numElementsY; elementIndexY++) {\n const elementIndex = elementIndexX * this.numElementsY + elementIndexY;\n\n // Bottom boundary\n if (elementIndexY === 0) {\n boundaryElements[0].push([elementIndex, 0]);\n }\n\n // Left boundary\n if (elementIndexX === 0) {\n boundaryElements[1].push([elementIndex, 1]);\n }\n\n // Top boundary\n if (elementIndexY === this.numElementsY - 1) {\n boundaryElements[2].push([elementIndex, 2]);\n }\n\n // Right boundary\n if (elementIndexX === this.numElementsX - 1) {\n boundaryElements[3].push([elementIndex, 3]);\n }\n }\n }\n }\n\n debugLog(\"Identified boundary elements by side: \" + JSON.stringify(boundaryElements));\n return boundaryElements;\n }\n\n /**\n * Function to generate the nodal numbering (NOP) array for a structured mesh\n * This array represents the connectivity between elements and their corresponding nodes\n * @param {number} numElementsX - Number of elements along the x-axis\n * @param {number} [numElementsY] - Number of elements along the y-axis (optional for 1D)\n * @param {number} totalNodesX - Total number of nodes along the x-axis\n * @param {number} [totalNodesY] - Total number of nodes along the y-axis (optional for 1D)\n * @param {string} elementOrder - The order of elements, either 'linear' or 'quadratic'\n * @returns {array} NOP - A two-dimensional array which represents the element-to-node connectivity for the entire mesh\n */\n generateNodalNumbering(numElementsX, numElementsY, totalNodesX, totalNodesY, elementOrder) {\n let elementIndex = 0;\n let nop = [];\n\n if (this.meshDimension === \"1D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear 1D elements with the following nodes representation:\n *\n * 1 --- 2\n *\n */\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 2; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic 1D elements with the following nodes representation:\n *\n * 1--2--3\n *\n */\n let columnCounter = 0;\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 3; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex + columnCounter;\n }\n columnCounter += 1;\n }\n }\n } else if (this.meshDimension === \"2D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear rectangular elements with the following nodes representation:\n *\n * 1 --- 3\n * | |\n * 0 --- 2\n *\n */\n let rowCounter = 0;\n let columnCounter = 2;\n for (let elementIndex = 0; elementIndex < numElementsX * numElementsY; elementIndex++) {\n rowCounter += 1;\n nop[elementIndex] = [];\n nop[elementIndex][0] = elementIndex + columnCounter - 1;\n nop[elementIndex][1] = elementIndex + columnCounter;\n nop[elementIndex][2] = elementIndex + columnCounter + numElementsY;\n nop[elementIndex][3] = elementIndex + columnCounter + numElementsY + 1;\n if (rowCounter === numElementsY) {\n columnCounter += 1;\n rowCounter = 0;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic rectangular elements with the following nodes representation:\n *\n * 2--5--8\n * | |\n * 1 4 7\n * | |\n * 0--3--6\n *\n */\n for (let elementIndexX = 1; elementIndexX <= numElementsX; elementIndexX++) {\n for (let elementIndexY = 1; elementIndexY <= numElementsY; elementIndexY++) {\n nop[elementIndex] = [];\n for (let nodeIndex1 = 1; nodeIndex1 <= 3; nodeIndex1++) {\n let nodeIndex2 = 3 * nodeIndex1 - 2;\n nop[elementIndex][nodeIndex2 - 1] =\n totalNodesY * (2 * elementIndexX + nodeIndex1 - 3) + 2 * elementIndexY - 1;\n nop[elementIndex][nodeIndex2] = nop[elementIndex][nodeIndex2 - 1] + 1;\n nop[elementIndex][nodeIndex2 + 1] = nop[elementIndex][nodeIndex2 - 1] + 2;\n }\n elementIndex = elementIndex + 1;\n }\n }\n }\n }\n\n return nop;\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to handle thermal boundary conditions application\n */\nexport class ThermalBoundaryConditions {\n /**\n * Constructor to initialize the ThermalBoundaryConditions class\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @param {array} boundaryElements - Array containing elements that belong to each boundary\n * @param {array} nop - Nodal numbering (NOP) array representing the connectivity between elements and nodes\n * @param {string} meshDimension - The dimension of the mesh (e.g., \"2D\")\n * @param {string} elementOrder - The order of elements (e.g., \"linear\", \"quadratic\")\n */\n constructor(boundaryConditions, boundaryElements, nop, meshDimension, elementOrder) {\n this.boundaryConditions = boundaryConditions;\n this.boundaryElements = boundaryElements;\n this.nop = nop;\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n }\n\n /**\n * Function to impose constant temperature boundary conditions (Dirichlet type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n */\n imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix) {\n basicLog(\"Applying constant temperature boundary conditions (Dirichlet type)\");\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 1: [1], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 2: [2], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0, 2], // Nodes at the bottom side of the reference element\n 1: [0, 1], // Nodes at the left side of the reference element\n 2: [1, 3], // Nodes at the top side of the reference element\n 3: [2, 3], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0, 3, 6], // Nodes at the bottom side of the reference element\n 1: [0, 1, 2], // Nodes at the left side of the reference element\n 2: [2, 5, 8], // Nodes at the top side of the reference element\n 3: [6, 7, 8], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n }\n }\n\n /**\n * Function to impose convection boundary conditions (Robin type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n * @param {array} gaussPoints - Array of Gauss points for numerical integration\n * @param {array} gaussWeights - Array of Gauss weights for numerical integration\n * @param {array} nodesXCoordinates - Array of x-coordinates of nodes\n * @param {array} nodesYCoordinates - Array of y-coordinates of nodes\n * @param {object} basisFunctionsData - Object containing basis functions and their derivatives\n */\n imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n ) {\n basicLog(\"Applying convection boundary conditions (Robin type)\");\n // Extract convection parameters from boundary conditions\n let convectionHeatTranfCoeff = [];\n let convectionExtTemp = [];\n Object.keys(this.boundaryConditions).forEach((key) => {\n const boundaryCondition = this.boundaryConditions[key];\n if (boundaryCondition[0] === \"convection\") {\n convectionHeatTranfCoeff[key] = boundaryCondition[1];\n convectionExtTemp[key] = boundaryCondition[2];\n }\n });\n\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n let nodeIndex;\n if (this.elementOrder === \"linear\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 1;\n }\n } else if (this.elementOrder === \"quadratic\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 2;\n }\n }\n\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n residualVector[globalNodeIndex] += -convectionCoeff * extTemp;\n jacobianMatrix[globalNodeIndex][globalNodeIndex] += convectionCoeff;\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 2;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 0;\n lastNodeIndex = 2;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 1;\n firstNodeIndex = 1;\n lastNodeIndex = 4;\n nodeIncrement = 2;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 2;\n lastNodeIndex = 4;\n nodeIncrement = 1;\n }\n\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[0] * tangentVectorLength * basisFunction[localNodeIndex] * convectionCoeff * extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[0] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n for (let gaussPointIndex = 0; gaussPointIndex < 3; gaussPointIndex++) {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 7;\n nodeIncrement = 3;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 1;\n firstNodeIndex = 2;\n lastNodeIndex = 9;\n nodeIncrement = 3;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 6;\n lastNodeIndex = 9;\n nodeIncrement = 1;\n }\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n convectionCoeff *\n extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n }\n }\n });\n }\n });\n }\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nconst proxyMarker = Symbol(\"Comlink.proxy\");\nconst createEndpoint = Symbol(\"Comlink.endpoint\");\nconst releaseProxy = Symbol(\"Comlink.releaseProxy\");\nconst finalizer = Symbol(\"Comlink.finalizer\");\nconst throwMarker = Symbol(\"Comlink.thrown\");\nconst isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n/**\n * Internal transfer handle to handle objects marked to proxy.\n */\nconst proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n};\n/**\n * Internal transfer handler to handle thrown exceptions.\n */\nconst throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n};\n/**\n * Allows customizing the serialization of certain values.\n */\nconst transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n]);\nfunction isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n}\nfunction expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n}\nfunction isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n}\nfunction closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n}\nfunction wrap(ep, target) {\n const pendingListeners = new Map();\n ep.addEventListener(\"message\", function handleMessage(ev) {\n const { data } = ev;\n if (!data || !data.id) {\n return;\n }\n const resolver = pendingListeners.get(data.id);\n if (!resolver) {\n return;\n }\n try {\n resolver(data);\n }\n finally {\n pendingListeners.delete(data.id);\n }\n });\n return createProxy(ep, pendingListeners, [], target);\n}\nfunction throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n}\nfunction releaseEndpoint(ep) {\n return requestResponseMessage(ep, new Map(), {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n}\nconst proxyCounter = new WeakMap();\nconst proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\nfunction registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n}\nfunction unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n}\nfunction createProxy(ep, pendingListeners, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n pendingListeners.clear();\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, pendingListeners, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, pendingListeners, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, pendingListeners, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, pendingListeners, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n}\nfunction myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n}\nfunction processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n}\nconst transferCache = new WeakMap();\nfunction transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n}\nfunction proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n}\nfunction windowEndpoint(w, context = globalThis, targetOrigin = \"*\") {\n return {\n postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),\n addEventListener: context.addEventListener.bind(context),\n removeEventListener: context.removeEventListener.bind(context),\n };\n}\nfunction toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n}\nfunction fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n}\nfunction requestResponseMessage(ep, pendingListeners, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n pendingListeners.set(id, resolve);\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n}\nfunction generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n}\n\nexport { createEndpoint, expose, finalizer, proxy, proxyMarker, releaseProxy, transfer, transferHandlers, windowEndpoint, wrap };\n//# sourceMappingURL=comlink.mjs.map\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { jacobiMethod } from \"./methods/jacobiMethodScript.js\";\nimport { assembleSolidHeatTransferMat } from \"./solvers/solidHeatTransferScript.js\";\nimport { basicLog, debugLog, errorLog } from \"./utilities/loggingScript.js\";\n\n/**\n * Class to implement finite element analysis in JavaScript\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing the solution vector and additional mesh information\n */\nexport class FEAScriptModel {\n constructor() {\n this.solverConfig = null;\n this.meshConfig = {};\n this.boundaryConditions = {};\n this.solverMethod = \"lusolve\"; // Default solver method\n basicLog(\"FEAScriptModel instance created\");\n }\n\n setSolverConfig(solverConfig) {\n this.solverConfig = solverConfig;\n debugLog(`Solver config set to: ${solverConfig}`);\n }\n\n setMeshConfig(meshConfig) {\n this.meshConfig = meshConfig;\n debugLog(\n `Mesh config set with dimensions: ${meshConfig.meshDimension}`\n );\n }\n\n addBoundaryCondition(boundaryKey, condition) {\n this.boundaryConditions[boundaryKey] = condition;\n debugLog(`Boundary condition added for boundary: ${boundaryKey}, type: ${condition[0]}`);\n }\n\n setSolverMethod(solverMethod) {\n this.solverMethod = solverMethod;\n debugLog(`Solver method set to: ${solverMethod}`);\n }\n\n solve() {\n if (!this.solverConfig || !this.meshConfig || !this.boundaryConditions) {\n const error = \"Solver config, mesh config, and boundary conditions must be set before solving.\";\n console.error(error);\n throw new Error(error);\n }\n\n let jacobianMatrix = [];\n let residualVector = [];\n let solutionVector = [];\n let nodesCoordinates = {};\n\n // Assembly matrices\n basicLog(\"Beginning matrix assembly...\");\n console.time(\"assemblyMatrices\");\n if (this.solverConfig === \"solidHeatTransferScript\") {\n basicLog(`Using solver: ${this.solverConfig}`);\n ({ jacobianMatrix, residualVector, nodesCoordinates } = assembleSolidHeatTransferMat(\n this.meshConfig,\n this.boundaryConditions\n ));\n }\n console.timeEnd(\"assemblyMatrices\");\n basicLog(\"Matrix assembly completed\");\n\n // System solving\n basicLog(`Solving system using ${this.solverMethod}...`);\n console.time(\"systemSolving\");\n if (this.solverMethod === \"lusolve\") {\n solutionVector = math.lusolve(jacobianMatrix, residualVector);\n } else if (this.solverMethod === \"jacobi\") {\n // Create initial guess of zeros\n const initialGuess = new Array(residualVector.length).fill(0);\n // Call Jacobi method with desired max iterations and tolerance\n const jacobiResult = jacobiMethod(jacobianMatrix, residualVector, initialGuess, 1000, 1e-6);\n\n // Log convergence information\n if (jacobiResult.converged) {\n debugLog(`Jacobi method converged in ${jacobiResult.iterations} iterations`);\n } else {\n debugLog(`Jacobi method did not converge after ${jacobiResult.iterations} iterations`);\n }\n\n solutionVector = jacobiResult.solution;\n }\n console.timeEnd(\"systemSolving\");\n basicLog(\"System solved successfully\");\n\n return { solutionVector, nodesCoordinates };\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { numericalIntegration } from \"../methods/numericalIntegrationScript.js\";\nimport { basisFunctions } from \"../mesh/basisFunctionsScript.js\";\nimport { meshGeneration } from \"../mesh/meshGenerationScript.js\";\nimport { ThermalBoundaryConditions } from \"./thermalBoundaryConditionsScript.js\";\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to assemble the solid heat transfer matrix\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing:\n * - jacobianMatrix: The assembled Jacobian matrix\n * - residualVector: The assembled residual vector\n * - nodesCoordinates: Object containing x and y coordinates of nodes\n */\nexport function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {\n basicLog(\"Starting solid heat transfer matrix assembly...\");\n\n // Extract mesh details from the configuration object\n const {\n meshDimension, // The dimension of the mesh\n numElementsX, // Number of elements in x-direction\n numElementsY, // Number of elements in y-direction (only for 2D)\n maxX, // Max x-coordinate (m) of the domain\n maxY, // Max y-coordinate (m) of the domain (only for 2D)\n elementOrder, // The order of elements\n parsedMesh, // The pre-parsed mesh data (if available)\n } = meshConfig;\n\n // Create a new instance of the meshGeneration class\n debugLog(\"Generating mesh...\");\n const meshGenerationData = new meshGeneration({\n numElementsX,\n numElementsY,\n maxX,\n maxY,\n meshDimension,\n elementOrder,\n parsedMesh, // Pass the parsed mesh to the mesh generator\n });\n\n // Generate the mesh\n const nodesCoordinatesAndNumbering = meshGenerationData.generateMesh();\n\n // Extract nodes coordinates and nodal numbering (NOP) from the mesh data\n let nodesXCoordinates = nodesCoordinatesAndNumbering.nodesXCoordinates;\n let nodesYCoordinates = nodesCoordinatesAndNumbering.nodesYCoordinates;\n let totalNodesX = nodesCoordinatesAndNumbering.totalNodesX;\n let totalNodesY = nodesCoordinatesAndNumbering.totalNodesY;\n let nop = nodesCoordinatesAndNumbering.nodalNumbering;\n let boundaryElements = nodesCoordinatesAndNumbering.boundaryElements;\n\n // Check the mesh type\n const isParsedMesh = parsedMesh !== undefined && parsedMesh !== null;\n\n // Calculate totalElements and totalNodes based on mesh type\n let totalElements, totalNodes;\n\n if (isParsedMesh) {\n totalElements = nop.length; // Number of elements is the length of the nodal numbering array\n totalNodes = nodesXCoordinates.length; // Number of nodes is the length of the coordinates array\n\n // Debug log for mesh size\n debugLog(`Using parsed mesh with ${totalElements} elements and ${totalNodes} nodes`);\n } else {\n // For structured mesh, calculate based on dimensions\n totalElements = numElementsX * (meshDimension === \"2D\" ? numElementsY : 1);\n totalNodes = totalNodesX * (meshDimension === \"2D\" ? totalNodesY : 1);\n // Debug log for mesh size\n debugLog(`Using mesh generated from geometry with ${totalElements} elements and ${totalNodes} nodes`);\n }\n\n // Initialize variables for matrix assembly\n let localToGlobalMap = []; // Maps local element node indices to global mesh node indices\n let gaussPoints = []; // Gauss points\n let gaussWeights = []; // Gauss weights\n let basisFunction = []; // Basis functions\n let basisFunctionDerivKsi = []; // Derivatives of basis functions with respect to ksi\n let basisFunctionDerivEta = []; // Derivatives of basis functions with respect to eta (only for 2D)\n let basisFunctionDerivX = []; // The x-derivative of the basis function\n let basisFunctionDerivY = []; // The y-derivative of the basis function (only for 2D)\n let residualVector = []; // Galerkin residuals\n let jacobianMatrix = []; // Jacobian matrix\n let xCoordinates; // x-coordinate (physical coordinates)\n let yCoordinates; // y-coordinate (physical coordinates) (only for 2D)\n let ksiDerivX; // ksi-derivative of xCoordinates\n let etaDerivX; // eta-derivative of xCoordinates (ksi and eta are natural coordinates that vary within a reference element) (only for 2D)\n let ksiDerivY; // ksi-derivative of yCoordinates (only for 2D)\n let etaDerivY; // eta-derivative of yCoordinates (only for 2D)\n let detJacobian; // The jacobian of the isoparametric mapping\n\n // Initialize jacobianMatrix and residualVector arrays\n for (let nodeIndex = 0; nodeIndex < totalNodes; nodeIndex++) {\n residualVector[nodeIndex] = 0;\n jacobianMatrix.push([]);\n for (let colIndex = 0; colIndex < totalNodes; colIndex++) {\n jacobianMatrix[nodeIndex][colIndex] = 0;\n }\n }\n\n // Initialize the basisFunctions class\n const basisFunctionsData = new basisFunctions({\n meshDimension,\n elementOrder,\n });\n\n // Initialize the numericalIntegration class\n const numIntegrationData = new numericalIntegration({\n meshDimension,\n elementOrder,\n });\n\n // Calculate Gauss points and weights\n let gaussPointsAndWeights = numIntegrationData.getGaussPointsAndWeights();\n gaussPoints = gaussPointsAndWeights.gaussPoints;\n gaussWeights = gaussPointsAndWeights.gaussWeights;\n\n // Determine the number of nodes in the reference element based on the first element in the nop array\n const numNodes = nop[0].length;\n\n // Matrix assembly\n for (let elementIndex = 0; elementIndex < totalElements; elementIndex++) {\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n // Subtract 1 from nop in order to start numbering from 0\n localToGlobalMap[localNodeIndex] = nop[elementIndex][localNodeIndex] - 1;\n }\n\n // Loop over Gauss points\n for (let gaussPointIndex1 = 0; gaussPointIndex1 < gaussPoints.length; gaussPointIndex1++) {\n // 1D solid heat transfer\n if (meshDimension === \"1D\") {\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n xCoordinates = 0;\n ksiDerivX = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates += nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n detJacobian = ksiDerivX;\n }\n\n // Compute x-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] = basisFunctionDerivKsi[localNodeIndex] / detJacobian; // The x-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2]);\n }\n }\n // 2D solid heat transfer\n } else if (meshDimension === \"2D\") {\n for (let gaussPointIndex2 = 0; gaussPointIndex2 < gaussPoints.length; gaussPointIndex2++) {\n // Initialise variables for isoparametric mapping\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1],\n gaussPoints[gaussPointIndex2]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n xCoordinates = 0;\n yCoordinates = 0;\n ksiDerivX = 0;\n etaDerivX = 0;\n ksiDerivY = 0;\n etaDerivY = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n yCoordinates +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n ksiDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n detJacobian = meshDimension === \"2D\" ? ksiDerivX * etaDerivY - etaDerivX * ksiDerivY : ksiDerivX;\n }\n\n // Compute x-derivative and y-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] =\n (etaDerivY * basisFunctionDerivKsi[localNodeIndex] -\n ksiDerivY * basisFunctionDerivEta[localNodeIndex]) /\n detJacobian; // The x-derivative of the n basis function\n basisFunctionDerivY[localNodeIndex] =\n (ksiDerivX * basisFunctionDerivEta[localNodeIndex] -\n etaDerivX * basisFunctionDerivKsi[localNodeIndex]) /\n detJacobian; // The y-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n gaussWeights[gaussPointIndex2] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2] +\n basisFunctionDerivY[localNodeIndex1] * basisFunctionDerivY[localNodeIndex2]);\n }\n }\n }\n }\n }\n }\n\n // Create an instance of ThermalBoundaryConditions\n debugLog(\"Applying thermal boundary conditions...\");\n const thermalBoundaryConditions = new ThermalBoundaryConditions(\n boundaryConditions,\n boundaryElements,\n nop,\n meshDimension,\n elementOrder\n );\n\n // Impose Convection boundary conditions\n thermalBoundaryConditions.imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n );\n debugLog(\"Convection boundary conditions applied\");\n\n // Impose ConstantTemp boundary conditions\n thermalBoundaryConditions.imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix);\n debugLog(\"Constant temperature boundary conditions applied\");\n\n basicLog(\"Solid heat transfer matrix assembly completed\");\n\n return {\n jacobianMatrix,\n residualVector,\n nodesCoordinates: {\n nodesXCoordinates,\n nodesYCoordinates,\n },\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to solve a system of linear equations using the Jacobi iterative method\n * @param {array} A - The coefficient matrix (must be square)\n * @param {array} b - The right-hand side vector\n * @param {array} x0 - Initial guess for solution vector\n * @param {number} [maxIterations=100] - Maximum number of iterations\n * @param {number} [tolerance=1e-7] - Convergence tolerance\n * @returns {object} An object containing:\n * - solution: The solution vector\n * - iterations: The number of iterations performed\n * - converged: Boolean indicating whether the method converged\n */\nexport function jacobiMethod(A, b, x0, maxIterations = 100, tolerance = 1e-7) {\n const n = A.length; // Size of the square matrix\n let x = [...x0]; // Current solution (starts with initial guess)\n let xNew = new Array(n); // Next iteration's solution\n\n for (let iteration = 0; iteration < maxIterations; iteration++) {\n // Perform one iteration\n for (let i = 0; i < n; i++) {\n let sum = 0;\n // Calculate sum of A[i][j] * x[j] for j ≠ i\n for (let j = 0; j < n; j++) {\n if (j !== i) {\n sum += A[i][j] * x[j];\n }\n }\n // Update xNew[i] using the Jacobi formula\n xNew[i] = (b[i] - sum) / A[i][i];\n }\n\n // Check convergence\n let maxDiff = 0;\n for (let i = 0; i < n; i++) {\n maxDiff = Math.max(maxDiff, Math.abs(xNew[i] - x[i]));\n }\n\n // Update x for next iteration\n x = [...xNew];\n\n // Successfully converged if maxDiff is less than tolerance\n if (maxDiff < tolerance) {\n return {\n solution: x,\n iterations: iteration + 1,\n converged: true,\n };\n }\n }\n\n // maxIterations were reached without convergence\n return {\n solution: x,\n iterations: maxIterations,\n converged: false,\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// External imports\nimport * as Comlink from \"../vendor/comlink.mjs\";\n\n// Internal imports\nimport { basicLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to facilitate communication with web workers for FEAScript operations\n */\nexport class FEAScriptWorker {\n /**\n * Constructor to initialize the FEAScriptWorker class\n * Sets up the worker and initializes the workerWrapper.\n */\n constructor() {\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n\n this._initWorker();\n }\n\n /**\n * Function to initialize the web worker and wrap it using Comlink.\n * @private\n * @throws Will throw an error if the worker fails to initialize.\n */\n async _initWorker() {\n try {\n this.worker = new Worker(new URL(\"./wrapperScript.js\", import.meta.url), {\n type: \"module\",\n });\n\n this.worker.onerror = (event) => {\n console.error(\"FEAScriptWorker: Worker error:\", event);\n };\n const workerWrapper = Comlink.wrap(this.worker);\n\n this.feaWorker = await new workerWrapper();\n\n this.isReady = true;\n } catch (error) {\n console.error(\"Failed to initialize worker\", error);\n throw error;\n }\n }\n\n /**\n * Function to ensure that the worker is ready before performing any operations.\n * @private\n * @returns {Promise} Resolves when the worker is ready.\n * @throws Will throw an error if the worker is not ready within the timeout period.\n */\n async _ensureReady() {\n if (this.isReady) return Promise.resolve();\n\n return new Promise((resolve, reject) => {\n let attempts = 0;\n const maxAttempts = 50; // 5 seconds max\n\n const checkReady = () => {\n attempts++;\n if (this.isReady) {\n resolve();\n } else if (attempts >= maxAttempts) {\n reject(new Error(\"Timeout waiting for worker to be ready\"));\n } else {\n setTimeout(checkReady, 1000);\n }\n };\n checkReady();\n });\n }\n\n /**\n * Function to set the solver configuration in the worker.\n * @param {string} solverConfig - The solver configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setSolverConfig(solverConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver config to: ${solverConfig}`);\n return this.feaWorker.setSolverConfig(solverConfig);\n }\n\n /**\n * Sets the mesh configuration in the worker.\n * @param {object} meshConfig - The mesh configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setMeshConfig(meshConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting mesh config`);\n return this.feaWorker.setMeshConfig(meshConfig);\n }\n\n /**\n * Adds a boundary condition to the worker.\n * @param {string} boundaryKey - The key identifying the boundary.\n * @param {array} condition - The boundary condition to add.\n * @returns {Promise} Resolves when the boundary condition is added.\n */\n async addBoundaryCondition(boundaryKey, condition) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Adding boundary condition for boundary: ${boundaryKey}`);\n return this.feaWorker.addBoundaryCondition(boundaryKey, condition);\n }\n\n /**\n * Sets the solver method in the worker.\n * @param {string} solverMethod - The solver method to set.\n * @returns {Promise} Resolves when the solver method is set.\n */\n async setSolverMethod(solverMethod) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver method to: ${solverMethod}`);\n return this.feaWorker.setSolverMethod(solverMethod);\n }\n\n /**\n * Requests the worker to solve the problem.\n * @returns {Promise} Resolves with the solution result.\n */\n async solve() {\n await this._ensureReady();\n basicLog(\"FEAScriptWorker: Requesting solution from worker...\");\n\n const startTime = performance.now();\n const result = await this.feaWorker.solve();\n const endTime = performance.now();\n\n basicLog(`FEAScriptWorker: Solution completed in ${((endTime - startTime) / 1000).toFixed(2)}s`);\n return result;\n }\n\n /**\n * Retrieves model information from the worker.\n * @returns {Promise} Resolves with the model information.\n */\n async getModelInfo() {\n await this._ensureReady();\n return this.feaWorker.getModelInfo();\n }\n\n /**\n * Sends a ping request to the worker to check its availability.\n * @returns {Promise} Resolves if the worker responds.\n */\n async ping() {\n await this._ensureReady();\n return this.feaWorker.ping();\n }\n\n /**\n * Terminates the worker and cleans up resources.\n */\n terminate() {\n if (this.worker) {\n this.worker.terminate();\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n }\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\nexport { FEAScriptModel } from \"./FEAScript.js\";\nexport { importGmshQuadTri } from \"./readers/gmshReaderScript.js\";\nexport { logSystem, printVersion } from \"./utilities/loggingScript.js\";\nexport { plotSolution } from \"./visualization/plotSolutionScript.js\";\nexport { FEAScriptWorker } from \"./workers/workerScript.js\";\nexport const VERSION = \"0.1.1\";","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to import mesh data from Gmsh format containing quadrilateral and triangular elements\n * @param {File} file - The Gmsh file to be parsed (.msh version 4.1)\n * @returns {object} The parsed mesh data including node coordinates, element connectivity, and boundary conditions\n */\nconst importGmshQuadTri = async (file) => {\n let result = {\n nodesXCoordinates: [],\n nodesYCoordinates: [],\n nodalNumbering: {\n quadElements: [],\n triangleElements: [],\n },\n boundaryElements: [],\n boundaryConditions: [],\n boundaryNodePairs: {}, // Store boundary node pairs for processing in meshGenerationScript\n gmshV: 0,\n ascii: false,\n fltBytes: \"8\",\n totalNodesX: 0,\n totalNodesY: 0,\n physicalPropMap: [],\n elementTypes: {},\n };\n\n let content = await file.text();\n let lines = content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\" && line !== \" \");\n\n let section = \"\";\n let lineIndex = 0;\n\n let nodeEntityBlocks = 0;\n let totalNodes = 0;\n let nodeBlocksProcessed = 0;\n let currentNodeBlock = { numNodes: 0 };\n let nodeTagsCollected = 0;\n let nodeTags = [];\n let nodeCoordinatesCollected = 0;\n\n let elementEntityBlocks = 0;\n let totalElements = 0;\n let elementBlocksProcessed = 0;\n let currentElementBlock = {\n dim: 0,\n tag: 0,\n elementType: 0,\n numElements: 0,\n };\n let elementsProcessedInBlock = 0;\n\n let boundaryElementsByTag = {};\n\n while (lineIndex < lines.length) {\n const line = lines[lineIndex];\n\n if (line === \"$MeshFormat\") {\n section = \"meshFormat\";\n lineIndex++;\n continue;\n } else if (line === \"$EndMeshFormat\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$PhysicalNames\") {\n section = \"physicalNames\";\n lineIndex++;\n continue;\n } else if (line === \"$EndPhysicalNames\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Entities\") {\n section = \"entities\";\n lineIndex++;\n continue;\n } else if (line === \"$EndEntities\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Nodes\") {\n section = \"nodes\";\n lineIndex++;\n continue;\n } else if (line === \"$EndNodes\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Elements\") {\n section = \"elements\";\n lineIndex++;\n continue;\n } else if (line === \"$EndElements\") {\n section = \"\";\n lineIndex++;\n continue;\n }\n\n const parts = line.split(/\\s+/).filter((part) => part !== \"\");\n\n if (section === \"meshFormat\") {\n result.gmshV = parseFloat(parts[0]);\n result.ascii = parts[1] === \"0\";\n result.fltBytes = parts[2];\n } else if (section === \"physicalNames\") {\n if (parts.length >= 3) {\n if (!/^\\d+$/.test(parts[0])) {\n lineIndex++;\n continue;\n }\n\n const dimension = parseInt(parts[0], 10);\n const tag = parseInt(parts[1], 10);\n let name = parts.slice(2).join(\" \");\n name = name.replace(/^\"|\"$/g, \"\");\n\n result.physicalPropMap.push({\n tag,\n dimension,\n name,\n });\n }\n } else if (section === \"nodes\") {\n if (nodeEntityBlocks === 0) {\n nodeEntityBlocks = parseInt(parts[0], 10);\n totalNodes = parseInt(parts[1], 10);\n result.nodesXCoordinates = new Array(totalNodes).fill(0);\n result.nodesYCoordinates = new Array(totalNodes).fill(0);\n lineIndex++;\n continue;\n }\n\n if (nodeBlocksProcessed < nodeEntityBlocks && currentNodeBlock.numNodes === 0) {\n currentNodeBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n parametric: parseInt(parts[2], 10),\n numNodes: parseInt(parts[3], 10),\n };\n\n nodeTags = [];\n nodeTagsCollected = 0;\n nodeCoordinatesCollected = 0;\n\n lineIndex++;\n continue;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n for (let i = 0; i < parts.length && nodeTagsCollected < currentNodeBlock.numNodes; i++) {\n nodeTags.push(parseInt(parts[i], 10));\n nodeTagsCollected++;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n lineIndex++;\n continue;\n }\n\n lineIndex++;\n continue;\n }\n\n if (nodeCoordinatesCollected < currentNodeBlock.numNodes) {\n const nodeTag = nodeTags[nodeCoordinatesCollected] - 1;\n const x = parseFloat(parts[0]);\n const y = parseFloat(parts[1]);\n\n result.nodesXCoordinates[nodeTag] = x;\n result.nodesYCoordinates[nodeTag] = y;\n result.totalNodesX++;\n result.totalNodesY++;\n\n nodeCoordinatesCollected++;\n\n if (nodeCoordinatesCollected === currentNodeBlock.numNodes) {\n nodeBlocksProcessed++;\n currentNodeBlock = { numNodes: 0 };\n }\n }\n } else if (section === \"elements\") {\n if (elementEntityBlocks === 0) {\n elementEntityBlocks = parseInt(parts[0], 10);\n totalElements = parseInt(parts[1], 10);\n lineIndex++;\n continue;\n }\n\n if (elementBlocksProcessed < elementEntityBlocks && currentElementBlock.numElements === 0) {\n currentElementBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n elementType: parseInt(parts[2], 10),\n numElements: parseInt(parts[3], 10),\n };\n\n result.elementTypes[currentElementBlock.elementType] =\n (result.elementTypes[currentElementBlock.elementType] || 0) + currentElementBlock.numElements;\n\n elementsProcessedInBlock = 0;\n lineIndex++;\n continue;\n }\n\n if (elementsProcessedInBlock < currentElementBlock.numElements) {\n const elementTag = parseInt(parts[0], 10);\n const nodeIndices = parts.slice(1).map((idx) => parseInt(idx, 10));\n\n if (currentElementBlock.elementType === 1 || currentElementBlock.elementType === 8) {\n const physicalTag = currentElementBlock.tag;\n\n if (!boundaryElementsByTag[physicalTag]) {\n boundaryElementsByTag[physicalTag] = [];\n }\n\n boundaryElementsByTag[physicalTag].push(nodeIndices);\n\n // Store boundary node pairs for later processing in meshGenerationScript\n if (!result.boundaryNodePairs[physicalTag]) {\n result.boundaryNodePairs[physicalTag] = [];\n }\n result.boundaryNodePairs[physicalTag].push(nodeIndices);\n } else if (currentElementBlock.elementType === 2) {\n // Linear triangle elements (3 nodes)\n result.nodalNumbering.triangleElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 3) {\n // Linear quadrilateral elements (4 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 10) {\n // Quadratic quadrilateral elements (9 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n }\n\n elementsProcessedInBlock++;\n\n if (elementsProcessedInBlock === currentElementBlock.numElements) {\n elementBlocksProcessed++;\n currentElementBlock = { numElements: 0 };\n }\n }\n }\n\n lineIndex++;\n }\n\n // Store boundary conditions information\n result.physicalPropMap.forEach((prop) => {\n if (prop.dimension === 1) {\n const boundaryNodes = boundaryElementsByTag[prop.tag] || [];\n\n if (boundaryNodes.length > 0) {\n result.boundaryConditions.push({\n name: prop.name,\n tag: prop.tag,\n nodes: boundaryNodes,\n });\n }\n }\n });\n\n debugLog(\n `Parsed boundary node pairs by physical tag: ${JSON.stringify(\n result.boundaryNodePairs\n )}. These pairs will be used to identify boundary elements in the mesh.`\n );\n\n return result;\n};\n\nexport { importGmshQuadTri };\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to create plots of the solution vector\n * @param {*} solutionVector - The computed solution vector\n * @param {*} nodesCoordinates - Object containing x and y coordinates for the nodes\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {string} meshDimension - The dimension of the solution\n * @param {string} plotType - The type of plot\n * @param {string} plotDivId - The id of the div where the plot will be rendered\n * @param {string} [meshType=\"structured\"] - Type of mesh: \"structured\" or \"unstructured\"\n */\nexport function plotSolution(\n solutionVector,\n nodesCoordinates,\n solverConfig,\n meshDimension,\n plotType,\n plotDivId,\n meshType = \"structured\"\n) {\n const { nodesXCoordinates, nodesYCoordinates } = nodesCoordinates;\n\n if (meshDimension === \"1D\" && plotType === \"line\") {\n // Check if solutionVector is a nested array\n let yData;\n if (solutionVector.length > 0 && Array.isArray(solutionVector[0])) {\n yData = solutionVector.map((arr) => arr[0]);\n } else {\n yData = solutionVector;\n }\n let xData = Array.from(nodesXCoordinates);\n\n let lineData = {\n x: xData,\n y: yData,\n mode: \"lines\",\n type: \"scatter\",\n line: { color: \"rgb(219, 64, 82)\", width: 2 },\n name: \"Solution\",\n };\n\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxPlotWidth = Math.max(...xData);\n let zoomFactor = maxWindowWidth / maxPlotWidth;\n let plotWidth = Math.max(zoomFactor * maxPlotWidth, 400);\n let plotHeight = 350;\n\n let layout = {\n title: `line plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"Solution\" },\n margin: { l: 70, r: 40, t: 50, b: 50 },\n };\n\n Plotly.newPlot(plotDivId, [lineData], layout, { responsive: true });\n } else if (meshDimension === \"2D\" && plotType === \"contour\") {\n // Use the user-provided mesh type\n const isStructured = meshType === \"structured\";\n \n // For auto-detection (if needed)\n const uniqueXCoords = new Set(nodesXCoordinates).size;\n const uniqueYCoords = new Set(nodesYCoordinates).size;\n \n // Extract scalar values from solution vector\n let zValues = Array.isArray(solutionVector[0]) \n ? solutionVector.map(val => val[0]) \n : solutionVector;\n \n // Common sizing parameters for both plot types\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxX = Math.max(...nodesXCoordinates);\n let maxY = Math.max(...nodesYCoordinates);\n let aspectRatio = maxY / maxX;\n let plotWidth = Math.min(maxWindowWidth, 600);\n let plotHeight = plotWidth * aspectRatio * 0.8; // Slightly reduce height for better appearance\n \n // Common layout properties\n let layout = {\n title: `${plotType} plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"y\" },\n margin: { l: 50, r: 50, t: 50, b: 50 },\n hovermode: 'closest'\n };\n \n if (isStructured) {\n // Calculate the number of nodes along the x-axis and y-axis\n const numNodesX = uniqueXCoords;\n const numNodesY = uniqueYCoords;\n\n // Reshape the nodesXCoordinates and nodesYCoordinates arrays to match the grid dimensions\n let reshapedXCoordinates = math.reshape(Array.from(nodesXCoordinates), [numNodesX, numNodesY]);\n let reshapedYCoordinates = math.reshape(Array.from(nodesYCoordinates), [numNodesX, numNodesY]);\n\n // Reshape the solution array to match the grid dimensions\n let reshapedSolution = math.reshape(Array.from(solutionVector), [numNodesX, numNodesY]);\n\n // Transpose the reshapedSolution array to get column-wise data\n let transposedSolution = math.transpose(reshapedSolution);\n\n // Create an array for x-coordinates used in the contour plot\n let reshapedXForPlot = [];\n for (let i = 0; i < numNodesX * numNodesY; i += numNodesY) {\n let xValue = nodesXCoordinates[i];\n reshapedXForPlot.push(xValue);\n }\n\n // Create the data structure for the contour plot\n let contourData = {\n z: transposedSolution,\n type: \"contour\",\n contours: {\n coloring: \"heatmap\",\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n x: reshapedXForPlot,\n y: reshapedYCoordinates[0],\n name: 'Solution Field'\n };\n\n // Create the plot using Plotly\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n } else {\n // Create an interpolated contour plot for the unstructured mesh\n let contourData = {\n x: nodesXCoordinates,\n y: nodesYCoordinates,\n z: zValues,\n type: 'contour',\n contours: {\n coloring: 'heatmap',\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n name: 'Solution Field'\n };\n \n // Create the plot using only the contour fill\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n }\n }\n}\n"],"names":["numericalIntegration","constructor","meshDimension","elementOrder","this","getGaussPointsAndWeights","gaussPoints","gaussWeights","Math","sqrt","currentLogLevel","debugLog","message","console","log","basicLog","errorLog","basisFunctions","getBasisFunctions","ksi","eta","basisFunction","basisFunctionDerivKsi","basisFunctionDerivEta","l1","c","l2","l3","dl1","dl2","dl3","meshGeneration","numElementsX","maxX","numElementsY","maxY","parsedMesh","generateMesh","nodalNumbering","Array","isArray","quadElements","triangleElements","JSON","stringify","elementTypes","mappedNodalNumbering","elemIdx","length","gmshNodes","feaScriptNodes","push","physicalPropMap","boundaryElements","undefined","fixedBoundaryElements","i","boundaryNodePairs","boundaryElementsProcessed","forEach","prop","dimension","tag","nodesPair","node1","node2","name","foundElement","elemNodes","includes","side","node1Index","indexOf","node2Index","join","generateMeshFromGeometry","nodesXCoordinates","nodesYCoordinates","totalNodesX","totalNodesY","deltaX","deltaY","nodeIndex","generateNodalNumbering","findBoundaryElements","nodeIndexY","nodeIndexX","nnode","maxSides","sideIndex","elementIndexX","elementIndexY","elementIndex","nop","columnCounter","rowCounter","nodeIndex1","nodeIndex2","ThermalBoundaryConditions","boundaryConditions","imposeConstantTempBoundaryConditions","residualVector","jacobianMatrix","Object","keys","boundaryKey","tempValue","globalNodeIndex","colIndex","imposeConvectionBoundaryConditions","basisFunctionsData","convectionHeatTranfCoeff","convectionExtTemp","key","boundaryCondition","convectionCoeff","extTemp","gaussPoint1","gaussPoint2","firstNodeIndex","lastNodeIndex","nodeIncrement","basisFunctionsAndDerivatives","ksiDerivX","ksiDerivY","etaDerivX","etaDerivY","numNodes","tangentVectorLength","localNodeIndex","localNodeIndex2","globalNodeIndex2","gaussPointIndex","proxyMarker","Symbol","createEndpoint","releaseProxy","finalizer","throwMarker","isObject","val","transferHandlers","Map","canHandle","serialize","obj","port1","port2","MessageChannel","expose","deserialize","port","start","wrap","value","serialized","Error","isError","stack","assign","ep","globalThis","allowedOrigins","addEventListener","callback","ev","data","origin","allowedOrigin","RegExp","test","isAllowedOrigin","warn","id","type","path","argumentList","map","fromWireValue","returnValue","parent","slice","reduce","rawValue","apply","proxy","transfers","transferCache","set","transfer","Promise","resolve","catch","then","wireValue","transferables","toWireValue","postMessage","removeEventListener","closeEndPoint","error","TypeError","endpoint","isMessagePort","close","target","pendingListeners","resolver","get","delete","createProxy","throwIfProxyReleased","isReleased","releaseEndpoint","requestResponseMessage","proxyCounter","WeakMap","proxyFinalizers","FinalizationRegistry","newCount","isProxyReleased","Proxy","_target","unregister","unregisterProxy","clear","r","p","toString","bind","_thisArg","rawArgumentList","last","processArguments","construct","register","registerProxy","processed","v","arr","prototype","concat","handler","serializedValue","msg","fill","floor","random","Number","MAX_SAFE_INTEGER","solverConfig","meshConfig","solverMethod","setSolverConfig","setMeshConfig","addBoundaryCondition","condition","setSolverMethod","solve","solutionVector","nodesCoordinates","time","nodesCoordinatesAndNumbering","totalElements","totalNodes","xCoordinates","yCoordinates","detJacobian","localToGlobalMap","basisFunctionDerivX","basisFunctionDerivY","gaussPointsAndWeights","gaussPointIndex1","localNodeIndex1","localToGlobalMap1","localToGlobalMap2","gaussPointIndex2","thermalBoundaryConditions","assembleSolidHeatTransferMat","timeEnd","math","lusolve","jacobiResult","A","b","x0","maxIterations","tolerance","n","x","xNew","iteration","sum","j","maxDiff","max","abs","solution","iterations","converged","jacobiMethod","worker","feaWorker","isReady","_initWorker","Worker","URL","document","require","__filename","href","currentScript","tagName","toUpperCase","src","baseURI","onerror","event","workerWrapper","Comlink.wrap","_ensureReady","reject","attempts","checkReady","setTimeout","startTime","performance","now","result","toFixed","getModelInfo","ping","terminate","async","file","gmshV","ascii","fltBytes","lines","text","split","line","trim","filter","section","lineIndex","nodeEntityBlocks","nodeBlocksProcessed","currentNodeBlock","nodeTagsCollected","nodeTags","nodeCoordinatesCollected","elementEntityBlocks","elementBlocksProcessed","currentElementBlock","dim","elementType","numElements","elementsProcessedInBlock","boundaryElementsByTag","parts","part","parseFloat","parseInt","replace","parametric","nodeTag","y","nodeIndices","idx","physicalTag","boundaryNodes","nodes","level","plotType","plotDivId","meshType","yData","xData","from","lineData","mode","color","width","maxWindowWidth","min","window","innerWidth","maxPlotWidth","zoomFactor","layout","title","height","xaxis","yaxis","margin","l","t","Plotly","newPlot","responsive","isStructured","uniqueXCoords","Set","size","uniqueYCoords","zValues","aspectRatio","plotWidth","hovermode","numNodesX","numNodesY","reshape","reshapedYCoordinates","reshapedSolution","transposedSolution","transpose","reshapedXForPlot","xValue","contourData","z","contours","coloring","showlabels","colorbar","commitResponse","fetch","commitData","json","latestCommitDate","Date","commit","committer","date","toLocaleString"],"mappings":"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"} \ No newline at end of file diff --git a/dist/feascript.esm.js b/dist/feascript.esm.js new file mode 100644 index 0000000..899a50b --- /dev/null +++ b/dist/feascript.esm.js @@ -0,0 +1,7 @@ +class e{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getGaussPointsAndWeights(){let e=[],t=[];return"linear"===this.elementOrder?(e[0]=.5,t[0]=1):"quadratic"===this.elementOrder&&(e[0]=(1-Math.sqrt(.6))/2,e[1]=.5,e[2]=(1+Math.sqrt(.6))/2,t[0]=5/18,t[1]=8/18,t[2]=5/18),{gaussPoints:e,gaussWeights:t}}}let t="basic";function n(e){"basic"!==e&&"debug"!==e?(console.log("%c[WARN] Invalid log level: "+e+". Using basic instead.","color: #FFC107; font-weight: bold;"),t="basic"):(t=e,o(`Log level set to: ${e}`))}function s(e){"debug"===t&&console.log("%c[DEBUG] "+e,"color: #2196F3; font-weight: bold;")}function o(e){console.log("%c[INFO] "+e,"color: #4CAF50; font-weight: bold;")}function i(e){console.log("%c[ERROR] "+e,"color: #F44336; font-weight: bold;")}async function r(){o("Fetching latest FEAScript version information...");try{const e=await fetch("https://api.github.com/repos/FEAScript/FEAScript/commits/main"),t=await e.json(),n=new Date(t.commit.committer.date).toLocaleString();return o(`Latest FEAScript update: ${n}`),n}catch(e){return i("Failed to fetch version information: "+e),"Version information unavailable"}}class a{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getBasisFunctions(e,t=null){let n=[],s=[],o=[];if("1D"===this.meshDimension)"linear"===this.elementOrder?(n[0]=1-e,n[1]=e,s[0]=-1,s[1]=1):"quadratic"===this.elementOrder&&(n[0]=1-3*e+2*e**2,n[1]=4*e-4*e**2,n[2]=2*e**2-e,s[0]=4*e-3,s[1]=4-8*e,s[2]=4*e-1);else if("2D"===this.meshDimension){if(null===t)return void i("Eta coordinate is required for 2D elements");if("linear"===this.elementOrder){function r(e){return 1-e}n[0]=r(e)*r(t),n[1]=r(e)*t,n[2]=e*r(t),n[3]=e*t,s[0]=-1*r(t),s[1]=-1*t,s[2]=1*r(t),s[3]=1*t,o[0]=-1*r(e),o[1]=1*r(e),o[2]=-1*e,o[3]=1*e}else if("quadratic"===this.elementOrder){function a(e){return 2*e**2-3*e+1}function l(e){return-4*e**2+4*e}function d(e){return 2*e**2-e}function h(e){return 4*e-3}function m(e){return-8*e+4}function u(e){return 4*e-1}n[0]=a(e)*a(t),n[1]=a(e)*l(t),n[2]=a(e)*d(t),n[3]=l(e)*a(t),n[4]=l(e)*l(t),n[5]=l(e)*d(t),n[6]=d(e)*a(t),n[7]=d(e)*l(t),n[8]=d(e)*d(t),s[0]=h(e)*a(t),s[1]=h(e)*l(t),s[2]=h(e)*d(t),s[3]=m(e)*a(t),s[4]=m(e)*l(t),s[5]=m(e)*d(t),s[6]=u(e)*a(t),s[7]=u(e)*l(t),s[8]=u(e)*d(t),o[0]=a(e)*h(t),o[1]=a(e)*m(t),o[2]=a(e)*u(t),o[3]=l(e)*h(t),o[4]=l(e)*m(t),o[5]=l(e)*u(t),o[6]=d(e)*h(t),o[7]=d(e)*m(t),o[8]=d(e)*u(t)}}return{basisFunction:n,basisFunctionDerivKsi:s,basisFunctionDerivEta:o}}}class l{constructor({numElementsX:e=null,maxX:t=null,numElementsY:n=null,maxY:s=null,meshDimension:o=null,elementOrder:i="linear",parsedMesh:r=null}){this.numElementsX=e,this.numElementsY=n,this.maxX=t,this.maxY=s,this.meshDimension=o,this.elementOrder=i,this.parsedMesh=r}generateMesh(){if(this.parsedMesh){if(this.parsedMesh.nodalNumbering&&"object"==typeof this.parsedMesh.nodalNumbering&&!Array.isArray(this.parsedMesh.nodalNumbering)){const e=this.parsedMesh.nodalNumbering.quadElements||[];if(this.parsedMesh.nodalNumbering.triangleElements,s("Initial parsed mesh nodal numbering from GMSH format: "+JSON.stringify(this.parsedMesh.nodalNumbering)),this.parsedMesh.elementTypes[3]||this.parsedMesh.elementTypes[10]){const t=[];for(let n=0;n0&&void 0===this.parsedMesh.boundaryElements[0]){const e=[];for(let t=1;t{if(1===e.dimension){const t=this.parsedMesh.boundaryNodePairs[e.tag]||[];t.length>0&&(this.parsedMesh.boundaryElements[e.tag]||(this.parsedMesh.boundaryElements[e.tag]=[]),t.forEach((t=>{const n=t[0],o=t[1];s(`Processing boundary node pair: [${n}, ${o}] for boundary ${e.tag} (${e.name||"unnamed"})`);let r=!1;for(let t=0;t0&&void 0===this.parsedMesh.boundaryElements[0])){const e=[];for(let t=1;t{if("constantTemp"===this.boundaryConditions[n][0]){const o=this.boundaryConditions[n][1];s(`Boundary ${n}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[n].forEach((([n,i])=>{if("linear"===this.elementOrder){({0:[0],1:[1]})[i].forEach((i=>{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{if("constantTemp"===this.boundaryConditions[n][0]){const o=this.boundaryConditions[n][1];s(`Boundary ${n}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[n].forEach((([n,i])=>{if("linear"===this.elementOrder){({0:[0,2],1:[0,1],2:[1,3],3:[2,3]})[i].forEach((i=>{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const t=this.boundaryConditions[e];"convection"===t[0]&&(d[e]=t[1],h[e]=t[2])})),"1D"===this.meshDimension?Object.keys(this.boundaryConditions).forEach((n=>{if("convection"===this.boundaryConditions[n][0]){const o=d[n],i=h[n];s(`Boundary ${n}: Applying convection with heat transfer coefficient h=${o} W/(m²·K) and external temperature T∞=${i} K`),this.boundaryElements[n].forEach((([n,r])=>{let a;"linear"===this.elementOrder?a=0===r?0:1:"quadratic"===this.elementOrder&&(a=0===r?0:2);const l=this.nop[n][a]-1;s(` - Applied convection boundary condition to node ${l+1} (element ${n+1}, local node ${a+1})`),e[l]+=-o*i,t[l][l]+=o}))}})):"2D"===this.meshDimension&&Object.keys(this.boundaryConditions).forEach((o=>{if("convection"===this.boundaryConditions[o][0]){const m=d[o],u=h[o];s(`Boundary ${o}: Applying convection with heat transfer coefficient h=${m} W/(m²·K) and external temperature T∞=${u} K`),this.boundaryElements[o].forEach((([o,d])=>{if("linear"===this.elementOrder){let h,c,f,p,y;0===d?(h=n[0],c=0,f=0,p=3,y=2):1===d?(h=0,c=n[0],f=0,p=2,y=1):2===d?(h=n[0],c=1,f=1,p=4,y=2):3===d&&(h=1,c=n[0],f=2,p=4,y=1);let g=l.getBasisFunctions(h,c),b=g.basisFunction,E=g.basisFunctionDerivKsi,M=g.basisFunctionDerivEta,$=0,v=0,w=0,C=0;const N=this.nop[o].length;for(let e=0;e{let t={nodesXCoordinates:[],nodesYCoordinates:[],nodalNumbering:{quadElements:[],triangleElements:[]},boundaryElements:[],boundaryConditions:[],boundaryNodePairs:{},gmshV:0,ascii:!1,fltBytes:"8",totalNodesX:0,totalNodesY:0,physicalPropMap:[],elementTypes:{}},n=(await e.text()).split("\n").map((e=>e.trim())).filter((e=>""!==e&&" "!==e)),o="",i=0,r=0,a=0,l=0,d={numNodes:0},h=0,m=[],u=0,c=0,f=0,p={dim:0,tag:0,elementType:0,numElements:0},y=0,g={};for(;i""!==e));if("meshFormat"===o)t.gmshV=parseFloat(s[0]),t.ascii="0"===s[1],t.fltBytes=s[2];else if("physicalNames"===o){if(s.length>=3){if(!/^\d+$/.test(s[0])){i++;continue}const e=parseInt(s[0],10),n=parseInt(s[1],10);let o=s.slice(2).join(" ");o=o.replace(/^"|"$/g,""),t.physicalPropMap.push({tag:n,dimension:e,name:o})}}else if("nodes"===o){if(0===r){r=parseInt(s[0],10),a=parseInt(s[1],10),t.nodesXCoordinates=new Array(a).fill(0),t.nodesYCoordinates=new Array(a).fill(0),i++;continue}if(lparseInt(e,10)));if(1===p.elementType||8===p.elementType){const n=p.tag;g[n]||(g[n]=[]),g[n].push(e),t.boundaryNodePairs[n]||(t.boundaryNodePairs[n]=[]),t.boundaryNodePairs[n].push(e)}else 2===p.elementType?t.nodalNumbering.triangleElements.push(e):(3===p.elementType||10===p.elementType)&&t.nodalNumbering.quadElements.push(e);y++,y===p.numElements&&(f++,p={numElements:0})}}i++}return t.physicalPropMap.forEach((e=>{if(1===e.dimension){const n=g[e.tag]||[];n.length>0&&t.boundaryConditions.push({name:e.name,tag:e.tag,nodes:n})}})),s(`Parsed boundary node pairs by physical tag: ${JSON.stringify(t.boundaryNodePairs)}. These pairs will be used to identify boundary elements in the mesh.`),t};function u(e,t,n,s,o,i,r="structured"){const{nodesXCoordinates:a,nodesYCoordinates:l}=t;if("1D"===s&&"line"===o){let t;t=e.length>0&&Array.isArray(e[0])?e.map((e=>e[0])):e;let s=Array.from(a),o={x:s,y:t,mode:"lines",type:"scatter",line:{color:"rgb(219, 64, 82)",width:2},name:"Solution"},r=Math.min(window.innerWidth,700),l=Math.max(...s),d=r/l,h={title:`line plot - ${n}`,width:Math.max(d*l,400),height:350,xaxis:{title:"x"},yaxis:{title:"Solution"},margin:{l:70,r:40,t:50,b:50}};Plotly.newPlot(i,[o],h,{responsive:!0})}else if("2D"===s&&"contour"===o){const t="structured"===r,s=new Set(a).size,d=new Set(l).size;let h=Array.isArray(e[0])?e.map((e=>e[0])):e,m=Math.min(window.innerWidth,700),u=Math.max(...a),c=Math.max(...l)/u,f=Math.min(m,600),p={title:`${o} plot - ${n}`,width:f,height:f*c*.8,xaxis:{title:"x"},yaxis:{title:"y"},margin:{l:50,r:50,t:50,b:50},hovermode:"closest"};if(t){const t=s,n=d;math.reshape(Array.from(a),[t,n]);let o=math.reshape(Array.from(l),[t,n]),r=math.reshape(Array.from(e),[t,n]),h=math.transpose(r),m=[];for(let e=0;e"object"==typeof e&&null!==e||"function"==typeof e,E=new Map([["proxy",{canHandle:e=>b(e)&&e[c],serialize(e){const{port1:t,port2:n}=new MessageChannel;return M(e,t),[n,[n]]},deserialize:e=>(e.start(),v(e))}],["throw",{canHandle:e=>b(e)&&g in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function M(e,t=globalThis,n=["*"]){t.addEventListener("message",(function s(o){if(!o||!o.data)return;if(!function(e,t){for(const n of e){if(t===n||"*"===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}return!1}(n,o.origin))return void console.warn(`Invalid origin '${o.origin}' for comlink proxy`);const{id:i,type:r,path:a}=Object.assign({path:[]},o.data),l=(o.data.argumentList||[]).map(F);let d;try{const t=a.slice(0,-1).reduce(((e,t)=>e[t]),e),n=a.reduce(((e,t)=>e[t]),e);switch(r){case"GET":d=n;break;case"SET":t[a.slice(-1)[0]]=F(o.data.value),d=!0;break;case"APPLY":d=n.apply(t,l);break;case"CONSTRUCT":d=function(e){return Object.assign(e,{[c]:!0})}(new n(...l));break;case"ENDPOINT":{const{port1:t,port2:n}=new MessageChannel;M(e,n),d=function(e,t){return x.set(e,t),e}(t,[t])}break;case"RELEASE":d=void 0;break;default:return}}catch(e){d={value:e,[g]:0}}Promise.resolve(d).catch((e=>({value:e,[g]:0}))).then((n=>{const[o,a]=A(n);t.postMessage(Object.assign(Object.assign({},o),{id:i}),a),"RELEASE"===r&&(t.removeEventListener("message",s),$(t),y in e&&"function"==typeof e[y]&&e[y]())})).catch((e=>{const[n,s]=A({value:new TypeError("Unserializable return value"),[g]:0});t.postMessage(Object.assign(Object.assign({},n),{id:i}),s)}))})),t.start&&t.start()}function $(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function v(e,t){const n=new Map;return e.addEventListener("message",(function(e){const{data:t}=e;if(!t||!t.id)return;const s=n.get(t.id);if(s)try{s(t)}finally{n.delete(t.id)}})),D(e,n,[],t)}function w(e){if(e)throw new Error("Proxy has been released and is not useable")}function C(e){return T(e,new Map,{type:"RELEASE"}).then((()=>{$(e)}))}const N=new WeakMap,S="FinalizationRegistry"in globalThis&&new FinalizationRegistry((e=>{const t=(N.get(e)||0)-1;N.set(e,t),0===t&&C(e)}));function D(e,t,n=[],s=function(){}){let o=!1;const i=new Proxy(s,{get(s,r){if(w(o),r===p)return()=>{!function(e){S&&S.unregister(e)}(i),C(e),t.clear(),o=!0};if("then"===r){if(0===n.length)return{then:()=>i};const s=T(e,t,{type:"GET",path:n.map((e=>e.toString()))}).then(F);return s.then.bind(s)}return D(e,t,[...n,r])},set(s,i,r){w(o);const[a,l]=A(r);return T(e,t,{type:"SET",path:[...n,i].map((e=>e.toString())),value:a},l).then(F)},apply(s,i,r){w(o);const a=n[n.length-1];if(a===f)return T(e,t,{type:"ENDPOINT"}).then(F);if("bind"===a)return D(e,t,n.slice(0,-1));const[l,d]=O(r);return T(e,t,{type:"APPLY",path:n.map((e=>e.toString())),argumentList:l},d).then(F)},construct(s,i){w(o);const[r,a]=O(i);return T(e,t,{type:"CONSTRUCT",path:n.map((e=>e.toString())),argumentList:r},a).then(F)}});return function(e,t){const n=(N.get(t)||0)+1;N.set(t,n),S&&S.register(e,t,e)}(i,e),i}function O(e){const t=e.map(A);return[t.map((e=>e[0])),(n=t.map((e=>e[1])),Array.prototype.concat.apply([],n))];var n}const x=new WeakMap;function A(e){for(const[t,n]of E)if(n.canHandle(e)){const[s,o]=n.serialize(e);return[{type:"HANDLER",name:t,value:s},o]}return[{type:"RAW",value:e},x.get(e)||[]]}function F(e){switch(e.type){case"HANDLER":return E.get(e.name).deserialize(e.value);case"RAW":return e.value}}function T(e,t,n,s){return new Promise((o=>{const i=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");t.set(i,o),e.start&&e.start(),e.postMessage(Object.assign({id:i},n),s)}))}class k{constructor(){this.worker=null,this.feaWorker=null,this.isReady=!1,this._initWorker()}async _initWorker(){try{this.worker=new Worker(new URL("./wrapperScript.js",import.meta.url),{type:"module"}),this.worker.onerror=e=>{console.error("FEAScriptWorker: Worker error:",e)};const e=v(this.worker);this.feaWorker=await new e,this.isReady=!0}catch(e){throw console.error("Failed to initialize worker",e),e}}async _ensureReady(){return this.isReady?Promise.resolve():new Promise(((e,t)=>{let n=0;const s=()=>{n++,this.isReady?e():n>=50?t(new Error("Timeout waiting for worker to be ready")):setTimeout(s,1e3)};s()}))}async setSolverConfig(e){return await this._ensureReady(),o(`FEAScriptWorker: Setting solver config to: ${e}`),this.feaWorker.setSolverConfig(e)}async setMeshConfig(e){return await this._ensureReady(),o("FEAScriptWorker: Setting mesh config"),this.feaWorker.setMeshConfig(e)}async addBoundaryCondition(e,t){return await this._ensureReady(),o(`FEAScriptWorker: Adding boundary condition for boundary: ${e}`),this.feaWorker.addBoundaryCondition(e,t)}async setSolverMethod(e){return await this._ensureReady(),o(`FEAScriptWorker: Setting solver method to: ${e}`),this.feaWorker.setSolverMethod(e)}async solve(){await this._ensureReady(),o("FEAScriptWorker: Requesting solution from worker...");const e=performance.now(),t=await this.feaWorker.solve();return o(`FEAScriptWorker: Solution completed in ${((performance.now()-e)/1e3).toFixed(2)}s`),t}async getModelInfo(){return await this._ensureReady(),this.feaWorker.getModelInfo()}async ping(){return await this._ensureReady(),this.feaWorker.ping()}terminate(){this.worker&&(this.worker.terminate(),this.worker=null,this.feaWorker=null,this.isReady=!1)}}const X="0.1.1";export{h as FEAScriptModel,k as FEAScriptWorker,X as VERSION,m as importGmshQuadTri,n as logSystem,u as plotSolution,r as printVersion}; +//# sourceMappingURL=feascript.esm.js.map diff --git a/dist/feascript.esm.js.map b/dist/feascript.esm.js.map new file mode 100644 index 0000000..ed35053 --- /dev/null +++ b/dist/feascript.esm.js.map @@ -0,0 +1 @@ +{"version":3,"file":"feascript.esm.js","sources":["../src/methods/numericalIntegrationScript.js","../src/utilities/loggingScript.js","../src/mesh/basisFunctionsScript.js","../src/mesh/meshGenerationScript.js","../src/solvers/thermalBoundaryConditionsScript.js","../src/FEAScript.js","../src/solvers/solidHeatTransferScript.js","../src/methods/jacobiMethodScript.js","../src/readers/gmshReaderScript.js","../src/visualization/plotSolutionScript.js","../src/vendor/comlink.mjs","../src/workers/workerScript.js","../src/index.js"],"sourcesContent":["// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Class to handle numerical integration using Gauss quadrature\n */\nexport class numericalIntegration {\n /**\n * Constructor to initialize the numericalIntegration class\n * @param {string} meshDimension - The dimension of the mesh\n * @param {string} elementOrder - The order of elements\n */\n constructor({ meshDimension, elementOrder }) {\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n }\n\n /**\n * Function to return Gauss points and weights based on element configuration\n * @returns {object} An object containing:\n * - gaussPoints: Array of Gauss points\n * - gaussWeights: Array of Gauss weights\n */\n getGaussPointsAndWeights() {\n let gaussPoints = []; // Gauss points\n let gaussWeights = []; // Gauss weights\n\n if (this.elementOrder === \"linear\") {\n // For linear elements, use 1-point Gauss quadrature\n gaussPoints[0] = 0.5;\n gaussWeights[0] = 1;\n } else if (this.elementOrder === \"quadratic\") {\n // For quadratic elements, use 3-point Gauss quadrature\n gaussPoints[0] = (1 - Math.sqrt(3 / 5)) / 2;\n gaussPoints[1] = 0.5;\n gaussPoints[2] = (1 + Math.sqrt(3 / 5)) / 2;\n gaussWeights[0] = 5 / 18;\n gaussWeights[1] = 8 / 18;\n gaussWeights[2] = 5 / 18;\n }\n\n return { gaussPoints, gaussWeights };\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Global logging level\nlet currentLogLevel = \"basic\";\n\n/**\n * Function to set the logging system level\n * @param {string} level - Logging level (basic, debug)\n */\nexport function logSystem(level) {\n if (level !== \"basic\" && level !== \"debug\") {\n console.log(\n \"%c[WARN] Invalid log level: \" + level + \". Using basic instead.\",\n \"color: #FFC107; font-weight: bold;\"\n ); // Yellow for warnings\n currentLogLevel = \"basic\";\n } else {\n currentLogLevel = level;\n basicLog(`Log level set to: ${level}`);\n }\n}\n\n/**\n * Function to log debug messages - only logs if level is 'debug'\n * @param {string} message - Message to log\n */\nexport function debugLog(message) {\n if (currentLogLevel === \"debug\") {\n console.log(\"%c[DEBUG] \" + message, \"color: #2196F3; font-weight: bold;\"); // Blue color for debug\n }\n}\n\n/**\n * Function to log basic information - always logs\n * @param {string} message - Message to log\n */\nexport function basicLog(message) {\n console.log(\"%c[INFO] \" + message, \"color: #4CAF50; font-weight: bold;\"); // Green color for basic info\n}\n\n/**\n * Function to log error messages\n * @param {string} message - Message to log\n */\nexport function errorLog(message) {\n console.log(\"%c[ERROR] \" + message, \"color: #F44336; font-weight: bold;\"); // Red color for errors\n}\n\n/**\n * Function to handle version information and fetch the latest update date and release from GitHub\n */\nexport async function printVersion() {\n basicLog(\"Fetching latest FEAScript version information...\");\n try {\n const commitResponse = await fetch(\"https://api.github.com/repos/FEAScript/FEAScript/commits/main\");\n const commitData = await commitResponse.json();\n const latestCommitDate = new Date(commitData.commit.committer.date).toLocaleString();\n basicLog(`Latest FEAScript update: ${latestCommitDate}`);\n return latestCommitDate;\n } catch (error) {\n errorLog(\"Failed to fetch version information: \" + error);\n return \"Version information unavailable\";\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to handle basis functions and their derivatives based on element configuration\n */\nexport class basisFunctions {\n /**\n * Constructor to initialize the basisFunctions class\n * @param {string} meshDimension - The dimension of the mesh\n * @param {string} elementOrder - The order of elements\n */\n constructor({ meshDimension, elementOrder }) {\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n }\n\n /**\n * Function to calculate basis functions and their derivatives based on the dimension and order\n * @param {number} ksi - Natural coordinate (for both 1D and 2D)\n * @param {number} [eta] - Second natural coordinate (only for 2D elements)\n * @returns {object} An object containing:\n * - basisFunction: Array of evaluated basis functions\n * - basisFunctionDerivKsi: Array of derivatives of basis functions with respect to ksi\n * - basisFunctionDerivEta: Array of derivatives of basis functions with respect to eta (only for 2D elements)\n */\n getBasisFunctions(ksi, eta = null) {\n let basisFunction = [];\n let basisFunctionDerivKsi = [];\n let basisFunctionDerivEta = [];\n\n if (this.meshDimension === \"1D\") {\n if (this.elementOrder === \"linear\") {\n // Linear basis functions for 1D elements\n basisFunction[0] = 1 - ksi;\n basisFunction[1] = ksi;\n\n // Derivatives of basis functions with respect to ksi\n basisFunctionDerivKsi[0] = -1;\n basisFunctionDerivKsi[1] = 1;\n } else if (this.elementOrder === \"quadratic\") {\n // Quadratic basis functions for 1D elements\n basisFunction[0] = 1 - 3 * ksi + 2 * ksi ** 2;\n basisFunction[1] = 4 * ksi - 4 * ksi ** 2;\n basisFunction[2] = -ksi + 2 * ksi ** 2;\n\n // Derivatives of basis functions with respect to ksi\n basisFunctionDerivKsi[0] = -3 + 4 * ksi;\n basisFunctionDerivKsi[1] = 4 - 8 * ksi;\n basisFunctionDerivKsi[2] = -1 + 4 * ksi;\n }\n } else if (this.meshDimension === \"2D\") {\n if (eta === null) {\n errorLog(\"Eta coordinate is required for 2D elements\");\n return;\n }\n\n if (this.elementOrder === \"linear\") {\n // Linear basis functions for 2D elements\n function l1(c) {\n return 1 - c;\n }\n function l2(c) {\n return c;\n }\n function dl1() {\n return -1;\n }\n function dl2() {\n return 1;\n }\n\n // Evaluate basis functions at (ksi, eta)\n basisFunction[0] = l1(ksi) * l1(eta);\n basisFunction[1] = l1(ksi) * l2(eta);\n basisFunction[2] = l2(ksi) * l1(eta);\n basisFunction[3] = l2(ksi) * l2(eta);\n\n // Derivatives with respect to ksi\n basisFunctionDerivKsi[0] = dl1() * l1(eta);\n basisFunctionDerivKsi[1] = dl1() * l2(eta);\n basisFunctionDerivKsi[2] = dl2() * l1(eta);\n basisFunctionDerivKsi[3] = dl2() * l2(eta);\n\n // Derivatives with respect to eta\n basisFunctionDerivEta[0] = l1(ksi) * dl1();\n basisFunctionDerivEta[1] = l1(ksi) * dl2();\n basisFunctionDerivEta[2] = l2(ksi) * dl1();\n basisFunctionDerivEta[3] = l2(ksi) * dl2();\n } else if (this.elementOrder === \"quadratic\") {\n // Quadratic basis functions for 2D elements\n function l1(c) {\n return 2 * c ** 2 - 3 * c + 1;\n }\n function l2(c) {\n return -4 * c ** 2 + 4 * c;\n }\n function l3(c) {\n return 2 * c ** 2 - c;\n }\n function dl1(c) {\n return 4 * c - 3;\n }\n function dl2(c) {\n return -8 * c + 4;\n }\n function dl3(c) {\n return 4 * c - 1;\n }\n\n // Evaluate basis functions at (ksi, eta)\n basisFunction[0] = l1(ksi) * l1(eta);\n basisFunction[1] = l1(ksi) * l2(eta);\n basisFunction[2] = l1(ksi) * l3(eta);\n basisFunction[3] = l2(ksi) * l1(eta);\n basisFunction[4] = l2(ksi) * l2(eta);\n basisFunction[5] = l2(ksi) * l3(eta);\n basisFunction[6] = l3(ksi) * l1(eta);\n basisFunction[7] = l3(ksi) * l2(eta);\n basisFunction[8] = l3(ksi) * l3(eta);\n\n // Derivatives with respect to ksi\n basisFunctionDerivKsi[0] = dl1(ksi) * l1(eta);\n basisFunctionDerivKsi[1] = dl1(ksi) * l2(eta);\n basisFunctionDerivKsi[2] = dl1(ksi) * l3(eta);\n basisFunctionDerivKsi[3] = dl2(ksi) * l1(eta);\n basisFunctionDerivKsi[4] = dl2(ksi) * l2(eta);\n basisFunctionDerivKsi[5] = dl2(ksi) * l3(eta);\n basisFunctionDerivKsi[6] = dl3(ksi) * l1(eta);\n basisFunctionDerivKsi[7] = dl3(ksi) * l2(eta);\n basisFunctionDerivKsi[8] = dl3(ksi) * l3(eta);\n\n // Derivatives with respect to eta\n basisFunctionDerivEta[0] = l1(ksi) * dl1(eta);\n basisFunctionDerivEta[1] = l1(ksi) * dl2(eta);\n basisFunctionDerivEta[2] = l1(ksi) * dl3(eta);\n basisFunctionDerivEta[3] = l2(ksi) * dl1(eta);\n basisFunctionDerivEta[4] = l2(ksi) * dl2(eta);\n basisFunctionDerivEta[5] = l2(ksi) * dl3(eta);\n basisFunctionDerivEta[6] = l3(ksi) * dl1(eta);\n basisFunctionDerivEta[7] = l3(ksi) * dl2(eta);\n basisFunctionDerivEta[8] = l3(ksi) * dl3(eta);\n }\n }\n\n return { basisFunction, basisFunctionDerivKsi, basisFunctionDerivEta };\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to handle the generation of structured finite element meshes\n */\nexport class meshGeneration {\n /**\n * Constructor to initialize the meshGeneration class\n * @param {object} config - Configuration object for the mesh\n * @param {number} [config.numElementsX] - Number of elements along the x-axis (required for geometry-based mesh)\n * @param {number} [config.maxX] - Maximum x-coordinate of the mesh (required for geometry-based mesh)\n * @param {number} [config.numElementsY=1] - Number of elements along the y-axis (for 1D meshes)\n * @param {number} [config.maxY=0] - Maximum y-coordinate of the mesh (for 1D meshes)\n * @param {string} [config.meshDimension='2D'] - The dimension of the mesh, either 1D or 2D\n * @param {string} [config.elementOrder='linear'] - The order of elements, either 'linear' or 'quadratic'\n * @param {object} [config.parsedMesh=null] - Optional pre-parsed mesh data\n */\n constructor({\n numElementsX = null,\n maxX = null,\n numElementsY = null,\n maxY = null,\n meshDimension = null,\n elementOrder = \"linear\",\n parsedMesh = null,\n }) {\n this.numElementsX = numElementsX;\n this.numElementsY = numElementsY;\n this.maxX = maxX;\n this.maxY = maxY;\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n this.parsedMesh = parsedMesh;\n }\n\n /**\n * Function to generate the mesh based on the dimension or use a pre-parsed mesh\n * @returns {object} The generated mesh containing node coordinates and total nodes\n */\n generateMesh() {\n // If pre-parsed mesh data is provided, use it directly\n if (this.parsedMesh) {\n // Process the nodalNumbering from gmshReader format to the format expected by the solver\n if (this.parsedMesh.nodalNumbering) {\n if (\n typeof this.parsedMesh.nodalNumbering === \"object\" &&\n !Array.isArray(this.parsedMesh.nodalNumbering)\n ) {\n // Store the nodal numbering structure before converting\n const quadElements = this.parsedMesh.nodalNumbering.quadElements || [];\n const triangleElements = this.parsedMesh.nodalNumbering.triangleElements || [];\n\n debugLog(\n \"Initial parsed mesh nodal numbering from GMSH format: \" +\n JSON.stringify(this.parsedMesh.nodalNumbering)\n );\n\n // Check if it has quadElements or triangleElements structure from gmshReader\n if (this.parsedMesh.elementTypes[3] || this.parsedMesh.elementTypes[10]) {\n // Map nodal numbering from GMSH format to FEAScript format for quad elements\n const mappedNodalNumbering = [];\n\n for (let elemIdx = 0; elemIdx < quadElements.length; elemIdx++) {\n const gmshNodes = quadElements[elemIdx];\n const feaScriptNodes = new Array(gmshNodes.length);\n\n // Check for element type based on number of nodes\n if (gmshNodes.length === 4) {\n // Simple mapping for linear quad elements (4 nodes)\n // GMSH: FEAScript:\n // 3 --- 2 1 --- 3\n // | | --> | |\n // 0 --- 1 0 --- 2\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[3]; // 3 -> 1\n feaScriptNodes[2] = gmshNodes[1]; // 1 -> 2\n feaScriptNodes[3] = gmshNodes[2]; // 2 -> 3\n } else if (gmshNodes.length === 9) {\n // Mapping for quadratic quad elements (9 nodes)\n // GMSH: FEAScript:\n // 3--6--2 2--5--8\n // | | | |\n // 7 8 5 --> 1 4 7\n // | | | |\n // 0--4--1 0--3--6\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[7]; // 7 -> 1\n feaScriptNodes[2] = gmshNodes[3]; // 3 -> 2\n feaScriptNodes[3] = gmshNodes[4]; // 4 -> 3\n feaScriptNodes[4] = gmshNodes[8]; // 8 -> 4\n feaScriptNodes[5] = gmshNodes[6]; // 6 -> 5\n feaScriptNodes[6] = gmshNodes[1]; // 1 -> 6\n feaScriptNodes[7] = gmshNodes[5]; // 5 -> 7\n feaScriptNodes[8] = gmshNodes[2]; // 2 -> 8\n }\n\n mappedNodalNumbering.push(feaScriptNodes);\n }\n\n this.parsedMesh.nodalNumbering = mappedNodalNumbering;\n } else if (this.parsedMesh.elementTypes[2]) {\n }\n\n debugLog(\n \"Nodal numbering after mapping from GMSH to FEAScript format: \" +\n JSON.stringify(this.parsedMesh.nodalNumbering)\n );\n\n // Process boundary elements if they exist and if physical property mapping exists\n if (this.parsedMesh.physicalPropMap && this.parsedMesh.boundaryElements) {\n // Check if boundary elements need to be processed\n if (\n Array.isArray(this.parsedMesh.boundaryElements) &&\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n // Create a new array without the empty first element\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n\n // If boundary node pairs exist but boundary elements haven't been processed\n if (this.parsedMesh.boundaryNodePairs && !this.parsedMesh.boundaryElementsProcessed) {\n // Reset boundary elements array\n this.parsedMesh.boundaryElements = [];\n\n // Process each physical property from the Gmsh file\n this.parsedMesh.physicalPropMap.forEach((prop) => {\n // Only process 1D physical entities (boundary lines)\n if (prop.dimension === 1) {\n // Get all node pairs for this boundary\n const boundaryNodePairs = this.parsedMesh.boundaryNodePairs[prop.tag] || [];\n\n if (boundaryNodePairs.length > 0) {\n // Initialize array for this boundary tag\n if (!this.parsedMesh.boundaryElements[prop.tag]) {\n this.parsedMesh.boundaryElements[prop.tag] = [];\n }\n\n // For each boundary line segment (defined by a pair of nodes)\n boundaryNodePairs.forEach((nodesPair) => {\n const node1 = nodesPair[0]; // First node in the pair\n const node2 = nodesPair[1]; // Second node in the pair\n\n debugLog(\n `Processing boundary node pair: [${node1}, ${node2}] for boundary ${prop.tag} (${\n prop.name || \"unnamed\"\n })`\n );\n\n // Search through all elements to find which one contains both nodes\n let foundElement = false;\n\n // Loop through all elements in the mesh\n for (let elemIdx = 0; elemIdx < this.parsedMesh.nodalNumbering.length; elemIdx++) {\n const elemNodes = this.parsedMesh.nodalNumbering[elemIdx];\n\n // For linear quadrilateral linear elements (4 nodes)\n if (elemNodes.length === 4) {\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript linear quadrilateral numbering:\n // 1 --- 3\n // | |\n // 0 --- 2\n\n if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0)\n ) {\n side = 0; // Bottom side\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0)\n ) {\n side = 1; // Left side\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 1 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 1)\n ) {\n side = 2; // Top side\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 2)\n ) {\n side = 3; // Right side\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n } else if (elemNodes.length === 9) {\n // For quadratic quadrilateral elements (9 nodes)\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript quadratic quadrilateral numbering:\n // 2--5--8\n // | |\n // 1 4 7\n // | |\n // 0--3--6\n\n if (\n (node1Index === 0 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 0) ||\n (node1Index === 3 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 3)\n ) {\n side = 0; // Bottom side (nodes 0, 3, 6)\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0) ||\n (node1Index === 1 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 1)\n ) {\n side = 1; // Left side (nodes 0, 1, 2)\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 5) ||\n (node1Index === 5 && node2Index === 2) ||\n (node1Index === 5 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 5)\n ) {\n side = 2; // Top side (nodes 2, 5, 8)\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 6 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 7) ||\n (node1Index === 7 && node2Index === 6) ||\n (node1Index === 7 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 7)\n ) {\n side = 3; // Right side (nodes 6, 7, 8)\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n }\n }\n\n if (!foundElement) {\n errorLog(\n `Could not find element containing boundary nodes ${node1} and ${node2}. Boundary may be incomplete.`\n );\n }\n });\n }\n }\n });\n\n // Mark as processed\n this.parsedMesh.boundaryElementsProcessed = true;\n\n // Fix boundary elements array - remove undefined entries\n if (\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n }\n }\n }\n }\n\n debugLog(\"Processed boundary elements by tag: \" + JSON.stringify(this.parsedMesh.boundaryElements));\n\n return this.parsedMesh;\n } else {\n // Validate required geometry parameters based on mesh dimension\n if (this.meshDimension === \"1D\") {\n if (this.numElementsX === null || this.maxX === null) {\n errorLog(\"numElementsX and maxX are required parameters when generating a 1D mesh from geometry\");\n }\n } else if (this.meshDimension === \"2D\") {\n if (\n this.numElementsX === null ||\n this.maxX === null ||\n this.numElementsY === null ||\n this.maxY === null\n ) {\n errorLog(\n \"numElementsX, maxX, numElementsY, and maxY are required parameters when generating a 2D mesh from geometry\"\n );\n }\n }\n\n // Generate mesh based on dimension\n return this.generateMeshFromGeometry();\n }\n }\n\n /**\n * Function to generate a structured mesh based on the geometry configuration\n * @returns {object} An object containing the coordinates of nodes,\n * total number of nodes, nodal numbering (NOP) array, and boundary elements\n */\n generateMeshFromGeometry() {\n let nodesXCoordinates = [];\n let nodesYCoordinates = [];\n const xStart = 0;\n const yStart = 0;\n let totalNodesX, totalNodesY, deltaX, deltaY;\n\n if (this.meshDimension === \"1D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX;\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX / 2;\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n null, // numElementsY (not used in 1D)\n totalNodesX,\n null, // totalNodesY (not used in 1D)\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n\n // Return x coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n totalNodesX,\n nodalNumbering,\n boundaryElements,\n };\n } else if (this.meshDimension === \"2D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n totalNodesY = this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + nodeIndexY * deltaY;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + nodeIndexX * deltaX;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + nodeIndexY * deltaY;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n totalNodesY = 2 * this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + (nodeIndexY * deltaY) / 2;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + (nodeIndexX * deltaX) / 2;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + (nodeIndexY * deltaY) / 2;\n }\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n this.numElementsY,\n totalNodesX,\n totalNodesY,\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n debugLog(\"Generated node Y coordinates: \" + JSON.stringify(nodesYCoordinates));\n\n // Return x and y coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n nodesYCoordinates,\n totalNodesX,\n totalNodesY,\n nodalNumbering,\n boundaryElements,\n };\n }\n }\n\n /**\n * Function to find the elements that belong to each boundary of a domain\n * @returns {array} An array containing arrays of elements and their adjacent boundary side for each boundary\n * Each element in the array is of the form [elementIndex, side], where 'side' indicates which side\n * of the reference element is in contact with the physical boundary:\n *\n * For 1D domains (line segments):\n * 0 - Left node of reference element (maps to physical left endpoint)\n * 1 - Right node of reference element (maps to physical right endpoint)\n *\n * For 2D domains (rectangular):\n * 0 - Bottom side of reference element (maps to physical bottom boundary)\n * 1 - Left side of reference element (maps to physical left boundary)\n * 2 - Top side of reference element (maps to physical top boundary)\n * 3 - Right side of reference element (maps to physical right boundary)\n */\n findBoundaryElements() {\n const boundaryElements = [];\n const maxSides = this.meshDimension === \"1D\" ? 2 : 4; // Number of element sides based on mesh dimension\n for (let sideIndex = 0; sideIndex < maxSides; sideIndex++) {\n boundaryElements.push([]);\n }\n\n if (this.meshDimension === \"1D\") {\n // Left boundary (element 0, side 0)\n boundaryElements[0].push([0, 0]);\n\n // Right boundary (last element, side 1)\n boundaryElements[1].push([this.numElementsX - 1, 1]);\n } else if (this.meshDimension === \"2D\") {\n for (let elementIndexX = 0; elementIndexX < this.numElementsX; elementIndexX++) {\n for (let elementIndexY = 0; elementIndexY < this.numElementsY; elementIndexY++) {\n const elementIndex = elementIndexX * this.numElementsY + elementIndexY;\n\n // Bottom boundary\n if (elementIndexY === 0) {\n boundaryElements[0].push([elementIndex, 0]);\n }\n\n // Left boundary\n if (elementIndexX === 0) {\n boundaryElements[1].push([elementIndex, 1]);\n }\n\n // Top boundary\n if (elementIndexY === this.numElementsY - 1) {\n boundaryElements[2].push([elementIndex, 2]);\n }\n\n // Right boundary\n if (elementIndexX === this.numElementsX - 1) {\n boundaryElements[3].push([elementIndex, 3]);\n }\n }\n }\n }\n\n debugLog(\"Identified boundary elements by side: \" + JSON.stringify(boundaryElements));\n return boundaryElements;\n }\n\n /**\n * Function to generate the nodal numbering (NOP) array for a structured mesh\n * This array represents the connectivity between elements and their corresponding nodes\n * @param {number} numElementsX - Number of elements along the x-axis\n * @param {number} [numElementsY] - Number of elements along the y-axis (optional for 1D)\n * @param {number} totalNodesX - Total number of nodes along the x-axis\n * @param {number} [totalNodesY] - Total number of nodes along the y-axis (optional for 1D)\n * @param {string} elementOrder - The order of elements, either 'linear' or 'quadratic'\n * @returns {array} NOP - A two-dimensional array which represents the element-to-node connectivity for the entire mesh\n */\n generateNodalNumbering(numElementsX, numElementsY, totalNodesX, totalNodesY, elementOrder) {\n let elementIndex = 0;\n let nop = [];\n\n if (this.meshDimension === \"1D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear 1D elements with the following nodes representation:\n *\n * 1 --- 2\n *\n */\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 2; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic 1D elements with the following nodes representation:\n *\n * 1--2--3\n *\n */\n let columnCounter = 0;\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 3; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex + columnCounter;\n }\n columnCounter += 1;\n }\n }\n } else if (this.meshDimension === \"2D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear rectangular elements with the following nodes representation:\n *\n * 1 --- 3\n * | |\n * 0 --- 2\n *\n */\n let rowCounter = 0;\n let columnCounter = 2;\n for (let elementIndex = 0; elementIndex < numElementsX * numElementsY; elementIndex++) {\n rowCounter += 1;\n nop[elementIndex] = [];\n nop[elementIndex][0] = elementIndex + columnCounter - 1;\n nop[elementIndex][1] = elementIndex + columnCounter;\n nop[elementIndex][2] = elementIndex + columnCounter + numElementsY;\n nop[elementIndex][3] = elementIndex + columnCounter + numElementsY + 1;\n if (rowCounter === numElementsY) {\n columnCounter += 1;\n rowCounter = 0;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic rectangular elements with the following nodes representation:\n *\n * 2--5--8\n * | |\n * 1 4 7\n * | |\n * 0--3--6\n *\n */\n for (let elementIndexX = 1; elementIndexX <= numElementsX; elementIndexX++) {\n for (let elementIndexY = 1; elementIndexY <= numElementsY; elementIndexY++) {\n nop[elementIndex] = [];\n for (let nodeIndex1 = 1; nodeIndex1 <= 3; nodeIndex1++) {\n let nodeIndex2 = 3 * nodeIndex1 - 2;\n nop[elementIndex][nodeIndex2 - 1] =\n totalNodesY * (2 * elementIndexX + nodeIndex1 - 3) + 2 * elementIndexY - 1;\n nop[elementIndex][nodeIndex2] = nop[elementIndex][nodeIndex2 - 1] + 1;\n nop[elementIndex][nodeIndex2 + 1] = nop[elementIndex][nodeIndex2 - 1] + 2;\n }\n elementIndex = elementIndex + 1;\n }\n }\n }\n }\n\n return nop;\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to handle thermal boundary conditions application\n */\nexport class ThermalBoundaryConditions {\n /**\n * Constructor to initialize the ThermalBoundaryConditions class\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @param {array} boundaryElements - Array containing elements that belong to each boundary\n * @param {array} nop - Nodal numbering (NOP) array representing the connectivity between elements and nodes\n * @param {string} meshDimension - The dimension of the mesh (e.g., \"2D\")\n * @param {string} elementOrder - The order of elements (e.g., \"linear\", \"quadratic\")\n */\n constructor(boundaryConditions, boundaryElements, nop, meshDimension, elementOrder) {\n this.boundaryConditions = boundaryConditions;\n this.boundaryElements = boundaryElements;\n this.nop = nop;\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n }\n\n /**\n * Function to impose constant temperature boundary conditions (Dirichlet type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n */\n imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix) {\n basicLog(\"Applying constant temperature boundary conditions (Dirichlet type)\");\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 1: [1], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 2: [2], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0, 2], // Nodes at the bottom side of the reference element\n 1: [0, 1], // Nodes at the left side of the reference element\n 2: [1, 3], // Nodes at the top side of the reference element\n 3: [2, 3], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0, 3, 6], // Nodes at the bottom side of the reference element\n 1: [0, 1, 2], // Nodes at the left side of the reference element\n 2: [2, 5, 8], // Nodes at the top side of the reference element\n 3: [6, 7, 8], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n }\n }\n\n /**\n * Function to impose convection boundary conditions (Robin type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n * @param {array} gaussPoints - Array of Gauss points for numerical integration\n * @param {array} gaussWeights - Array of Gauss weights for numerical integration\n * @param {array} nodesXCoordinates - Array of x-coordinates of nodes\n * @param {array} nodesYCoordinates - Array of y-coordinates of nodes\n * @param {object} basisFunctionsData - Object containing basis functions and their derivatives\n */\n imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n ) {\n basicLog(\"Applying convection boundary conditions (Robin type)\");\n // Extract convection parameters from boundary conditions\n let convectionHeatTranfCoeff = [];\n let convectionExtTemp = [];\n Object.keys(this.boundaryConditions).forEach((key) => {\n const boundaryCondition = this.boundaryConditions[key];\n if (boundaryCondition[0] === \"convection\") {\n convectionHeatTranfCoeff[key] = boundaryCondition[1];\n convectionExtTemp[key] = boundaryCondition[2];\n }\n });\n\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n let nodeIndex;\n if (this.elementOrder === \"linear\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 1;\n }\n } else if (this.elementOrder === \"quadratic\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 2;\n }\n }\n\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n residualVector[globalNodeIndex] += -convectionCoeff * extTemp;\n jacobianMatrix[globalNodeIndex][globalNodeIndex] += convectionCoeff;\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 2;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 0;\n lastNodeIndex = 2;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 1;\n firstNodeIndex = 1;\n lastNodeIndex = 4;\n nodeIncrement = 2;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 2;\n lastNodeIndex = 4;\n nodeIncrement = 1;\n }\n\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[0] * tangentVectorLength * basisFunction[localNodeIndex] * convectionCoeff * extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[0] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n for (let gaussPointIndex = 0; gaussPointIndex < 3; gaussPointIndex++) {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 7;\n nodeIncrement = 3;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 1;\n firstNodeIndex = 2;\n lastNodeIndex = 9;\n nodeIncrement = 3;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 6;\n lastNodeIndex = 9;\n nodeIncrement = 1;\n }\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n convectionCoeff *\n extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n }\n }\n });\n }\n });\n }\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { jacobiMethod } from \"./methods/jacobiMethodScript.js\";\nimport { assembleSolidHeatTransferMat } from \"./solvers/solidHeatTransferScript.js\";\nimport { basicLog, debugLog, errorLog } from \"./utilities/loggingScript.js\";\n\n/**\n * Class to implement finite element analysis in JavaScript\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing the solution vector and additional mesh information\n */\nexport class FEAScriptModel {\n constructor() {\n this.solverConfig = null;\n this.meshConfig = {};\n this.boundaryConditions = {};\n this.solverMethod = \"lusolve\"; // Default solver method\n basicLog(\"FEAScriptModel instance created\");\n }\n\n setSolverConfig(solverConfig) {\n this.solverConfig = solverConfig;\n debugLog(`Solver config set to: ${solverConfig}`);\n }\n\n setMeshConfig(meshConfig) {\n this.meshConfig = meshConfig;\n debugLog(\n `Mesh config set with dimensions: ${meshConfig.meshDimension}`\n );\n }\n\n addBoundaryCondition(boundaryKey, condition) {\n this.boundaryConditions[boundaryKey] = condition;\n debugLog(`Boundary condition added for boundary: ${boundaryKey}, type: ${condition[0]}`);\n }\n\n setSolverMethod(solverMethod) {\n this.solverMethod = solverMethod;\n debugLog(`Solver method set to: ${solverMethod}`);\n }\n\n solve() {\n if (!this.solverConfig || !this.meshConfig || !this.boundaryConditions) {\n const error = \"Solver config, mesh config, and boundary conditions must be set before solving.\";\n console.error(error);\n throw new Error(error);\n }\n\n let jacobianMatrix = [];\n let residualVector = [];\n let solutionVector = [];\n let nodesCoordinates = {};\n\n // Assembly matrices\n basicLog(\"Beginning matrix assembly...\");\n console.time(\"assemblyMatrices\");\n if (this.solverConfig === \"solidHeatTransferScript\") {\n basicLog(`Using solver: ${this.solverConfig}`);\n ({ jacobianMatrix, residualVector, nodesCoordinates } = assembleSolidHeatTransferMat(\n this.meshConfig,\n this.boundaryConditions\n ));\n }\n console.timeEnd(\"assemblyMatrices\");\n basicLog(\"Matrix assembly completed\");\n\n // System solving\n basicLog(`Solving system using ${this.solverMethod}...`);\n console.time(\"systemSolving\");\n if (this.solverMethod === \"lusolve\") {\n solutionVector = math.lusolve(jacobianMatrix, residualVector);\n } else if (this.solverMethod === \"jacobi\") {\n // Create initial guess of zeros\n const initialGuess = new Array(residualVector.length).fill(0);\n // Call Jacobi method with desired max iterations and tolerance\n const jacobiResult = jacobiMethod(jacobianMatrix, residualVector, initialGuess, 1000, 1e-6);\n\n // Log convergence information\n if (jacobiResult.converged) {\n debugLog(`Jacobi method converged in ${jacobiResult.iterations} iterations`);\n } else {\n debugLog(`Jacobi method did not converge after ${jacobiResult.iterations} iterations`);\n }\n\n solutionVector = jacobiResult.solution;\n }\n console.timeEnd(\"systemSolving\");\n basicLog(\"System solved successfully\");\n\n return { solutionVector, nodesCoordinates };\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { numericalIntegration } from \"../methods/numericalIntegrationScript.js\";\nimport { basisFunctions } from \"../mesh/basisFunctionsScript.js\";\nimport { meshGeneration } from \"../mesh/meshGenerationScript.js\";\nimport { ThermalBoundaryConditions } from \"./thermalBoundaryConditionsScript.js\";\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to assemble the solid heat transfer matrix\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing:\n * - jacobianMatrix: The assembled Jacobian matrix\n * - residualVector: The assembled residual vector\n * - nodesCoordinates: Object containing x and y coordinates of nodes\n */\nexport function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {\n basicLog(\"Starting solid heat transfer matrix assembly...\");\n\n // Extract mesh details from the configuration object\n const {\n meshDimension, // The dimension of the mesh\n numElementsX, // Number of elements in x-direction\n numElementsY, // Number of elements in y-direction (only for 2D)\n maxX, // Max x-coordinate (m) of the domain\n maxY, // Max y-coordinate (m) of the domain (only for 2D)\n elementOrder, // The order of elements\n parsedMesh, // The pre-parsed mesh data (if available)\n } = meshConfig;\n\n // Create a new instance of the meshGeneration class\n debugLog(\"Generating mesh...\");\n const meshGenerationData = new meshGeneration({\n numElementsX,\n numElementsY,\n maxX,\n maxY,\n meshDimension,\n elementOrder,\n parsedMesh, // Pass the parsed mesh to the mesh generator\n });\n\n // Generate the mesh\n const nodesCoordinatesAndNumbering = meshGenerationData.generateMesh();\n\n // Extract nodes coordinates and nodal numbering (NOP) from the mesh data\n let nodesXCoordinates = nodesCoordinatesAndNumbering.nodesXCoordinates;\n let nodesYCoordinates = nodesCoordinatesAndNumbering.nodesYCoordinates;\n let totalNodesX = nodesCoordinatesAndNumbering.totalNodesX;\n let totalNodesY = nodesCoordinatesAndNumbering.totalNodesY;\n let nop = nodesCoordinatesAndNumbering.nodalNumbering;\n let boundaryElements = nodesCoordinatesAndNumbering.boundaryElements;\n\n // Check the mesh type\n const isParsedMesh = parsedMesh !== undefined && parsedMesh !== null;\n\n // Calculate totalElements and totalNodes based on mesh type\n let totalElements, totalNodes;\n\n if (isParsedMesh) {\n totalElements = nop.length; // Number of elements is the length of the nodal numbering array\n totalNodes = nodesXCoordinates.length; // Number of nodes is the length of the coordinates array\n\n // Debug log for mesh size\n debugLog(`Using parsed mesh with ${totalElements} elements and ${totalNodes} nodes`);\n } else {\n // For structured mesh, calculate based on dimensions\n totalElements = numElementsX * (meshDimension === \"2D\" ? numElementsY : 1);\n totalNodes = totalNodesX * (meshDimension === \"2D\" ? totalNodesY : 1);\n // Debug log for mesh size\n debugLog(`Using mesh generated from geometry with ${totalElements} elements and ${totalNodes} nodes`);\n }\n\n // Initialize variables for matrix assembly\n let localToGlobalMap = []; // Maps local element node indices to global mesh node indices\n let gaussPoints = []; // Gauss points\n let gaussWeights = []; // Gauss weights\n let basisFunction = []; // Basis functions\n let basisFunctionDerivKsi = []; // Derivatives of basis functions with respect to ksi\n let basisFunctionDerivEta = []; // Derivatives of basis functions with respect to eta (only for 2D)\n let basisFunctionDerivX = []; // The x-derivative of the basis function\n let basisFunctionDerivY = []; // The y-derivative of the basis function (only for 2D)\n let residualVector = []; // Galerkin residuals\n let jacobianMatrix = []; // Jacobian matrix\n let xCoordinates; // x-coordinate (physical coordinates)\n let yCoordinates; // y-coordinate (physical coordinates) (only for 2D)\n let ksiDerivX; // ksi-derivative of xCoordinates\n let etaDerivX; // eta-derivative of xCoordinates (ksi and eta are natural coordinates that vary within a reference element) (only for 2D)\n let ksiDerivY; // ksi-derivative of yCoordinates (only for 2D)\n let etaDerivY; // eta-derivative of yCoordinates (only for 2D)\n let detJacobian; // The jacobian of the isoparametric mapping\n\n // Initialize jacobianMatrix and residualVector arrays\n for (let nodeIndex = 0; nodeIndex < totalNodes; nodeIndex++) {\n residualVector[nodeIndex] = 0;\n jacobianMatrix.push([]);\n for (let colIndex = 0; colIndex < totalNodes; colIndex++) {\n jacobianMatrix[nodeIndex][colIndex] = 0;\n }\n }\n\n // Initialize the basisFunctions class\n const basisFunctionsData = new basisFunctions({\n meshDimension,\n elementOrder,\n });\n\n // Initialize the numericalIntegration class\n const numIntegrationData = new numericalIntegration({\n meshDimension,\n elementOrder,\n });\n\n // Calculate Gauss points and weights\n let gaussPointsAndWeights = numIntegrationData.getGaussPointsAndWeights();\n gaussPoints = gaussPointsAndWeights.gaussPoints;\n gaussWeights = gaussPointsAndWeights.gaussWeights;\n\n // Determine the number of nodes in the reference element based on the first element in the nop array\n const numNodes = nop[0].length;\n\n // Matrix assembly\n for (let elementIndex = 0; elementIndex < totalElements; elementIndex++) {\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n // Subtract 1 from nop in order to start numbering from 0\n localToGlobalMap[localNodeIndex] = nop[elementIndex][localNodeIndex] - 1;\n }\n\n // Loop over Gauss points\n for (let gaussPointIndex1 = 0; gaussPointIndex1 < gaussPoints.length; gaussPointIndex1++) {\n // 1D solid heat transfer\n if (meshDimension === \"1D\") {\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n xCoordinates = 0;\n ksiDerivX = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates += nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n detJacobian = ksiDerivX;\n }\n\n // Compute x-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] = basisFunctionDerivKsi[localNodeIndex] / detJacobian; // The x-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2]);\n }\n }\n // 2D solid heat transfer\n } else if (meshDimension === \"2D\") {\n for (let gaussPointIndex2 = 0; gaussPointIndex2 < gaussPoints.length; gaussPointIndex2++) {\n // Initialise variables for isoparametric mapping\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1],\n gaussPoints[gaussPointIndex2]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n xCoordinates = 0;\n yCoordinates = 0;\n ksiDerivX = 0;\n etaDerivX = 0;\n ksiDerivY = 0;\n etaDerivY = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n yCoordinates +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n ksiDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n detJacobian = meshDimension === \"2D\" ? ksiDerivX * etaDerivY - etaDerivX * ksiDerivY : ksiDerivX;\n }\n\n // Compute x-derivative and y-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] =\n (etaDerivY * basisFunctionDerivKsi[localNodeIndex] -\n ksiDerivY * basisFunctionDerivEta[localNodeIndex]) /\n detJacobian; // The x-derivative of the n basis function\n basisFunctionDerivY[localNodeIndex] =\n (ksiDerivX * basisFunctionDerivEta[localNodeIndex] -\n etaDerivX * basisFunctionDerivKsi[localNodeIndex]) /\n detJacobian; // The y-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n gaussWeights[gaussPointIndex2] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2] +\n basisFunctionDerivY[localNodeIndex1] * basisFunctionDerivY[localNodeIndex2]);\n }\n }\n }\n }\n }\n }\n\n // Create an instance of ThermalBoundaryConditions\n debugLog(\"Applying thermal boundary conditions...\");\n const thermalBoundaryConditions = new ThermalBoundaryConditions(\n boundaryConditions,\n boundaryElements,\n nop,\n meshDimension,\n elementOrder\n );\n\n // Impose Convection boundary conditions\n thermalBoundaryConditions.imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n );\n debugLog(\"Convection boundary conditions applied\");\n\n // Impose ConstantTemp boundary conditions\n thermalBoundaryConditions.imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix);\n debugLog(\"Constant temperature boundary conditions applied\");\n\n basicLog(\"Solid heat transfer matrix assembly completed\");\n\n return {\n jacobianMatrix,\n residualVector,\n nodesCoordinates: {\n nodesXCoordinates,\n nodesYCoordinates,\n },\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to solve a system of linear equations using the Jacobi iterative method\n * @param {array} A - The coefficient matrix (must be square)\n * @param {array} b - The right-hand side vector\n * @param {array} x0 - Initial guess for solution vector\n * @param {number} [maxIterations=100] - Maximum number of iterations\n * @param {number} [tolerance=1e-7] - Convergence tolerance\n * @returns {object} An object containing:\n * - solution: The solution vector\n * - iterations: The number of iterations performed\n * - converged: Boolean indicating whether the method converged\n */\nexport function jacobiMethod(A, b, x0, maxIterations = 100, tolerance = 1e-7) {\n const n = A.length; // Size of the square matrix\n let x = [...x0]; // Current solution (starts with initial guess)\n let xNew = new Array(n); // Next iteration's solution\n\n for (let iteration = 0; iteration < maxIterations; iteration++) {\n // Perform one iteration\n for (let i = 0; i < n; i++) {\n let sum = 0;\n // Calculate sum of A[i][j] * x[j] for j ≠ i\n for (let j = 0; j < n; j++) {\n if (j !== i) {\n sum += A[i][j] * x[j];\n }\n }\n // Update xNew[i] using the Jacobi formula\n xNew[i] = (b[i] - sum) / A[i][i];\n }\n\n // Check convergence\n let maxDiff = 0;\n for (let i = 0; i < n; i++) {\n maxDiff = Math.max(maxDiff, Math.abs(xNew[i] - x[i]));\n }\n\n // Update x for next iteration\n x = [...xNew];\n\n // Successfully converged if maxDiff is less than tolerance\n if (maxDiff < tolerance) {\n return {\n solution: x,\n iterations: iteration + 1,\n converged: true,\n };\n }\n }\n\n // maxIterations were reached without convergence\n return {\n solution: x,\n iterations: maxIterations,\n converged: false,\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to import mesh data from Gmsh format containing quadrilateral and triangular elements\n * @param {File} file - The Gmsh file to be parsed (.msh version 4.1)\n * @returns {object} The parsed mesh data including node coordinates, element connectivity, and boundary conditions\n */\nconst importGmshQuadTri = async (file) => {\n let result = {\n nodesXCoordinates: [],\n nodesYCoordinates: [],\n nodalNumbering: {\n quadElements: [],\n triangleElements: [],\n },\n boundaryElements: [],\n boundaryConditions: [],\n boundaryNodePairs: {}, // Store boundary node pairs for processing in meshGenerationScript\n gmshV: 0,\n ascii: false,\n fltBytes: \"8\",\n totalNodesX: 0,\n totalNodesY: 0,\n physicalPropMap: [],\n elementTypes: {},\n };\n\n let content = await file.text();\n let lines = content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\" && line !== \" \");\n\n let section = \"\";\n let lineIndex = 0;\n\n let nodeEntityBlocks = 0;\n let totalNodes = 0;\n let nodeBlocksProcessed = 0;\n let currentNodeBlock = { numNodes: 0 };\n let nodeTagsCollected = 0;\n let nodeTags = [];\n let nodeCoordinatesCollected = 0;\n\n let elementEntityBlocks = 0;\n let totalElements = 0;\n let elementBlocksProcessed = 0;\n let currentElementBlock = {\n dim: 0,\n tag: 0,\n elementType: 0,\n numElements: 0,\n };\n let elementsProcessedInBlock = 0;\n\n let boundaryElementsByTag = {};\n\n while (lineIndex < lines.length) {\n const line = lines[lineIndex];\n\n if (line === \"$MeshFormat\") {\n section = \"meshFormat\";\n lineIndex++;\n continue;\n } else if (line === \"$EndMeshFormat\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$PhysicalNames\") {\n section = \"physicalNames\";\n lineIndex++;\n continue;\n } else if (line === \"$EndPhysicalNames\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Entities\") {\n section = \"entities\";\n lineIndex++;\n continue;\n } else if (line === \"$EndEntities\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Nodes\") {\n section = \"nodes\";\n lineIndex++;\n continue;\n } else if (line === \"$EndNodes\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Elements\") {\n section = \"elements\";\n lineIndex++;\n continue;\n } else if (line === \"$EndElements\") {\n section = \"\";\n lineIndex++;\n continue;\n }\n\n const parts = line.split(/\\s+/).filter((part) => part !== \"\");\n\n if (section === \"meshFormat\") {\n result.gmshV = parseFloat(parts[0]);\n result.ascii = parts[1] === \"0\";\n result.fltBytes = parts[2];\n } else if (section === \"physicalNames\") {\n if (parts.length >= 3) {\n if (!/^\\d+$/.test(parts[0])) {\n lineIndex++;\n continue;\n }\n\n const dimension = parseInt(parts[0], 10);\n const tag = parseInt(parts[1], 10);\n let name = parts.slice(2).join(\" \");\n name = name.replace(/^\"|\"$/g, \"\");\n\n result.physicalPropMap.push({\n tag,\n dimension,\n name,\n });\n }\n } else if (section === \"nodes\") {\n if (nodeEntityBlocks === 0) {\n nodeEntityBlocks = parseInt(parts[0], 10);\n totalNodes = parseInt(parts[1], 10);\n result.nodesXCoordinates = new Array(totalNodes).fill(0);\n result.nodesYCoordinates = new Array(totalNodes).fill(0);\n lineIndex++;\n continue;\n }\n\n if (nodeBlocksProcessed < nodeEntityBlocks && currentNodeBlock.numNodes === 0) {\n currentNodeBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n parametric: parseInt(parts[2], 10),\n numNodes: parseInt(parts[3], 10),\n };\n\n nodeTags = [];\n nodeTagsCollected = 0;\n nodeCoordinatesCollected = 0;\n\n lineIndex++;\n continue;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n for (let i = 0; i < parts.length && nodeTagsCollected < currentNodeBlock.numNodes; i++) {\n nodeTags.push(parseInt(parts[i], 10));\n nodeTagsCollected++;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n lineIndex++;\n continue;\n }\n\n lineIndex++;\n continue;\n }\n\n if (nodeCoordinatesCollected < currentNodeBlock.numNodes) {\n const nodeTag = nodeTags[nodeCoordinatesCollected] - 1;\n const x = parseFloat(parts[0]);\n const y = parseFloat(parts[1]);\n\n result.nodesXCoordinates[nodeTag] = x;\n result.nodesYCoordinates[nodeTag] = y;\n result.totalNodesX++;\n result.totalNodesY++;\n\n nodeCoordinatesCollected++;\n\n if (nodeCoordinatesCollected === currentNodeBlock.numNodes) {\n nodeBlocksProcessed++;\n currentNodeBlock = { numNodes: 0 };\n }\n }\n } else if (section === \"elements\") {\n if (elementEntityBlocks === 0) {\n elementEntityBlocks = parseInt(parts[0], 10);\n totalElements = parseInt(parts[1], 10);\n lineIndex++;\n continue;\n }\n\n if (elementBlocksProcessed < elementEntityBlocks && currentElementBlock.numElements === 0) {\n currentElementBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n elementType: parseInt(parts[2], 10),\n numElements: parseInt(parts[3], 10),\n };\n\n result.elementTypes[currentElementBlock.elementType] =\n (result.elementTypes[currentElementBlock.elementType] || 0) + currentElementBlock.numElements;\n\n elementsProcessedInBlock = 0;\n lineIndex++;\n continue;\n }\n\n if (elementsProcessedInBlock < currentElementBlock.numElements) {\n const elementTag = parseInt(parts[0], 10);\n const nodeIndices = parts.slice(1).map((idx) => parseInt(idx, 10));\n\n if (currentElementBlock.elementType === 1 || currentElementBlock.elementType === 8) {\n const physicalTag = currentElementBlock.tag;\n\n if (!boundaryElementsByTag[physicalTag]) {\n boundaryElementsByTag[physicalTag] = [];\n }\n\n boundaryElementsByTag[physicalTag].push(nodeIndices);\n\n // Store boundary node pairs for later processing in meshGenerationScript\n if (!result.boundaryNodePairs[physicalTag]) {\n result.boundaryNodePairs[physicalTag] = [];\n }\n result.boundaryNodePairs[physicalTag].push(nodeIndices);\n } else if (currentElementBlock.elementType === 2) {\n // Linear triangle elements (3 nodes)\n result.nodalNumbering.triangleElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 3) {\n // Linear quadrilateral elements (4 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 10) {\n // Quadratic quadrilateral elements (9 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n }\n\n elementsProcessedInBlock++;\n\n if (elementsProcessedInBlock === currentElementBlock.numElements) {\n elementBlocksProcessed++;\n currentElementBlock = { numElements: 0 };\n }\n }\n }\n\n lineIndex++;\n }\n\n // Store boundary conditions information\n result.physicalPropMap.forEach((prop) => {\n if (prop.dimension === 1) {\n const boundaryNodes = boundaryElementsByTag[prop.tag] || [];\n\n if (boundaryNodes.length > 0) {\n result.boundaryConditions.push({\n name: prop.name,\n tag: prop.tag,\n nodes: boundaryNodes,\n });\n }\n }\n });\n\n debugLog(\n `Parsed boundary node pairs by physical tag: ${JSON.stringify(\n result.boundaryNodePairs\n )}. These pairs will be used to identify boundary elements in the mesh.`\n );\n\n return result;\n};\n\nexport { importGmshQuadTri };\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to create plots of the solution vector\n * @param {*} solutionVector - The computed solution vector\n * @param {*} nodesCoordinates - Object containing x and y coordinates for the nodes\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {string} meshDimension - The dimension of the solution\n * @param {string} plotType - The type of plot\n * @param {string} plotDivId - The id of the div where the plot will be rendered\n * @param {string} [meshType=\"structured\"] - Type of mesh: \"structured\" or \"unstructured\"\n */\nexport function plotSolution(\n solutionVector,\n nodesCoordinates,\n solverConfig,\n meshDimension,\n plotType,\n plotDivId,\n meshType = \"structured\"\n) {\n const { nodesXCoordinates, nodesYCoordinates } = nodesCoordinates;\n\n if (meshDimension === \"1D\" && plotType === \"line\") {\n // Check if solutionVector is a nested array\n let yData;\n if (solutionVector.length > 0 && Array.isArray(solutionVector[0])) {\n yData = solutionVector.map((arr) => arr[0]);\n } else {\n yData = solutionVector;\n }\n let xData = Array.from(nodesXCoordinates);\n\n let lineData = {\n x: xData,\n y: yData,\n mode: \"lines\",\n type: \"scatter\",\n line: { color: \"rgb(219, 64, 82)\", width: 2 },\n name: \"Solution\",\n };\n\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxPlotWidth = Math.max(...xData);\n let zoomFactor = maxWindowWidth / maxPlotWidth;\n let plotWidth = Math.max(zoomFactor * maxPlotWidth, 400);\n let plotHeight = 350;\n\n let layout = {\n title: `line plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"Solution\" },\n margin: { l: 70, r: 40, t: 50, b: 50 },\n };\n\n Plotly.newPlot(plotDivId, [lineData], layout, { responsive: true });\n } else if (meshDimension === \"2D\" && plotType === \"contour\") {\n // Use the user-provided mesh type\n const isStructured = meshType === \"structured\";\n \n // For auto-detection (if needed)\n const uniqueXCoords = new Set(nodesXCoordinates).size;\n const uniqueYCoords = new Set(nodesYCoordinates).size;\n \n // Extract scalar values from solution vector\n let zValues = Array.isArray(solutionVector[0]) \n ? solutionVector.map(val => val[0]) \n : solutionVector;\n \n // Common sizing parameters for both plot types\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxX = Math.max(...nodesXCoordinates);\n let maxY = Math.max(...nodesYCoordinates);\n let aspectRatio = maxY / maxX;\n let plotWidth = Math.min(maxWindowWidth, 600);\n let plotHeight = plotWidth * aspectRatio * 0.8; // Slightly reduce height for better appearance\n \n // Common layout properties\n let layout = {\n title: `${plotType} plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"y\" },\n margin: { l: 50, r: 50, t: 50, b: 50 },\n hovermode: 'closest'\n };\n \n if (isStructured) {\n // Calculate the number of nodes along the x-axis and y-axis\n const numNodesX = uniqueXCoords;\n const numNodesY = uniqueYCoords;\n\n // Reshape the nodesXCoordinates and nodesYCoordinates arrays to match the grid dimensions\n let reshapedXCoordinates = math.reshape(Array.from(nodesXCoordinates), [numNodesX, numNodesY]);\n let reshapedYCoordinates = math.reshape(Array.from(nodesYCoordinates), [numNodesX, numNodesY]);\n\n // Reshape the solution array to match the grid dimensions\n let reshapedSolution = math.reshape(Array.from(solutionVector), [numNodesX, numNodesY]);\n\n // Transpose the reshapedSolution array to get column-wise data\n let transposedSolution = math.transpose(reshapedSolution);\n\n // Create an array for x-coordinates used in the contour plot\n let reshapedXForPlot = [];\n for (let i = 0; i < numNodesX * numNodesY; i += numNodesY) {\n let xValue = nodesXCoordinates[i];\n reshapedXForPlot.push(xValue);\n }\n\n // Create the data structure for the contour plot\n let contourData = {\n z: transposedSolution,\n type: \"contour\",\n contours: {\n coloring: \"heatmap\",\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n x: reshapedXForPlot,\n y: reshapedYCoordinates[0],\n name: 'Solution Field'\n };\n\n // Create the plot using Plotly\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n } else {\n // Create an interpolated contour plot for the unstructured mesh\n let contourData = {\n x: nodesXCoordinates,\n y: nodesYCoordinates,\n z: zValues,\n type: 'contour',\n contours: {\n coloring: 'heatmap',\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n name: 'Solution Field'\n };\n \n // Create the plot using only the contour fill\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n }\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nconst proxyMarker = Symbol(\"Comlink.proxy\");\nconst createEndpoint = Symbol(\"Comlink.endpoint\");\nconst releaseProxy = Symbol(\"Comlink.releaseProxy\");\nconst finalizer = Symbol(\"Comlink.finalizer\");\nconst throwMarker = Symbol(\"Comlink.thrown\");\nconst isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n/**\n * Internal transfer handle to handle objects marked to proxy.\n */\nconst proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n};\n/**\n * Internal transfer handler to handle thrown exceptions.\n */\nconst throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n};\n/**\n * Allows customizing the serialization of certain values.\n */\nconst transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n]);\nfunction isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n}\nfunction expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n}\nfunction isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n}\nfunction closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n}\nfunction wrap(ep, target) {\n const pendingListeners = new Map();\n ep.addEventListener(\"message\", function handleMessage(ev) {\n const { data } = ev;\n if (!data || !data.id) {\n return;\n }\n const resolver = pendingListeners.get(data.id);\n if (!resolver) {\n return;\n }\n try {\n resolver(data);\n }\n finally {\n pendingListeners.delete(data.id);\n }\n });\n return createProxy(ep, pendingListeners, [], target);\n}\nfunction throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n}\nfunction releaseEndpoint(ep) {\n return requestResponseMessage(ep, new Map(), {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n}\nconst proxyCounter = new WeakMap();\nconst proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\nfunction registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n}\nfunction unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n}\nfunction createProxy(ep, pendingListeners, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n pendingListeners.clear();\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, pendingListeners, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, pendingListeners, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, pendingListeners, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, pendingListeners, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n}\nfunction myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n}\nfunction processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n}\nconst transferCache = new WeakMap();\nfunction transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n}\nfunction proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n}\nfunction windowEndpoint(w, context = globalThis, targetOrigin = \"*\") {\n return {\n postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),\n addEventListener: context.addEventListener.bind(context),\n removeEventListener: context.removeEventListener.bind(context),\n };\n}\nfunction toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n}\nfunction fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n}\nfunction requestResponseMessage(ep, pendingListeners, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n pendingListeners.set(id, resolve);\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n}\nfunction generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n}\n\nexport { createEndpoint, expose, finalizer, proxy, proxyMarker, releaseProxy, transfer, transferHandlers, windowEndpoint, wrap };\n//# sourceMappingURL=comlink.mjs.map\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// External imports\nimport * as Comlink from \"../vendor/comlink.mjs\";\n\n// Internal imports\nimport { basicLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to facilitate communication with web workers for FEAScript operations\n */\nexport class FEAScriptWorker {\n /**\n * Constructor to initialize the FEAScriptWorker class\n * Sets up the worker and initializes the workerWrapper.\n */\n constructor() {\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n\n this._initWorker();\n }\n\n /**\n * Function to initialize the web worker and wrap it using Comlink.\n * @private\n * @throws Will throw an error if the worker fails to initialize.\n */\n async _initWorker() {\n try {\n this.worker = new Worker(new URL(\"./wrapperScript.js\", import.meta.url), {\n type: \"module\",\n });\n\n this.worker.onerror = (event) => {\n console.error(\"FEAScriptWorker: Worker error:\", event);\n };\n const workerWrapper = Comlink.wrap(this.worker);\n\n this.feaWorker = await new workerWrapper();\n\n this.isReady = true;\n } catch (error) {\n console.error(\"Failed to initialize worker\", error);\n throw error;\n }\n }\n\n /**\n * Function to ensure that the worker is ready before performing any operations.\n * @private\n * @returns {Promise} Resolves when the worker is ready.\n * @throws Will throw an error if the worker is not ready within the timeout period.\n */\n async _ensureReady() {\n if (this.isReady) return Promise.resolve();\n\n return new Promise((resolve, reject) => {\n let attempts = 0;\n const maxAttempts = 50; // 5 seconds max\n\n const checkReady = () => {\n attempts++;\n if (this.isReady) {\n resolve();\n } else if (attempts >= maxAttempts) {\n reject(new Error(\"Timeout waiting for worker to be ready\"));\n } else {\n setTimeout(checkReady, 1000);\n }\n };\n checkReady();\n });\n }\n\n /**\n * Function to set the solver configuration in the worker.\n * @param {string} solverConfig - The solver configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setSolverConfig(solverConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver config to: ${solverConfig}`);\n return this.feaWorker.setSolverConfig(solverConfig);\n }\n\n /**\n * Sets the mesh configuration in the worker.\n * @param {object} meshConfig - The mesh configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setMeshConfig(meshConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting mesh config`);\n return this.feaWorker.setMeshConfig(meshConfig);\n }\n\n /**\n * Adds a boundary condition to the worker.\n * @param {string} boundaryKey - The key identifying the boundary.\n * @param {array} condition - The boundary condition to add.\n * @returns {Promise} Resolves when the boundary condition is added.\n */\n async addBoundaryCondition(boundaryKey, condition) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Adding boundary condition for boundary: ${boundaryKey}`);\n return this.feaWorker.addBoundaryCondition(boundaryKey, condition);\n }\n\n /**\n * Sets the solver method in the worker.\n * @param {string} solverMethod - The solver method to set.\n * @returns {Promise} Resolves when the solver method is set.\n */\n async setSolverMethod(solverMethod) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver method to: ${solverMethod}`);\n return this.feaWorker.setSolverMethod(solverMethod);\n }\n\n /**\n * Requests the worker to solve the problem.\n * @returns {Promise} Resolves with the solution result.\n */\n async solve() {\n await this._ensureReady();\n basicLog(\"FEAScriptWorker: Requesting solution from worker...\");\n\n const startTime = performance.now();\n const result = await this.feaWorker.solve();\n const endTime = performance.now();\n\n basicLog(`FEAScriptWorker: Solution completed in ${((endTime - startTime) / 1000).toFixed(2)}s`);\n return result;\n }\n\n /**\n * Retrieves model information from the worker.\n * @returns {Promise} Resolves with the model information.\n */\n async getModelInfo() {\n await this._ensureReady();\n return this.feaWorker.getModelInfo();\n }\n\n /**\n * Sends a ping request to the worker to check its availability.\n * @returns {Promise} Resolves if the worker responds.\n */\n async ping() {\n await this._ensureReady();\n return this.feaWorker.ping();\n }\n\n /**\n * Terminates the worker and cleans up resources.\n */\n terminate() {\n if (this.worker) {\n this.worker.terminate();\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n }\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\nexport { FEAScriptModel } from \"./FEAScript.js\";\nexport { importGmshQuadTri } from \"./readers/gmshReaderScript.js\";\nexport { logSystem, printVersion } from \"./utilities/loggingScript.js\";\nexport { plotSolution } from \"./visualization/plotSolutionScript.js\";\nexport { FEAScriptWorker } from \"./workers/workerScript.js\";\nexport const VERSION = \"0.1.1\";"],"names":["numericalIntegration","constructor","meshDimension","elementOrder","this","getGaussPointsAndWeights","gaussPoints","gaussWeights","Math","sqrt","currentLogLevel","logSystem","level","console","log","basicLog","debugLog","message","errorLog","async","printVersion","commitResponse","fetch","commitData","json","latestCommitDate","Date","commit","committer","date","toLocaleString","error","basisFunctions","getBasisFunctions","ksi","eta","basisFunction","basisFunctionDerivKsi","basisFunctionDerivEta","l1","c","l2","l3","dl1","dl2","dl3","meshGeneration","numElementsX","maxX","numElementsY","maxY","parsedMesh","generateMesh","nodalNumbering","Array","isArray","quadElements","triangleElements","JSON","stringify","elementTypes","mappedNodalNumbering","elemIdx","length","gmshNodes","feaScriptNodes","push","physicalPropMap","boundaryElements","undefined","fixedBoundaryElements","i","boundaryNodePairs","boundaryElementsProcessed","forEach","prop","dimension","tag","nodesPair","node1","node2","name","foundElement","elemNodes","includes","side","node1Index","indexOf","node2Index","join","generateMeshFromGeometry","nodesXCoordinates","nodesYCoordinates","totalNodesX","totalNodesY","deltaX","deltaY","nodeIndex","generateNodalNumbering","findBoundaryElements","nodeIndexY","nodeIndexX","nnode","maxSides","sideIndex","elementIndexX","elementIndexY","elementIndex","nop","columnCounter","rowCounter","nodeIndex1","nodeIndex2","ThermalBoundaryConditions","boundaryConditions","imposeConstantTempBoundaryConditions","residualVector","jacobianMatrix","Object","keys","boundaryKey","tempValue","globalNodeIndex","colIndex","imposeConvectionBoundaryConditions","basisFunctionsData","convectionHeatTranfCoeff","convectionExtTemp","key","boundaryCondition","convectionCoeff","extTemp","gaussPoint1","gaussPoint2","firstNodeIndex","lastNodeIndex","nodeIncrement","basisFunctionsAndDerivatives","ksiDerivX","ksiDerivY","etaDerivX","etaDerivY","numNodes","tangentVectorLength","localNodeIndex","localNodeIndex2","globalNodeIndex2","gaussPointIndex","FEAScriptModel","solverConfig","meshConfig","solverMethod","setSolverConfig","setMeshConfig","addBoundaryCondition","condition","setSolverMethod","solve","Error","solutionVector","nodesCoordinates","time","nodesCoordinatesAndNumbering","totalElements","totalNodes","xCoordinates","yCoordinates","detJacobian","localToGlobalMap","basisFunctionDerivX","basisFunctionDerivY","gaussPointsAndWeights","gaussPointIndex1","localNodeIndex1","localToGlobalMap1","localToGlobalMap2","gaussPointIndex2","thermalBoundaryConditions","assembleSolidHeatTransferMat","timeEnd","math","lusolve","jacobiResult","A","b","x0","maxIterations","tolerance","n","x","xNew","iteration","sum","j","maxDiff","max","abs","solution","iterations","converged","jacobiMethod","fill","importGmshQuadTri","file","result","gmshV","ascii","fltBytes","lines","text","split","map","line","trim","filter","section","lineIndex","nodeEntityBlocks","nodeBlocksProcessed","currentNodeBlock","nodeTagsCollected","nodeTags","nodeCoordinatesCollected","elementEntityBlocks","elementBlocksProcessed","currentElementBlock","dim","elementType","numElements","elementsProcessedInBlock","boundaryElementsByTag","parts","part","parseFloat","test","parseInt","slice","replace","parametric","nodeTag","y","nodeIndices","idx","physicalTag","boundaryNodes","nodes","plotSolution","plotType","plotDivId","meshType","yData","arr","xData","from","lineData","mode","type","color","width","maxWindowWidth","min","window","innerWidth","maxPlotWidth","zoomFactor","layout","title","height","xaxis","yaxis","margin","l","r","t","Plotly","newPlot","responsive","isStructured","uniqueXCoords","Set","size","uniqueYCoords","zValues","val","aspectRatio","plotWidth","hovermode","numNodesX","numNodesY","reshape","reshapedYCoordinates","reshapedSolution","transposedSolution","transpose","reshapedXForPlot","xValue","contourData","z","contours","coloring","showlabels","colorbar","proxyMarker","Symbol","createEndpoint","releaseProxy","finalizer","throwMarker","isObject","transferHandlers","Map","canHandle","serialize","obj","port1","port2","MessageChannel","expose","deserialize","port","start","wrap","value","serialized","isError","stack","assign","ep","globalThis","allowedOrigins","addEventListener","callback","ev","data","origin","allowedOrigin","RegExp","isAllowedOrigin","warn","id","path","argumentList","fromWireValue","returnValue","parent","reduce","rawValue","apply","proxy","transfers","transferCache","set","transfer","Promise","resolve","catch","then","wireValue","transferables","toWireValue","postMessage","removeEventListener","closeEndPoint","TypeError","endpoint","isMessagePort","close","target","pendingListeners","resolver","get","delete","createProxy","throwIfProxyReleased","isReleased","releaseEndpoint","requestResponseMessage","proxyCounter","WeakMap","proxyFinalizers","FinalizationRegistry","newCount","isProxyReleased","Proxy","_target","unregister","unregisterProxy","clear","p","toString","bind","_thisArg","rawArgumentList","last","processArguments","construct","register","registerProxy","processed","v","prototype","concat","handler","serializedValue","msg","floor","random","Number","MAX_SAFE_INTEGER","FEAScriptWorker","worker","feaWorker","isReady","_initWorker","Worker","URL","url","onerror","event","workerWrapper","Comlink.wrap","_ensureReady","reject","attempts","checkReady","setTimeout","startTime","performance","now","toFixed","getModelInfo","ping","terminate","VERSION"],"mappings":"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"} \ No newline at end of file diff --git a/dist/feascript.umd.js b/dist/feascript.umd.js new file mode 100644 index 0000000..1a0e0a3 --- /dev/null +++ b/dist/feascript.umd.js @@ -0,0 +1,8 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).FEAScript={})}(this,(function(e){"use strict";class t{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getGaussPointsAndWeights(){let e=[],t=[];return"linear"===this.elementOrder?(e[0]=.5,t[0]=1):"quadratic"===this.elementOrder&&(e[0]=(1-Math.sqrt(.6))/2,e[1]=.5,e[2]=(1+Math.sqrt(.6))/2,t[0]=5/18,t[1]=8/18,t[2]=5/18),{gaussPoints:e,gaussWeights:t}}}let n="basic";function s(e){"debug"===n&&console.log("%c[DEBUG] "+e,"color: #2196F3; font-weight: bold;")}function o(e){console.log("%c[INFO] "+e,"color: #4CAF50; font-weight: bold;")}function i(e){console.log("%c[ERROR] "+e,"color: #F44336; font-weight: bold;")}class r{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getBasisFunctions(e,t=null){let n=[],s=[],o=[];if("1D"===this.meshDimension)"linear"===this.elementOrder?(n[0]=1-e,n[1]=e,s[0]=-1,s[1]=1):"quadratic"===this.elementOrder&&(n[0]=1-3*e+2*e**2,n[1]=4*e-4*e**2,n[2]=2*e**2-e,s[0]=4*e-3,s[1]=4-8*e,s[2]=4*e-1);else if("2D"===this.meshDimension){if(null===t)return void i("Eta coordinate is required for 2D elements");if("linear"===this.elementOrder){function r(e){return 1-e}n[0]=r(e)*r(t),n[1]=r(e)*t,n[2]=e*r(t),n[3]=e*t,s[0]=-1*r(t),s[1]=-1*t,s[2]=1*r(t),s[3]=1*t,o[0]=-1*r(e),o[1]=1*r(e),o[2]=-1*e,o[3]=1*e}else if("quadratic"===this.elementOrder){function a(e){return 2*e**2-3*e+1}function l(e){return-4*e**2+4*e}function d(e){return 2*e**2-e}function h(e){return 4*e-3}function m(e){return-8*e+4}function u(e){return 4*e-1}n[0]=a(e)*a(t),n[1]=a(e)*l(t),n[2]=a(e)*d(t),n[3]=l(e)*a(t),n[4]=l(e)*l(t),n[5]=l(e)*d(t),n[6]=d(e)*a(t),n[7]=d(e)*l(t),n[8]=d(e)*d(t),s[0]=h(e)*a(t),s[1]=h(e)*l(t),s[2]=h(e)*d(t),s[3]=m(e)*a(t),s[4]=m(e)*l(t),s[5]=m(e)*d(t),s[6]=u(e)*a(t),s[7]=u(e)*l(t),s[8]=u(e)*d(t),o[0]=a(e)*h(t),o[1]=a(e)*m(t),o[2]=a(e)*u(t),o[3]=l(e)*h(t),o[4]=l(e)*m(t),o[5]=l(e)*u(t),o[6]=d(e)*h(t),o[7]=d(e)*m(t),o[8]=d(e)*u(t)}}return{basisFunction:n,basisFunctionDerivKsi:s,basisFunctionDerivEta:o}}}class a{constructor({numElementsX:e=null,maxX:t=null,numElementsY:n=null,maxY:s=null,meshDimension:o=null,elementOrder:i="linear",parsedMesh:r=null}){this.numElementsX=e,this.numElementsY=n,this.maxX=t,this.maxY=s,this.meshDimension=o,this.elementOrder=i,this.parsedMesh=r}generateMesh(){if(this.parsedMesh){if(this.parsedMesh.nodalNumbering&&"object"==typeof this.parsedMesh.nodalNumbering&&!Array.isArray(this.parsedMesh.nodalNumbering)){const e=this.parsedMesh.nodalNumbering.quadElements||[];if(this.parsedMesh.nodalNumbering.triangleElements,s("Initial parsed mesh nodal numbering from GMSH format: "+JSON.stringify(this.parsedMesh.nodalNumbering)),this.parsedMesh.elementTypes[3]||this.parsedMesh.elementTypes[10]){const t=[];for(let n=0;n0&&void 0===this.parsedMesh.boundaryElements[0]){const e=[];for(let t=1;t{if(1===e.dimension){const t=this.parsedMesh.boundaryNodePairs[e.tag]||[];t.length>0&&(this.parsedMesh.boundaryElements[e.tag]||(this.parsedMesh.boundaryElements[e.tag]=[]),t.forEach((t=>{const n=t[0],o=t[1];s(`Processing boundary node pair: [${n}, ${o}] for boundary ${e.tag} (${e.name||"unnamed"})`);let r=!1;for(let t=0;t0&&void 0===this.parsedMesh.boundaryElements[0])){const e=[];for(let t=1;t{if("constantTemp"===this.boundaryConditions[n][0]){const o=this.boundaryConditions[n][1];s(`Boundary ${n}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[n].forEach((([n,i])=>{if("linear"===this.elementOrder){({0:[0],1:[1]})[i].forEach((i=>{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{if("constantTemp"===this.boundaryConditions[n][0]){const o=this.boundaryConditions[n][1];s(`Boundary ${n}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[n].forEach((([n,i])=>{if("linear"===this.elementOrder){({0:[0,2],1:[0,1],2:[1,3],3:[2,3]})[i].forEach((i=>{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const t=this.boundaryConditions[e];"convection"===t[0]&&(d[e]=t[1],h[e]=t[2])})),"1D"===this.meshDimension?Object.keys(this.boundaryConditions).forEach((n=>{if("convection"===this.boundaryConditions[n][0]){const o=d[n],i=h[n];s(`Boundary ${n}: Applying convection with heat transfer coefficient h=${o} W/(m²·K) and external temperature T∞=${i} K`),this.boundaryElements[n].forEach((([n,r])=>{let a;"linear"===this.elementOrder?a=0===r?0:1:"quadratic"===this.elementOrder&&(a=0===r?0:2);const l=this.nop[n][a]-1;s(` - Applied convection boundary condition to node ${l+1} (element ${n+1}, local node ${a+1})`),e[l]+=-o*i,t[l][l]+=o}))}})):"2D"===this.meshDimension&&Object.keys(this.boundaryConditions).forEach((o=>{if("convection"===this.boundaryConditions[o][0]){const m=d[o],u=h[o];s(`Boundary ${o}: Applying convection with heat transfer coefficient h=${m} W/(m²·K) and external temperature T∞=${u} K`),this.boundaryElements[o].forEach((([o,d])=>{if("linear"===this.elementOrder){let h,c,f,p,y;0===d?(h=n[0],c=0,f=0,p=3,y=2):1===d?(h=0,c=n[0],f=0,p=2,y=1):2===d?(h=n[0],c=1,f=1,p=4,y=2):3===d&&(h=1,c=n[0],f=2,p=4,y=1);let g=l.getBasisFunctions(h,c),b=g.basisFunction,E=g.basisFunctionDerivKsi,M=g.basisFunctionDerivEta,$=0,v=0,w=0,C=0;const S=this.nop[o].length;for(let e=0;e"object"==typeof e&&null!==e||"function"==typeof e,p=new Map([["proxy",{canHandle:e=>f(e)&&e[d],serialize(e){const{port1:t,port2:n}=new MessageChannel;return y(e,t),[n,[n]]},deserialize:e=>(e.start(),b(e))}],["throw",{canHandle:e=>f(e)&&c in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function y(e,t=globalThis,n=["*"]){t.addEventListener("message",(function s(o){if(!o||!o.data)return;if(!function(e,t){for(const n of e){if(t===n||"*"===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}return!1}(n,o.origin))return void console.warn(`Invalid origin '${o.origin}' for comlink proxy`);const{id:i,type:r,path:a}=Object.assign({path:[]},o.data),l=(o.data.argumentList||[]).map(D);let h;try{const t=a.slice(0,-1).reduce(((e,t)=>e[t]),e),n=a.reduce(((e,t)=>e[t]),e);switch(r){case"GET":h=n;break;case"SET":t[a.slice(-1)[0]]=D(o.data.value),h=!0;break;case"APPLY":h=n.apply(t,l);break;case"CONSTRUCT":h=function(e){return Object.assign(e,{[d]:!0})}(new n(...l));break;case"ENDPOINT":{const{port1:t,port2:n}=new MessageChannel;y(e,n),h=function(e,t){return S.set(e,t),e}(t,[t])}break;case"RELEASE":h=void 0;break;default:return}}catch(e){h={value:e,[c]:0}}Promise.resolve(h).catch((e=>({value:e,[c]:0}))).then((n=>{const[o,a]=N(n);t.postMessage(Object.assign(Object.assign({},o),{id:i}),a),"RELEASE"===r&&(t.removeEventListener("message",s),g(t),u in e&&"function"==typeof e[u]&&e[u]())})).catch((e=>{const[n,s]=N({value:new TypeError("Unserializable return value"),[c]:0});t.postMessage(Object.assign(Object.assign({},n),{id:i}),s)}))})),t.start&&t.start()}function g(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function b(e,t){const n=new Map;return e.addEventListener("message",(function(e){const{data:t}=e;if(!t||!t.id)return;const s=n.get(t.id);if(s)try{s(t)}finally{n.delete(t.id)}})),w(e,n,[],t)}function E(e){if(e)throw new Error("Proxy has been released and is not useable")}function M(e){return O(e,new Map,{type:"RELEASE"}).then((()=>{g(e)}))}const $=new WeakMap,v="FinalizationRegistry"in globalThis&&new FinalizationRegistry((e=>{const t=($.get(e)||0)-1;$.set(e,t),0===t&&M(e)}));function w(e,t,n=[],s=function(){}){let o=!1;const i=new Proxy(s,{get(s,r){if(E(o),r===m)return()=>{!function(e){v&&v.unregister(e)}(i),M(e),t.clear(),o=!0};if("then"===r){if(0===n.length)return{then:()=>i};const s=O(e,t,{type:"GET",path:n.map((e=>e.toString()))}).then(D);return s.then.bind(s)}return w(e,t,[...n,r])},set(s,i,r){E(o);const[a,l]=N(r);return O(e,t,{type:"SET",path:[...n,i].map((e=>e.toString())),value:a},l).then(D)},apply(s,i,r){E(o);const a=n[n.length-1];if(a===h)return O(e,t,{type:"ENDPOINT"}).then(D);if("bind"===a)return w(e,t,n.slice(0,-1));const[l,d]=C(r);return O(e,t,{type:"APPLY",path:n.map((e=>e.toString())),argumentList:l},d).then(D)},construct(s,i){E(o);const[r,a]=C(i);return O(e,t,{type:"CONSTRUCT",path:n.map((e=>e.toString())),argumentList:r},a).then(D)}});return function(e,t){const n=($.get(t)||0)+1;$.set(t,n),v&&v.register(e,t,e)}(i,e),i}function C(e){const t=e.map(N);return[t.map((e=>e[0])),(n=t.map((e=>e[1])),Array.prototype.concat.apply([],n))];var n}const S=new WeakMap;function N(e){for(const[t,n]of p)if(n.canHandle(e)){const[s,o]=n.serialize(e);return[{type:"HANDLER",name:t,value:s},o]}return[{type:"RAW",value:e},S.get(e)||[]]}function D(e){switch(e.type){case"HANDLER":return p.get(e.name).deserialize(e.value);case"RAW":return e.value}}function O(e,t,n,s){return new Promise((o=>{const i=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");t.set(i,o),e.start&&e.start(),e.postMessage(Object.assign({id:i},n),s)}))}e.FEAScriptModel=class{constructor(){this.solverConfig=null,this.meshConfig={},this.boundaryConditions={},this.solverMethod="lusolve",o("FEAScriptModel instance created")}setSolverConfig(e){this.solverConfig=e,s(`Solver config set to: ${e}`)}setMeshConfig(e){this.meshConfig=e,s(`Mesh config set with dimensions: ${e.meshDimension}`)}addBoundaryCondition(e,t){this.boundaryConditions[e]=t,s(`Boundary condition added for boundary: ${e}, type: ${t[0]}`)}setSolverMethod(e){this.solverMethod=e,s(`Solver method set to: ${e}`)}solve(){if(!this.solverConfig||!this.meshConfig||!this.boundaryConditions){const e="Solver config, mesh config, and boundary conditions must be set before solving.";throw console.error(e),new Error(e)}let e=[],n=[],i=[],d={};if(o("Beginning matrix assembly..."),console.time("assemblyMatrices"),"solidHeatTransferScript"===this.solverConfig&&(o(`Using solver: ${this.solverConfig}`),({jacobianMatrix:e,residualVector:n,nodesCoordinates:d}=function(e,n){o("Starting solid heat transfer matrix assembly...");const{meshDimension:i,numElementsX:d,numElementsY:h,maxX:m,maxY:u,elementOrder:c,parsedMesh:f}=e;s("Generating mesh...");const p=new a({numElementsX:d,numElementsY:h,maxX:m,maxY:u,meshDimension:i,elementOrder:c,parsedMesh:f}).generateMesh();let y,g,b=p.nodesXCoordinates,E=p.nodesYCoordinates,M=p.totalNodesX,$=p.totalNodesY,v=p.nodalNumbering,w=p.boundaryElements;null!=f?(y=v.length,g=b.length,s(`Using parsed mesh with ${y} elements and ${g} nodes`)):(y=d*("2D"===i?h:1),g=M*("2D"===i?$:1),s(`Using mesh generated from geometry with ${y} elements and ${g} nodes`));let C,S,N,D,O,x,A,F=[],T=[],k=[],X=[],P=[],R=[],Y=[],W=[],I=[],j=[];for(let e=0;e{console.error("FEAScriptWorker: Worker error:",e)};const e=b(this.worker);this.feaWorker=await new e,this.isReady=!0}catch(e){throw console.error("Failed to initialize worker",e),e}}async _ensureReady(){return this.isReady?Promise.resolve():new Promise(((e,t)=>{let n=0;const s=()=>{n++,this.isReady?e():n>=50?t(new Error("Timeout waiting for worker to be ready")):setTimeout(s,1e3)};s()}))}async setSolverConfig(e){return await this._ensureReady(),o(`FEAScriptWorker: Setting solver config to: ${e}`),this.feaWorker.setSolverConfig(e)}async setMeshConfig(e){return await this._ensureReady(),o("FEAScriptWorker: Setting mesh config"),this.feaWorker.setMeshConfig(e)}async addBoundaryCondition(e,t){return await this._ensureReady(),o(`FEAScriptWorker: Adding boundary condition for boundary: ${e}`),this.feaWorker.addBoundaryCondition(e,t)}async setSolverMethod(e){return await this._ensureReady(),o(`FEAScriptWorker: Setting solver method to: ${e}`),this.feaWorker.setSolverMethod(e)}async solve(){await this._ensureReady(),o("FEAScriptWorker: Requesting solution from worker...");const e=performance.now(),t=await this.feaWorker.solve();return o(`FEAScriptWorker: Solution completed in ${((performance.now()-e)/1e3).toFixed(2)}s`),t}async getModelInfo(){return await this._ensureReady(),this.feaWorker.getModelInfo()}async ping(){return await this._ensureReady(),this.feaWorker.ping()}terminate(){this.worker&&(this.worker.terminate(),this.worker=null,this.feaWorker=null,this.isReady=!1)}},e.VERSION="0.1.1",e.importGmshQuadTri=async e=>{let t={nodesXCoordinates:[],nodesYCoordinates:[],nodalNumbering:{quadElements:[],triangleElements:[]},boundaryElements:[],boundaryConditions:[],boundaryNodePairs:{},gmshV:0,ascii:!1,fltBytes:"8",totalNodesX:0,totalNodesY:0,physicalPropMap:[],elementTypes:{}},n=(await e.text()).split("\n").map((e=>e.trim())).filter((e=>""!==e&&" "!==e)),o="",i=0,r=0,a=0,l=0,d={numNodes:0},h=0,m=[],u=0,c=0,f=0,p={dim:0,tag:0,elementType:0,numElements:0},y=0,g={};for(;i""!==e));if("meshFormat"===o)t.gmshV=parseFloat(s[0]),t.ascii="0"===s[1],t.fltBytes=s[2];else if("physicalNames"===o){if(s.length>=3){if(!/^\d+$/.test(s[0])){i++;continue}const e=parseInt(s[0],10),n=parseInt(s[1],10);let o=s.slice(2).join(" ");o=o.replace(/^"|"$/g,""),t.physicalPropMap.push({tag:n,dimension:e,name:o})}}else if("nodes"===o){if(0===r){r=parseInt(s[0],10),a=parseInt(s[1],10),t.nodesXCoordinates=new Array(a).fill(0),t.nodesYCoordinates=new Array(a).fill(0),i++;continue}if(lparseInt(e,10)));if(1===p.elementType||8===p.elementType){const n=p.tag;g[n]||(g[n]=[]),g[n].push(e),t.boundaryNodePairs[n]||(t.boundaryNodePairs[n]=[]),t.boundaryNodePairs[n].push(e)}else 2===p.elementType?t.nodalNumbering.triangleElements.push(e):(3===p.elementType||10===p.elementType)&&t.nodalNumbering.quadElements.push(e);y++,y===p.numElements&&(f++,p={numElements:0})}}i++}return t.physicalPropMap.forEach((e=>{if(1===e.dimension){const n=g[e.tag]||[];n.length>0&&t.boundaryConditions.push({name:e.name,tag:e.tag,nodes:n})}})),s(`Parsed boundary node pairs by physical tag: ${JSON.stringify(t.boundaryNodePairs)}. These pairs will be used to identify boundary elements in the mesh.`),t},e.logSystem=function(e){"basic"!==e&&"debug"!==e?(console.log("%c[WARN] Invalid log level: "+e+". Using basic instead.","color: #FFC107; font-weight: bold;"),n="basic"):(n=e,o(`Log level set to: ${e}`))},e.plotSolution=function(e,t,n,s,o,i,r="structured"){const{nodesXCoordinates:a,nodesYCoordinates:l}=t;if("1D"===s&&"line"===o){let t;t=e.length>0&&Array.isArray(e[0])?e.map((e=>e[0])):e;let s=Array.from(a),o={x:s,y:t,mode:"lines",type:"scatter",line:{color:"rgb(219, 64, 82)",width:2},name:"Solution"},r=Math.min(window.innerWidth,700),l=Math.max(...s),d=r/l,h={title:`line plot - ${n}`,width:Math.max(d*l,400),height:350,xaxis:{title:"x"},yaxis:{title:"Solution"},margin:{l:70,r:40,t:50,b:50}};Plotly.newPlot(i,[o],h,{responsive:!0})}else if("2D"===s&&"contour"===o){const t="structured"===r,s=new Set(a).size,d=new Set(l).size;let h=Array.isArray(e[0])?e.map((e=>e[0])):e,m=Math.min(window.innerWidth,700),u=Math.max(...a),c=Math.max(...l)/u,f=Math.min(m,600),p={title:`${o} plot - ${n}`,width:f,height:f*c*.8,xaxis:{title:"x"},yaxis:{title:"y"},margin:{l:50,r:50,t:50,b:50},hovermode:"closest"};if(t){const t=s,n=d;math.reshape(Array.from(a),[t,n]);let o=math.reshape(Array.from(l),[t,n]),r=math.reshape(Array.from(e),[t,n]),h=math.transpose(r),m=[];for(let e=0;e | |\n // 0 --- 1 0 --- 2\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[3]; // 3 -> 1\n feaScriptNodes[2] = gmshNodes[1]; // 1 -> 2\n feaScriptNodes[3] = gmshNodes[2]; // 2 -> 3\n } else if (gmshNodes.length === 9) {\n // Mapping for quadratic quad elements (9 nodes)\n // GMSH: FEAScript:\n // 3--6--2 2--5--8\n // | | | |\n // 7 8 5 --> 1 4 7\n // | | | |\n // 0--4--1 0--3--6\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[7]; // 7 -> 1\n feaScriptNodes[2] = gmshNodes[3]; // 3 -> 2\n feaScriptNodes[3] = gmshNodes[4]; // 4 -> 3\n feaScriptNodes[4] = gmshNodes[8]; // 8 -> 4\n feaScriptNodes[5] = gmshNodes[6]; // 6 -> 5\n feaScriptNodes[6] = gmshNodes[1]; // 1 -> 6\n feaScriptNodes[7] = gmshNodes[5]; // 5 -> 7\n feaScriptNodes[8] = gmshNodes[2]; // 2 -> 8\n }\n\n mappedNodalNumbering.push(feaScriptNodes);\n }\n\n this.parsedMesh.nodalNumbering = mappedNodalNumbering;\n } else if (this.parsedMesh.elementTypes[2]) {\n }\n\n debugLog(\n \"Nodal numbering after mapping from GMSH to FEAScript format: \" +\n JSON.stringify(this.parsedMesh.nodalNumbering)\n );\n\n // Process boundary elements if they exist and if physical property mapping exists\n if (this.parsedMesh.physicalPropMap && this.parsedMesh.boundaryElements) {\n // Check if boundary elements need to be processed\n if (\n Array.isArray(this.parsedMesh.boundaryElements) &&\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n // Create a new array without the empty first element\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n\n // If boundary node pairs exist but boundary elements haven't been processed\n if (this.parsedMesh.boundaryNodePairs && !this.parsedMesh.boundaryElementsProcessed) {\n // Reset boundary elements array\n this.parsedMesh.boundaryElements = [];\n\n // Process each physical property from the Gmsh file\n this.parsedMesh.physicalPropMap.forEach((prop) => {\n // Only process 1D physical entities (boundary lines)\n if (prop.dimension === 1) {\n // Get all node pairs for this boundary\n const boundaryNodePairs = this.parsedMesh.boundaryNodePairs[prop.tag] || [];\n\n if (boundaryNodePairs.length > 0) {\n // Initialize array for this boundary tag\n if (!this.parsedMesh.boundaryElements[prop.tag]) {\n this.parsedMesh.boundaryElements[prop.tag] = [];\n }\n\n // For each boundary line segment (defined by a pair of nodes)\n boundaryNodePairs.forEach((nodesPair) => {\n const node1 = nodesPair[0]; // First node in the pair\n const node2 = nodesPair[1]; // Second node in the pair\n\n debugLog(\n `Processing boundary node pair: [${node1}, ${node2}] for boundary ${prop.tag} (${\n prop.name || \"unnamed\"\n })`\n );\n\n // Search through all elements to find which one contains both nodes\n let foundElement = false;\n\n // Loop through all elements in the mesh\n for (let elemIdx = 0; elemIdx < this.parsedMesh.nodalNumbering.length; elemIdx++) {\n const elemNodes = this.parsedMesh.nodalNumbering[elemIdx];\n\n // For linear quadrilateral linear elements (4 nodes)\n if (elemNodes.length === 4) {\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript linear quadrilateral numbering:\n // 1 --- 3\n // | |\n // 0 --- 2\n\n if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0)\n ) {\n side = 0; // Bottom side\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0)\n ) {\n side = 1; // Left side\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 1 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 1)\n ) {\n side = 2; // Top side\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 2)\n ) {\n side = 3; // Right side\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n } else if (elemNodes.length === 9) {\n // For quadratic quadrilateral elements (9 nodes)\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript quadratic quadrilateral numbering:\n // 2--5--8\n // | |\n // 1 4 7\n // | |\n // 0--3--6\n\n if (\n (node1Index === 0 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 0) ||\n (node1Index === 3 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 3)\n ) {\n side = 0; // Bottom side (nodes 0, 3, 6)\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0) ||\n (node1Index === 1 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 1)\n ) {\n side = 1; // Left side (nodes 0, 1, 2)\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 5) ||\n (node1Index === 5 && node2Index === 2) ||\n (node1Index === 5 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 5)\n ) {\n side = 2; // Top side (nodes 2, 5, 8)\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 6 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 7) ||\n (node1Index === 7 && node2Index === 6) ||\n (node1Index === 7 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 7)\n ) {\n side = 3; // Right side (nodes 6, 7, 8)\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n }\n }\n\n if (!foundElement) {\n errorLog(\n `Could not find element containing boundary nodes ${node1} and ${node2}. Boundary may be incomplete.`\n );\n }\n });\n }\n }\n });\n\n // Mark as processed\n this.parsedMesh.boundaryElementsProcessed = true;\n\n // Fix boundary elements array - remove undefined entries\n if (\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n }\n }\n }\n }\n\n debugLog(\"Processed boundary elements by tag: \" + JSON.stringify(this.parsedMesh.boundaryElements));\n\n return this.parsedMesh;\n } else {\n // Validate required geometry parameters based on mesh dimension\n if (this.meshDimension === \"1D\") {\n if (this.numElementsX === null || this.maxX === null) {\n errorLog(\"numElementsX and maxX are required parameters when generating a 1D mesh from geometry\");\n }\n } else if (this.meshDimension === \"2D\") {\n if (\n this.numElementsX === null ||\n this.maxX === null ||\n this.numElementsY === null ||\n this.maxY === null\n ) {\n errorLog(\n \"numElementsX, maxX, numElementsY, and maxY are required parameters when generating a 2D mesh from geometry\"\n );\n }\n }\n\n // Generate mesh based on dimension\n return this.generateMeshFromGeometry();\n }\n }\n\n /**\n * Function to generate a structured mesh based on the geometry configuration\n * @returns {object} An object containing the coordinates of nodes,\n * total number of nodes, nodal numbering (NOP) array, and boundary elements\n */\n generateMeshFromGeometry() {\n let nodesXCoordinates = [];\n let nodesYCoordinates = [];\n const xStart = 0;\n const yStart = 0;\n let totalNodesX, totalNodesY, deltaX, deltaY;\n\n if (this.meshDimension === \"1D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX;\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX / 2;\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n null, // numElementsY (not used in 1D)\n totalNodesX,\n null, // totalNodesY (not used in 1D)\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n\n // Return x coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n totalNodesX,\n nodalNumbering,\n boundaryElements,\n };\n } else if (this.meshDimension === \"2D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n totalNodesY = this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + nodeIndexY * deltaY;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + nodeIndexX * deltaX;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + nodeIndexY * deltaY;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n totalNodesY = 2 * this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + (nodeIndexY * deltaY) / 2;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + (nodeIndexX * deltaX) / 2;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + (nodeIndexY * deltaY) / 2;\n }\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n this.numElementsY,\n totalNodesX,\n totalNodesY,\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n debugLog(\"Generated node Y coordinates: \" + JSON.stringify(nodesYCoordinates));\n\n // Return x and y coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n nodesYCoordinates,\n totalNodesX,\n totalNodesY,\n nodalNumbering,\n boundaryElements,\n };\n }\n }\n\n /**\n * Function to find the elements that belong to each boundary of a domain\n * @returns {array} An array containing arrays of elements and their adjacent boundary side for each boundary\n * Each element in the array is of the form [elementIndex, side], where 'side' indicates which side\n * of the reference element is in contact with the physical boundary:\n *\n * For 1D domains (line segments):\n * 0 - Left node of reference element (maps to physical left endpoint)\n * 1 - Right node of reference element (maps to physical right endpoint)\n *\n * For 2D domains (rectangular):\n * 0 - Bottom side of reference element (maps to physical bottom boundary)\n * 1 - Left side of reference element (maps to physical left boundary)\n * 2 - Top side of reference element (maps to physical top boundary)\n * 3 - Right side of reference element (maps to physical right boundary)\n */\n findBoundaryElements() {\n const boundaryElements = [];\n const maxSides = this.meshDimension === \"1D\" ? 2 : 4; // Number of element sides based on mesh dimension\n for (let sideIndex = 0; sideIndex < maxSides; sideIndex++) {\n boundaryElements.push([]);\n }\n\n if (this.meshDimension === \"1D\") {\n // Left boundary (element 0, side 0)\n boundaryElements[0].push([0, 0]);\n\n // Right boundary (last element, side 1)\n boundaryElements[1].push([this.numElementsX - 1, 1]);\n } else if (this.meshDimension === \"2D\") {\n for (let elementIndexX = 0; elementIndexX < this.numElementsX; elementIndexX++) {\n for (let elementIndexY = 0; elementIndexY < this.numElementsY; elementIndexY++) {\n const elementIndex = elementIndexX * this.numElementsY + elementIndexY;\n\n // Bottom boundary\n if (elementIndexY === 0) {\n boundaryElements[0].push([elementIndex, 0]);\n }\n\n // Left boundary\n if (elementIndexX === 0) {\n boundaryElements[1].push([elementIndex, 1]);\n }\n\n // Top boundary\n if (elementIndexY === this.numElementsY - 1) {\n boundaryElements[2].push([elementIndex, 2]);\n }\n\n // Right boundary\n if (elementIndexX === this.numElementsX - 1) {\n boundaryElements[3].push([elementIndex, 3]);\n }\n }\n }\n }\n\n debugLog(\"Identified boundary elements by side: \" + JSON.stringify(boundaryElements));\n return boundaryElements;\n }\n\n /**\n * Function to generate the nodal numbering (NOP) array for a structured mesh\n * This array represents the connectivity between elements and their corresponding nodes\n * @param {number} numElementsX - Number of elements along the x-axis\n * @param {number} [numElementsY] - Number of elements along the y-axis (optional for 1D)\n * @param {number} totalNodesX - Total number of nodes along the x-axis\n * @param {number} [totalNodesY] - Total number of nodes along the y-axis (optional for 1D)\n * @param {string} elementOrder - The order of elements, either 'linear' or 'quadratic'\n * @returns {array} NOP - A two-dimensional array which represents the element-to-node connectivity for the entire mesh\n */\n generateNodalNumbering(numElementsX, numElementsY, totalNodesX, totalNodesY, elementOrder) {\n let elementIndex = 0;\n let nop = [];\n\n if (this.meshDimension === \"1D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear 1D elements with the following nodes representation:\n *\n * 1 --- 2\n *\n */\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 2; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic 1D elements with the following nodes representation:\n *\n * 1--2--3\n *\n */\n let columnCounter = 0;\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 3; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex + columnCounter;\n }\n columnCounter += 1;\n }\n }\n } else if (this.meshDimension === \"2D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear rectangular elements with the following nodes representation:\n *\n * 1 --- 3\n * | |\n * 0 --- 2\n *\n */\n let rowCounter = 0;\n let columnCounter = 2;\n for (let elementIndex = 0; elementIndex < numElementsX * numElementsY; elementIndex++) {\n rowCounter += 1;\n nop[elementIndex] = [];\n nop[elementIndex][0] = elementIndex + columnCounter - 1;\n nop[elementIndex][1] = elementIndex + columnCounter;\n nop[elementIndex][2] = elementIndex + columnCounter + numElementsY;\n nop[elementIndex][3] = elementIndex + columnCounter + numElementsY + 1;\n if (rowCounter === numElementsY) {\n columnCounter += 1;\n rowCounter = 0;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic rectangular elements with the following nodes representation:\n *\n * 2--5--8\n * | |\n * 1 4 7\n * | |\n * 0--3--6\n *\n */\n for (let elementIndexX = 1; elementIndexX <= numElementsX; elementIndexX++) {\n for (let elementIndexY = 1; elementIndexY <= numElementsY; elementIndexY++) {\n nop[elementIndex] = [];\n for (let nodeIndex1 = 1; nodeIndex1 <= 3; nodeIndex1++) {\n let nodeIndex2 = 3 * nodeIndex1 - 2;\n nop[elementIndex][nodeIndex2 - 1] =\n totalNodesY * (2 * elementIndexX + nodeIndex1 - 3) + 2 * elementIndexY - 1;\n nop[elementIndex][nodeIndex2] = nop[elementIndex][nodeIndex2 - 1] + 1;\n nop[elementIndex][nodeIndex2 + 1] = nop[elementIndex][nodeIndex2 - 1] + 2;\n }\n elementIndex = elementIndex + 1;\n }\n }\n }\n }\n\n return nop;\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to handle thermal boundary conditions application\n */\nexport class ThermalBoundaryConditions {\n /**\n * Constructor to initialize the ThermalBoundaryConditions class\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @param {array} boundaryElements - Array containing elements that belong to each boundary\n * @param {array} nop - Nodal numbering (NOP) array representing the connectivity between elements and nodes\n * @param {string} meshDimension - The dimension of the mesh (e.g., \"2D\")\n * @param {string} elementOrder - The order of elements (e.g., \"linear\", \"quadratic\")\n */\n constructor(boundaryConditions, boundaryElements, nop, meshDimension, elementOrder) {\n this.boundaryConditions = boundaryConditions;\n this.boundaryElements = boundaryElements;\n this.nop = nop;\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n }\n\n /**\n * Function to impose constant temperature boundary conditions (Dirichlet type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n */\n imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix) {\n basicLog(\"Applying constant temperature boundary conditions (Dirichlet type)\");\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 1: [1], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 2: [2], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0, 2], // Nodes at the bottom side of the reference element\n 1: [0, 1], // Nodes at the left side of the reference element\n 2: [1, 3], // Nodes at the top side of the reference element\n 3: [2, 3], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0, 3, 6], // Nodes at the bottom side of the reference element\n 1: [0, 1, 2], // Nodes at the left side of the reference element\n 2: [2, 5, 8], // Nodes at the top side of the reference element\n 3: [6, 7, 8], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n }\n }\n\n /**\n * Function to impose convection boundary conditions (Robin type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n * @param {array} gaussPoints - Array of Gauss points for numerical integration\n * @param {array} gaussWeights - Array of Gauss weights for numerical integration\n * @param {array} nodesXCoordinates - Array of x-coordinates of nodes\n * @param {array} nodesYCoordinates - Array of y-coordinates of nodes\n * @param {object} basisFunctionsData - Object containing basis functions and their derivatives\n */\n imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n ) {\n basicLog(\"Applying convection boundary conditions (Robin type)\");\n // Extract convection parameters from boundary conditions\n let convectionHeatTranfCoeff = [];\n let convectionExtTemp = [];\n Object.keys(this.boundaryConditions).forEach((key) => {\n const boundaryCondition = this.boundaryConditions[key];\n if (boundaryCondition[0] === \"convection\") {\n convectionHeatTranfCoeff[key] = boundaryCondition[1];\n convectionExtTemp[key] = boundaryCondition[2];\n }\n });\n\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n let nodeIndex;\n if (this.elementOrder === \"linear\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 1;\n }\n } else if (this.elementOrder === \"quadratic\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 2;\n }\n }\n\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n residualVector[globalNodeIndex] += -convectionCoeff * extTemp;\n jacobianMatrix[globalNodeIndex][globalNodeIndex] += convectionCoeff;\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 2;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 0;\n lastNodeIndex = 2;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 1;\n firstNodeIndex = 1;\n lastNodeIndex = 4;\n nodeIncrement = 2;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 2;\n lastNodeIndex = 4;\n nodeIncrement = 1;\n }\n\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[0] * tangentVectorLength * basisFunction[localNodeIndex] * convectionCoeff * extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[0] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n for (let gaussPointIndex = 0; gaussPointIndex < 3; gaussPointIndex++) {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 7;\n nodeIncrement = 3;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 1;\n firstNodeIndex = 2;\n lastNodeIndex = 9;\n nodeIncrement = 3;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 6;\n lastNodeIndex = 9;\n nodeIncrement = 1;\n }\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n convectionCoeff *\n extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n }\n }\n });\n }\n });\n }\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nconst proxyMarker = Symbol(\"Comlink.proxy\");\nconst createEndpoint = Symbol(\"Comlink.endpoint\");\nconst releaseProxy = Symbol(\"Comlink.releaseProxy\");\nconst finalizer = Symbol(\"Comlink.finalizer\");\nconst throwMarker = Symbol(\"Comlink.thrown\");\nconst isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n/**\n * Internal transfer handle to handle objects marked to proxy.\n */\nconst proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n};\n/**\n * Internal transfer handler to handle thrown exceptions.\n */\nconst throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n};\n/**\n * Allows customizing the serialization of certain values.\n */\nconst transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n]);\nfunction isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n}\nfunction expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n}\nfunction isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n}\nfunction closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n}\nfunction wrap(ep, target) {\n const pendingListeners = new Map();\n ep.addEventListener(\"message\", function handleMessage(ev) {\n const { data } = ev;\n if (!data || !data.id) {\n return;\n }\n const resolver = pendingListeners.get(data.id);\n if (!resolver) {\n return;\n }\n try {\n resolver(data);\n }\n finally {\n pendingListeners.delete(data.id);\n }\n });\n return createProxy(ep, pendingListeners, [], target);\n}\nfunction throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n}\nfunction releaseEndpoint(ep) {\n return requestResponseMessage(ep, new Map(), {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n}\nconst proxyCounter = new WeakMap();\nconst proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\nfunction registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n}\nfunction unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n}\nfunction createProxy(ep, pendingListeners, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n pendingListeners.clear();\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, pendingListeners, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, pendingListeners, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, pendingListeners, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, pendingListeners, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n}\nfunction myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n}\nfunction processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n}\nconst transferCache = new WeakMap();\nfunction transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n}\nfunction proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n}\nfunction windowEndpoint(w, context = globalThis, targetOrigin = \"*\") {\n return {\n postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),\n addEventListener: context.addEventListener.bind(context),\n removeEventListener: context.removeEventListener.bind(context),\n };\n}\nfunction toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n}\nfunction fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n}\nfunction requestResponseMessage(ep, pendingListeners, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n pendingListeners.set(id, resolve);\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n}\nfunction generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n}\n\nexport { createEndpoint, expose, finalizer, proxy, proxyMarker, releaseProxy, transfer, transferHandlers, windowEndpoint, wrap };\n//# sourceMappingURL=comlink.mjs.map\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { jacobiMethod } from \"./methods/jacobiMethodScript.js\";\nimport { assembleSolidHeatTransferMat } from \"./solvers/solidHeatTransferScript.js\";\nimport { basicLog, debugLog, errorLog } from \"./utilities/loggingScript.js\";\n\n/**\n * Class to implement finite element analysis in JavaScript\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing the solution vector and additional mesh information\n */\nexport class FEAScriptModel {\n constructor() {\n this.solverConfig = null;\n this.meshConfig = {};\n this.boundaryConditions = {};\n this.solverMethod = \"lusolve\"; // Default solver method\n basicLog(\"FEAScriptModel instance created\");\n }\n\n setSolverConfig(solverConfig) {\n this.solverConfig = solverConfig;\n debugLog(`Solver config set to: ${solverConfig}`);\n }\n\n setMeshConfig(meshConfig) {\n this.meshConfig = meshConfig;\n debugLog(\n `Mesh config set with dimensions: ${meshConfig.meshDimension}`\n );\n }\n\n addBoundaryCondition(boundaryKey, condition) {\n this.boundaryConditions[boundaryKey] = condition;\n debugLog(`Boundary condition added for boundary: ${boundaryKey}, type: ${condition[0]}`);\n }\n\n setSolverMethod(solverMethod) {\n this.solverMethod = solverMethod;\n debugLog(`Solver method set to: ${solverMethod}`);\n }\n\n solve() {\n if (!this.solverConfig || !this.meshConfig || !this.boundaryConditions) {\n const error = \"Solver config, mesh config, and boundary conditions must be set before solving.\";\n console.error(error);\n throw new Error(error);\n }\n\n let jacobianMatrix = [];\n let residualVector = [];\n let solutionVector = [];\n let nodesCoordinates = {};\n\n // Assembly matrices\n basicLog(\"Beginning matrix assembly...\");\n console.time(\"assemblyMatrices\");\n if (this.solverConfig === \"solidHeatTransferScript\") {\n basicLog(`Using solver: ${this.solverConfig}`);\n ({ jacobianMatrix, residualVector, nodesCoordinates } = assembleSolidHeatTransferMat(\n this.meshConfig,\n this.boundaryConditions\n ));\n }\n console.timeEnd(\"assemblyMatrices\");\n basicLog(\"Matrix assembly completed\");\n\n // System solving\n basicLog(`Solving system using ${this.solverMethod}...`);\n console.time(\"systemSolving\");\n if (this.solverMethod === \"lusolve\") {\n solutionVector = math.lusolve(jacobianMatrix, residualVector);\n } else if (this.solverMethod === \"jacobi\") {\n // Create initial guess of zeros\n const initialGuess = new Array(residualVector.length).fill(0);\n // Call Jacobi method with desired max iterations and tolerance\n const jacobiResult = jacobiMethod(jacobianMatrix, residualVector, initialGuess, 1000, 1e-6);\n\n // Log convergence information\n if (jacobiResult.converged) {\n debugLog(`Jacobi method converged in ${jacobiResult.iterations} iterations`);\n } else {\n debugLog(`Jacobi method did not converge after ${jacobiResult.iterations} iterations`);\n }\n\n solutionVector = jacobiResult.solution;\n }\n console.timeEnd(\"systemSolving\");\n basicLog(\"System solved successfully\");\n\n return { solutionVector, nodesCoordinates };\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { numericalIntegration } from \"../methods/numericalIntegrationScript.js\";\nimport { basisFunctions } from \"../mesh/basisFunctionsScript.js\";\nimport { meshGeneration } from \"../mesh/meshGenerationScript.js\";\nimport { ThermalBoundaryConditions } from \"./thermalBoundaryConditionsScript.js\";\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to assemble the solid heat transfer matrix\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing:\n * - jacobianMatrix: The assembled Jacobian matrix\n * - residualVector: The assembled residual vector\n * - nodesCoordinates: Object containing x and y coordinates of nodes\n */\nexport function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {\n basicLog(\"Starting solid heat transfer matrix assembly...\");\n\n // Extract mesh details from the configuration object\n const {\n meshDimension, // The dimension of the mesh\n numElementsX, // Number of elements in x-direction\n numElementsY, // Number of elements in y-direction (only for 2D)\n maxX, // Max x-coordinate (m) of the domain\n maxY, // Max y-coordinate (m) of the domain (only for 2D)\n elementOrder, // The order of elements\n parsedMesh, // The pre-parsed mesh data (if available)\n } = meshConfig;\n\n // Create a new instance of the meshGeneration class\n debugLog(\"Generating mesh...\");\n const meshGenerationData = new meshGeneration({\n numElementsX,\n numElementsY,\n maxX,\n maxY,\n meshDimension,\n elementOrder,\n parsedMesh, // Pass the parsed mesh to the mesh generator\n });\n\n // Generate the mesh\n const nodesCoordinatesAndNumbering = meshGenerationData.generateMesh();\n\n // Extract nodes coordinates and nodal numbering (NOP) from the mesh data\n let nodesXCoordinates = nodesCoordinatesAndNumbering.nodesXCoordinates;\n let nodesYCoordinates = nodesCoordinatesAndNumbering.nodesYCoordinates;\n let totalNodesX = nodesCoordinatesAndNumbering.totalNodesX;\n let totalNodesY = nodesCoordinatesAndNumbering.totalNodesY;\n let nop = nodesCoordinatesAndNumbering.nodalNumbering;\n let boundaryElements = nodesCoordinatesAndNumbering.boundaryElements;\n\n // Check the mesh type\n const isParsedMesh = parsedMesh !== undefined && parsedMesh !== null;\n\n // Calculate totalElements and totalNodes based on mesh type\n let totalElements, totalNodes;\n\n if (isParsedMesh) {\n totalElements = nop.length; // Number of elements is the length of the nodal numbering array\n totalNodes = nodesXCoordinates.length; // Number of nodes is the length of the coordinates array\n\n // Debug log for mesh size\n debugLog(`Using parsed mesh with ${totalElements} elements and ${totalNodes} nodes`);\n } else {\n // For structured mesh, calculate based on dimensions\n totalElements = numElementsX * (meshDimension === \"2D\" ? numElementsY : 1);\n totalNodes = totalNodesX * (meshDimension === \"2D\" ? totalNodesY : 1);\n // Debug log for mesh size\n debugLog(`Using mesh generated from geometry with ${totalElements} elements and ${totalNodes} nodes`);\n }\n\n // Initialize variables for matrix assembly\n let localToGlobalMap = []; // Maps local element node indices to global mesh node indices\n let gaussPoints = []; // Gauss points\n let gaussWeights = []; // Gauss weights\n let basisFunction = []; // Basis functions\n let basisFunctionDerivKsi = []; // Derivatives of basis functions with respect to ksi\n let basisFunctionDerivEta = []; // Derivatives of basis functions with respect to eta (only for 2D)\n let basisFunctionDerivX = []; // The x-derivative of the basis function\n let basisFunctionDerivY = []; // The y-derivative of the basis function (only for 2D)\n let residualVector = []; // Galerkin residuals\n let jacobianMatrix = []; // Jacobian matrix\n let xCoordinates; // x-coordinate (physical coordinates)\n let yCoordinates; // y-coordinate (physical coordinates) (only for 2D)\n let ksiDerivX; // ksi-derivative of xCoordinates\n let etaDerivX; // eta-derivative of xCoordinates (ksi and eta are natural coordinates that vary within a reference element) (only for 2D)\n let ksiDerivY; // ksi-derivative of yCoordinates (only for 2D)\n let etaDerivY; // eta-derivative of yCoordinates (only for 2D)\n let detJacobian; // The jacobian of the isoparametric mapping\n\n // Initialize jacobianMatrix and residualVector arrays\n for (let nodeIndex = 0; nodeIndex < totalNodes; nodeIndex++) {\n residualVector[nodeIndex] = 0;\n jacobianMatrix.push([]);\n for (let colIndex = 0; colIndex < totalNodes; colIndex++) {\n jacobianMatrix[nodeIndex][colIndex] = 0;\n }\n }\n\n // Initialize the basisFunctions class\n const basisFunctionsData = new basisFunctions({\n meshDimension,\n elementOrder,\n });\n\n // Initialize the numericalIntegration class\n const numIntegrationData = new numericalIntegration({\n meshDimension,\n elementOrder,\n });\n\n // Calculate Gauss points and weights\n let gaussPointsAndWeights = numIntegrationData.getGaussPointsAndWeights();\n gaussPoints = gaussPointsAndWeights.gaussPoints;\n gaussWeights = gaussPointsAndWeights.gaussWeights;\n\n // Determine the number of nodes in the reference element based on the first element in the nop array\n const numNodes = nop[0].length;\n\n // Matrix assembly\n for (let elementIndex = 0; elementIndex < totalElements; elementIndex++) {\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n // Subtract 1 from nop in order to start numbering from 0\n localToGlobalMap[localNodeIndex] = nop[elementIndex][localNodeIndex] - 1;\n }\n\n // Loop over Gauss points\n for (let gaussPointIndex1 = 0; gaussPointIndex1 < gaussPoints.length; gaussPointIndex1++) {\n // 1D solid heat transfer\n if (meshDimension === \"1D\") {\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n xCoordinates = 0;\n ksiDerivX = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates += nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n detJacobian = ksiDerivX;\n }\n\n // Compute x-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] = basisFunctionDerivKsi[localNodeIndex] / detJacobian; // The x-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2]);\n }\n }\n // 2D solid heat transfer\n } else if (meshDimension === \"2D\") {\n for (let gaussPointIndex2 = 0; gaussPointIndex2 < gaussPoints.length; gaussPointIndex2++) {\n // Initialise variables for isoparametric mapping\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1],\n gaussPoints[gaussPointIndex2]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n xCoordinates = 0;\n yCoordinates = 0;\n ksiDerivX = 0;\n etaDerivX = 0;\n ksiDerivY = 0;\n etaDerivY = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n yCoordinates +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n ksiDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n detJacobian = meshDimension === \"2D\" ? ksiDerivX * etaDerivY - etaDerivX * ksiDerivY : ksiDerivX;\n }\n\n // Compute x-derivative and y-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] =\n (etaDerivY * basisFunctionDerivKsi[localNodeIndex] -\n ksiDerivY * basisFunctionDerivEta[localNodeIndex]) /\n detJacobian; // The x-derivative of the n basis function\n basisFunctionDerivY[localNodeIndex] =\n (ksiDerivX * basisFunctionDerivEta[localNodeIndex] -\n etaDerivX * basisFunctionDerivKsi[localNodeIndex]) /\n detJacobian; // The y-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n gaussWeights[gaussPointIndex2] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2] +\n basisFunctionDerivY[localNodeIndex1] * basisFunctionDerivY[localNodeIndex2]);\n }\n }\n }\n }\n }\n }\n\n // Create an instance of ThermalBoundaryConditions\n debugLog(\"Applying thermal boundary conditions...\");\n const thermalBoundaryConditions = new ThermalBoundaryConditions(\n boundaryConditions,\n boundaryElements,\n nop,\n meshDimension,\n elementOrder\n );\n\n // Impose Convection boundary conditions\n thermalBoundaryConditions.imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n );\n debugLog(\"Convection boundary conditions applied\");\n\n // Impose ConstantTemp boundary conditions\n thermalBoundaryConditions.imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix);\n debugLog(\"Constant temperature boundary conditions applied\");\n\n basicLog(\"Solid heat transfer matrix assembly completed\");\n\n return {\n jacobianMatrix,\n residualVector,\n nodesCoordinates: {\n nodesXCoordinates,\n nodesYCoordinates,\n },\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to solve a system of linear equations using the Jacobi iterative method\n * @param {array} A - The coefficient matrix (must be square)\n * @param {array} b - The right-hand side vector\n * @param {array} x0 - Initial guess for solution vector\n * @param {number} [maxIterations=100] - Maximum number of iterations\n * @param {number} [tolerance=1e-7] - Convergence tolerance\n * @returns {object} An object containing:\n * - solution: The solution vector\n * - iterations: The number of iterations performed\n * - converged: Boolean indicating whether the method converged\n */\nexport function jacobiMethod(A, b, x0, maxIterations = 100, tolerance = 1e-7) {\n const n = A.length; // Size of the square matrix\n let x = [...x0]; // Current solution (starts with initial guess)\n let xNew = new Array(n); // Next iteration's solution\n\n for (let iteration = 0; iteration < maxIterations; iteration++) {\n // Perform one iteration\n for (let i = 0; i < n; i++) {\n let sum = 0;\n // Calculate sum of A[i][j] * x[j] for j ≠ i\n for (let j = 0; j < n; j++) {\n if (j !== i) {\n sum += A[i][j] * x[j];\n }\n }\n // Update xNew[i] using the Jacobi formula\n xNew[i] = (b[i] - sum) / A[i][i];\n }\n\n // Check convergence\n let maxDiff = 0;\n for (let i = 0; i < n; i++) {\n maxDiff = Math.max(maxDiff, Math.abs(xNew[i] - x[i]));\n }\n\n // Update x for next iteration\n x = [...xNew];\n\n // Successfully converged if maxDiff is less than tolerance\n if (maxDiff < tolerance) {\n return {\n solution: x,\n iterations: iteration + 1,\n converged: true,\n };\n }\n }\n\n // maxIterations were reached without convergence\n return {\n solution: x,\n iterations: maxIterations,\n converged: false,\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// External imports\nimport * as Comlink from \"../vendor/comlink.mjs\";\n\n// Internal imports\nimport { basicLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to facilitate communication with web workers for FEAScript operations\n */\nexport class FEAScriptWorker {\n /**\n * Constructor to initialize the FEAScriptWorker class\n * Sets up the worker and initializes the workerWrapper.\n */\n constructor() {\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n\n this._initWorker();\n }\n\n /**\n * Function to initialize the web worker and wrap it using Comlink.\n * @private\n * @throws Will throw an error if the worker fails to initialize.\n */\n async _initWorker() {\n try {\n this.worker = new Worker(new URL(\"./wrapperScript.js\", import.meta.url), {\n type: \"module\",\n });\n\n this.worker.onerror = (event) => {\n console.error(\"FEAScriptWorker: Worker error:\", event);\n };\n const workerWrapper = Comlink.wrap(this.worker);\n\n this.feaWorker = await new workerWrapper();\n\n this.isReady = true;\n } catch (error) {\n console.error(\"Failed to initialize worker\", error);\n throw error;\n }\n }\n\n /**\n * Function to ensure that the worker is ready before performing any operations.\n * @private\n * @returns {Promise} Resolves when the worker is ready.\n * @throws Will throw an error if the worker is not ready within the timeout period.\n */\n async _ensureReady() {\n if (this.isReady) return Promise.resolve();\n\n return new Promise((resolve, reject) => {\n let attempts = 0;\n const maxAttempts = 50; // 5 seconds max\n\n const checkReady = () => {\n attempts++;\n if (this.isReady) {\n resolve();\n } else if (attempts >= maxAttempts) {\n reject(new Error(\"Timeout waiting for worker to be ready\"));\n } else {\n setTimeout(checkReady, 1000);\n }\n };\n checkReady();\n });\n }\n\n /**\n * Function to set the solver configuration in the worker.\n * @param {string} solverConfig - The solver configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setSolverConfig(solverConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver config to: ${solverConfig}`);\n return this.feaWorker.setSolverConfig(solverConfig);\n }\n\n /**\n * Sets the mesh configuration in the worker.\n * @param {object} meshConfig - The mesh configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setMeshConfig(meshConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting mesh config`);\n return this.feaWorker.setMeshConfig(meshConfig);\n }\n\n /**\n * Adds a boundary condition to the worker.\n * @param {string} boundaryKey - The key identifying the boundary.\n * @param {array} condition - The boundary condition to add.\n * @returns {Promise} Resolves when the boundary condition is added.\n */\n async addBoundaryCondition(boundaryKey, condition) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Adding boundary condition for boundary: ${boundaryKey}`);\n return this.feaWorker.addBoundaryCondition(boundaryKey, condition);\n }\n\n /**\n * Sets the solver method in the worker.\n * @param {string} solverMethod - The solver method to set.\n * @returns {Promise} Resolves when the solver method is set.\n */\n async setSolverMethod(solverMethod) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver method to: ${solverMethod}`);\n return this.feaWorker.setSolverMethod(solverMethod);\n }\n\n /**\n * Requests the worker to solve the problem.\n * @returns {Promise} Resolves with the solution result.\n */\n async solve() {\n await this._ensureReady();\n basicLog(\"FEAScriptWorker: Requesting solution from worker...\");\n\n const startTime = performance.now();\n const result = await this.feaWorker.solve();\n const endTime = performance.now();\n\n basicLog(`FEAScriptWorker: Solution completed in ${((endTime - startTime) / 1000).toFixed(2)}s`);\n return result;\n }\n\n /**\n * Retrieves model information from the worker.\n * @returns {Promise} Resolves with the model information.\n */\n async getModelInfo() {\n await this._ensureReady();\n return this.feaWorker.getModelInfo();\n }\n\n /**\n * Sends a ping request to the worker to check its availability.\n * @returns {Promise} Resolves if the worker responds.\n */\n async ping() {\n await this._ensureReady();\n return this.feaWorker.ping();\n }\n\n /**\n * Terminates the worker and cleans up resources.\n */\n terminate() {\n if (this.worker) {\n this.worker.terminate();\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n }\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\nexport { FEAScriptModel } from \"./FEAScript.js\";\nexport { importGmshQuadTri } from \"./readers/gmshReaderScript.js\";\nexport { logSystem, printVersion } from \"./utilities/loggingScript.js\";\nexport { plotSolution } from \"./visualization/plotSolutionScript.js\";\nexport { FEAScriptWorker } from \"./workers/workerScript.js\";\nexport const VERSION = \"0.1.1\";","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to import mesh data from Gmsh format containing quadrilateral and triangular elements\n * @param {File} file - The Gmsh file to be parsed (.msh version 4.1)\n * @returns {object} The parsed mesh data including node coordinates, element connectivity, and boundary conditions\n */\nconst importGmshQuadTri = async (file) => {\n let result = {\n nodesXCoordinates: [],\n nodesYCoordinates: [],\n nodalNumbering: {\n quadElements: [],\n triangleElements: [],\n },\n boundaryElements: [],\n boundaryConditions: [],\n boundaryNodePairs: {}, // Store boundary node pairs for processing in meshGenerationScript\n gmshV: 0,\n ascii: false,\n fltBytes: \"8\",\n totalNodesX: 0,\n totalNodesY: 0,\n physicalPropMap: [],\n elementTypes: {},\n };\n\n let content = await file.text();\n let lines = content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\" && line !== \" \");\n\n let section = \"\";\n let lineIndex = 0;\n\n let nodeEntityBlocks = 0;\n let totalNodes = 0;\n let nodeBlocksProcessed = 0;\n let currentNodeBlock = { numNodes: 0 };\n let nodeTagsCollected = 0;\n let nodeTags = [];\n let nodeCoordinatesCollected = 0;\n\n let elementEntityBlocks = 0;\n let totalElements = 0;\n let elementBlocksProcessed = 0;\n let currentElementBlock = {\n dim: 0,\n tag: 0,\n elementType: 0,\n numElements: 0,\n };\n let elementsProcessedInBlock = 0;\n\n let boundaryElementsByTag = {};\n\n while (lineIndex < lines.length) {\n const line = lines[lineIndex];\n\n if (line === \"$MeshFormat\") {\n section = \"meshFormat\";\n lineIndex++;\n continue;\n } else if (line === \"$EndMeshFormat\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$PhysicalNames\") {\n section = \"physicalNames\";\n lineIndex++;\n continue;\n } else if (line === \"$EndPhysicalNames\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Entities\") {\n section = \"entities\";\n lineIndex++;\n continue;\n } else if (line === \"$EndEntities\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Nodes\") {\n section = \"nodes\";\n lineIndex++;\n continue;\n } else if (line === \"$EndNodes\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Elements\") {\n section = \"elements\";\n lineIndex++;\n continue;\n } else if (line === \"$EndElements\") {\n section = \"\";\n lineIndex++;\n continue;\n }\n\n const parts = line.split(/\\s+/).filter((part) => part !== \"\");\n\n if (section === \"meshFormat\") {\n result.gmshV = parseFloat(parts[0]);\n result.ascii = parts[1] === \"0\";\n result.fltBytes = parts[2];\n } else if (section === \"physicalNames\") {\n if (parts.length >= 3) {\n if (!/^\\d+$/.test(parts[0])) {\n lineIndex++;\n continue;\n }\n\n const dimension = parseInt(parts[0], 10);\n const tag = parseInt(parts[1], 10);\n let name = parts.slice(2).join(\" \");\n name = name.replace(/^\"|\"$/g, \"\");\n\n result.physicalPropMap.push({\n tag,\n dimension,\n name,\n });\n }\n } else if (section === \"nodes\") {\n if (nodeEntityBlocks === 0) {\n nodeEntityBlocks = parseInt(parts[0], 10);\n totalNodes = parseInt(parts[1], 10);\n result.nodesXCoordinates = new Array(totalNodes).fill(0);\n result.nodesYCoordinates = new Array(totalNodes).fill(0);\n lineIndex++;\n continue;\n }\n\n if (nodeBlocksProcessed < nodeEntityBlocks && currentNodeBlock.numNodes === 0) {\n currentNodeBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n parametric: parseInt(parts[2], 10),\n numNodes: parseInt(parts[3], 10),\n };\n\n nodeTags = [];\n nodeTagsCollected = 0;\n nodeCoordinatesCollected = 0;\n\n lineIndex++;\n continue;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n for (let i = 0; i < parts.length && nodeTagsCollected < currentNodeBlock.numNodes; i++) {\n nodeTags.push(parseInt(parts[i], 10));\n nodeTagsCollected++;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n lineIndex++;\n continue;\n }\n\n lineIndex++;\n continue;\n }\n\n if (nodeCoordinatesCollected < currentNodeBlock.numNodes) {\n const nodeTag = nodeTags[nodeCoordinatesCollected] - 1;\n const x = parseFloat(parts[0]);\n const y = parseFloat(parts[1]);\n\n result.nodesXCoordinates[nodeTag] = x;\n result.nodesYCoordinates[nodeTag] = y;\n result.totalNodesX++;\n result.totalNodesY++;\n\n nodeCoordinatesCollected++;\n\n if (nodeCoordinatesCollected === currentNodeBlock.numNodes) {\n nodeBlocksProcessed++;\n currentNodeBlock = { numNodes: 0 };\n }\n }\n } else if (section === \"elements\") {\n if (elementEntityBlocks === 0) {\n elementEntityBlocks = parseInt(parts[0], 10);\n totalElements = parseInt(parts[1], 10);\n lineIndex++;\n continue;\n }\n\n if (elementBlocksProcessed < elementEntityBlocks && currentElementBlock.numElements === 0) {\n currentElementBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n elementType: parseInt(parts[2], 10),\n numElements: parseInt(parts[3], 10),\n };\n\n result.elementTypes[currentElementBlock.elementType] =\n (result.elementTypes[currentElementBlock.elementType] || 0) + currentElementBlock.numElements;\n\n elementsProcessedInBlock = 0;\n lineIndex++;\n continue;\n }\n\n if (elementsProcessedInBlock < currentElementBlock.numElements) {\n const elementTag = parseInt(parts[0], 10);\n const nodeIndices = parts.slice(1).map((idx) => parseInt(idx, 10));\n\n if (currentElementBlock.elementType === 1 || currentElementBlock.elementType === 8) {\n const physicalTag = currentElementBlock.tag;\n\n if (!boundaryElementsByTag[physicalTag]) {\n boundaryElementsByTag[physicalTag] = [];\n }\n\n boundaryElementsByTag[physicalTag].push(nodeIndices);\n\n // Store boundary node pairs for later processing in meshGenerationScript\n if (!result.boundaryNodePairs[physicalTag]) {\n result.boundaryNodePairs[physicalTag] = [];\n }\n result.boundaryNodePairs[physicalTag].push(nodeIndices);\n } else if (currentElementBlock.elementType === 2) {\n // Linear triangle elements (3 nodes)\n result.nodalNumbering.triangleElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 3) {\n // Linear quadrilateral elements (4 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 10) {\n // Quadratic quadrilateral elements (9 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n }\n\n elementsProcessedInBlock++;\n\n if (elementsProcessedInBlock === currentElementBlock.numElements) {\n elementBlocksProcessed++;\n currentElementBlock = { numElements: 0 };\n }\n }\n }\n\n lineIndex++;\n }\n\n // Store boundary conditions information\n result.physicalPropMap.forEach((prop) => {\n if (prop.dimension === 1) {\n const boundaryNodes = boundaryElementsByTag[prop.tag] || [];\n\n if (boundaryNodes.length > 0) {\n result.boundaryConditions.push({\n name: prop.name,\n tag: prop.tag,\n nodes: boundaryNodes,\n });\n }\n }\n });\n\n debugLog(\n `Parsed boundary node pairs by physical tag: ${JSON.stringify(\n result.boundaryNodePairs\n )}. These pairs will be used to identify boundary elements in the mesh.`\n );\n\n return result;\n};\n\nexport { importGmshQuadTri };\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to create plots of the solution vector\n * @param {*} solutionVector - The computed solution vector\n * @param {*} nodesCoordinates - Object containing x and y coordinates for the nodes\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {string} meshDimension - The dimension of the solution\n * @param {string} plotType - The type of plot\n * @param {string} plotDivId - The id of the div where the plot will be rendered\n * @param {string} [meshType=\"structured\"] - Type of mesh: \"structured\" or \"unstructured\"\n */\nexport function plotSolution(\n solutionVector,\n nodesCoordinates,\n solverConfig,\n meshDimension,\n plotType,\n plotDivId,\n meshType = \"structured\"\n) {\n const { nodesXCoordinates, nodesYCoordinates } = nodesCoordinates;\n\n if (meshDimension === \"1D\" && plotType === \"line\") {\n // Check if solutionVector is a nested array\n let yData;\n if (solutionVector.length > 0 && Array.isArray(solutionVector[0])) {\n yData = solutionVector.map((arr) => arr[0]);\n } else {\n yData = solutionVector;\n }\n let xData = Array.from(nodesXCoordinates);\n\n let lineData = {\n x: xData,\n y: yData,\n mode: \"lines\",\n type: \"scatter\",\n line: { color: \"rgb(219, 64, 82)\", width: 2 },\n name: \"Solution\",\n };\n\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxPlotWidth = Math.max(...xData);\n let zoomFactor = maxWindowWidth / maxPlotWidth;\n let plotWidth = Math.max(zoomFactor * maxPlotWidth, 400);\n let plotHeight = 350;\n\n let layout = {\n title: `line plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"Solution\" },\n margin: { l: 70, r: 40, t: 50, b: 50 },\n };\n\n Plotly.newPlot(plotDivId, [lineData], layout, { responsive: true });\n } else if (meshDimension === \"2D\" && plotType === \"contour\") {\n // Use the user-provided mesh type\n const isStructured = meshType === \"structured\";\n \n // For auto-detection (if needed)\n const uniqueXCoords = new Set(nodesXCoordinates).size;\n const uniqueYCoords = new Set(nodesYCoordinates).size;\n \n // Extract scalar values from solution vector\n let zValues = Array.isArray(solutionVector[0]) \n ? solutionVector.map(val => val[0]) \n : solutionVector;\n \n // Common sizing parameters for both plot types\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxX = Math.max(...nodesXCoordinates);\n let maxY = Math.max(...nodesYCoordinates);\n let aspectRatio = maxY / maxX;\n let plotWidth = Math.min(maxWindowWidth, 600);\n let plotHeight = plotWidth * aspectRatio * 0.8; // Slightly reduce height for better appearance\n \n // Common layout properties\n let layout = {\n title: `${plotType} plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"y\" },\n margin: { l: 50, r: 50, t: 50, b: 50 },\n hovermode: 'closest'\n };\n \n if (isStructured) {\n // Calculate the number of nodes along the x-axis and y-axis\n const numNodesX = uniqueXCoords;\n const numNodesY = uniqueYCoords;\n\n // Reshape the nodesXCoordinates and nodesYCoordinates arrays to match the grid dimensions\n let reshapedXCoordinates = math.reshape(Array.from(nodesXCoordinates), [numNodesX, numNodesY]);\n let reshapedYCoordinates = math.reshape(Array.from(nodesYCoordinates), [numNodesX, numNodesY]);\n\n // Reshape the solution array to match the grid dimensions\n let reshapedSolution = math.reshape(Array.from(solutionVector), [numNodesX, numNodesY]);\n\n // Transpose the reshapedSolution array to get column-wise data\n let transposedSolution = math.transpose(reshapedSolution);\n\n // Create an array for x-coordinates used in the contour plot\n let reshapedXForPlot = [];\n for (let i = 0; i < numNodesX * numNodesY; i += numNodesY) {\n let xValue = nodesXCoordinates[i];\n reshapedXForPlot.push(xValue);\n }\n\n // Create the data structure for the contour plot\n let contourData = {\n z: transposedSolution,\n type: \"contour\",\n contours: {\n coloring: \"heatmap\",\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n x: reshapedXForPlot,\n y: reshapedYCoordinates[0],\n name: 'Solution Field'\n };\n\n // Create the plot using Plotly\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n } else {\n // Create an interpolated contour plot for the unstructured mesh\n let contourData = {\n x: nodesXCoordinates,\n y: nodesYCoordinates,\n z: zValues,\n type: 'contour',\n contours: {\n coloring: 'heatmap',\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n name: 'Solution Field'\n };\n \n // Create the plot using only the contour fill\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n }\n }\n}\n"],"names":["numericalIntegration","constructor","meshDimension","elementOrder","this","getGaussPointsAndWeights","gaussPoints","gaussWeights","Math","sqrt","currentLogLevel","debugLog","message","console","log","basicLog","errorLog","basisFunctions","getBasisFunctions","ksi","eta","basisFunction","basisFunctionDerivKsi","basisFunctionDerivEta","l1","c","l2","l3","dl1","dl2","dl3","meshGeneration","numElementsX","maxX","numElementsY","maxY","parsedMesh","generateMesh","nodalNumbering","Array","isArray","quadElements","triangleElements","JSON","stringify","elementTypes","mappedNodalNumbering","elemIdx","length","gmshNodes","feaScriptNodes","push","physicalPropMap","boundaryElements","undefined","fixedBoundaryElements","i","boundaryNodePairs","boundaryElementsProcessed","forEach","prop","dimension","tag","nodesPair","node1","node2","name","foundElement","elemNodes","includes","side","node1Index","indexOf","node2Index","join","generateMeshFromGeometry","nodesXCoordinates","nodesYCoordinates","totalNodesX","totalNodesY","deltaX","deltaY","nodeIndex","generateNodalNumbering","findBoundaryElements","nodeIndexY","nodeIndexX","nnode","maxSides","sideIndex","elementIndexX","elementIndexY","elementIndex","nop","columnCounter","rowCounter","nodeIndex1","nodeIndex2","ThermalBoundaryConditions","boundaryConditions","imposeConstantTempBoundaryConditions","residualVector","jacobianMatrix","Object","keys","boundaryKey","tempValue","globalNodeIndex","colIndex","imposeConvectionBoundaryConditions","basisFunctionsData","convectionHeatTranfCoeff","convectionExtTemp","key","boundaryCondition","convectionCoeff","extTemp","gaussPoint1","gaussPoint2","firstNodeIndex","lastNodeIndex","nodeIncrement","basisFunctionsAndDerivatives","ksiDerivX","ksiDerivY","etaDerivX","etaDerivY","numNodes","tangentVectorLength","localNodeIndex","localNodeIndex2","globalNodeIndex2","gaussPointIndex","proxyMarker","Symbol","createEndpoint","releaseProxy","finalizer","throwMarker","isObject","val","transferHandlers","Map","canHandle","serialize","obj","port1","port2","MessageChannel","expose","deserialize","port","start","wrap","value","serialized","Error","isError","stack","assign","ep","globalThis","allowedOrigins","addEventListener","callback","ev","data","origin","allowedOrigin","RegExp","test","isAllowedOrigin","warn","id","type","path","argumentList","map","fromWireValue","returnValue","parent","slice","reduce","rawValue","apply","proxy","transfers","transferCache","set","transfer","Promise","resolve","catch","then","wireValue","transferables","toWireValue","postMessage","removeEventListener","closeEndPoint","error","TypeError","endpoint","isMessagePort","close","target","pendingListeners","resolver","get","delete","createProxy","throwIfProxyReleased","isReleased","releaseEndpoint","requestResponseMessage","proxyCounter","WeakMap","proxyFinalizers","FinalizationRegistry","newCount","isProxyReleased","Proxy","_target","unregister","unregisterProxy","clear","r","p","toString","bind","_thisArg","rawArgumentList","last","processArguments","construct","register","registerProxy","processed","v","arr","prototype","concat","handler","serializedValue","msg","fill","floor","random","Number","MAX_SAFE_INTEGER","solverConfig","meshConfig","solverMethod","setSolverConfig","setMeshConfig","addBoundaryCondition","condition","setSolverMethod","solve","solutionVector","nodesCoordinates","time","nodesCoordinatesAndNumbering","totalElements","totalNodes","xCoordinates","yCoordinates","detJacobian","localToGlobalMap","basisFunctionDerivX","basisFunctionDerivY","gaussPointsAndWeights","gaussPointIndex1","localNodeIndex1","localToGlobalMap1","localToGlobalMap2","gaussPointIndex2","thermalBoundaryConditions","assembleSolidHeatTransferMat","timeEnd","math","lusolve","jacobiResult","A","b","x0","maxIterations","tolerance","n","x","xNew","iteration","sum","j","maxDiff","max","abs","solution","iterations","converged","jacobiMethod","worker","feaWorker","isReady","_initWorker","Worker","URL","document","location","require","__filename","href","currentScript","tagName","toUpperCase","src","baseURI","onerror","event","workerWrapper","Comlink.wrap","_ensureReady","reject","attempts","checkReady","setTimeout","startTime","performance","now","result","toFixed","getModelInfo","ping","terminate","async","file","gmshV","ascii","fltBytes","lines","text","split","line","trim","filter","section","lineIndex","nodeEntityBlocks","nodeBlocksProcessed","currentNodeBlock","nodeTagsCollected","nodeTags","nodeCoordinatesCollected","elementEntityBlocks","elementBlocksProcessed","currentElementBlock","dim","elementType","numElements","elementsProcessedInBlock","boundaryElementsByTag","parts","part","parseFloat","parseInt","replace","parametric","nodeTag","y","nodeIndices","idx","physicalTag","boundaryNodes","nodes","level","plotType","plotDivId","meshType","yData","xData","from","lineData","mode","color","width","maxWindowWidth","min","window","innerWidth","maxPlotWidth","zoomFactor","layout","title","height","xaxis","yaxis","margin","l","t","Plotly","newPlot","responsive","isStructured","uniqueXCoords","Set","size","uniqueYCoords","zValues","aspectRatio","plotWidth","hovermode","numNodesX","numNodesY","reshape","reshapedYCoordinates","reshapedSolution","transposedSolution","transpose","reshapedXForPlot","xValue","contourData","z","contours","coloring","showlabels","colorbar","commitResponse","fetch","commitData","json","latestCommitDate","Date","commit","committer","date","toLocaleString"],"mappings":"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"} \ No newline at end of file diff --git a/feascript-0.1.1.tgz b/feascript-0.1.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..aa2d2604109e0ef78132fcfb85e2fa79fc76f7e9 GIT binary patch literal 141436 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 z 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

!@Nv}u{KI#7tN}%k!471to5mynIE{SB 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

!zmB!C{!mqYbMIMLm0 zn#oSs&Q7!)_K~4D2L{J!U5Z+y?moM3wir4M)X|yN)QLhEYKu}QRO(}h>bm{R&YlVj zSnD!24eRqq*+f|2P;a#?x{i)koaXj%Y?iOSV3rFuqVI8D8YJ;j$3gyRJG1aoST>!P z1`dwJ&^b$Z_2YP{7V;7~3LG#qek4QHLWU9{L(V^+t4_)~5m3sO%^j55@=T&u-5@vK2XJ$`Omg$4YkIbNsl4`-(zjcJ8 zze2n1O2;SQSa-dcQbK?UCq0xuqL?DBtz}I`Y=%7;R>a1Y>cUmAU(w(-7O}tfdMToD zn^guCO|CS?RG3_v_NKNw;+2gCgcKT=$hSu`0;AI~zHDG8cXcdeS(O}sRDl8$%KhmT z1~#E}Ya;7WNE2$!)9aVHzCj;R|87csFkY7_T5Xpiz?Q{C7(o&`ADrkh^u#rLtf?FJvO6g_nfnAyiflvY%OEVN> zmcDV;Xy`nWOZH81r6dUJXraO&R(PYr)%j)_iFSG%mEuaE5uAKUqt9ci@T0PiTvnHQ zdB>T=OjUi!7nEmaV%=j<(kxs7NDg$1_b3IGc4VBfyTF58yW|2KvGaXHC=bLr z>;wl*VoUF1TNu+~FEI=s;K-JKT4DRXG^(%@<{Zia4bTbYg95zCS%M zRJy}{mh`FAcM_+PqfMn94qI^KQ7h2yo90BQ;^<+#1$h(D@2xFwo8P&-{guW)eXZj- zOB@})8r}E162Y8&)`+<1xP!o)vhaOxsw1CZ7`)w*{%~;;)vy}bIJz!sr{5e6;&JFr z7quG;I`FINOCi1zj@4JfQG^z=4f>W2GXdYMmN5v??v>h72xGMPjWD3^=<0w0&WV_shn^5rdup%nXNjw~Q=g+0PJV7=Hzycqh7 zO9`!@*QPk+R&GjWD?L$tNwl(J8^tz~iaE;;hs0v-za6j-Bw+F>@$w`P>!{`M@#jlwYK3aYUJV7f{i(ARx;7rfQ9g1c6&foQZmSuJcxSyFcCEqh&sc*z<)@F_ znG+rg>S#yn+6hm$%>=#EXc3Yhp>AMO2tAP$?1XYvy+U8}`witGUDmc-u`4F3RAmor%e>`puH z+3bn!2tQD}RH#rWRqX;L$2LdVa3sqGFDDNE{v<;UDP zBMbuuWwT8qUDzlhsVg^**wgN9(V9SUIjtg}-yRp=sw14RQnp#j(-}zg15!zjvKSXv z$|?w>gHfi`;u3{kXf2+@5TX1(sp`Q^B&l(992%+c_ac6{E*5M(f~d8Vkmbt0Tr19y zO9vj>VUiF!Gp#)gO0hXd4=4TDp*USnYV(QWj-&LX<&yAB@nLTEa231aT}g&28T-`~ zqGLFIIj-gWQTUqJv)dzxr;A1Q`2wXL?NB#y_-HKwTrX>LVY4WC9ysZw%poU8$URnG zs>?f~DtduRj#j$529k0K&yNcpzT07<^>>hmd;HexinqNTj(2qP_Y6<^L2VZY)T#3^JKxt(*>LDoJn{_je||?W7iV;#c&}=*Rj|yQ6JT>rlb7<@%>wo) zaj?;HF;x1Q?@^9aG^_ExIEh5|phQ{*G@lp3V$D$`BeQZ<*NJ*%@>4oe6^|BP7Fi{h zsPv{YWSrKC#@EG26#E3M*s|yrAH~2KfZ=(_5X%vWrgh8#hbM1~p@Fk?%&(fcoY>u!TyWPv8&ZrFl6EV z+pS309RFO^nA!<{mJ;7Ceh1gv&P+@{a00XR%H-0|n<8u=NUJkiIxk8uiqg9V?3F37 zw+z@TQ(*ICy%Otre}~s|cEFui!iZb#UyOl&$(*JzGWNEN44iNH{QG%7#0{56n{dNa zhy)=oAndUUYV_lV<2KIkL%1P?>h@n+VDOl@V|uzco+du>isTjkx}^zKJSwakv$PRh zDcw|+#>Ph?YCbi(!b=*TRph1KE^P9j2N9YcI=k+Q7;1S_EU-*kEcQ#7lK`}?=WH&Q z*DJ~xtQ`9S)MiPXoz=s^7My-XC8KnX#j!uXgkA=WU=J!Br(WVeD|VR61C&Hi%|&GU zU6BY;>g;Wlf-;8(ZtjFuu)P~vf*`~y$9>Mu333wu5SVLJeW?94EKv{}uL%~B(4*4{s0Ub!m@ZxL3y7Ll5mhz667YWsQDTbe1%`3E2ATwo1Y z+i`9{jGzfulnL(CzbfLgDsx`p2CKAm?J%s-8R6!r{fRkxOQu~F$>k1r_zW(-7_n0% zsPdWOaL&ZS`FDkzMkvqDrWOf0+KQe$y`wjk{+7%QB(<*bmdq{be4KD{m0GLpupl9i zQZ0|L?87lxKy^C#;at;0WpOKvzjUytu*6V1JNJY@je{qh8!ndwf;aHSp4d~nUli5yyBrw5EBs!_Wa8ZlzuS}eAw~h?M_#}>In}ocfi`Z)Kb37xOt8<< zP9o!%y?cV(azZor;}PYj+E)wksCYmJXeo(gQ5hgyu^g-Ti9oxu3Z6zS-xZgNw_p1U#r|p8-qV7DKDoHlFU$TOll?W`z!f2zyw_H?&iV zr}Bxsj2pIeVo{`YUO_~J*|U6C`SDPT{jtZqKk%|Tr1v@fb8OoVGc{T%2aLI%{N8IZJdE$y-G#Q>)t#&%x>;^;X$oi)#zv+i(5Dc8n^SYc&CH;2!m+Gp~J05r0! z{09#A$Pvew>__#*W)DPF#CY%ax5MATc8r?9+6gT@DAymlwJ~c@Gt6REyWs@RBKVtv zZb)L)>E9Yoju@R!HkO6)Byo=;LSWu}*UCjyUmxRnZ!U z?uqYsbgppvAif;X{th>V66w=5NfF9mTIEw9wGqkN6B)^AON9b4U)l+ih}V=>uw1-M zA_Cj6=Wn+~5*~qDfzQzw^ZaHb~zwR(0aiteK5v;+}%&fC8TM_e9NKt1K zGiu}K$ErwQR+6XLU_PFrNGxEcNSk`-Y^mc*SCp6j6K}q-uWqxbXCQL)i7k8qx5cE+ z4D1dSc85;VXEl~$8R~N1gQ42OaAl!$qN_ zFBXn2zxR?lTIJ#;y>BPf8BO`UccLoc)s8+J*0z(NkfYSTDKmc_Ei+Ss?HG39dPjBw z%;r1V$fPBf(>y1mwdh3pQAp}njeEWo12E$0=d+M%71f;woXW;tuz58YaI zD(uTC#?Y)V9g@`szSqIt$G)D52@9Igr?ECKZ)C4AFAvA8@*24=)9;@rG2@|08~J$zZIE-WKqI8V?AjSwWOT6 zCZpBmy@hU(a)I>i`_zxT(<4%waIc(RInEjcC_b55e6X4PH${m&bY(2Yq%7a5F=_G2%Gup?Z=wtS+k4cZnL8mHXo*d&2HB;)gfK(opt^3IVX$tfealEb^u z-gQNiuds8h<>-}%>(L`z;w{E56Z3(j@qxJCV5i_*+pA^eL#nQEkjJ3LyP0&*V5hai z23329y9j-~xZxWd-qPB$Mf_4B7ta=Hr=;bwnOj3@@2!g8$c1Zsd5y5n#RK|rZJuN` z;L^(W?Jg5;d7qs<`@&(sXB8-W_>S6*@fP-_n+U&?cNrw&d6+-ar^_;`Lcd~{gJ>G3 z7JHor#kC5&+im3cb*~eLHn@Bw8$Q%pCA_?67YSUuw8Nb7W&XK?PLfLadW(Oax6f_q9wDCqolNy%=>WvxTO zW#@{^Xq|SJg#)T6+~7c!3v$+1!cYSq0on=JWmo$e<;z;OHHT`Icifgmi4`nS5j^a0 z#?X2)uio1_uT~%Ue3Rl;5I(D0blj#}nT-Nl z%-a3pTAjCP4)u0QDlb3S2elYGk!e)q6|P0QGV9D%g*va)`z;)cJ&*TM&Py`9qy8x3 zSZ86TotH9G6>aCBf-?IQNL9I@ug8o8@PP=WB@N)5q7gswZ{(HAk<7Eg`vJ@Kn4sW& z*Mi+8%AC@w(J64RUsDzO$!$3VGMuNfO9Hj0iP1${Sr~`n=Lz{g#Eh>rwE`Vm${pu;o#pkIwxYH; z@TYQH5{nE43f=5+JFrew5B*w-wBh`I4ctp}Q6)z&T&FcEC=nBigZ+%0XLf*dld_yyDuxJt4bmQn%TWzbowS z!InL`umZCZ*`Z^W9NzXW;li)!XMtV(IPxV@P|rzb97^DzNw9PyC*B?3$V9zaD9YX( zQg6rvJt3v@s6iR1F%xaUqj-xEC7dmgO>=T0P_D|5RcwF;;1f9oN(G7%_HnDDhA9$o zn>b*f0)?ZL)$Y&M%`tM-k$=p-X?(ITuV^OJ{C$48Pw}5!GL-A=xkLH2b0}_a6mT&^ z(h<456^+h?R6^=ds5Q~=e21fLl@sHX=p-~xX7;N+<|o=$WFw9Z%2QtH0aKhfx5wgL z9jpRv1N5}S0o?GWTig{{y~D9=h|xKf@=!=!Bv+4*Ay+Cg>n?4Bh1W3JTDm&2TzHMI zP%r@A!bQR6*F{pp$86PHQ8WUYbX7Jt5zQThz9*Jro6dJsC=XwiD8f0DYn%d%LK5X3 zk8>tShqfv2x}5MjEY`O!2f2v3Y-7l?%_-1%)X(sC8@IxN*@uh)i#NP@!0Fk1Z{7(B zoI5tzgjusEis7#Ly)BZ|ROD>JG>tp*q1u%XxKp&bXN)UyPJ?9}?hGCZ5)%Cn*co%I z$cjlY8%jfK@n&edDmp1=fK4W2HDm&I5A2L8N{{5AMqYh+{$BIs+$2sr+TaVa_^G}@ ziv4Pd59OY+`L^?%y7wH?MF)B9Z8`W(WytZjWE8cEJW18Zvc{;R3X`kC$`6R{O6c4W zv^k@jIz^0NBL)%%lobGRyC@GDP2&UHcIK!9SsIL&3X1)=yCd>Mdt@_<+vPgO+`M4l z36A8MkcCyTwYh)>`b{msRGN07R1li=4h0ZY(UGJzdCK;?7&*@AFiAMmO{F1;DAD*Q za!hsw(ziv<kB^%I~iA4_kv z4t2^OV0Y?F7@IfS*XX49)}2x+DAEF%=~6YpC*2;ooeg=FE&h8(qd=Ei)^BKuDG`W5 z90DD-_e&zazbZVO^@fnNA_)abXWqM65Wbv>&w5E~UmxXbbKc@4daJ^jsl)hQ=$~|B z*71NMZwnlPU%9o#X?#-JnVnkpTP8z?FK+CU&g9lbtU8Js;h(AQvva>L9(D?pAk``O zEY5ngM{`I$3{K)*WN%?#s8$qu!dV6JZeY+-PqIY+Y~ zE*h@O8zZ?DJ}V&Z9VCB>-3%qBP`>Dr3%^K8&~;IU3&s}2A?5G@(GxCcLfDtY*%^*d zs;WQ%+F88hH8Qlbm`6V_WIntBYFeVYL$&a{{3ICD3-=#H+JigmCIa7o+j2GdmI{R0Psq7t*jrL4FXOd z#K#qn`p0xM8U8617LRyHk2vn7Lt)uRL7hXiNkG&JXFT`Dc&3YradzB7LFNxc?k65~ z=#1Jyw-|^cZUeEJEEV-v?V^f+!Z%;z)FK@`a(fwZ{XY(viJ@L)j&fR^@q%gNeo7 zQn5=WGY@B_&%P(lh*|F%YrqAkZ6PFB;v|yeI*A;FULnM;PAOWe9w z7Ibnrqzt=+rx{6O5{Y(r|A|f0ezBu<$mR~!$TM2!h$v3}$sEAj4%cilERu3`L{2iB z^EW*>GxXDCNh61|@+suQHlOSwSp8!9)HSthSU)*&PJPUJD(C<8i(QrYS!u=f>sf~4 zU^dQlDU&516)bV1N%Th>`i@ro6AF$wVopjReErdWoerG8RtKuM0@e$77=hN_8gqs? zfBY(f{D!+HWu4ElDAy&~5(Tl7>u^V_h`WW3=K^ z2H_q<^%`eFiE@om(o>t(7PZp0E7~r>3W{j(_|)A&o{Ll5*m4-dODEpNy^ZX6T-c$*v;Mw>hLMUi zft`JJaGG^F12{{*Ta;qXHlMI-h~Oa3M?zr}Jv-ENgp0H%B3;SaWog;M;juqTJ4vho zcS6{2hN8!o(d9K+zaYNVLM=!nq)VEKJZX3COWLFr>4w#w zu-Gv`-|f*BAH_VBJYj!oZ>uP%T^dDV)7mn7?AOkz44En z-~;vKkZ~SA8PJ*jYAA%G7jHMXwbec=5bIj(#hw-_hpYPTDI* z@~x-~tM0H{*N0(#i%Jh;s>(H)<-$cB@@())gy2KD4a`n~`++4v2!LDb zxP5w4msdB`1n1w@IVp=h_U85xof{FCdA@o2Z$JP0FZW;1ZQQz7-a^w4 z1`C&-8#MZUZ;%_do4K1H*LHia(8l88;@ZlJmGpjbWo<3Lwr>5m<<+&te12_h5y~y* zSMp1%@b}Lkz%UrNeL&?EItl+->hE9Vzi)5uy?)?#J8#}CXWv}UC)AoYvg$p<&9kw?DSK zou;1#`QGa^yZwbmx83qPx4E|dtqe+cdMohPZ*F<+;JEL0f=jQTh&L1L#%**j{2Dza z6np6QZxJN_O(@`Zn%>BG)A!saR=H{i*N5~wsdIiXbX)!-5p1E?>JE;&t)WT1uWF!y zP6Mwq!0}#Kuq^90`cM7||BF2ve-{?Mbg=p#Trm7&EqwVx1=I`vFZ0_R{r$uG!>s=Y zwj%yeJqrQ+0Tt+t#LW_auw=CTKja^*j_o6aFJG`Y{93RCeq0P*{lRZE90X?60%MLf z@$Vd?LS_D-GIOy$a5w*85-$9PRK?~A19-uxP^mu{lZ6O`+5h8;FR%WasQz2D`l)vj z_yg~qbv+pLf_Dqrk^!^EYy|rw=m!vf{q;-7`qi>qZV*_5u66Bpnk~;#(!=sY@nH=E z5D-?y9YWc=q1%Ml!@h?A0GK!Gb^8OWL6DN9kM#{oTHKw~sCR9S{IG z6FduqLox&cE~@`W&+WTy>l?rTtez|sJte>Gbx>?t^VTr{X{zV$B|*hPDfPXU2Zaaq zKFm{5y-UBLs`w_FUcf(%5c|wGv+=A6>uHXAZUF{9EZzp5AIz%nwSoqa4+cys_Jjkd z6I4oPq-NiPq3MXR>UCih0}F=Mdhq4i-CbT3GLkX;J-HRKq zF?g~HKuP+E2^(fi69R6^*5 zPE%CPDC)MnfsO!>?DN<6z~}My!=eI6w5)2Li~E;WCSgcEe6YT}fhEav`(NHDG;nHJ zW#DQ4qIf3@)5o*&^MpszB%=Sc4t!qx3V1E%R^J;R1HRjkXPsC;NPY9Np=NH%CTbHoX&GU-z&bsKfn(x27;nH)oWSo1gR`&sl^{ofDk1L{BWhRe|658L= zN)y&X1W`Tsmic{G_Kioe`_B5?H+p{heNK}-$pepsA)2Dv5x7@g0E61?w8r=)z)@k) zeqjAV<$g(I2T>VCz4*njQ&@l?A@ZW0#sjflPak$1?vhhHseI+Z6+pAv&@JUR*UHPu zL&t+wYz;k&iqpVxgEJ6M@(omKvram1xvd9x91sOxgIa2+O=`txP~9un(@B8N)z!sG zB&hT~ucOf*?AjC>c>O*Umkjh8T_%V#blEvPtRJTLxxBKnyu3E4&xfG&hCQZcg9*JA z){yYU7{iXr^rbgwT(cl`2VO9+hP@{Iu;?Ew&kHjxGr<@;280K<0>@|WI^vC*4Lgl^P_6LVv(1S-0M2-94 z`UCC{v?JFix98`s{K56`f)=R0*XstM$3^?a@PdUlSOl_Bv#pXla8)~I^SPSt3`xxupEm zJAdk(uc>#U_od%KKTsP576?oJ0XC4FPFc0SXBET4gdmys1>KzKKIVvu8udbv&sj-F zc3^MxK`}Z&j?!6gY88Ppa>C1keUn)}fr$=g5j}!>x#t?<)bBA?ckPQnH6(U6I z4BHo8|H--ye4y1HdMSWw8(k>tcd*qA={ViNwUsXsl%>*K3XIR*!2JqPjy#}g)9NGu zBb^x`E|t_+%)QiYX7H5e3-iF58A5Z-D9KW)mXLfqfv7H zfO?Z)I|KLSuz{!(=_cKLMPr6#0HrL|1r=b}Y8mc614DM=rF@j6nO?}Drl?TF`xluf zWU1s!hCA(WXPb)+|FD_s-U3wXJ#9NT$ zWpw8A@28c^>)y-n@Ly6l4wU!udx^LVoR1RZt+gb6{raosX-uT+iYPg+eod@H?#21U zM*ftsS%!86qO* zN~s#DX;8=!t6E$S7+6Z$&rO`FfHD-E0~Ui{SbFjd)rv1oE>8Rlg=U1l94W4#r_SV; zPFo(OsTi3vS5;b?tJLYXuTQn+=$kT;Q5pmg<^oqCi7r6 z#l`V6PUYu*!GE^>0`wGLspxa`ny^EBNIn2`uE2o3uM1 zeZss;0lJ~BZ&ye^F{<||+XKo=%@A_%>?g%#7h0 zx$?SgZ_pplv(FvdoSV{U+Z|D3H2~KhwgIl@deOEvzP}}{d*>hWQ#&{o9Tc8F9_AT( zbN*pb@6R~3KNA7Vts4bccW-_8WvTSb*GU^eFd=+A8G#LueK!TXZcKjogJ}aZvN(tXX^Dl!6D&i}9B%iG=`|l?ig}~M=5uB%h7SUZ>mG^0 zxaX0mnFK+2q5B7|#hZz|nzx`i=c;@zb<{*d5G4Y{K2 z_Ih4(FEUr+!)y__4DKu=xN38R=NsOuhrb(y%(cAE)!Awa}Pxvz|%o| z7FA7F4(oyH&fS%jF^rCgxQ09^3G>G9*8e^EO%nG+Smk0%i{hfNDM*Ur4;bm)ne%@LVFY@%XoLKS?VR}K4 ze^~M#@cB{M!7yWQ(Qw`PKRPjmd1G z{Y_?zb<5hYtX084z#c1>wf>zj7w6|!=I0fw&Ces^e=@7BbLI6Hv6{}O&t|n1uDp`S zYO%^IX5|g8yn&ThrdD1xE3a|oHLSckweni}^je!*dEKnM%9U5K^7_=u8|ia1#?DW1 zzDZjAa=jtw)n+?$ku@j=YMSnu*pdM>x|^D&BrHXBgr^zRvAu{2;a(14aZ_uNQYaEM zi9bOrlLp3xNShE!J)fKi@M7e{s*h$7yy;z!13JVFhD{H2=&|Yu6$_@RX0kps+e7{8 z-~T-}gc1{}k0hyPN|%hI-SIdk{=!2Xv2R|}tRFRF@W07sNE{{8ib>+cXdSs4fgpTA zZ4#`oj=@{+5>%H+ml9Stq*C9bVXP1BDZ{)nrDB5y=0VSl3F%o`uaUK;OqAPk%l#j;(clbrt7~=>)XC;Aeku- zJv?L>N0RvS1$0a>m<++@xsB@tu|;whXF&xPF$>e-OlvzLx^lqk4#3W25ayiq;U6g) zW*y^`1=Z0Dt8jr1(4K^qQPe=IBuUN0(ZObNO(U=|pThE}l>(97R!e6Q-T?4JS)Wvu zXMB9*KUh<_<1=A6aId~5`YZIl#Oi9&F{Mw;{NdgR%d=RYENDNuI<`BNdBZ-WqA`Q8 z4hfMcBvaKQBY^@juE7~r;9ZfqoDquvdi7iyU1coKCBuvpT(K`z!*^*stTP4{&ZEsQ zD@hfBaDax1r-|s>o&{6G}0DWhD{@XX|+*8)# zUrSG4`4Fot{I_p%T%WAW-@c_cWs#W4b=KIUk-_Mu3(<4MpRwzQbjXd(M)xnI1{*g{a2Oy%;Tba01uexjIAzJhmCL8dyE zlRbY^%S~`9PcxyT|7G-v1p*7rUSo>DyQMi;AfF3pDFM*p+?4T|CWI^&Jha~6P<00b zFc9$Fw0eq3feDWzf{Hk(SU*0l*BCzN4fywIPK%<@=I!s(W`yRgdJX#LUqb)<52b&e z=)db-4qk`)yH5G|pHBNEk}bc4_REQb_*%4IBHAB=0{1GUKd$fp(<#67BPqZ1YLs8* zTr!wn=5=U)SgmZm7T?dXv=y37Lt{gCF*Pp2QD*e_ywuKScb-(xv()t0*VHbcf1Xmb z=Ba07c7G1(h;}2<`761fHGhO|Iew=`6tTw!{h>Fd#zo(AZzq;{nqZZN6ED#S*_>{K zlw%vKp`tU(4(m^g=BGvT)1vw7STt#K{TW70YFNYzjhfVuh?g2k>ERGR!bnX(5umC`NtWO+K&!8X(dv(+(drL!SV(qV%37;gK=(g|17qz+ zj>M}io9izDwEkKct^Y_Gt^Y75kL1_2thN3s{QA@B^V8|`3QnK2PZM~8f@^dh5DUF7tezXyxfF=NgtFH z`aC7qc$y`CFy)|3&F$Y>ZjctUH+{0GSiF#J5}GOdqqMnd&0Br1-M#n1$Wx44>-)*a za^ijczOdNu4vb9^&(Dr){Xvnf-y7TdBcfYpW7$`WagD)#iUirmerjSUl;&?jR*$pt z1xaL)41G%Yd@R;mpPM32N~Df?W0HP+_aojNf-%@CWr0jrV9}9ykU@PdFEJk-mLZ<8 zQ@S%`i`7b-$I3;fOLZ2KkBKMczceyn8bDC2Qa$vvs~%|`dARmEDqRL1b&zQd#0gH( zcQaY$Q(9iT84`IWoJpS4^;kiJ3P}abL-&&*g#}X2DW@!aCY`fHp<_M0S z13(7TW(63L55PQ@nvER}&g|9q=Xl-Z@rp^JlxzYfiS%^T)Y6%);TFj@O$E+V3h**F zIvTkB0eK|#*W>8x7G3@WJ*Ax!V8HO<95d{+2JV^od;aI7vevMX(V527Hd9P8hIqkS zIJf6T@9}!KSbakqicy-+GIDjT6{QDY1-Uf_`at;jcO7r-Lre#VH>t{gm0{7zpE3XA zSLi->c@|;%j3l8Z)iHhMPs*oI-ncZ-l%R3>IYC^=;%e8`Jj7_oRP!vOwvxoCoYiQI zxn~d?V?oQHaWzC?>UUtNo=fC`Bq*9>m;@xsc=A)Y>d2k)WJzg7&!a?BXrN&j)h{!; z!lo&R6_o>qqW;fxiJz<*#@N8n1?emkEqSBl#Y0acleJ*5r!NiRGWu=8{K!rnCxb<_ z4^cX*Pfzc^E1CKal=TLW?TKD`#QY^M$bGh+!X?GqGcjtz@ zJJ-KFN8p_&OT0zX2#%wj03h0}w>q-FhN?q?brhzMaXwolPT|0r7kSxnFnmQ+sEOP|C_jIKNK-cRnMyBoa*Hj1>0*`&&b-@=oPY=VxmL4F z7s5updqhBT?(wdb=G&teftlJ@-45tBZ`=lMDymj!m-jMy{9ZJO2j0w$wWrt0u5VjlLPSoy;$i=O>2pwKaF2mTvL(nmBMp>h zY^cx5C)-((P<>2G1l2@asDHLoU^A)n`GmVs5yf&;i!|r?EG=;E-xwg)b8pZBCKYWP zr!?grOfn)+R%rj0K4_1>$kAwT4Ho3wdQbZ0n|3Slc&)ZDn3NISrI2V<80h850jA7yT>U!;WM*OK>YX0sIqERhiidWOGtx997IB6I7g_lp zbab6Ll|)BmIiS=JS;-`Hr4?`ymRsnV$Eor6-)3lR#*scIvG}aXB9dG^NJy`9POg8~ zc`ca&HXEybG4ACP0=Q|QVVY)SUz+P+G4Ayf zC(x2{qu+gAw&(|S#U$4xtzyRZVr#Wb~J$AzMF_Fm9hkpTdarY5M@JjFEClYzdUse^S1OxSRru3CjYZ(MbP2V?$K32HhY3oDVoK@oG4~jS!%W-Mb_5j@XHYSD z2o7wZT!DGB+m$)?CRyq%MQx^y zhc5G`jd%W$twM!aTVDP!!CxUaNw<_5)+`b~m&w`4exz6ZkzVybUwYMEOS`xNLA??2 zT=m^<6K=@p1|XGF^@ys9D-2Ind{lbX>}DoqT0Kt}f1TS)`4!lvCA1HTLTVfWvtLUo9PzS-aM!rUgvfv=pkuXQ1P`wbv0nA6J8{-7*o!Jm&7r21f~qTR)v+db<@OO0A2 zacaDDw$F*mV4xpyNH7c_)>+uH-^3Sbf`(Ey2t1XiDoU_gyT4$fthnERe<=o9gdU90%WJ@ z2EJ(3z6pQbudnJF3=^V_%$&(SeF~a`P+TuhYrJUk)fvwIzqu-;zgGQWJvVt77&ZCp z?{Z8Jxov$BrOVNpnz?&A+e=sc(nb!%|1(9;#<6om)3J^(a`M!1I-1L zJ*cT$M_A2O(oGdvQ^j;sJ;SVFrnVkZ?7cCQF9f&9mdQOgc??M+-s{}KIPSw< zXM#U}z0=e*ck=0%#JHp{zbKLE(r;4x)O@~(2EL_~Lz%wz+9VrMaEaGn5QbqaHjL%` z>a;Deo;EfM@YCp>igfV|yZpZ$Fn1680 zvm8=je-{H0+!)*u1oI$FWZAw*h9xQ_A0zIW4&3LJPCnrwsd5z0EM_AN7Lvh1Ur$E|MYrR5{ioo)21q$EhD~l4=K&ACq+^XbV^q zN=2aOZkJ^Y1qB~@f*H)3I<{`R`Zo0vDTrj(TUPaiCDq)MJSqORdLBC%#rmlN0)a9C ztoQK2;t44+EDht#s?SmqiLHb7s8=Cyx@@#DV{6%0HsYur0S|Ze@vpxprumRNS^F3%8fJ89qkax!10yl2RI6OZI)$$isg zzQ@UXN&bGCgf{;%_c}?ee-=bH(bl6Skok|vgW$t|=Btk%N8&%~k@&=84^C1gGZYKj z!*U^a5%uD}+zo6O2gW1q<9ZJ}{P6S>;F&5&ZTt+OGzlmfXDwNLIYS3xPCKKJ0Sin# zlyyXK0NIZTMIj`tiZj9LDaWM=simpFnF`A%L27vhNEK&-)bdP_dV^LZGrTy*7eq>N}ivqomX~AP}e2Aq$sb-!CIu)?KpZ=v!c?B&HMe}@y)YJAM9&(6GvF$)JlZ(5@(qu z!hSHN4N=1029G&8ptRVT%)C(MC#zds0HWlt zI=$!~RH4ne0z|6Ew@J0<1pWY$=1igMIc<^WZP80p-22aVwALp3VNy3|vYWG)@8)54 z0K-5_Ya-y6$L3ok&`OeP=C|lwoaJrrC8!FQY}8MUON|>YoYH zPlV#iOi(P&2*u?Yq4)$1(+i_waW)_>&jiG^7e&RD8G-mD?b9s!rPcFw zKTU7-Cuy#%^y!7QS5Mbp{b?GkKS_s`l`7sUtUpDQ^+;XT#4e~q#7j2p#H6tA}Q5b21%TtPn)n2 zpP^HGnpW*8dbP|w`Q3DDFR5L7Dq=kfwVsGvPu022qIJtUKc|^%KH8^zlA?wG{e<)z|UuH5NdHpAS`j)z}s`=!&@J5>C&%sA2m`?a8c6~10xSmMDM z>7ZtmXf&<{y&H@hR~xs^JI(ypSM2O>M(vvg{7g<2+-$EGGJeG8S-)&mL`E>ZR*&Iq z5QqEFnyrrhU9We+xF3l8XdRpUsMqLU^*VRi^TE$;y+Rao-; z?3wFI$$97NtK5J4Z}|2v7;?JFiZiYyRa$uMU@%Rwh%#=cv=tOFHDz>7>Lt##VEhft z3kDEbNUzutZ(|cH_LPfmJ!sRrbu}F^MS4Lq_@XWRH!i5hjQ2r^=Gj1!?jSJ)7=>`2 z#RC3W&OJc9!tgFv4dXbt3_Ui9cG%482o3>2V{DEp74?riQ0^COt-$|&6Kv~4K_t*o z!-5jVxZuS?47qUgmX_~&L6_=iZ9dGfBt0YIDPRnnNj=2ODzUj5_<7dV7=)?yfLClq zbhM4y z{vUR;o^_zL2tn4V*aCkn*bBFVmMjUsGm5bZ)o(;Oe6SRJNW6Qn=MlCU_L~q<0JsQP z;euEQdwT-0RT~VuCnB~gIhQoMR-YF5AX2M`$RmusgE)>Z+j-cSSXytufIpL-lb`17 z^P%>Wg){b)1HtO!TzwGtJFVzmgr60)(N`1X$T}0^1A*$vO=a$WHzP|gTwIBA9aEL7)2KPVch4#n|oZB z4@L}h+$ECUL=mCqp4X9Dv_# zzD?brM>iZ@)ZPF;oL?&BUKi&W@7NfyC(dLr!5Yt4_5>_W_geveCc(zJ(%?>n-oj>| z(o)Ri`T7-cjCRvW#@DjVTlS9__qh18;FgY9`33fpQN4Bh374tV$mzgiV;9rNkoq1n z1b4>B-+ag%Z_PH|+7ri1tM^4)JGO9NmcD^Uuz@8Kr&7n!WDq2X(etP8?CYv>5i+^nkYk=PaMoBbX!bKkl{!2VJ?Lj?fK;9fY*uzbOo2;jYz;J_?%R59 zDN9_~XB04sLw5Wy#$XucwdN9+7z;Rzye3N8d9xXZkZhgt>FvDHy`>96_AhsWWEUjv z1?SB$#vn%>MbP!u5|C!R9K-iMN2I*TlO#A4#+S$*ncxCU4I6)=?>U?IKEqGWKhJ=^ zS)NUeun$Q&z+tly29QM~%mo*aE-VfycP-aoO9uS2n=`Bi=7)X<1O2 z!*NY(168DY4+;EE_5dT#7=(skY5>q0PDbwo6@y`yfs8RIp=zAV8nmUw*3`8R0xGkM zp`=9=>za^71>*oLFER|_FrmNu3w{Dw71`pb@hDkUDBtm10kvduYGBiq7cD2d7WE$0 zrA2}h?c|eUrB)5eN;6e8HQojzv;ELE6Tk9Zm!hL>y|dt)|ScE~A35#7X@! z*2)WVB9qSwK@0!c*X=`=AT|l-CmslORqRDH};yQ;Y;laafrri992c1$j%}?WR#(2arFhN_HaUVw-WSlwZe)B|Ly9@nJ z4RikG=WJ}UI7Bj4#R)+5u=v7x)NbT^bCcI>b_QT!VF3nC`^nIm=og4_a_1GKs_RAe zAeg*XPOJWU&ab^C0+16I%D=JBf6KMP{#B)fx4?6*zI z8qOm93jkTKEuM|C0$nF4t1U>!FFVXte+<^@xAU3}p(%e&L2MnfNC_-)>sPS!a(b7D zUyiOpeF-$9)dQn8e(mu^Cs&X%*>W~eaYo8a^Pfql!%LE*ne?_#B`*)DZF3Ult_OG^ zGg$+}?gstbZ%B0Je#_tHR+Jp6=y(K)eAm%UC;HOXe{!!_vyC`C9fq5Tmr_$`5Yrm2aEe8P^0Oe9m* zJp2ZHrWISyu$MFOR}C6(M&=fDdr*3x!ZvXaKM9ET-n9m^bjpul1`J{qCutnlU%{O= z+$N*)->z(p;K;g!Mi~oyd|W9Riky_L2aW?UW)p2D6sy(?E$gLL(*AeS~wm0{K*E;=(O0kpL4r|);S|j zRp<2AnzP~m%H$xw>>ti4{;Bv@zZF}!W(QdQ>#Nsvvw(h|U~|%gJ1A4KD{y0!f^xy& zdfI~SGEy*P)OxHIV0L&h$2*|3ifcRq5n$A#8)48S0F zm_;^;U-3WjNBx(2HvTRyLO;3OA5>8N$t`~UiUs5g`Y-?M9RB?y_lH^k59o#e!FoAp z;15;---xm0_#Y^l?Eeq(2dYE=(8AZRP@Mf*%<=J2G4|>YdZUejj|_XDkwZ=RJ4Zvo zGJjy1xzrqJntu=o7k>q)LiacV_JW3jrT(CiEGAl*{XeSs^yc1wdpM>Xe)MsbP zRlnbj*B2Kr7#h}lQ5PfdYB-F1w2*s=*mH^LS>J!_q2)DV%(VJooht2arPqA~n6%Vo4HGUF7ahb`Nr zaH+_C>Fo~sQ8VgCVZ7MvTrwW<(g0sTpucQSS?YUDHdLObihI(s&CY--+-7qD1JW4M z5HW^!D;NgU61k-DtVS^snui?C#_O~%qRZUt+`h=OlZ(4yJ-QeRKLE7HVeA~0H<}U& zk|40XY$%-=sg7>xc%8?V5DKGtPSlL8t)(N@+tV#s5(@!C3S-WI3Ux=6Jysn$ZSKdV zH;*n5o#p_K2%fMDZhRRp9_cfQ+N{%-NN5Ef5u8BRaj`ahht{ClX@pHWTr?XCb>5(} zsIeyGul7OvtikzX?)L}%lLctWBGfqFDHs@jfUg*mfex)imUn!ex#~KV;wdp7;hMk? zqlUNv=Mf6n`Crqfl-K7sapwBt2jP9gz0`lBCIO64IELhOo%P&bf7dHL{FWR@RRS-s z;AjrQfUkN;4nUmGzd@7wFwj%HAu>F~FecTCnf~E{yQdqYWVn?|0;VTY1~2oC5?4pvy(&v`OcDuBbo9GNjq*V13?Q!C&UBL5F6=gf&ThD#0i~; z4E9KVhKv*~;3;7GqF`U#5>I|inywh1Wy}z`+)iW_Ok_t(Bri;S6-3eg72}}jN%uGv zk}2LCI&8<3yRa^TCuk(b4cQrpG?=G1A@&42qfoj7zoppn3b`e@~|9OXl%Q!wL+_CNU#<-Au_q)I#D*8eK(! zIm2y;AS8*W|t;JW1=J$+7pk$f!kLe+?M$GRSjT~Ktj3PGE`Ga*OLqDs~^OP5l z&|c_ywgs0X#B4?z&8%$1`u($L8`iNb>)1Rr*D>3-fK?-z_ghplPu66mMAmUpDM^*r zEt4MM*$;EJ=E~NT9a5P-k$u(p)m)}Pr5`+S2f%sm3=ByN2bkPlrIOYWfUp*pjHIyv z-*!A!P+R(U(1~UU>;-5PAS>m25vLf6apUztOXTxA#qy-@hk_hAP%$@p-C%rHU9m7) zy|W4R#;RT}-)S?h8!&LW#4ijO+eW=s8ULndO3&q6b7HWKPKzzBtZ*hPj3-vG^`{4@ zm(b~8xO#2i+%i4r#bE>VC9-6<7rv&~e2u_wCeL`eV93@AZZol;homZouP!xjw+ z0yKrah3Jj4>HO~A{+!yL5+R^5sa7~O^$L^5x{#{y!D#C2u}z)Xn(BA@6sRsfoz{p} z)KdLy_UdQaM7lE!omCT$vSu>*=(J{%<+WXS71nRml7UiCAyX9ZOO!>^RrvtH*rek) z__-#&amBajBxu$LO+;7#gB&#prUEcP4zzNjzEf|`!K0r zB`uduR8Tqa*WV3bJg6zdGVrfBkp~)}P{A4kGLI5X*B^r(?*aX%`4Y=jRC@G`wa_Ro zV`=hP*_CtuW>DhXdQQf)Gk~ve=E=?J`&Mi1u^`roG^pEw_+5q_CWDS5!t8V-RIN-|vbZcbGvz*I5TQg$V1g4tVkQ)gyVTm-9|u-w77%CNBU6=*$u^-E)fpcfgqBFVbO6j-uXaYJ-qZ<`~3lBZEdFLbMvh7g1av&O_$u zAa}RYXi2GwxVdzG87>f+AM(FHLa5QDlEh%FD!asxSQ+iBHY8i+Cl5@qpZZya_?0+} zv;&Uu&*}h6j}vT3%eK4ZxBK~1p)hCeOFj0@14oMzjek4f=r zqy_82B{=`Y>wt_Rx!qLC8HkO(q@|eQqp7BO6S-52`~bLHj5oiSY@+#9+c>hlRQ?Cn zVk*CbN@HVwGIk$9vKS`$lJT3fu*R`@pB^KH>6GU>0R-Vu% z*0e2x%_KO4 z2*09YPvD4RW@X8k)Us_-%M&KGY{}?mo7VF5X)Px`*%RDt3R2%vudFFhCZ;|qTJnqN zdolGfKONtTb`o%!ny=}ZW{+gaR(E;g>8Y6=WofO970NpCm#ruM@@yx58Vxj_K2EBi zqREHK_eyv<@u)A%Tz2`JUesK}7fO8jozh*tXp+l}(>j@Nay;o{c1q0bB$wGKGP9Fj zPGWLqVROFQ;hAD}lH}%lb3Ta$${4`e_Z&br^Y!PkUuNRS?==d@_c$9Y&c4q|JQ5b) za}?8IVQ$(9H!@mgNp0w_wI%&o1MIq$yH2Im%;K=oCT3Qa`#aK&nb__W^P*+UoRKAe zo%T7`5_itFuyeV^2|U&l`FuMN&Sn6DjxRHf-v$I7xn_doj6fJa5(rsn`wW5Sdx|_S zCGb^s+)zZr&C~V>%_s=-_OMRF=#KY0Cy_ zyzVW5WjXt^gURIr(#rmWU7t$g{#NM`3;P)b{67R(RQiiX>`b-FVe zvB4Ytwxo|dzAr1Krc+a`wTG3HY|WlI`5d!v&{ut%k^1vVBa$6g|p2{xBi`O z^lNiFGvhW{m)VLCX@h7<+p|_Yd(A2G4UeSs!^h=^kIRerxL6!1&?zey2oFkjzBHqD z81!=C?ST95kyj;fk=!AT`;`qt<>asYBJj5MA?GmZ=?D!9!;6ck9>JY1-+X!Ls?56R zp_O*3`Z=$TX^&q+ST4+zuKOS)YK)dxm5Sj235;4I1cOnNE>a(IUs}PaB7NmP7MGUb z9<&;aqSm0L-DWF)I(swH$?;<`eEkmE@HEFm-39W|ejQ>Op7RA2b0|$*|y(Zg+ThbiLUAInBl@Zo*mv;|?y-5b`8VyTJI1F*TzlvH5$#RP%&NfQLXFrQW^*J+2UNaC(N z;*EoN!TuPM1UlI>#MM=ph8YTcWKeXzMBlz#15Z1GKhXAd?mzzb|0@@XTC%%q>h7Al zyG{r$=s$~g*HJ>Cfu80+CVKji%>d&-kGl;RC9DIhmnJ^|95xYALzMf-WCZy88hT}- zGW8mLvzRlG)w$*stl|%_B`QT17aH(pg1M?zrP!vUJbzW7H^F(F7bAVmzz}_#o3o5e z%pH4e8yH7rB!;uLz8Q}4np>^zl6)b@#>ClXh&~@dJL!;(cR#$`FY2Q%kVfkT>E$d2 zNa>${aAQBXv6uHa_D2~W$3HU(1+;LO2Uxkv4#Re%(_7RcnC~nE|d&urlpg>N^L$t5{bU zxXd*2OjefmovdapWas>#i{)rwlyOP65Nn@KdJx*ZN1@$+UYs0di?^1Juf>-BB}B9PnO|3_foOd%Fy@MfTgrz+G;&XeD^-D#w76w7+;u)| z0@XSUked0BJj(<#Yv38{R;&wVrqf228nBL3!CeqxUMI7;e5#VdHZA?lgGg%1Gcf*c zj|#;m%hs9_jcAxgJ>pDlVWaS+?fkZ4aM+GPrGxGV8j?kD!vN#v5v;hdf=Bwf zu8$d0OkcSXs6O{@kcHt2&&t#2AqaF69+RhH$RK!i1zyic_Flza(p*srL;j&&`Zttgdjg{vV|pVWkXFhQg7v{ke;$CeV~ zZKfCVDd9k$vAzua_DDAqBY{pqfyc~Y%FZ+b(>{iD@&J4W>Ex|EXGbQ+GmU0W3WEA_ zG*iwiD z2BAe3;1l6s9LUrY0=x9kLV|ZfMKrJyn4}rmT+p~Jv^#hCIU`GGPlQL*hN!{a;FowL z*>+<>%hORp%t79cQe?w?UNrn#4IebE$o(wzI~&m`Y~+{c9^xdj&>XVRfbF&r7O%x) zLdyt^DxynbpFRc?Qmv+O;WDIn)D>1}c9gJh1hcIyn$*Ul3T%W$A`bJAf+yq{nIs>J zkVc?>89$2Hm?BFLbA2@8GyuAod+T`pK0^0U?s9JEV<4St8x=Lc`$J9$V|aa0 z(IP5wf!V5DSkNkd$WT5g4b5czO{NA%mvw(=hJR>=Uq~}7Gqfavt2ZNw-)Qj|LAmu^^ic9wS5PxU1((GJP)K*CT61DrESS>Tahup@g}O zD}(K)_1qHgj_sBx(l5?)xr=7s9V3LkzIrdOXS9fEs75b#E`1L?|P z6p+CDL!vA)Ayk$XD1PG|ENOG*B?WIH3rklz4YcMkyO~=X%3>>=Hp4~rO3GOFFN^=< z>(|EoUl$o85^Ix426wS6ie+I^KAf~bD$YEI7!yupS8!u(}gHdaWsXY8h#1@CRwy!(lBGpa*`iiP~rblFt_op3FKJMScO6Ysn#>#ZiZOC`?-r~cK=KEa@hk2X(sgs)np6*sMeF_ z_&RimY9v4&5y(wP-BgzbI1Cc|y!k(!v_E~NtcWn{fK_q_5>3R^zht$n2a;3`jHVsl zqTtw8u=ve-NTfrn@X>)w$Y=&?r(6#rYAS%~T+5TTPKG|=7wfRqd8I2C7BnS6_Nir8 zM|_`y%TQ&^c5*2#$0H9fzD;yJ-4`2>v;v8UEBPli@y8zk=lN+1VvKc)!sbOVDc$%l z)5d5a#bT;9hCPeB=dryp+k(lt7w1T?88t>iUZV!t3wchO6l)6n5zmXT2(uJ?pP*!1 z!sOgPP14p5!}mlWHk7Wc3bijg#r}I1WLi##k=!Adc5%g`(xBv5=oV+rGGg-zXCZk% z^O8ee$sDqIRj0=NX6AA07fvrZ=HgO%&~U*9Xjso2_u6+D_be3L!gFO4`;Q+VMUitE zmkxI3D|yZ*t`H`(U@`}L;sjE@vI+X3g-S^zKF(0Furhv7zslzsk?HCl9jMu2?-m+H z2)$w|jlI6pG0du+E<#g%ARp|E`10+8c~%;2NL5;baY|4YEhJ4^PXrpE^&EDZPzDLE ziI1m{29hsDL*3@i$5kW+m?DV|m=sc>enPR&8&0feewOi*Y`owM@}d z`abut0C(%LX!j1>n9jr8Am;vD+?rhtLQfDW{1+B})1xgVO*o0an`ChG;fF2U52Kpz z7qg~LanZnJESBLwCd7I9`5~F=T*Riq=$wsdl~W1GU(cB9RwVe932&$QX6=(kk@0wt z%S-b*0S8x@DwVf3WrjC>ZO=8UVwPB10D$88PL)NU@H(@6DH>LUYedwLNnfKO_&M~r z89ys0DG@sZ8|*{F+Ts_O1PtNh*HqJPgZK!1HTXzTAXqSNSx zhDcNs>E_{8a={C{oLnk=k&aj=04N_2I99YlgQwyQQHDQ&*E6LtQ z>(r2B62|K^0{H@*5!N}_W6e=rc(BKH@Nw;FU!deV!;5;S3CX#?zUp0`=a-9Xh1}aW zh1~n)IdI9oiyD2lE0(3Lm|%G@3?6NH(d2_MjaD!^iQ0|M-3c@y1K33E{2jhth}ulH z#E*sCJLTod>+UmbGHV8-JjADgS?gu*JDt`>z*G7qI$bnc(kgXrt!pj)Y*Z}d-k9Tq z>YEsQk=0*WT{71%7=uT!wtD@j-((>B4e!yBXuVE3j!N)yh|3Ym4_DaXy4Jb;Gzvx$ zSgDDgzP=i z+VbKOv=;U)lwbkUvVKU{J+s$6%c?5}DbiiD{SQ{S!=O0`dA|8HcOtgbCo1)EDoM== z)cH3XDP^4jA!UDzvg>xDsm_T`tHnmeX2TQy66+FkcTcuyaSy>l#xF*1P7`#-N~E>& zXSVWZ8RY}apn3>0G7+gWB2A|gNfH~nIVnb&C(t3)z|Tg9Kj)Sf-cy*nCKPRs*$!+B z>LI5n1lABv2MBu_23q*8?}Yk|v&r5nk-gO{vd2aO z`ReGn{i)vU#EfzINs&YaHA>#Ch>MwbPRku`$!r)jJDfouy@t{A*#7X-REmg8Hb7s4 z%6zbwJCo(kWI1hAhm86K-B1Y^h5-l+BF!>V@=}nWS{MZe>R$F3&z?+_EiK`pi$=n< zqy;F?zvU+~OYB&Yvo5HKX}7(4H)oIN=4{q(G9V@iDuU$E5RuMI*~2sm=d5Eqf+)op zk(ttECc2ZOy`+q&zMk$i9 zCE#oql42T%*bxjohj~?C4Xh~l$|dQN3@9N|Hjvt{{rDAfYDFF6e<-Dl07zfZ~tx!nD_Wr+&uXjYPCGD9cAJ3YEIy=KAzdYXKF1re{= zv2Ijj;_FrCt{I#&){VPnXnM?oo-7QT0yYE)=ckD6hbaEZ7y2E^828a=3@S>@Cs%SzgqwD%9f@2RpFHuxR5;=A{u+vb1JY$ z@N8#)veHSzC-q)DsgJ+`vp?}|uMa)b71vJZawi;yP4-4yfzUwW;4@?w56Tb-8 zNEjXWh~#fo+5;M+n|yZ@M^LLDBr7DJMNS>-dmrmJi!e6$u?+vL!0_>1179@ojd|P7 zUTD{Mr|_Lg3+CH1dJBKZ;}Lvca5~sZ$REw?Pxb=Y3HFyub?ldZB??QIxRGYB;LZq^ zL);pv^+u~190?O0z}>;@3`$iRBbYbp>R^1W_zKTk_WL3X$gn`XfP)kMn74-j+{A4k zd&ORa7g0NGKtm8A#7&opw5sw-%hH^@T!psisuG65x`!3g(7Yd95>Ue!+Ty>9{4cC0 zY$I%CAYCOmAjBle9~FN>@OjY&UcBOG_IK|>G$~$#4SZsGHyBS?4m)5gJQkzUNws)) zX1>!b4~?fY+*r+ia4LSB@fO4wMCYk>X6s-BzpQICgoq4Jgu%5)!9sMTClfzSJf9_= zvFR@Ef8bp`HjF;fpkC)rJ;>gR`U5OjX6_jcPmGtdWF~>`jcgvUf=12{_JVGEfZT** zy|?WUmJ?zS;_(T9$5cwY+ETE|N`#r3a3)3e;FKVW$?I&gqX^`L3l9=27@zzR&XI;` zgNadE)DLAXMd*vh(=y^sFYfEpY6j*rtyH}y_R*w-phUMRIg|GLj3~K$FEh;%Jr%o> zttCV6KCRY{pjKuIrqqk&^x7;NlN8k$DH)Bc0fdoYPqlIDyaVSLT{-&gMi&Yr(lo;$ z4)>ur?JJCuN=GU~XxT&*OY9j2O(ffti)NFF>CLc5rzmcVpiS>!kFkkkgY0+b{2B(< z>EXJ-Ul@9oj#KX{Xt(jGg^R8@M2eu-hVpnM1o#)i&C*Z?Mn6DMF<2%JS^Q$P>No6f z5XaFaat~bz$Rpw$f@ZUG7dG~K(Pe}P95fm}gu>m4;y#ceoLRGZPA!E)7$ISG2kRu; zV9$r)r9bN8){6Ud1SU${1wHr^!LWf-#lsa5A?RHWTD*HY?_hZt0X~U(q1dKm(jcDL zu}nyd){yua^ltDYxD$mS)6iHTh_;Ne_S=J?^a$0y_LlwR5t@kDfJP00(#OM#v5+_; zZFr(4<~v5xuMeIrbH6H?DYoM}!!QMLPbTc> zmpGR$E6h$1(L=0e(j(4{PNJ|M%FQCS25yJS1wJ0qu4!PG+5_KB#{R;fSck+EhibkE ze|21(guxAMAN;T(_92XrKOm>ZP>PM6j^B`u8yrM(SYp(_%Bc_9J*Nuyr)|?Ih*UIjZU-l27 zEloqr8D#mO2LYsgQ8P;$5k84{xb|a9{!RoM6ur=2P3tC@ssv9JwL;4mc0lQDlHpun z@Lud;WVSdqAGJJ&;uO*{ELz2nQ|sF^Q})V`$t0_kNL6U*+xE_K2rd&%%4D^8?z9lo zs|j`ls8tn_3;^sS-nWP#HwR*Uh_5(dQLj>6vxRZa1*&;)u0WPsUShY)>q4KvA4;6kAqsKPAQ|_CNrYpa!11XSsI}0y} zhs1X%$cr0iDl833*rPHw!NYn?y8(5Lu!WH#!{WeUj zwZg6E_#=;XQr*M)*kWxH>I@n9v`S}eDO4q|r&X%p>n%$qvnMw0g2(Xv9O9)tk zLt%(MOAo>GRI?9<5aI926d&CrB1hG*@HycYppDGw==oj@-wh?4_hqn zPAr2XEbphvY|HoAed%Sg`qIl}^@TL5d^oW$y-ZeLdKuN1w)146%2Bej`^-XGZ`p;k zshNdnRX;A*9UOcbog88K07#6-=zjJkTC9AcQak=xm32QqOPd;AS6ayqfdH85km z%%!VpbzNSK5w3&CV?8q_hqJDGj(>hdyxJR=GiE+iStU;9z43C5UcSXYd-(G6J9;;- zzgu*ta(~z!b$kg!ass5?ZJ?Xg60oig94$V`7C1Fk@(e)U#09&uITdAsTA-XflI4wgbR2z!ZAA$wP*xv@dix-iDWv1=<zIQHtlq@u2c^Oy# zco%VC56`+16ghzZOx9&FIHa?0%Ky231cow+_uyjqt z?c<^iM;M}xU`OpbO^ zWfm=8`PPP73}4xjbv}84502YnX<`{TSy*G0MUS`dbB4VFWJ%Gy1GTN1L=LzR2ZI~A-4Y>wiyhQ0?-uDC zlkZx1Qt$A-7|soSthHUGiPfF$YoUZF!%jt=fI_aWn1Vku&Th4TyHQWDsL_Fl0a5&NyBr?*7F3g zX_r490D{*>IIauSWVBETb%Eq#$NJjuxtqlDu;%wyN~B;IuoWG6%hXTD9Rg0kwu4$o z4W8WcEo=EU*>dwGTJErxJ4VZl8M}T=%i9?($E@WzG3H9oU-71Gvh7pShO+t|scw)y zu~YJd)&GiU5$>;iIrl6%=N`rBfYc%V99baD^WV;T~B3Wv)V|LEv@@;LPU zp0B^(*7);B{Sw>m&mZ;kxAgaX{SQJeJlNmtAJpr4n{D1yhi%nP=@Qj%fmeuFi7wnZ zm3LXS%I3QyleEmbdIKA~QuO-I!W7#>{XFrcm6~KP7_9n^OCmCC0ysyspXYg`UBEv%B80T4ys7JOGi`{WGbhA zB->#WpEr7dUk>FLu0#*Ea3}k!pY3Enq$2}z&JY~7btx&42K%JG*`(HSp=zgESI2U| ztTr!ojHN!Qp}zATIoT5~0c%r+uG#tgNpztK9O}Jp@Tr5M6}Gu|l-lL*p0LX~8sYae zF7<7=)b;^CTK+7!q{?RFQs0NQ82G1_SKkkpstT7-QQ$K%<9i}hRUs6&Yw`c~SarOi z0|BV)hIxZhU73m0>Q@uq&Ksh+^zX`4qFY6xyET>QdMl;t>>`m)mrF#KJ@Kb5|GhVe z^ro2Yjf+(rXWk_i1Llr51f;+7+HQ+5$s=Ok-B84Q>?1)y)$r8G;``i^xx=A@G1(SE5tmHH|T-`L_BWS z#m4YSM~QoZ;31Ps;lnMmDP#_~r_oB)7GLmil?L$!A$m!ij!%*po)DLuYgcW2(sxQ( z5xfcH>R*^>Q7SFO;C^hQYpKP*Y`>jTfiZ)HkM~7Mksylzs02skuEVw_DzWc*4OM=8Cju=ia^Jk zRhZ$)QId*Ff`;uBOB#IcGl?ITy{ED|)hqh`BxI`SM?Qx7E8P$2U+BHa8-jf92l~xenjV4A5}m1C0)2}n$oRL#-kox z)Rl>sDRZ4Af82KbgBBW_R8Mj8q{>{O+eKo!*m+&nmP}GvPJ`J|IrO=i2WixVv3DH? zctIos7{U^#%vGnn=F)i|B4}DJ>@Ki|l^Ybd#)+buC;McRQbHvn9vcjp$f$?gLI z4BZpoG01NJ*psvFN&F>X`RRo|uqE*SX?HeWE}__Sm<`i#DQM~fbJgoJ`36wel-wGdw zi-_n)e9uY>89L?9S>?-4<%+h_t@pUCbPMw=>07DiTep(0ZKZ88TkwUS731z3=0>Q% z>VdrlY7;>3tsQTR&ph7#k=8%^tRp*1Se={Ax-Pe%##_4+uI<^0@PM`BY(*=ioH)41D$cn(hF#9+yV7+T{3&=^6JaHmp7hK?7gj+ zzv7cgEX zc1%x4grRulbK@cpKuR+tnUzNN8r^zShwk?Jo3oMcTd~!uPNnUwDgy3(?v|BmW4uX# zTPc$gu}pn66p8oWZK$c$>HR5jkSFx?i6(PQOMw$@Yg0R>?Y3ya>)7Lr6RN@ZAo)>p zhdjqScXd;$g&H_o&(R0#HCE~AEj@w#g(ojcyo)q1yr_6#{q`WLa8SxEC4W~qbLVvl z3KvhN+V3}sY&E_M*%qyzKa*}hdz6)z8m0e(a{r**KPY#Ca=*nL)Y!5R!-fSG*3S=eKsOO10tR-fFn7i0@`^?*xw_GXvUnyLtxu`Pa=$>$4t4bf!}?qzW_ zdt1C9n)Jdr=r#Uy$W#E`+jaIf*-yY_38OQLZGzCj zdmMz{8Aj_sUtaRoKS7Tl@@DK4?%i<|tYG8-_<(DCLUfIdlXZGLU*YeVfH~3(3r7n^7$p51DL=LM4WWFEUb>f^fnnHhMVi)CP!~u2*I#TQ3!Ce zU9mN-fy}%`=P6FO$4@XC<~Fpx%TH+!&$lw#A%Sm_$8E-|WCDRvLqvoF|C9qRfDX{H z?^xIX0GUB*!J!COxqQZlTM@JlQ;REx|r7 z_SSXELsEaC;(&G%-Mi86iuet7P9xt~QNS7Uj7EF!>L(6A1pYByke*7I!mT+u`6`Ow z@fixl_WVsohiSOPkNY-Up+jj(Uisi%;{f+$C_G% z3*75!>~+8*tK@KV12)>TeK>!bdY32UWWX0~&7DS&*$JT2Vzg}edXdjKDERj?E<=Ej@8h{r!ZsXB6R2by5P1ZV z%-hEiAgv>M!eiH*UAwegZIaDyJv_G7HuQBKnN%3IP>ZYXVE{d%Mi`p`u$?t<)PpVR zJBT6W*yBn_INDAKpPC*S)YXR+uV#ouAV53Kh}Zz`16w&nQ*qLgvWIO4?LvKLK;r?c zO#cw)x0{|Hz;Oj4LsZ29GEb&dg?VI47E3zZDu65TOMpTccC8`Tc+mEE$O^VoHxJ}* zL=Q&2;Yi`~9c=Q=A!6~s6%0ic%n8tAc#VKkyRYKtBH%~8E96fP#z@HPcq7rEV(86# z&ACwMg)GE)^pm#;`-Y;GoY%U7RwEbro-0?#?Wt36fEO3wq9ac+PUTC);^Q8{{Z?~$ zw`EWv>FvYmzO|dv&iuMl|50Eg@AUZ-0-3YssH*ha(*7h-O}ROYYgS>X_SG^-BEa z2a%#gK_L1i5t+`ZkTi}*@jbWngLU=xTe#*BX~5g6ihaT_27ziw$EN|edm`F+0N5gC zHFiNqGlC82tr685lf7WCu(H1D$ z9Nn3cj8`QIcjiD^>)(+m;l@Y zix2?8D^cg+28R+Fo6(He3)Uo?P?cE8+5xu)M+(u^=Ht0ly8A}hed)8Va{36BLGTKes4rt zlFJ6p2;zg7N9^E1lZs;mm6eiG)u6o8;ga() zL$+1md_3oFL$tee*;Z#nh+6~?7n}HEsh`qP$x!^ zY{H5%;EvBW*^TS}W2pUZk65=G4-f#o$3k#R*(1h?bk@8J-YpL}x5#UbF%H4}9y!@l6Rem+A`Le1 zd1#E$A$9xJK95F#ksdBlEp>9gk51~%5;cUbU2pf%D%z5E&MQ`Z! z_Gx%vyt3rIM|6$d0r!{#$Ze?UayAfQ+!*caVB)jA-q&Xv?d!8820`5VZLdjaVKgzd zKG2-GG9B)tLS{=uW(qeO4u<$Y1Z8LYa|RQkD)&?0rdp zc)z7T384{;@zC*m2p=vS0k%t!yf(1=I~p=xBLomI%jvt<2WpPq{t8D0k}^-lC%8UX zb-P>m{?aY+zw=wHDR0%IIK{Dt+RL*M1<)>axtU+9Xr3($Z2(zhYCaOHLKO*!7i3iPJM$b?YwsZ)a7fRpS?rm zV#w{X=~8&kv3n^a^m!vc#$JQs4%Z!F$yJ|9zLoL0{We(gVvoz{S*P`Q=2W_%s5!3a zzN?Gq)9H{EX-WJ27Cv0Lj;A|__75zP_PvYx3}MpQL%c8Jn_@&v?cshqwdL^PxR(lf zrr(0cJ7kW&BX7Z1O5EA7EwUseyWK9fc(UXQ zU6_CGshek?_-t(O-G;UmE(FFiJUXTu(Ki6b-2s;k4|q*5@hkaS>B?J1Czl~OD97OO z0m1D405G^qZ^JwOc60z()gyv;hm!P3(-VmUoHC*+4<14jf8!;c7IPI&S zCF|R_m8T=U=g)-meSd70p5K{R`f)o1c_&{O6eUX+dFdryddFxxIgn)An?~Eo(#f`I zuU_)A{QiK>aE=bJRu0teg$sKJ&xLL+>J;rZnqg|GQ zVEKr~vE*Lw@UV!wr|+V_!iA3x_!w2VP*VZ}G6+sG*q{(3CHgbJrNT5b4w13tJZQE36;=zVp$hUDyUn=Y8}&VQfOffRdG z;{eJ@-g$>x;Bn5`U(=lYNlev)3f@uHhtZx0`!0B{H+v#ykpF2yP(tjjyiJ4zO(m-D zP!V$Y2Bn`plx_Vs8G*drQ?B(s%(OD3-LzfA0aQEKtKX$^wkA*;u}BF~a7gd>WLzTc z=vtdNQ?KXpYHNg*^M~A|5s-|(yR6~6T`@j1k*D$9g9dF6?WH%J@t#^Yz@PFK#hl%z zYhIzc+&M;5FWkAGYG|{yFAw06dq7vykRHgD(g#)CNLBodO$VY11RC79b(dY#;spJw zKxyCE;1M;roA3LQaBKwJzm@7j|CZ;YsygN728jbf1V#_u#Z`^xT|$9#o`~lq-qHHq z(&8cCnBXGi8DGm+{*Vh610>5q2%8KSuTsKjb*qQQzK@K3&pJf9k>D_V-0gC`!p;vDpzP-0g0TG}} z(mA2L=&#m{)=4!hwY1#G^A_)@No|ML8jko4H#txSjV2wuqjFGlhL0Z4Qn4*-;I#>_ zhx6iZwozfntq|!&UAF4s$9?TRRmF~x$#qcg#@j^*IH+B_;Zos!g_P?jPWiC7t<8Av z5-omCJla6lN4jbb<67N#@us92Bh9g#`$Pn*N20w0NIR$2=F*jSs>u5IEAGmXu}C5f zl0$bbL$oH?w|;^u!P~zAwY^vC0Qay9RAujq)RcrqeX^?r z&cVNS$J@BaOCsAKBNPCgO^0+9Wf@}>(5^c4mCm}{1x4XTl`CK09)TL{w0R_Rs5$Sw zWguhTRf(6OJ#u_q;_>}ANsmk&0Mb;IMjPDdp!uP-`8$C3sov-nrZB8ylbAY?Eya>- z($s91`yRHvYHj;XiLp_oCA8&TD{%)<-peAg9!7IMdQd1BX^L(EqR|8pz2zVp86bM+ zaS-iD5LMAGxLSp)bbrm-;-JLk&+6caTa=TXb(K_V2SAyR^?p|2Wu@z(31FM+Y2SFx z#@^kLtn0VXI397144N6TGOnV%Q4+DXsvPfqGNKQhQgwK&4RMQa0^aRg^h6l)>^a8> zHCb^qq2hbIM#GBRB~HHBMyuW*i+#_avwvSRs0u*A`>cvQl5_(idTU!9$YkM_%ky+4 z>5<``I>Bpr#rux*rb6%O8Baqbo}?XXlriEP*N8@fJo#PsL_Fa=(|b=`V_+zxqHGb4 zEpiQ~ zA|Damj1uv_MNz0GY*K49?*kE35#9O8O9+&1Rqo5Xg06y<=^IY6|uuw-^y5^FD zFF^2NlA#0QEGV>YfOtby$Pc{h84!O|6;Li`)QM#s3RN|n-c4Q9hTc7V3SkEU9!-Wo2-Hn{3&)Cqcxw= z9>?1t6SFKy-xQShSxIxi*O$1&g0!;_sJOBNz+LhNXDFzN~ zGa13E!dLsMj$CA3&o=B!UPSYgBcr^^j`^NJ*2K{pw}mdRCu=?_F3DtF zpyZ8vL!UkRN>cyc%09;SL2CkMuegulfFsbfKst^JTw-k z_Zyq)qwkg%~^d z67nV45bxxYG|6(WPM4`J&qjxt<=Wm-O(4iNAjGM7DwB&sdFbh{f-90&-XBqlyb%HV z>X2`UC6J34gp29-yg|R{**|JcgZzM-d%)+^P;>I%xqJZ`pDMG1vdvTzwJV^nFslVl znOqh%@YJ1BvMCgP0&RxXA{s}^eJfYE4z~DPYS+fJYs-@B9%+ef(G3jHWq^*^UDqLd zWOZ7rl!E;D%}Ocg@sxrC?)mwdI$y0NlL(dwuj}1oX?}k1j){lp?{UMqE5#+eb1@@s zb(foogEuT)cWv;dL1G(_&qayM&)HVnyg%VtVA%BM^~l#=v-I{*tn>1QQ`x#if8%PQ z{%Lf8?zJuVEzf+;ruPX&v3XbiX7V&^oRm@(;8y2hnY}v-oezpuxVMNIfHzjTJ3lC| z$lsPdyg4Cj!{G_fhJ_lE0pK~1)W|(K1h9KM?M?0O2qOYGqkXznI@P{#nXL{UV95E^ z5Pf}qS?P%EY9s(vZT0(&_Pe<$ zVnmj^UTc$29@ZFDo)r7QLtVznvGAIL(06CtJO7*lri@m?`})g9{ClbsUxaAuAp*u16AH$Ss8u~ zwR_~^Nm3wcop2>JG~7k5XS;JEDI*VSNruluo~@-zF4^wV2_fy`30rM${59qHHk=9CO3;)ZnL`j ziTYt@Rps#QaR#}eI7Rh$u8rXI(81z_98|b7keXDRK-t4IOq(6Vs&X5{mTcZps0fVD zvx#@f&z*7q_}SCZ3|TfAQ*hcZ@3kq*{m$Z%GzuYSWHMw}{tP_~gw8qgDZ0S{pch%n zqF+zbGh^WhCrjs~!pBJ-PDCal!+qDs3y*HVFFY{$;{0bKi!y--zX|N`(M=%K811Ob z=q2xNhew@_cnxp!)x&@J@!#Laf8C&d6I_OihwNag`U|bbcj#kjY3c2oH#ysT_TQV; zmDSvTSy_F%R4l%IyTr;Z6_-}uyk&p?3;+z`e$Zn>d4Wl?|8ny0KgfT-M6JtQ+^c_l zb=B{8!4XQA7^ ze3iS48vUz}uih`c$_35-$5*mQ4$8dx*MIq!|C&?n)jPfLU;gEbeDN)x9!I^?TAa&8 zaW2R;qsy!QT?qf?E}}LYNiJ-Lt+3tC#Zha}4Ej;0%}Sm3g5EfHK8TwAT-45O1;c>a zU&vMZxvgj(vW89>ifoYdy|gbpHSL zjdr(<xIqe-Fl=&nc6N5YXLg;k>3ETa!%VD*M`6r)8pb2$ zPp45h6o4MP8UxkvCm(Z$CoL#TZc83`jmB5(KmYjqKiSq+$t+kkoTVw8ELyNx9PpHl zxj$d9fX{i9O!3U#))sp_i-)+IABFjX$O+?|r?>u)XKdmx*l_H}BhFHP8U}#M&sfaw z7;rbArCc2VV1~p-7yvQ>MVbV&ArCyF3}p5Rd&2V^k9Y|Nlk=d_Fo=blL;$K3{}B1^&3pE z9fFkKdapC*pn;oqN}U`g@ohLlPEHVg1Ab?@_|6VVp632;^PoYq9#|=mG3RNAP`FM; zzpfTj?lcb=Y{R{g*J3yx22WwftJIIPTb??CWeofy=@)1%!JrxfUnLY9f_apCo$_of zce+R9#~iE_sD|O<5W+@X@F24ZnGEQ|Fb5?C5vMFjCO$|L_ue~hHW;lv4nd(ZShmlc z-D8LSz?{8fr-eJTXXAU!Ho!9Og^se3h>{q zhp*je*%TUf1kMV)WCHF5#R~!oLNYQbP(KL1mXjSd=Q;|$hw2Kf>^sFmQY#>23(Pq6 zCp<^@y44=Y{YVp~^4_C1k$HRrp!gY>%^{PTg$rGYYY7-)NL{zgtpDq`H*MemE`&yEUxe`1dLr%H!3^W^;&|&uM<~76~ z0Cnen)MSTWF*k>Z0gefNv%|wf<|G8-uungwu}3f#&msW+;Rj~J-pc$Ql0qq~9_IHz zW|@OQ_8vr(HOp^e1I+({>;NZ-*PbmJmFqpFWq7`O2x1K4PArD@%TuV6i2*@+UlZ`4 zMN1*G4vB>>5Yd$Q2&WADm@x0Q=$}0b@tD3s7Kf>K2k4JQ`l^;ez)3PfCf4j~b18=! zCT4xY)sp`X1_EFy=z-v0P=xb3N%-4C`_J7f);p+}#EJsn@|`kBH6aMqfCCKqRMdkS z`)P7R_Rn}l05}99&~+1%J({q^a4&}0Qa^db^AaQ|&mP{&9RVFM2BI+NVmD2bR9|gu z5ENwVpD?3U`@kSYlK!DR_G{MRXCjngUqE^CXR8)AhAdM7;`e$eILh#i0;3;QxTQI? zESa(_l`(?!W*r~ObKm*^+fux*L#DL1!~iP1Mte&*T^1;@a>kSU+tMOMVM2dAsJy~a z?4sQfu)f}4d9%grsb<|t1a=#=#%!RLhx(iiA?PNP@O!NOFe6hdMP&#YH{@yVD}^@g z#x$8s`46zwKJC|cL|AFndN}E%`VNr{Ky`KqKv=OT&kHgox_R&n!eSV^zWys~K>>+h z6w5J}bp^2oAfC%yX^THC z=P^%RM=C4`wAcb0LpNaQE}z?se#GaGQkg9a7dG-Sjg*^Vmn{=O^D*4o;&VOhz8w1}t2` zmzH5j%@1~v&a<=2tBdEIsuYWv_c)NSmbp9-hFEnd*Yms$PEzFxc`~kHf#(6MW5UBxeyx__s9aI4TV|0d!Y`sh3h_ND1eh`L|HD zL$whHSb50q5MCurfjKaJlgznSK?Vm-`2?m`=A0_ktTE7G1U{e}2j|$ha{06d1P@&H zq_9x9c}>N==mcRdQcMr5rciT*Nt%o5ywq})&D5(c7gc3Nt?*U{_z8dMB^;HN>?&a$ z;0#@^y|*IXuj(D3Ge%VqC9Ly2E~-dCqs)n5oo2P#x6R8c{(nK8S9_^{Q5|4EYD?+j zRbxt+OTC^7GfCSyL<(0mO4V}73^nYL2+|qekWte_D3yl6F^V-yhb`nt?~3h9RVuee zTzCWxKXuyp6j(%;X9}?_0)(|Hv(pQH$%su0LeZ8}GBm3~74k7FrBKi3W>f4D&0x_; ziE9{aUNov!wYYA?M94al2ZweQT5DUiZ1e4^)s({FTIF52hFnEtudC1*fXB>v4XH~* zgQdEOem*tdNxC*V>~Hl)f1mm_Wn#(u_bIFHL) zL3%Hfu{g=`z7b2P(AJhtAULl5O`=;%a#qH8 z%LA{7E=yvk*5~geGi+E(+j#+bmb4!Y=CKMFXkw21Meh89k3eSW!olEFHfkV7(Qfqo zqz2q2HktI&cCdg5!e)X_9@zn|0W;favTe3oYM23+5nQW4WEo9~AKcnb)p9DbtW#u7 z_IMng3PmP5uxDj@sSS_xJ9VT@j)O&6@mGMTAw&R*OL?L3=l09Jpz7os>2Y-k#?n(ZX)@=7e^W zmf7~zD*8wtz|x@jc-(t=+TCZ}%P)nEGj*4G4O?Hc3D3t#ARdiovne)Y=sH}U(znsw zBnj*kdsw?<`1oj)Bmv~}Q3P2%*DpMnpDp4c&>SbT3{t0`e*Dub_uqf{Yx7n6ryuJI zp7|zKx8hA*tN-V!s8r9@{obmU$?E}A(hty5?LxX#4yzJcug97$iDqh{O|NpuL5|W9 zY1EP4ko@_IB}5kanYw-G>mCUblR?$x3utgw<~x=(PXEKXoK3o*@8?67wuQXl?DdSI zE0h9|J?CRTXV>Idn%67{gZN*6{#y>I_7u+Gt>%)0OPn>_*(_x+u7%dpF3nJHUDsG6 zX!sELr}QavZRPqOTITvIiB;D5z`$Xg{{vZO(N8F?^M7TNzh?Pub`$d}m19}F*Oxm+ zX-~sO$v#;;j{My9)6}YrkJ8j%;8VXmK{jFUY3S$jW(>1^TwMNeic=f zfriRK3(g=P=4^g}q_o#|63*;P62^OGyx0@3vt+xVY{!9PPVR~l;;u!{uld{DdZr;v zUA;)r-=nCkTzhC&G*2N(pJXFjMUlIAMvqkhX-Zu|VKjS|bvHhBw?5W;)OGh#;^v7C+pGo?%juiP zs4|4YxcmF^M#sB_qS)Qh1}IPxqfRlExs8$}b?GZ?9V8Q&+mins&O1GN`RelMarYI} zCfz69i)NYZ?0%`;8+orG2D#3*L)13#Nd^6POS8sm$+s4*@@>EDeYW)fg3vO$aV1My z6{T)jL9j)4ROsT{?N3;i%+eu;7(WGipI@9DYX4&fxzPB{$Ir*l$Ir*lumAI3c=!aG H0L%&i&^77` literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..21f115f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4525 @@ +{ + "name": "feascript", + "version": "0.1.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "feascript", + "version": "0.1.1", + "license": "MIT", + "devDependencies": { + "@rollup/plugin-commonjs": "^28.0.3", + "@rollup/plugin-node-resolve": "^16.0.1", + "@types/estree": "^1.0.7", + "mathjs": "^11.12.0", + "rollup": "^2.79.2", + "rollup-plugin-terser": "^7.0.2", + "rollup-plugin-typescript2": "^0.36.0", + "typescript": "^5.8.3" + }, + "peerDependencies": { + "mathjs": "^11.12.0", + "plotly.js": "^2.27.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz", + "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@choojs/findup": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@choojs/findup/-/findup-0.2.1.tgz", + "integrity": "sha512-YstAqNb0MCN8PjdLCDfRsBcGVRN41f3vgLvaI0IrIcBp4AqILRSS0DeWNGkicC+f/zRIPJLc+9RURVSepwvfBw==", + "license": "MIT", + "peer": true, + "dependencies": { + "commander": "^2.15.1" + }, + "bin": { + "findup": "bin/findup.js" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mapbox/geojson-rewind": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz", + "integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", + "license": "ISC", + "peer": true, + "dependencies": { + "get-stream": "^6.0.1", + "minimist": "^1.2.6" + }, + "bin": { + "geojson-rewind": "geojson-rewind" + } + }, + "node_modules/@mapbox/geojson-types": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-types/-/geojson-types-1.0.2.tgz", + "integrity": "sha512-e9EBqHHv3EORHrSfbR9DqecPNn+AmuAoQxV6aL8Xu30bJMJR1o8PZLZzpk1Wq7/NfCbuhmakHTPYRhoqLsXRnw==", + "license": "ISC", + "peer": true + }, + "node_modules/@mapbox/jsonlint-lines-primitives": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", + "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@mapbox/mapbox-gl-supported": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz", + "integrity": "sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg==", + "license": "BSD-3-Clause", + "peer": true, + "peerDependencies": { + "mapbox-gl": ">=0.32.1 <2.0.0" + } + }, + "node_modules/@mapbox/point-geometry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", + "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==", + "license": "ISC", + "peer": true + }, + "node_modules/@mapbox/tiny-sdf": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.2.5.tgz", + "integrity": "sha512-cD8A/zJlm6fdJOk6DqPUV8mcpyJkRz2x2R+/fYcWDYG3oWbG7/L7Yl/WqQ1VZCjnL9OTIMAn6c+BC5Eru4sQEw==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/@mapbox/unitbezier": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz", + "integrity": "sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/@mapbox/vector-tile": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", + "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "@mapbox/point-geometry": "~0.1.0" + } + }, + "node_modules/@mapbox/whoots-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", + "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-20.4.0.tgz", + "integrity": "sha512-AzBy3095fTFPjDjmWpR2w6HVRAZJ6hQZUCwk5Plz6EyfnfuQW1odeW5i2Ai47Y6TBA2hQnC+azscjBSALpaWgw==", + "license": "ISC", + "peer": true, + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "~2.0.2", + "@mapbox/unitbezier": "^0.0.1", + "json-stringify-pretty-compact": "^4.0.0", + "minimist": "^1.2.8", + "quickselect": "^2.0.0", + "rw": "^1.3.3", + "tinyqueue": "^3.0.0" + }, + "bin": { + "gl-style-format": "dist/gl-style-format.mjs", + "gl-style-migrate": "dist/gl-style-migrate.mjs", + "gl-style-validate": "dist/gl-style-validate.mjs" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec/node_modules/@mapbox/unitbezier": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/@maplibre/maplibre-gl-style-spec/node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "license": "ISC", + "peer": true + }, + "node_modules/@plotly/d3": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@plotly/d3/-/d3-3.8.2.tgz", + "integrity": "sha512-wvsNmh1GYjyJfyEBPKJLTMzgf2c2bEbSIL50lmqVUi+o1NHaLPi1Lb4v7VxXXJn043BhNyrxUrWI85Q+zmjOVA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@plotly/d3-sankey": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@plotly/d3-sankey/-/d3-sankey-0.7.2.tgz", + "integrity": "sha512-2jdVos1N3mMp3QW0k2q1ph7Gd6j5PY1YihBrwpkFnKqO+cqtZq3AdEYUeSGXMeLsBDQYiqTVcihYfk8vr5tqhw==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "d3-array": "1", + "d3-collection": "1", + "d3-shape": "^1.2.0" + } + }, + "node_modules/@plotly/d3-sankey-circular": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@plotly/d3-sankey-circular/-/d3-sankey-circular-0.33.1.tgz", + "integrity": "sha512-FgBV1HEvCr3DV7RHhDsPXyryknucxtfnLwPtCKKxdolKyTFYoLX/ibEfX39iFYIL7DYbVeRtP43dbFcrHNE+KQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "d3-array": "^1.2.1", + "d3-collection": "^1.0.4", + "d3-shape": "^1.2.0", + "elementary-circuits-directed-graph": "^1.0.4" + } + }, + "node_modules/@plotly/mapbox-gl": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/@plotly/mapbox-gl/-/mapbox-gl-1.13.4.tgz", + "integrity": "sha512-sR3/Pe5LqT/fhYgp4rT4aSFf1rTsxMbGiH6Hojc7PH36ny5Bn17iVFUjpzycafETURuFbLZUfjODO8LvSI+5zQ==", + "license": "SEE LICENSE IN LICENSE.txt", + "peer": true, + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.2", + "@mapbox/geojson-types": "^1.0.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/mapbox-gl-supported": "^1.5.0", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^1.1.1", + "@mapbox/unitbezier": "^0.0.0", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "csscolorparser": "~1.0.3", + "earcut": "^2.2.2", + "geojson-vt": "^3.2.1", + "gl-matrix": "^3.2.1", + "grid-index": "^1.1.0", + "murmurhash-js": "^1.0.0", + "pbf": "^3.2.1", + "potpack": "^1.0.1", + "quickselect": "^2.0.0", + "rw": "^1.3.3", + "supercluster": "^7.1.0", + "tinyqueue": "^2.0.3", + "vt-pbf": "^3.1.1" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/@plotly/point-cluster": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@plotly/point-cluster/-/point-cluster-3.1.9.tgz", + "integrity": "sha512-MwaI6g9scKf68Orpr1pHZ597pYx9uP8UEFXLPbsCmuw3a84obwz6pnMXGc90VhgDNeNiLEdlmuK7CPo+5PIxXw==", + "license": "MIT", + "peer": true, + "dependencies": { + "array-bounds": "^1.0.1", + "binary-search-bounds": "^2.0.4", + "clamp": "^1.0.1", + "defined": "^1.0.0", + "dtype": "^2.0.0", + "flatten-vertex-data": "^1.0.2", + "is-obj": "^1.0.1", + "math-log2": "^1.0.1", + "parse-rect": "^1.2.0", + "pick-by-alias": "^1.2.0" + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "28.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.3.tgz", + "integrity": "sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.2.0", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.1.tgz", + "integrity": "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@turf/area": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/area/-/area-7.2.0.tgz", + "integrity": "sha512-zuTTdQ4eoTI9nSSjerIy4QwgvxqwJVciQJ8tOPuMHbXJ9N/dNjI7bU8tasjhxas/Cx3NE9NxVHtNpYHL0FSzoA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@turf/helpers": "^7.2.0", + "@turf/meta": "^7.2.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bbox": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-7.2.0.tgz", + "integrity": "sha512-wzHEjCXlYZiDludDbXkpBSmv8Zu6tPGLmJ1sXQ6qDwpLE1Ew3mcWqt8AaxfTP5QwDNQa3sf2vvgTEzNbPQkCiA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@turf/helpers": "^7.2.0", + "@turf/meta": "^7.2.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/centroid": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/centroid/-/centroid-7.2.0.tgz", + "integrity": "sha512-yJqDSw25T7P48au5KjvYqbDVZ7qVnipziVfZ9aSo7P2/jTE7d4BP21w0/XLi3T/9bry/t9PR1GDDDQljN4KfDw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@turf/helpers": "^7.2.0", + "@turf/meta": "^7.2.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/helpers": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-7.2.0.tgz", + "integrity": "sha512-cXo7bKNZoa7aC7ydLmUR02oB3IgDe7MxiPuRz3cCtYQHn+BJ6h1tihmamYDWWUlPHgSNF0i3ATc4WmDECZafKw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/meta": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-7.2.0.tgz", + "integrity": "sha512-igzTdHsQc8TV1RhPuOLVo74Px/hyPrVgVOTgjWQZzt3J9BVseCdpfY/0cJBdlSRI4S/yTmmHl7gAqjhpYH5Yaw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@turf/helpers": "^7.2.0", + "@types/geojson": "^7946.0.10" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "license": "MIT" + }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/geojson-vt": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz", + "integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/mapbox__point-geometry": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", + "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/mapbox__vector-tile": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", + "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/geojson": "*", + "@types/mapbox__point-geometry": "*", + "@types/pbf": "*" + } + }, + "node_modules/@types/node": { + "version": "22.15.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz", + "integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/pbf": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", + "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/supercluster": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0", + "peer": true + }, + "node_modules/abs-svg-path": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz", + "integrity": "sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==", + "license": "MIT", + "peer": true + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/almost-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/almost-equal/-/almost-equal-1.1.0.tgz", + "integrity": "sha512-0V/PkoculFl5+0Lp47JoxUcO0xSxhIBvm+BxHdD/OgXNmdRpRHCFnKVuUoWyS9EzQP+otSGv0m9Lb4yVkQBn2A==", + "license": "MIT", + "peer": true + }, + "node_modules/array-bounds": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-bounds/-/array-bounds-1.0.1.tgz", + "integrity": "sha512-8wdW3ZGk6UjMPJx/glyEt0sLzzwAE1bhToPsO1W2pbpR2gULyxe3BjSiuJFheP50T/GgODVPz2fuMUmIywt8cQ==", + "license": "MIT", + "peer": true + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-normalize": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array-normalize/-/array-normalize-1.1.4.tgz", + "integrity": "sha512-fCp0wKFLjvSPmCn4F5Tiw4M3lpMZoHlCjfcs7nNzuj3vqQQ1/a8cgB9DXcpDSn18c+coLnaW7rqfcYCvKbyJXg==", + "license": "MIT", + "peer": true, + "dependencies": { + "array-bounds": "^1.0.0" + } + }, + "node_modules/array-range": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-range/-/array-range-1.0.1.tgz", + "integrity": "sha512-shdaI1zT3CVNL2hnx9c0JMc0ZogGaxDs5e85akgHWKYa0yVbIyp06Ind3dVkTj/uuFrzaHBOyqFzo+VV6aXgtA==", + "license": "MIT", + "peer": true + }, + "node_modules/array-rearrange": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/array-rearrange/-/array-rearrange-2.2.2.tgz", + "integrity": "sha512-UfobP5N12Qm4Qu4fwLDIi2v6+wZsSf6snYSxAMeKhrh37YGnNWZPRmVEKc/2wfms53TLQnzfpG8wCx2Y/6NG1w==", + "license": "MIT", + "peer": true + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/binary-search-bounds": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-2.0.5.tgz", + "integrity": "sha512-H0ea4Fd3lS1+sTEB2TgcLoK21lLhwEJzlQv3IN47pJS976Gx4zoWe0ak3q+uYh60ppQxg9F16Ri4tS1sfD4+jA==", + "license": "MIT", + "peer": true + }, + "node_modules/bit-twiddle": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", + "integrity": "sha512-B9UhK0DKFZhoTFcfvAzhqsjStvGJp9vYWf3+6SNTtdSQnvIgfkHbgHrg/e4+TH71N2GDu8tpmCVoyfrL1d7ntA==", + "license": "MIT", + "peer": true + }, + "node_modules/bitmap-sdf": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bitmap-sdf/-/bitmap-sdf-1.0.4.tgz", + "integrity": "sha512-1G3U4n5JE6RAiALMxu0p1XmeZkTeCwGKykzsLTCqVzfSDaN6S7fKnkIkfejogz+iwqBWc0UYAIKnKHNN7pSfDg==", + "license": "MIT", + "peer": true + }, + "node_modules/bl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", + "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "license": "MIT", + "peer": true, + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/browserslist": { + "version": "4.24.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz", + "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001716", + "electron-to-chromium": "^1.5.149", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001718", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", + "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0", + "peer": true + }, + "node_modules/canvas-fit": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/canvas-fit/-/canvas-fit-1.5.0.tgz", + "integrity": "sha512-onIcjRpz69/Hx5bB5HGbYKUF2uC6QT6Gp+pfpGm3A7mPfcluSLV5v4Zu+oflDUwLdUw0rLIBhUbi0v8hM4FJQQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "element-size": "^1.1.1" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clamp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/clamp/-/clamp-1.0.1.tgz", + "integrity": "sha512-kgMuFyE78OC6Dyu3Dy7vcx4uy97EIbVxJB/B0eJ3bUNAkwdNcxYzgKltnyADiYwsR7SEqkkUPsEUT//OVS6XMA==", + "license": "MIT", + "peer": true + }, + "node_modules/color-alpha": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/color-alpha/-/color-alpha-1.0.4.tgz", + "integrity": "sha512-lr8/t5NPozTSqli+duAN+x+no/2WaKTeWvxhHGN+aXT6AJ8vPlzLa7UriyjWak0pSC2jHol9JgjBYnnHsGha9A==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-parse": "^1.3.8" + } + }, + "node_modules/color-alpha/node_modules/color-parse": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/color-parse/-/color-parse-1.4.3.tgz", + "integrity": "sha512-BADfVl/FHkQkyo8sRBwMYBqemqsgnu7JZAwUgvBvuwwuNUZAhSvLTbsEErS5bQXzOjDR0dWzJ4vXN2Q+QoPx0A==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "^1.0.0" + } + }, + "node_modules/color-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/color-id/-/color-id-1.1.0.tgz", + "integrity": "sha512-2iRtAn6dC/6/G7bBIo0uupVrIne1NsQJvJxZOBCzQOfk7jRq97feaDZ3RdzuHakRXXnHGNwglto3pqtRx1sX0g==", + "license": "MIT", + "peer": true, + "dependencies": { + "clamp": "^1.0.1" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT", + "peer": true + }, + "node_modules/color-normalize": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/color-normalize/-/color-normalize-1.5.0.tgz", + "integrity": "sha512-rUT/HDXMr6RFffrR53oX3HGWkDOP9goSAQGBkUaAYKjOE2JxozccdGyufageWDlInRAjm/jYPrf/Y38oa+7obw==", + "license": "MIT", + "peer": true, + "dependencies": { + "clamp": "^1.0.1", + "color-rgba": "^2.1.1", + "dtype": "^2.0.0" + } + }, + "node_modules/color-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/color-parse/-/color-parse-2.0.0.tgz", + "integrity": "sha512-g2Z+QnWsdHLppAbrpcFWo629kLOnOPtpxYV69GCqm92gqSgyXbzlfyN3MXs0412fPBkFmiuS+rXposgBgBa6Kg==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "^1.0.0" + } + }, + "node_modules/color-rgba": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/color-rgba/-/color-rgba-2.1.1.tgz", + "integrity": "sha512-VaX97wsqrMwLSOR6H7rU1Doa2zyVdmShabKrPEIFywLlHoibgD3QW9Dw6fSqM4+H/LfjprDNAUUW31qEQcGzNw==", + "license": "MIT", + "peer": true, + "dependencies": { + "clamp": "^1.0.1", + "color-parse": "^1.3.8", + "color-space": "^1.14.6" + } + }, + "node_modules/color-rgba/node_modules/color-parse": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/color-parse/-/color-parse-1.4.3.tgz", + "integrity": "sha512-BADfVl/FHkQkyo8sRBwMYBqemqsgnu7JZAwUgvBvuwwuNUZAhSvLTbsEErS5bQXzOjDR0dWzJ4vXN2Q+QoPx0A==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "^1.0.0" + } + }, + "node_modules/color-space": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/color-space/-/color-space-1.16.0.tgz", + "integrity": "sha512-A6WMiFzunQ8KEPFmj02OnnoUnqhmSaHaZ/0LVFcPTdlvm8+3aMJ5x1HRHy3bDHPkovkf4sS0f4wsVvwk71fKkg==", + "license": "MIT", + "peer": true, + "dependencies": { + "hsluv": "^0.0.3", + "mumath": "^3.3.4" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/complex.js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.2.tgz", + "integrity": "sha512-qtx7HRhPGSCBtGiST4/WGHuW+zeaND/6Ld+db6PbrulIB1i2Ev/2UPiqcmpQNPSyfBKraC0EOvOKCB5dGZKt3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT", + "peer": true + }, + "node_modules/country-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/country-regex/-/country-regex-1.1.0.tgz", + "integrity": "sha512-iSPlClZP8vX7MC3/u6s3lrDuoQyhQukh5LyABJ3hvfzbQ3Yyayd4fp04zjLnfi267B/B2FkumcWWgrbban7sSA==", + "license": "MIT", + "peer": true + }, + "node_modules/css-font": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-font/-/css-font-1.2.0.tgz", + "integrity": "sha512-V4U4Wps4dPDACJ4WpgofJ2RT5Yqwe1lEH6wlOOaIxMi0gTjdIijsc5FmxQlZ7ZZyKQkkutqqvULOp07l9c7ssA==", + "license": "MIT", + "peer": true, + "dependencies": { + "css-font-size-keywords": "^1.0.0", + "css-font-stretch-keywords": "^1.0.1", + "css-font-style-keywords": "^1.0.1", + "css-font-weight-keywords": "^1.0.0", + "css-global-keywords": "^1.0.1", + "css-system-font-keywords": "^1.0.0", + "pick-by-alias": "^1.2.0", + "string-split-by": "^1.0.0", + "unquote": "^1.1.0" + } + }, + "node_modules/css-font-size-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-font-size-keywords/-/css-font-size-keywords-1.0.0.tgz", + "integrity": "sha512-Q+svMDbMlelgCfH/RVDKtTDaf5021O486ZThQPIpahnIjUkMUslC+WuOQSWTgGSrNCH08Y7tYNEmmy0hkfMI8Q==", + "license": "MIT", + "peer": true + }, + "node_modules/css-font-stretch-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-font-stretch-keywords/-/css-font-stretch-keywords-1.0.1.tgz", + "integrity": "sha512-KmugPO2BNqoyp9zmBIUGwt58UQSfyk1X5DbOlkb2pckDXFSAfjsD5wenb88fNrD6fvS+vu90a/tsPpb9vb0SLg==", + "license": "MIT", + "peer": true + }, + "node_modules/css-font-style-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-font-style-keywords/-/css-font-style-keywords-1.0.1.tgz", + "integrity": "sha512-0Fn0aTpcDktnR1RzaBYorIxQily85M2KXRpzmxQPgh8pxUN9Fcn00I8u9I3grNr1QXVgCl9T5Imx0ZwKU973Vg==", + "license": "MIT", + "peer": true + }, + "node_modules/css-font-weight-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-font-weight-keywords/-/css-font-weight-keywords-1.0.0.tgz", + "integrity": "sha512-5So8/NH+oDD+EzsnF4iaG4ZFHQ3vaViePkL1ZbZ5iC/KrsCY+WHq/lvOgrtmuOQ9pBBZ1ADGpaf+A4lj1Z9eYA==", + "license": "MIT", + "peer": true + }, + "node_modules/css-global-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-global-keywords/-/css-global-keywords-1.0.1.tgz", + "integrity": "sha512-X1xgQhkZ9n94WDwntqst5D/FKkmiU0GlJSFZSV3kLvyJ1WC5VeyoXDOuleUD+SIuH9C7W05is++0Woh0CGfKjQ==", + "license": "MIT", + "peer": true + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "license": "MIT", + "peer": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-system-font-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-system-font-keywords/-/css-system-font-keywords-1.0.0.tgz", + "integrity": "sha512-1umTtVd/fXS25ftfjB71eASCrYhilmEsvDEI6wG/QplnmlfmVM5HkZ/ZX46DT5K3eblFPgLUHt5BRCb0YXkSFA==", + "license": "MIT", + "peer": true + }, + "node_modules/csscolorparser": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", + "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==", + "license": "MIT", + "peer": true + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "peer": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "license": "ISC", + "peer": true, + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-collection": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", + "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz", + "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-force": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz", + "integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-quadtree": "1", + "d3-timer": "1" + } + }, + "node_modules/d3-format": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", + "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-geo": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.12.1.tgz", + "integrity": "sha512-XG4d1c/UJSEX9NfU02KwBL6BYPj8YKHxgBEw5om2ZnTRSbIcego6dhHwcxuSR3clxh0EpE38os1DVPOmnYtTPg==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "d3-array": "1" + } + }, + "node_modules/d3-geo-projection": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/d3-geo-projection/-/d3-geo-projection-2.9.0.tgz", + "integrity": "sha512-ZULvK/zBn87of5rWAfFMc9mJOipeSo57O+BBitsKIXmU4rTVAnX1kSsJkE0R+TxY8pGNoM1nbyRRE7GYHhdOEQ==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "commander": "2", + "d3-array": "1", + "d3-geo": "^1.12.0", + "resolve": "^1.1.10" + }, + "bin": { + "geo2svg": "bin/geo2svg", + "geograticule": "bin/geograticule", + "geoproject": "bin/geoproject", + "geoquantize": "bin/geoquantize", + "geostitch": "bin/geostitch" + } + }, + "node_modules/d3-hierarchy": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz", + "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "peer": true, + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-quadtree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz", + "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", + "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-time-format": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.3.0.tgz", + "integrity": "sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "d3-time": "1" + } + }, + "node_modules/d3-timer": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz", + "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-kerning": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-kerning/-/detect-kerning-2.1.2.tgz", + "integrity": "sha512-I3JIbrnKPAntNLl1I6TpSQQdQ4AutYzv/sKMFKbepawV/hlH0GmYKhUoOEMd4xqaUHT+Bm0f4127lh5qs1m1tw==", + "license": "MIT", + "peer": true + }, + "node_modules/draw-svg-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/draw-svg-path/-/draw-svg-path-1.0.0.tgz", + "integrity": "sha512-P8j3IHxcgRMcY6sDzr0QvJDLzBnJJqpTG33UZ2Pvp8rw0apCHhJCWqYprqrXjrgHnJ6tuhP1iTJSAodPDHxwkg==", + "license": "MIT", + "peer": true, + "dependencies": { + "abs-svg-path": "~0.1.1", + "normalize-svg-path": "~0.1.0" + } + }, + "node_modules/dtype": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dtype/-/dtype-2.0.0.tgz", + "integrity": "sha512-s2YVcLKdFGS0hpFqJaTwscsyt0E8nNFdmo73Ocd81xNPj4URI4rj6D60A+vFMIw7BXWlb4yRkEwfBqcZzPGiZg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/dup": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dup/-/dup-1.0.0.tgz", + "integrity": "sha512-Bz5jxMMC0wgp23Zm15ip1x8IhYRqJvF3nFC0UInJUDkN1z4uNPk9jTnfCUJXbOGiQ1JbXLQsiV41Fb+HXcj5BA==", + "license": "MIT", + "peer": true + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "license": "MIT", + "peer": true, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/earcut": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==", + "license": "ISC", + "peer": true + }, + "node_modules/electron-to-chromium": { + "version": "1.5.155", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.155.tgz", + "integrity": "sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng==", + "license": "ISC", + "peer": true + }, + "node_modules/element-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/element-size/-/element-size-1.1.1.tgz", + "integrity": "sha512-eaN+GMOq/Q+BIWy0ybsgpcYImjGIdNLyjLFJU4XsLHXYQao5jCNb36GyN6C2qwmDDYSfIBmKpPpr4VnBdLCsPQ==", + "license": "MIT", + "peer": true + }, + "node_modules/elementary-circuits-directed-graph": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/elementary-circuits-directed-graph/-/elementary-circuits-directed-graph-1.3.1.tgz", + "integrity": "sha512-ZEiB5qkn2adYmpXGnJKkxT8uJHlW/mxmBpmeqawEHzPxh9HkLD4/1mFYX5l0On+f6rcPIt8/EWlRU2Vo3fX6dQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "strongly-connected-components": "^1.0.1" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT", + "peer": true + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "hasInstallScript": true, + "license": "ISC", + "peer": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "license": "MIT", + "peer": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "license": "ISC", + "peer": true, + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "license": "ISC", + "peer": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==", + "dev": true, + "license": "MIT" + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "license": "ISC", + "peer": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "license": "MIT", + "peer": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "license": "ISC", + "peer": true, + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/falafel": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.2.5.tgz", + "integrity": "sha512-HuC1qF9iTnHDnML9YZAdCDQwT0yKl/U55K4XSUXqGAA2GLoafFgWRqdAbhWJxXaYD4pyoVxAJ8wH670jMpI9DQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "acorn": "^7.1.1", + "isarray": "^2.0.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/falafel/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT", + "peer": true + }, + "node_modules/fast-isnumeric": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fast-isnumeric/-/fast-isnumeric-1.1.4.tgz", + "integrity": "sha512-1mM8qOr2LYz8zGaUdmiqRDiuue00Dxjgcb1NQR7TnhLVh6sQyngP9xvLo7Sl7LZpP/sk5eb+bcyWXw530NTBZw==", + "license": "MIT", + "peer": true, + "dependencies": { + "is-string-blank": "^1.0.1" + } + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flatten-vertex-data": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten-vertex-data/-/flatten-vertex-data-1.0.2.tgz", + "integrity": "sha512-BvCBFK2NZqerFTdMDgqfHBwxYWnxeCkwONsw6PvBMcUXqo8U/KDWwmXhqx1x2kLIg7DqIsJfOaJFOmlua3Lxuw==", + "license": "MIT", + "peer": true, + "dependencies": { + "dtype": "^2.0.0" + } + }, + "node_modules/font-atlas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/font-atlas/-/font-atlas-2.1.0.tgz", + "integrity": "sha512-kP3AmvX+HJpW4w3d+PiPR2X6E1yvsBXt2yhuCw+yReO9F1WYhvZwx3c95DGZGwg9xYzDGrgJYa885xmVA+28Cg==", + "license": "MIT", + "peer": true, + "dependencies": { + "css-font": "^1.0.0" + } + }, + "node_modules/font-measure": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/font-measure/-/font-measure-1.2.2.tgz", + "integrity": "sha512-mRLEpdrWzKe9hbfaF3Qpr06TAjquuBVP5cHy4b3hyeNdjc9i0PO6HniGsX5vjL5OWv7+Bd++NiooNpT/s8BvIA==", + "license": "MIT", + "peer": true, + "dependencies": { + "css-font": "^1.2.0" + } + }, + "node_modules/fraction.js": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz", + "integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "license": "MIT", + "peer": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/geojson-vt": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz", + "integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==", + "license": "ISC", + "peer": true + }, + "node_modules/get-canvas-context": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-canvas-context/-/get-canvas-context-1.0.2.tgz", + "integrity": "sha512-LnpfLf/TNzr9zVOGiIY6aKCz8EKuXmlYNV7CM2pUjBa/B+c2I15tS7KLySep75+FuerJdmArvJLcsAXWEy2H0A==", + "license": "MIT", + "peer": true + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gl-mat4": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gl-mat4/-/gl-mat4-1.2.0.tgz", + "integrity": "sha512-sT5C0pwB1/e9G9AvAoLsoaJtbMGjfd/jfxo8jMCKqYYEnjZuFvqV5rehqar0538EmssjdDeiEWnKyBSTw7quoA==", + "license": "Zlib", + "peer": true + }, + "node_modules/gl-matrix": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", + "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==", + "license": "MIT", + "peer": true + }, + "node_modules/gl-text": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gl-text/-/gl-text-1.4.0.tgz", + "integrity": "sha512-o47+XBqLCj1efmuNyCHt7/UEJmB9l66ql7pnobD6p+sgmBUdzfMZXIF0zD2+KRfpd99DJN+QXdvTFAGCKCVSmQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "bit-twiddle": "^1.0.2", + "color-normalize": "^1.5.0", + "css-font": "^1.2.0", + "detect-kerning": "^2.1.2", + "es6-weak-map": "^2.0.3", + "flatten-vertex-data": "^1.0.2", + "font-atlas": "^2.1.0", + "font-measure": "^1.2.2", + "gl-util": "^3.1.2", + "is-plain-obj": "^1.1.0", + "object-assign": "^4.1.1", + "parse-rect": "^1.2.0", + "parse-unit": "^1.0.1", + "pick-by-alias": "^1.2.0", + "regl": "^2.0.0", + "to-px": "^1.0.1", + "typedarray-pool": "^1.1.0" + } + }, + "node_modules/gl-util": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/gl-util/-/gl-util-3.1.3.tgz", + "integrity": "sha512-dvRTggw5MSkJnCbh74jZzSoTOGnVYK+Bt+Ckqm39CVcl6+zSsxqWk4lr5NKhkqXHL6qvZAU9h17ZF8mIskY9mA==", + "license": "MIT", + "peer": true, + "dependencies": { + "is-browser": "^2.0.1", + "is-firefox": "^1.0.3", + "is-plain-obj": "^1.1.0", + "number-is-integer": "^1.0.1", + "object-assign": "^4.1.0", + "pick-by-alias": "^1.2.0", + "weak-map": "^1.0.5" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/global-prefix": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-4.0.0.tgz", + "integrity": "sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ini": "^4.1.3", + "kind-of": "^6.0.3", + "which": "^4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/glsl-inject-defines": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/glsl-inject-defines/-/glsl-inject-defines-1.0.3.tgz", + "integrity": "sha512-W49jIhuDtF6w+7wCMcClk27a2hq8znvHtlGnrYkSWEr8tHe9eA2dcnohlcAmxLYBSpSSdzOkRdyPTrx9fw49+A==", + "license": "MIT", + "peer": true, + "dependencies": { + "glsl-token-inject-block": "^1.0.0", + "glsl-token-string": "^1.0.1", + "glsl-tokenizer": "^2.0.2" + } + }, + "node_modules/glsl-resolve": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/glsl-resolve/-/glsl-resolve-0.0.1.tgz", + "integrity": "sha512-xxFNsfnhZTK9NBhzJjSBGX6IOqYpvBHxxmo+4vapiljyGNCY0Bekzn0firQkQrazK59c1hYxMDxYS8MDlhw4gA==", + "license": "MIT", + "peer": true, + "dependencies": { + "resolve": "^0.6.1", + "xtend": "^2.1.2" + } + }, + "node_modules/glsl-resolve/node_modules/resolve": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz", + "integrity": "sha512-UHBY3viPlJKf85YijDUcikKX6tmF4SokIDp518ZDVT92JNDcG5uKIthaT/owt3Sar0lwtOafsQuwrg22/v2Dwg==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-resolve/node_modules/xtend": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.2.0.tgz", + "integrity": "sha512-SLt5uylT+4aoXxXuwtQp5ZnMMzhDb1Xkg4pEqc00WUJCQifPfV9Ub1VrNhp9kXkrjZD2I2Hl8WnjP37jzZLPZw==", + "peer": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/glsl-token-assignments": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/glsl-token-assignments/-/glsl-token-assignments-2.0.2.tgz", + "integrity": "sha512-OwXrxixCyHzzA0U2g4btSNAyB2Dx8XrztY5aVUCjRSh4/D0WoJn8Qdps7Xub3sz6zE73W3szLrmWtQ7QMpeHEQ==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-defines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glsl-token-defines/-/glsl-token-defines-1.0.0.tgz", + "integrity": "sha512-Vb5QMVeLjmOwvvOJuPNg3vnRlffscq2/qvIuTpMzuO/7s5kT+63iL6Dfo2FYLWbzuiycWpbC0/KV0biqFwHxaQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "glsl-tokenizer": "^2.0.0" + } + }, + "node_modules/glsl-token-depth": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/glsl-token-depth/-/glsl-token-depth-1.1.2.tgz", + "integrity": "sha512-eQnIBLc7vFf8axF9aoi/xW37LSWd2hCQr/3sZui8aBJnksq9C7zMeUYHVJWMhFzXrBU7fgIqni4EhXVW4/krpg==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-descope": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glsl-token-descope/-/glsl-token-descope-1.0.2.tgz", + "integrity": "sha512-kS2PTWkvi/YOeicVjXGgX5j7+8N7e56srNDEHDTVZ1dcESmbmpmgrnpjPcjxJjMxh56mSXYoFdZqb90gXkGjQw==", + "license": "MIT", + "peer": true, + "dependencies": { + "glsl-token-assignments": "^2.0.0", + "glsl-token-depth": "^1.1.0", + "glsl-token-properties": "^1.0.0", + "glsl-token-scope": "^1.1.0" + } + }, + "node_modules/glsl-token-inject-block": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/glsl-token-inject-block/-/glsl-token-inject-block-1.1.0.tgz", + "integrity": "sha512-q/m+ukdUBuHCOtLhSr0uFb/qYQr4/oKrPSdIK2C4TD+qLaJvqM9wfXIF/OOBjuSA3pUoYHurVRNao6LTVVUPWA==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-properties": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/glsl-token-properties/-/glsl-token-properties-1.0.1.tgz", + "integrity": "sha512-dSeW1cOIzbuUoYH0y+nxzwK9S9O3wsjttkq5ij9ZGw0OS41BirKJzzH48VLm8qLg+au6b0sINxGC0IrGwtQUcA==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-scope": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/glsl-token-scope/-/glsl-token-scope-1.1.2.tgz", + "integrity": "sha512-YKyOMk1B/tz9BwYUdfDoHvMIYTGtVv2vbDSLh94PT4+f87z21FVdou1KNKgF+nECBTo0fJ20dpm0B1vZB1Q03A==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/glsl-token-string/-/glsl-token-string-1.0.1.tgz", + "integrity": "sha512-1mtQ47Uxd47wrovl+T6RshKGkRRCYWhnELmkEcUAPALWGTFe2XZpH3r45XAwL2B6v+l0KNsCnoaZCSnhzKEksg==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-whitespace-trim": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glsl-token-whitespace-trim/-/glsl-token-whitespace-trim-1.0.0.tgz", + "integrity": "sha512-ZJtsPut/aDaUdLUNtmBYhaCmhIjpKNg7IgZSfX5wFReMc2vnj8zok+gB/3Quqs0TsBSX/fGnqUUYZDqyuc2xLQ==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-tokenizer": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz", + "integrity": "sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA==", + "license": "MIT", + "peer": true, + "dependencies": { + "through2": "^0.6.3" + } + }, + "node_modules/glsl-tokenizer/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-tokenizer/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "license": "MIT", + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/glsl-tokenizer/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-tokenizer/node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==", + "license": "MIT", + "peer": true, + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/glslify": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glslify/-/glslify-7.1.1.tgz", + "integrity": "sha512-bud98CJ6kGZcP9Yxcsi7Iz647wuDz3oN+IZsjCRi5X1PI7t/xPKeL0mOwXJjo+CRZMqvq0CkSJiywCcY7kVYog==", + "license": "MIT", + "peer": true, + "dependencies": { + "bl": "^2.2.1", + "concat-stream": "^1.5.2", + "duplexify": "^3.4.5", + "falafel": "^2.1.0", + "from2": "^2.3.0", + "glsl-resolve": "0.0.1", + "glsl-token-whitespace-trim": "^1.0.0", + "glslify-bundle": "^5.0.0", + "glslify-deps": "^1.2.5", + "minimist": "^1.2.5", + "resolve": "^1.1.5", + "stack-trace": "0.0.9", + "static-eval": "^2.0.5", + "through2": "^2.0.1", + "xtend": "^4.0.0" + }, + "bin": { + "glslify": "bin.js" + } + }, + "node_modules/glslify-bundle": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glslify-bundle/-/glslify-bundle-5.1.1.tgz", + "integrity": "sha512-plaAOQPv62M1r3OsWf2UbjN0hUYAB7Aph5bfH58VxJZJhloRNbxOL9tl/7H71K7OLJoSJ2ZqWOKk3ttQ6wy24A==", + "license": "MIT", + "peer": true, + "dependencies": { + "glsl-inject-defines": "^1.0.1", + "glsl-token-defines": "^1.0.0", + "glsl-token-depth": "^1.1.1", + "glsl-token-descope": "^1.0.2", + "glsl-token-scope": "^1.1.1", + "glsl-token-string": "^1.0.1", + "glsl-token-whitespace-trim": "^1.0.0", + "glsl-tokenizer": "^2.0.2", + "murmurhash-js": "^1.0.0", + "shallow-copy": "0.0.1" + } + }, + "node_modules/glslify-deps": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/glslify-deps/-/glslify-deps-1.3.2.tgz", + "integrity": "sha512-7S7IkHWygJRjcawveXQjRXLO2FTjijPDYC7QfZyAQanY+yGLCFHYnPtsGT9bdyHiwPTw/5a1m1M9hamT2aBpag==", + "license": "ISC", + "peer": true, + "dependencies": { + "@choojs/findup": "^0.2.0", + "events": "^3.2.0", + "glsl-resolve": "0.0.1", + "glsl-tokenizer": "^2.0.0", + "graceful-fs": "^4.1.2", + "inherits": "^2.0.1", + "map-limit": "0.0.1", + "resolve": "^1.0.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/grid-index": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.1.0.tgz", + "integrity": "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==", + "license": "ISC", + "peer": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-hover": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-hover/-/has-hover-1.0.1.tgz", + "integrity": "sha512-0G6w7LnlcpyDzpeGUTuT0CEw05+QlMuGVk1IHNAlHrGJITGodjZu3x8BNDUMfKJSZXNB2ZAclqc1bvrd+uUpfg==", + "license": "MIT", + "peer": true, + "dependencies": { + "is-browser": "^2.0.1" + } + }, + "node_modules/has-passive-events": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-passive-events/-/has-passive-events-1.0.0.tgz", + "integrity": "sha512-2vSj6IeIsgvsRMyeQ0JaCX5Q3lX4zMn5HpoVc7MEhQ6pv8Iq9rsXjsp+E5ZwaT7T0xhMT0KmU8gtt1EFVdbJiw==", + "license": "MIT", + "peer": true, + "dependencies": { + "is-browser": "^2.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hsluv": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/hsluv/-/hsluv-0.0.3.tgz", + "integrity": "sha512-08iL2VyCRbkQKBySkSh6m8zMUa3sADAxGVWs3Z1aPcUkTJeK0ETG4Fc27tEmQBGUAXZjIsXOZqBvacuVNSC/fQ==", + "license": "MIT", + "peer": true + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "license": "ISC", + "peer": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC", + "peer": true + }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/is-browser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-browser/-/is-browser-2.1.0.tgz", + "integrity": "sha512-F5rTJxDQ2sW81fcfOR1GnCXT6sVJC104fCyfj+mjpwNEwaPYSn5fte5jiHmBg3DHsIoL/l8Kvw5VN5SsTRcRFQ==", + "license": "MIT", + "peer": true + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-firefox": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-firefox/-/is-firefox-1.0.3.tgz", + "integrity": "sha512-6Q9ITjvWIm0Xdqv+5U12wgOKEM2KoBw4Y926m0OFkvlCxnbG94HKAsVz8w3fWcfAS5YA2fJORXX1dLrkprCCxA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-iexplorer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-iexplorer/-/is-iexplorer-1.0.0.tgz", + "integrity": "sha512-YeLzceuwg3K6O0MLM3UyUUjKAlyULetwryFp1mHy1I5PfArK0AEqlfa+MR4gkJjcbuJXoDJCvXbyqZVf5CR2Sg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-mobile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-mobile/-/is-mobile-4.0.0.tgz", + "integrity": "sha512-mlcHZA84t1qLSuWkt2v0I2l61PYdyQDt4aG1mLIXF5FDMm4+haBCxCPYSr/uwqQNRk1MiTizn0ypEuRAOLRAew==", + "license": "MIT", + "peer": true + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-string-blank": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-string-blank/-/is-string-blank-1.0.1.tgz", + "integrity": "sha512-9H+ZBCVs3L9OYqv8nuUAzpcT9OTgMD1yAWrG7ihlnibdkbtB850heAmYWxHuXc4CHy4lKeK69tN+ny1K7gBIrw==", + "license": "MIT", + "peer": true + }, + "node_modules/is-svg-path": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-svg-path/-/is-svg-path-1.0.2.tgz", + "integrity": "sha512-Lj4vePmqpPR1ZnRctHv8ltSh1OrSxHkhUkd7wi+VQdcdP15/KvQFyk7LhNuM7ZW0EVbJz8kZLVmL9quLrfq4Kg==", + "license": "MIT", + "peer": true + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT", + "peer": true + }, + "node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT", + "peer": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT", + "peer": true + }, + "node_modules/json-stringify-pretty-compact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", + "license": "MIT", + "peer": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==", + "license": "ISC", + "peer": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT", + "peer": true + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/map-limit": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/map-limit/-/map-limit-0.0.1.tgz", + "integrity": "sha512-pJpcfLPnIF/Sk3taPW21G/RQsEEirGaFpCW3oXRwH9dnFHPHNGjNyvh++rdmC2fNqEaTw2MhYJraoJWAHx8kEg==", + "license": "MIT", + "peer": true, + "dependencies": { + "once": "~1.3.0" + } + }, + "node_modules/map-limit/node_modules/once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==", + "license": "ISC", + "peer": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/mapbox-gl": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-1.13.3.tgz", + "integrity": "sha512-p8lJFEiqmEQlyv+DQxFAOG/XPWN0Wp7j/Psq93Zywz7qt9CcUKFYDBOoOEKzqe6gudHVJY8/Bhqw6VDpX2lSBg==", + "license": "SEE LICENSE IN LICENSE.txt", + "peer": true, + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.2", + "@mapbox/geojson-types": "^1.0.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/mapbox-gl-supported": "^1.5.0", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^1.1.1", + "@mapbox/unitbezier": "^0.0.0", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "csscolorparser": "~1.0.3", + "earcut": "^2.2.2", + "geojson-vt": "^3.2.1", + "gl-matrix": "^3.2.1", + "grid-index": "^1.1.0", + "murmurhash-js": "^1.0.0", + "pbf": "^3.2.1", + "potpack": "^1.0.1", + "quickselect": "^2.0.0", + "rw": "^1.3.3", + "supercluster": "^7.1.0", + "tinyqueue": "^2.0.3", + "vt-pbf": "^3.1.1" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/maplibre-gl": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.7.1.tgz", + "integrity": "sha512-lgL7XpIwsgICiL82ITplfS7IGwrB1OJIw/pCvprDp2dhmSSEBgmPzYRvwYYYvJGJD7fxUv1Tvpih4nZ6VrLuaA==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^2.0.6", + "@mapbox/unitbezier": "^0.0.1", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "@maplibre/maplibre-gl-style-spec": "^20.3.1", + "@types/geojson": "^7946.0.14", + "@types/geojson-vt": "3.2.5", + "@types/mapbox__point-geometry": "^0.1.4", + "@types/mapbox__vector-tile": "^1.3.4", + "@types/pbf": "^3.0.5", + "@types/supercluster": "^7.1.3", + "earcut": "^3.0.0", + "geojson-vt": "^4.0.2", + "gl-matrix": "^3.4.3", + "global-prefix": "^4.0.0", + "kdbush": "^4.0.2", + "murmurhash-js": "^1.0.0", + "pbf": "^3.3.0", + "potpack": "^2.0.0", + "quickselect": "^3.0.0", + "supercluster": "^8.0.1", + "tinyqueue": "^3.0.0", + "vt-pbf": "^3.1.3" + }, + "engines": { + "node": ">=16.14.0", + "npm": ">=8.1.0" + }, + "funding": { + "url": "https://github.com/maplibre/maplibre-gl-js?sponsor=1" + } + }, + "node_modules/maplibre-gl/node_modules/@mapbox/tiny-sdf": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz", + "integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/@mapbox/unitbezier": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/earcut": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.1.tgz", + "integrity": "sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw==", + "license": "ISC", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/geojson-vt": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz", + "integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==", + "license": "ISC", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/potpack": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz", + "integrity": "sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==", + "license": "ISC", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/quickselect": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", + "license": "ISC", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "license": "ISC", + "peer": true, + "dependencies": { + "kdbush": "^4.0.2" + } + }, + "node_modules/maplibre-gl/node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "license": "ISC", + "peer": true + }, + "node_modules/math-log2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-log2/-/math-log2-1.0.1.tgz", + "integrity": "sha512-9W0yGtkaMAkf74XGYVy4Dqw3YUMnTNB2eeiw9aQbUl4A3KmuCEHTt2DgAB07ENzOYAjsYSAYufkAq0Zd+jU7zA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mathjs": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-11.12.0.tgz", + "integrity": "sha512-UGhVw8rS1AyedyI55DGz9q1qZ0p98kyKPyc9vherBkoueLntPfKtPBh14x+V4cdUWK0NZV2TBwqRFlvadscSuw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.23.2", + "complex.js": "^2.1.1", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "4.3.4", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.1.1" + }, + "bin": { + "mathjs": "bin/cli.js" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mouse-change": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/mouse-change/-/mouse-change-1.4.0.tgz", + "integrity": "sha512-vpN0s+zLL2ykyyUDh+fayu9Xkor5v/zRD9jhSqjRS1cJTGS0+oakVZzNm5n19JvvEj0you+MXlYTpNxUDQUjkQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "mouse-event": "^1.0.0" + } + }, + "node_modules/mouse-event": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/mouse-event/-/mouse-event-1.0.5.tgz", + "integrity": "sha512-ItUxtL2IkeSKSp9cyaX2JLUuKk2uMoxBg4bbOWVd29+CskYJR9BGsUqtXenNzKbnDshvupjUewDIYVrOB6NmGw==", + "license": "MIT", + "peer": true + }, + "node_modules/mouse-event-offset": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mouse-event-offset/-/mouse-event-offset-3.0.2.tgz", + "integrity": "sha512-s9sqOs5B1Ykox3Xo8b3Ss2IQju4UwlW6LSR+Q5FXWpprJ5fzMLefIIItr3PH8RwzfGy6gxs/4GAmiNuZScE25w==", + "license": "MIT", + "peer": true + }, + "node_modules/mouse-wheel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mouse-wheel/-/mouse-wheel-1.2.0.tgz", + "integrity": "sha512-+OfYBiUOCTWcTECES49neZwL5AoGkXE+lFjIvzwNCnYRlso+EnfvovcBxGoyQ0yQt806eSPjS675K0EwWknXmw==", + "license": "MIT", + "peer": true, + "dependencies": { + "right-now": "^1.0.0", + "signum": "^1.0.0", + "to-px": "^1.0.1" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT", + "peer": true + }, + "node_modules/mumath": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/mumath/-/mumath-3.3.4.tgz", + "integrity": "sha512-VAFIOG6rsxoc7q/IaY3jdjmrsuX9f15KlRLYTHmixASBZkZEKC1IFqE2BC5CdhXmK6WLM1Re33z//AGmeRI6FA==", + "deprecated": "Redundant dependency in your project.", + "license": "Unlicense", + "peer": true, + "dependencies": { + "almost-equal": "^1.1.0" + } + }, + "node_modules/murmurhash-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==", + "license": "MIT", + "peer": true + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg==", + "license": "MIT", + "peer": true + }, + "node_modules/needle": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", + "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT", + "peer": true + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "license": "ISC", + "peer": true + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "license": "MIT", + "peer": true + }, + "node_modules/normalize-svg-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-0.1.0.tgz", + "integrity": "sha512-1/kmYej2iedi5+ROxkRESL/pI02pkg0OBnaR4hJkSIX6+ORzepwbuUXfrdZaPjysTsJInj0Rj5NuX027+dMBvA==", + "license": "MIT", + "peer": true + }, + "node_modules/number-is-integer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-integer/-/number-is-integer-1.0.1.tgz", + "integrity": "sha512-Dq3iuiFBkrbmuQjGFFF3zckXNCQoSD37/SdSbgcBailUx6knDvDwb5CympBgcoWHy36sfS12u74MHYkXyHq6bg==", + "license": "MIT", + "peer": true, + "dependencies": { + "is-finite": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "peer": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parenthesis": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/parenthesis/-/parenthesis-3.1.8.tgz", + "integrity": "sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw==", + "license": "MIT", + "peer": true + }, + "node_modules/parse-rect": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parse-rect/-/parse-rect-1.2.0.tgz", + "integrity": "sha512-4QZ6KYbnE6RTwg9E0HpLchUM9EZt6DnDxajFZZDSV4p/12ZJEvPO702DZpGvRYEPo00yKDys7jASi+/w7aO8LA==", + "license": "MIT", + "peer": true, + "dependencies": { + "pick-by-alias": "^1.2.0" + } + }, + "node_modules/parse-svg-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz", + "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==", + "license": "MIT", + "peer": true + }, + "node_modules/parse-unit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-unit/-/parse-unit-1.0.1.tgz", + "integrity": "sha512-hrqldJHokR3Qj88EIlV/kAyAi/G5R2+R56TBANxNMy0uPlYcttx0jnMW6Yx5KsKPSbC3KddM/7qQm3+0wEXKxg==", + "license": "MIT", + "peer": true + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/pbf": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.3.0.tgz", + "integrity": "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT", + "peer": true + }, + "node_modules/pick-by-alias": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pick-by-alias/-/pick-by-alias-1.2.0.tgz", + "integrity": "sha512-ESj2+eBxhGrcA1azgHs7lARG5+5iLakc/6nlfbpjcLl00HuuUOIuORhYXN4D1HfvMSKuVtFQjAlnwi1JHEeDIw==", + "license": "MIT", + "peer": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/plotly.js": { + "version": "2.35.3", + "resolved": "https://registry.npmjs.org/plotly.js/-/plotly.js-2.35.3.tgz", + "integrity": "sha512-7RaC6FxmCUhpD6H4MpD+QLUu3hCn76I11rotRefrh3m1iDvWqGnVqVk9dSaKmRAhFD3vsNsYea0OxnR1rc2IzQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@plotly/d3": "3.8.2", + "@plotly/d3-sankey": "0.7.2", + "@plotly/d3-sankey-circular": "0.33.1", + "@plotly/mapbox-gl": "1.13.4", + "@turf/area": "^7.1.0", + "@turf/bbox": "^7.1.0", + "@turf/centroid": "^7.1.0", + "base64-arraybuffer": "^1.0.2", + "canvas-fit": "^1.5.0", + "color-alpha": "1.0.4", + "color-normalize": "1.5.0", + "color-parse": "2.0.0", + "color-rgba": "2.1.1", + "country-regex": "^1.1.0", + "css-loader": "^7.1.2", + "d3-force": "^1.2.1", + "d3-format": "^1.4.5", + "d3-geo": "^1.12.1", + "d3-geo-projection": "^2.9.0", + "d3-hierarchy": "^1.1.9", + "d3-interpolate": "^3.0.1", + "d3-time": "^1.1.0", + "d3-time-format": "^2.2.3", + "fast-isnumeric": "^1.1.4", + "gl-mat4": "^1.2.0", + "gl-text": "^1.4.0", + "has-hover": "^1.0.1", + "has-passive-events": "^1.0.0", + "is-mobile": "^4.0.0", + "maplibre-gl": "^4.5.2", + "mouse-change": "^1.4.0", + "mouse-event-offset": "^3.0.2", + "mouse-wheel": "^1.2.0", + "native-promise-only": "^0.8.1", + "parse-svg-path": "^0.1.2", + "point-in-polygon": "^1.1.0", + "polybooljs": "^1.2.2", + "probe-image-size": "^7.2.3", + "regl": "npm:@plotly/regl@^2.1.2", + "regl-error2d": "^2.0.12", + "regl-line2d": "^3.1.3", + "regl-scatter2d": "^3.3.1", + "regl-splom": "^1.0.14", + "strongly-connected-components": "^1.0.1", + "style-loader": "^4.0.0", + "superscript-text": "^1.0.0", + "svg-path-sdf": "^1.1.3", + "tinycolor2": "^1.4.2", + "to-px": "1.0.1", + "topojson-client": "^3.1.0", + "webgl-context": "^2.2.0", + "world-calendars": "^1.0.3" + } + }, + "node_modules/point-in-polygon": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.1.0.tgz", + "integrity": "sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw==", + "license": "MIT", + "peer": true + }, + "node_modules/polybooljs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/polybooljs/-/polybooljs-1.2.2.tgz", + "integrity": "sha512-ziHW/02J0XuNuUtmidBc6GXE8YohYydp3DWPWXYsd7O721TjcmN+k6ezjdwkDqep+gnWnFY+yqZHvzElra2oCg==", + "license": "MIT", + "peer": true + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "license": "ISC", + "peer": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "license": "MIT", + "peer": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "license": "ISC", + "peer": true, + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "license": "ISC", + "peer": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "peer": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT", + "peer": true + }, + "node_modules/potpack": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", + "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==", + "license": "ISC", + "peer": true + }, + "node_modules/probe-image-size": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.2.3.tgz", + "integrity": "sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==", + "license": "MIT", + "peer": true, + "dependencies": { + "lodash.merge": "^4.6.2", + "needle": "^2.5.2", + "stream-parser": "~0.3.1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT", + "peer": true + }, + "node_modules/protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==", + "license": "MIT", + "peer": true + }, + "node_modules/quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==", + "license": "ISC", + "peer": true + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "license": "MIT", + "peer": true, + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT", + "peer": true + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT", + "peer": true + }, + "node_modules/regl": { + "name": "@plotly/regl", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@plotly/regl/-/regl-2.1.2.tgz", + "integrity": "sha512-Mdk+vUACbQvjd0m/1JJjOOafmkp/EpmHjISsopEz5Av44CBq7rPC05HHNbYGKVyNUF2zmEoBS/TT0pd0SPFFyw==", + "license": "MIT", + "peer": true + }, + "node_modules/regl-error2d": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/regl-error2d/-/regl-error2d-2.0.12.tgz", + "integrity": "sha512-r7BUprZoPO9AbyqM5qlJesrSRkl+hZnVKWKsVp7YhOl/3RIpi4UDGASGJY0puQ96u5fBYw/OlqV24IGcgJ0McA==", + "license": "MIT", + "peer": true, + "dependencies": { + "array-bounds": "^1.0.1", + "color-normalize": "^1.5.0", + "flatten-vertex-data": "^1.0.2", + "object-assign": "^4.1.1", + "pick-by-alias": "^1.2.0", + "to-float32": "^1.1.0", + "update-diff": "^1.1.0" + } + }, + "node_modules/regl-line2d": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/regl-line2d/-/regl-line2d-3.1.3.tgz", + "integrity": "sha512-fkgzW+tTn4QUQLpFKsUIE0sgWdCmXAM3ctXcCgoGBZTSX5FE2A0M7aynz7nrZT5baaftLrk9te54B+MEq4QcSA==", + "license": "MIT", + "peer": true, + "dependencies": { + "array-bounds": "^1.0.1", + "array-find-index": "^1.0.2", + "array-normalize": "^1.1.4", + "color-normalize": "^1.5.0", + "earcut": "^2.1.5", + "es6-weak-map": "^2.0.3", + "flatten-vertex-data": "^1.0.2", + "object-assign": "^4.1.1", + "parse-rect": "^1.2.0", + "pick-by-alias": "^1.2.0", + "to-float32": "^1.1.0" + } + }, + "node_modules/regl-scatter2d": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/regl-scatter2d/-/regl-scatter2d-3.3.1.tgz", + "integrity": "sha512-seOmMIVwaCwemSYz/y4WE0dbSO9svNFSqtTh5RE57I7PjGo3tcUYKtH0MTSoshcAsreoqN8HoCtnn8wfHXXfKQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@plotly/point-cluster": "^3.1.9", + "array-range": "^1.0.1", + "array-rearrange": "^2.2.2", + "clamp": "^1.0.1", + "color-id": "^1.1.0", + "color-normalize": "^1.5.0", + "color-rgba": "^2.1.1", + "flatten-vertex-data": "^1.0.2", + "glslify": "^7.0.0", + "is-iexplorer": "^1.0.0", + "object-assign": "^4.1.1", + "parse-rect": "^1.2.0", + "pick-by-alias": "^1.2.0", + "to-float32": "^1.1.0", + "update-diff": "^1.1.0" + } + }, + "node_modules/regl-splom": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/regl-splom/-/regl-splom-1.0.14.tgz", + "integrity": "sha512-OiLqjmPRYbd7kDlHC6/zDf6L8lxgDC65BhC8JirhP4ykrK4x22ZyS+BnY8EUinXKDeMgmpRwCvUmk7BK4Nweuw==", + "license": "MIT", + "peer": true, + "dependencies": { + "array-bounds": "^1.0.1", + "array-range": "^1.0.1", + "color-alpha": "^1.0.4", + "flatten-vertex-data": "^1.0.2", + "parse-rect": "^1.2.0", + "pick-by-alias": "^1.2.0", + "raf": "^3.4.1", + "regl-scatter2d": "^3.2.3" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, + "node_modules/right-now": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/right-now/-/right-now-1.0.0.tgz", + "integrity": "sha512-DA8+YS+sMIVpbsuKgy+Z67L9Lxb1p05mNxRpDPNksPDEFir4vmBlUtuN9jkTGn9YMMdlBuK7XQgFiz6ws+yhSg==", + "license": "MIT", + "peer": true + }, + "node_modules/rollup": { + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "dev": true, + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-plugin-typescript2": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.36.0.tgz", + "integrity": "sha512-NB2CSQDxSe9+Oe2ahZbf+B4bh7pHwjV5L+RSYpCu7Q5ROuN94F9b6ioWwKfz3ueL3KTtmX4o2MUH2cgHDIEUsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^4.1.2", + "find-cache-dir": "^3.3.2", + "fs-extra": "^10.0.0", + "semver": "^7.5.4", + "tslib": "^2.6.2" + }, + "peerDependencies": { + "rollup": ">=1.26.3", + "typescript": ">=2.4.0" + } + }, + "node_modules/rollup-plugin-typescript2/node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/rollup-plugin-typescript2/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT", + "peer": true + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC", + "peer": true + }, + "node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shallow-copy": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", + "integrity": "sha512-b6i4ZpVuUxB9h5gfCxPiusKYkqTMOjEbBs4wMaFbkfia4yFv92UKZ6Df8WXcKbn08JNL/abvg3FnMAOfakDvUw==", + "license": "MIT", + "peer": true + }, + "node_modules/signum": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/signum/-/signum-1.0.0.tgz", + "integrity": "sha512-yodFGwcyt59XRh7w5W3jPcIQb3Bwi21suEfT7MAWnBX3iCdklJpgDgvGT9o04UonglZN5SNMfJFkHIR/jO8GHw==", + "license": "MIT", + "peer": true + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/stack-trace": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", + "integrity": "sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==", + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/static-eval": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.1.tgz", + "integrity": "sha512-MgWpQ/ZjGieSVB3eOJVs4OA2LT/q1vx98KPCTTQPzq/aLr0YUXTsgryTXr4SLfR0ZfUUCiedM9n/ABeDIyy4mA==", + "license": "MIT", + "peer": true, + "dependencies": { + "escodegen": "^2.1.0" + } + }, + "node_modules/stream-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", + "integrity": "sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "2" + } + }, + "node_modules/stream-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/stream-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT", + "peer": true + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "license": "MIT", + "peer": true + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT", + "peer": true + }, + "node_modules/string-split-by": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string-split-by/-/string-split-by-1.0.0.tgz", + "integrity": "sha512-KaJKY+hfpzNyet/emP81PJA9hTVSfxNLS9SFTWxdCnnW1/zOOwiV248+EfoX7IQFcBaOp4G5YE6xTJMF+pLg6A==", + "license": "MIT", + "peer": true, + "dependencies": { + "parenthesis": "^3.1.5" + } + }, + "node_modules/strongly-connected-components": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strongly-connected-components/-/strongly-connected-components-1.0.1.tgz", + "integrity": "sha512-i0TFx4wPcO0FwX+4RkLJi1MxmcTv90jNZgxMu9XRnMXMeFUY1VJlIoXpZunPUvUUqbCT1pg5PEkFqqpcaElNaA==", + "license": "MIT", + "peer": true + }, + "node_modules/style-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", + "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.27.0" + } + }, + "node_modules/supercluster": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.5.tgz", + "integrity": "sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==", + "license": "ISC", + "peer": true, + "dependencies": { + "kdbush": "^3.0.0" + } + }, + "node_modules/supercluster/node_modules/kdbush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz", + "integrity": "sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew==", + "license": "ISC", + "peer": true + }, + "node_modules/superscript-text": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/superscript-text/-/superscript-text-1.0.0.tgz", + "integrity": "sha512-gwu8l5MtRZ6koO0icVTlmN5pm7Dhh1+Xpe9O4x6ObMAsW+3jPbW14d1DsBq1F4wiI+WOFjXF35pslgec/G8yCQ==", + "license": "MIT", + "peer": true + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-arc-to-cubic-bezier": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz", + "integrity": "sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g==", + "license": "ISC", + "peer": true + }, + "node_modules/svg-path-bounds": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/svg-path-bounds/-/svg-path-bounds-1.0.2.tgz", + "integrity": "sha512-H4/uAgLWrppIC0kHsb2/dWUYSmb4GE5UqH06uqWBcg6LBjX2fu0A8+JrO2/FJPZiSsNOKZAhyFFgsLTdYUvSqQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "abs-svg-path": "^0.1.1", + "is-svg-path": "^1.0.1", + "normalize-svg-path": "^1.0.0", + "parse-svg-path": "^0.1.2" + } + }, + "node_modules/svg-path-bounds/node_modules/normalize-svg-path": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-1.1.0.tgz", + "integrity": "sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==", + "license": "MIT", + "peer": true, + "dependencies": { + "svg-arc-to-cubic-bezier": "^3.0.0" + } + }, + "node_modules/svg-path-sdf": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/svg-path-sdf/-/svg-path-sdf-1.1.3.tgz", + "integrity": "sha512-vJJjVq/R5lSr2KLfVXVAStktfcfa1pNFjFOgyJnzZFXlO/fDZ5DmM8FpnSKKzLPfEYTVeXuVBTHF296TpxuJVg==", + "license": "MIT", + "peer": true, + "dependencies": { + "bitmap-sdf": "^1.0.0", + "draw-svg-path": "^1.0.0", + "is-svg-path": "^1.0.1", + "parse-svg-path": "^0.1.2", + "svg-path-bounds": "^1.0.1" + } + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.39.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.2.tgz", + "integrity": "sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "license": "MIT", + "peer": true + }, + "node_modules/tinyqueue": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", + "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==", + "license": "ISC", + "peer": true + }, + "node_modules/to-float32": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/to-float32/-/to-float32-1.1.0.tgz", + "integrity": "sha512-keDnAusn/vc+R3iEiSDw8TOF7gPiTLdK1ArvWtYbJQiVfmRg6i/CAvbKq3uIS0vWroAC7ZecN3DjQKw3aSklUg==", + "license": "MIT", + "peer": true + }, + "node_modules/to-px": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-px/-/to-px-1.0.1.tgz", + "integrity": "sha512-2y3LjBeIZYL19e5gczp14/uRWFDtDUErJPVN3VU9a7SJO+RjGRtYR47aMN2bZgGlxvW4ZcEz2ddUPVHXcMfuXw==", + "license": "MIT", + "peer": true, + "dependencies": { + "parse-unit": "^1.0.1" + } + }, + "node_modules/topojson-client": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", + "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", + "license": "ISC", + "peer": true, + "dependencies": { + "commander": "2" + }, + "bin": { + "topo2geo": "bin/topo2geo", + "topomerge": "bin/topomerge", + "topoquantize": "bin/topoquantize" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", + "license": "ISC", + "peer": true + }, + "node_modules/typed-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz", + "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT", + "peer": true + }, + "node_modules/typedarray-pool": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typedarray-pool/-/typedarray-pool-1.2.0.tgz", + "integrity": "sha512-YTSQbzX43yvtpfRtIDAYygoYtgT+Rpjuxy9iOpczrjpXLgGoyG7aS5USJXV2d3nn8uHTeb9rXDvzS27zUg5KYQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "bit-twiddle": "^1.0.0", + "dup": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", + "license": "MIT", + "peer": true + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-diff/-/update-diff-1.1.0.tgz", + "integrity": "sha512-rCiBPiHxZwT4+sBhEbChzpO5hYHjm91kScWgdHf4Qeafs6Ba7MBl+d9GlGv72bcTZQO0sLmtQS1pHSWoCLtN/A==", + "license": "MIT", + "peer": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT", + "peer": true + }, + "node_modules/vt-pbf": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", + "integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@mapbox/point-geometry": "0.1.0", + "@mapbox/vector-tile": "^1.3.1", + "pbf": "^3.2.1" + } + }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "license": "MIT", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/weak-map": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.8.tgz", + "integrity": "sha512-lNR9aAefbGPpHO7AEnY0hCFjz1eTkWCXYvkTRrTHs9qv8zJp+SkVYpzfLIFXQQiG3tVvbNFQgVg2bQS8YGgxyw==", + "license": "Apache-2.0", + "peer": true + }, + "node_modules/webgl-context": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webgl-context/-/webgl-context-2.2.0.tgz", + "integrity": "sha512-q/fGIivtqTT7PEoF07axFIlHNk/XCPaYpq64btnepopSWvKNFkoORlQYgqDigBIuGA1ExnFd/GnSUnBNEPQY7Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "get-canvas-context": "^1.0.1" + } + }, + "node_modules/webpack": { + "version": "5.99.9", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", + "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "license": "ISC", + "peer": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/world-calendars": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/world-calendars/-/world-calendars-1.0.3.tgz", + "integrity": "sha512-sAjLZkBnsbHkHWVhrsCU5Sa/EVuf9QqgvrN8zyJ2L/F9FR9Oc6CvVK0674+PGAtmmmYQMH98tCUSO4QLQv3/TQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "object-assign": "^4.1.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC", + "peer": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..418a144 --- /dev/null +++ b/package.json @@ -0,0 +1,60 @@ +{ + "name": "feascript", + "version": "0.1.1", + "description": "A lightweight finite element simulation library built in JavaScript for browser-based physics and engineering simulations", + "main": "dist/feascript.cjs.js", + "module": "dist/feascript.esm.js", + "browser": "dist/feascript.umd.js", + "exports": { + "import": "./dist/feascript.esm.js", + "require": "./dist/feascript.cjs.js" + }, + "files": [ + "dist", + "src" + ], + "types": "dist/types/index.d.ts", + "directories": { + "example": "examples" + }, + "scripts": { + "build": "rollup -c", + "prepublishOnly": "npm run build", + "test": "echo \"No tests configured\" && exit 0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/FEAScript/FEAScript-core.git" + }, + "keywords": [ + "finite element", + "simulation", + "javascript", + "web", + "FEA", + "FEM", + "finite element analysis", + "finite element method" + ], + "author": "Nikolaos Chamakos", + "license": "MIT", + "type": "module", + "bugs": { + "url": "https://github.com/FEAScript/FEAScript-core/issues" + }, + "homepage": "https://github.com/FEAScript/FEAScript-core#readme", + "peerDependencies": { + "mathjs": "^11.12.0", + "plotly.js": "^2.27.0" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^28.0.3", + "@rollup/plugin-node-resolve": "^16.0.1", + "@types/estree": "^1.0.7", + "mathjs": "^11.12.0", + "rollup": "^2.79.2", + "rollup-plugin-terser": "^7.0.2", + "rollup-plugin-typescript2": "^0.36.0", + "typescript": "^5.8.3" + } +} diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..445e8b3 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,39 @@ +import resolve from "@rollup/plugin-node-resolve"; +import commonjs from "@rollup/plugin-commonjs"; +import { terser } from "rollup-plugin-terser"; + +export default { + input: "src/index.js", + output: [ + { + file: "dist/feascript.cjs.js", + format: "cjs", + sourcemap: true, + + }, + { + file: "dist/feascript.esm.js", + format: "esm", + sourcemap: true, + }, + { + file: "dist/feascript.umd.js", + format: "umd", + name: "FEAScript", + sourcemap: true, + globals: { + mathjs: "math", + "plotly.js": "Plotly" + }, + }, + ], + plugins: [ + resolve({ + browser: true, + preferBuiltins: false, + }), + commonjs(), + terser(), + ], + external: ["mathjs", "plotly.js"], +}; diff --git a/src/index.js b/src/index.js index 5d709fd..c836d38 100644 --- a/src/index.js +++ b/src/index.js @@ -13,3 +13,4 @@ export { importGmshQuadTri } from "./readers/gmshReaderScript.js"; export { logSystem, printVersion } from "./utilities/loggingScript.js"; export { plotSolution } from "./visualization/plotSolutionScript.js"; export { FEAScriptWorker } from "./workers/workerScript.js"; +export const VERSION = "0.1.1"; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..3107ac8 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "outDir": "./dist", + "rootDir": "./src", + "allowJs": true, + "declaration": true, + "declarationDir": "./dist/types", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "lib": [ + "ES2020", + "DOM", + "DOM.Iterable", + "WebWorker", + "ESNext.AsyncIterable" + ], + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test"] +} From 261a474c11125770a9aed3723cbcbfec3d0c4091 Mon Sep 17 00:00:00 2001 From: nikoscham Date: Thu, 22 May 2025 13:29:30 +0300 Subject: [PATCH 3/6] Update author and contributors information in package.json --- package.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 418a144..9430b03 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,13 @@ "finite element analysis", "finite element method" ], - "author": "Nikolaos Chamakos", + "author": "Nikolaos Chamakos (https://www.npmjs.com/~nikoscham)", + "contributors": [ + { + "name": "sridhar-mani", + "url": "https://www.npmjs.com/~sridhar-mani" + } + ], "license": "MIT", "type": "module", "bugs": { From 21abdee3a0e386fb1fe8df57da9115ca7b7308e5 Mon Sep 17 00:00:00 2001 From: nikoscham Date: Thu, 22 May 2025 13:59:12 +0300 Subject: [PATCH 4/6] Add publishConfig to package.json for public access --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 9430b03..94de51e 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,9 @@ "url": "https://github.com/FEAScript/FEAScript-core/issues" }, "homepage": "https://github.com/FEAScript/FEAScript-core#readme", + "publishConfig": { + "access": "public" + }, "peerDependencies": { "mathjs": "^11.12.0", "plotly.js": "^2.27.0" From c5567279d1c11363a4845545d4b1a5994ee27520 Mon Sep 17 00:00:00 2001 From: Nikos Chamakos Date: Thu, 22 May 2025 15:23:33 +0300 Subject: [PATCH 5/6] sync with dev branch (#26) * Made the initial build for npm (#25) * Made the initial build for npm * fix: update package.json with correct license, description and module type - Change license from AGPLv3 to MIT to match actual project license - Replace HTML image tag with proper text description - Update type to "module" to align with ES module syntax * Prepare package for npm publishing and bump version to 0.1.1 * Update package.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update rollup.config.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update rollup.config.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: update test script to use jest and add jest as a devDependency * fix: remove (still) unused wasm plugin from rollup configuration * fix: remove unused rollup-plugin-wasm from devDependencies * fix: revert test script to no tests configured and remove jest from devDependencies * Add plotly.js as a peer and dev dependency; update Rollup config for external globals * fix: remove unused rollup-plugin-typescript2 from configuration * Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: update import paths in README for consistency with distribution bundle * fix: correct parameter syntax in addBoundaryCondition example --------- Co-authored-by: Sridhar.Mani Co-authored-by: Nikos Chamakos Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update author and contributors information in package.json * Add publishConfig to package.json for public access --------- Co-authored-by: sridhar <2019309038@student.annauniv.edu> Co-authored-by: Sridhar.Mani Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .gitignore | 3 + .npmignore | 4 + README.md | 55 +- dist/feascript.cjs.js | 8 + dist/feascript.cjs.js.map | 1 + dist/feascript.esm.js | 7 + dist/feascript.esm.js.map | 1 + dist/feascript.umd.js | 8 + dist/feascript.umd.js.map | 1 + feascript-0.1.1.tgz | Bin 0 -> 141436 bytes package-lock.json | 4525 +++++++++++++++++++++++++++++++++++++ package.json | 69 + rollup.config.js | 39 + src/index.js | 1 + tsconfig.json | 25 + 15 files changed, 4743 insertions(+), 4 deletions(-) create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 dist/feascript.cjs.js create mode 100644 dist/feascript.cjs.js.map create mode 100644 dist/feascript.esm.js create mode 100644 dist/feascript.esm.js.map create mode 100644 dist/feascript.umd.js create mode 100644 dist/feascript.umd.js.map create mode 100644 feascript-0.1.1.tgz create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 rollup.config.js create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9c7c58b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/node_modules +node_modules +node_modules/ \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..1742c61 --- /dev/null +++ b/.npmignore @@ -0,0 +1,4 @@ +examples/ +test/ +.gitignore +package-lock.json \ No newline at end of file diff --git a/README.md b/README.md index 040bbd8..9c05e59 100644 --- a/README.md +++ b/README.md @@ -6,20 +6,67 @@ > 🚧 **FEAScript is currently under heavy development.** Functionality and interfaces may change rapidly as new features and enhancements are introduced. 🚧 -## Getting Started +## Installation -FEAScript is entirely implemented in pure JavaScript and requires only a simple HTML page to operate. All simulations are executed locally in your browser, without the need for any cloud services. +FEAScript is entirely implemented in pure JavaScript and requires only a simple HTML page to operate. All simulations are executed locally in your browser, without the need for any cloud services. You can use FEAScript in your projects through one of the following methods: + +### Option 1: NPM Installation + +```bash +# Install FEAScript and its peer dependencies +npm install feascript mathjs plotly.js +``` + +Then import it in your JavaScript/TypeScript file: + +```javascript +// ES Modules +import { FEAScriptModel, plotSolution } from "feascript"; + +// CommonJS +const { FEAScriptModel, plotSolution } = require("feascript"); +``` + +**Important:** FEAScript is built as an ES module. If you're starting a new project, make sure to configure it to use ES modules by running: + +```bash +# Create package.json with type=module for ES modules support +echo '{"type":"module"}' > package.json +``` + +If you already have a package.json file, manually add `"type": "module"` to enable ES modules in your project. + +### Option 2: Direct Import from CDN + +Add this line to your HTML or JavaScript module: + +```javascript +import { FEAScriptModel, plotSolution } from "https://core.feascript.com/dist/feascript.umd.js"; +``` + +### Option 3: Download and Use Locally + +1. Download the latest release from [GitHub Releases](https://github.com/FEAScript/FEAScript-core/releases) +2. Include it in your project: + +```html + +``` ### Example Usage ```javascript // Import FEAScript library -import { FEAScriptModel, plotSolution } from "https://core.feascript.com/src/index.js"; +import { FEAScriptModel, plotSolution } from "https://core.feascript.com/dist/feascript.umd.js"; // Create and configure model const model = new FEAScriptModel(); model.setSolverConfig("solverType"); // e.g., "solidHeatTransfer" for a stationary solid heat transfer case -model.setMeshConfig({ // Define mesh configuration (assuming a rectangular domain for 2D) +model.setMeshConfig({ + // Define mesh configuration (assuming a rectangular domain for 2D) meshDimension: "1D" | "2D", // Mesh dimension elementOrder: "linear" | "quadratic", // Element order numElementsX: number, // Number of elements in x-direction diff --git a/dist/feascript.cjs.js b/dist/feascript.cjs.js new file mode 100644 index 0000000..6084723 --- /dev/null +++ b/dist/feascript.cjs.js @@ -0,0 +1,8 @@ +"use strict";Object.defineProperty(exports,"__esModule",{value:!0});class e{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getGaussPointsAndWeights(){let e=[],t=[];return"linear"===this.elementOrder?(e[0]=.5,t[0]=1):"quadratic"===this.elementOrder&&(e[0]=(1-Math.sqrt(.6))/2,e[1]=.5,e[2]=(1+Math.sqrt(.6))/2,t[0]=5/18,t[1]=8/18,t[2]=5/18),{gaussPoints:e,gaussWeights:t}}}let t="basic";function n(e){"debug"===t&&console.log("%c[DEBUG] "+e,"color: #2196F3; font-weight: bold;")}function s(e){console.log("%c[INFO] "+e,"color: #4CAF50; font-weight: bold;")}function o(e){console.log("%c[ERROR] "+e,"color: #F44336; font-weight: bold;")}class i{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getBasisFunctions(e,t=null){let n=[],s=[],i=[];if("1D"===this.meshDimension)"linear"===this.elementOrder?(n[0]=1-e,n[1]=e,s[0]=-1,s[1]=1):"quadratic"===this.elementOrder&&(n[0]=1-3*e+2*e**2,n[1]=4*e-4*e**2,n[2]=2*e**2-e,s[0]=4*e-3,s[1]=4-8*e,s[2]=4*e-1);else if("2D"===this.meshDimension){if(null===t)return void o("Eta coordinate is required for 2D elements");if("linear"===this.elementOrder){function r(e){return 1-e}n[0]=r(e)*r(t),n[1]=r(e)*t,n[2]=e*r(t),n[3]=e*t,s[0]=-1*r(t),s[1]=-1*t,s[2]=1*r(t),s[3]=1*t,i[0]=-1*r(e),i[1]=1*r(e),i[2]=-1*e,i[3]=1*e}else if("quadratic"===this.elementOrder){function a(e){return 2*e**2-3*e+1}function l(e){return-4*e**2+4*e}function d(e){return 2*e**2-e}function h(e){return 4*e-3}function m(e){return-8*e+4}function u(e){return 4*e-1}n[0]=a(e)*a(t),n[1]=a(e)*l(t),n[2]=a(e)*d(t),n[3]=l(e)*a(t),n[4]=l(e)*l(t),n[5]=l(e)*d(t),n[6]=d(e)*a(t),n[7]=d(e)*l(t),n[8]=d(e)*d(t),s[0]=h(e)*a(t),s[1]=h(e)*l(t),s[2]=h(e)*d(t),s[3]=m(e)*a(t),s[4]=m(e)*l(t),s[5]=m(e)*d(t),s[6]=u(e)*a(t),s[7]=u(e)*l(t),s[8]=u(e)*d(t),i[0]=a(e)*h(t),i[1]=a(e)*m(t),i[2]=a(e)*u(t),i[3]=l(e)*h(t),i[4]=l(e)*m(t),i[5]=l(e)*u(t),i[6]=d(e)*h(t),i[7]=d(e)*m(t),i[8]=d(e)*u(t)}}return{basisFunction:n,basisFunctionDerivKsi:s,basisFunctionDerivEta:i}}}class r{constructor({numElementsX:e=null,maxX:t=null,numElementsY:n=null,maxY:s=null,meshDimension:o=null,elementOrder:i="linear",parsedMesh:r=null}){this.numElementsX=e,this.numElementsY=n,this.maxX=t,this.maxY=s,this.meshDimension=o,this.elementOrder=i,this.parsedMesh=r}generateMesh(){if(this.parsedMesh){if(this.parsedMesh.nodalNumbering&&"object"==typeof this.parsedMesh.nodalNumbering&&!Array.isArray(this.parsedMesh.nodalNumbering)){const e=this.parsedMesh.nodalNumbering.quadElements||[];if(this.parsedMesh.nodalNumbering.triangleElements,n("Initial parsed mesh nodal numbering from GMSH format: "+JSON.stringify(this.parsedMesh.nodalNumbering)),this.parsedMesh.elementTypes[3]||this.parsedMesh.elementTypes[10]){const t=[];for(let n=0;n0&&void 0===this.parsedMesh.boundaryElements[0]){const e=[];for(let t=1;t{if(1===e.dimension){const t=this.parsedMesh.boundaryNodePairs[e.tag]||[];t.length>0&&(this.parsedMesh.boundaryElements[e.tag]||(this.parsedMesh.boundaryElements[e.tag]=[]),t.forEach((t=>{const s=t[0],i=t[1];n(`Processing boundary node pair: [${s}, ${i}] for boundary ${e.tag} (${e.name||"unnamed"})`);let r=!1;for(let t=0;t0&&void 0===this.parsedMesh.boundaryElements[0])){const e=[];for(let t=1;t{if("constantTemp"===this.boundaryConditions[s][0]){const o=this.boundaryConditions[s][1];n(`Boundary ${s}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[s].forEach((([s,i])=>{if("linear"===this.elementOrder){({0:[0],1:[1]})[i].forEach((i=>{const r=this.nop[s][i]-1;n(` - Applied fixed temperature to node ${r+1} (element ${s+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[s][i]-1;n(` - Applied fixed temperature to node ${r+1} (element ${s+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{if("constantTemp"===this.boundaryConditions[s][0]){const o=this.boundaryConditions[s][1];n(`Boundary ${s}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[s].forEach((([s,i])=>{if("linear"===this.elementOrder){({0:[0,2],1:[0,1],2:[1,3],3:[2,3]})[i].forEach((i=>{const r=this.nop[s][i]-1;n(` - Applied fixed temperature to node ${r+1} (element ${s+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[s][i]-1;n(` - Applied fixed temperature to node ${r+1} (element ${s+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const t=this.boundaryConditions[e];"convection"===t[0]&&(d[e]=t[1],h[e]=t[2])})),"1D"===this.meshDimension?Object.keys(this.boundaryConditions).forEach((s=>{if("convection"===this.boundaryConditions[s][0]){const o=d[s],i=h[s];n(`Boundary ${s}: Applying convection with heat transfer coefficient h=${o} W/(m²·K) and external temperature T∞=${i} K`),this.boundaryElements[s].forEach((([s,r])=>{let a;"linear"===this.elementOrder?a=0===r?0:1:"quadratic"===this.elementOrder&&(a=0===r?0:2);const l=this.nop[s][a]-1;n(` - Applied convection boundary condition to node ${l+1} (element ${s+1}, local node ${a+1})`),e[l]+=-o*i,t[l][l]+=o}))}})):"2D"===this.meshDimension&&Object.keys(this.boundaryConditions).forEach((s=>{if("convection"===this.boundaryConditions[s][0]){const m=d[s],u=h[s];n(`Boundary ${s}: Applying convection with heat transfer coefficient h=${m} W/(m²·K) and external temperature T∞=${u} K`),this.boundaryElements[s].forEach((([s,d])=>{if("linear"===this.elementOrder){let h,c,f,p,y;0===d?(h=o[0],c=0,f=0,p=3,y=2):1===d?(h=0,c=o[0],f=0,p=2,y=1):2===d?(h=o[0],c=1,f=1,p=4,y=2):3===d&&(h=1,c=o[0],f=2,p=4,y=1);let g=l.getBasisFunctions(h,c),b=g.basisFunction,E=g.basisFunctionDerivKsi,M=g.basisFunctionDerivEta,$=0,v=0,w=0,C=0;const N=this.nop[s].length;for(let e=0;e"object"==typeof e&&null!==e||"function"==typeof e,f=new Map([["proxy",{canHandle:e=>c(e)&&e[l],serialize(e){const{port1:t,port2:n}=new MessageChannel;return p(e,t),[n,[n]]},deserialize:e=>(e.start(),g(e))}],["throw",{canHandle:e=>c(e)&&u in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function p(e,t=globalThis,n=["*"]){t.addEventListener("message",(function s(o){if(!o||!o.data)return;if(!function(e,t){for(const n of e){if(t===n||"*"===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}return!1}(n,o.origin))return void console.warn(`Invalid origin '${o.origin}' for comlink proxy`);const{id:i,type:r,path:a}=Object.assign({path:[]},o.data),d=(o.data.argumentList||[]).map(S);let h;try{const t=a.slice(0,-1).reduce(((e,t)=>e[t]),e),n=a.reduce(((e,t)=>e[t]),e);switch(r){case"GET":h=n;break;case"SET":t[a.slice(-1)[0]]=S(o.data.value),h=!0;break;case"APPLY":h=n.apply(t,d);break;case"CONSTRUCT":h=function(e){return Object.assign(e,{[l]:!0})}(new n(...d));break;case"ENDPOINT":{const{port1:t,port2:n}=new MessageChannel;p(e,n),h=function(e,t){return C.set(e,t),e}(t,[t])}break;case"RELEASE":h=void 0;break;default:return}}catch(e){h={value:e,[u]:0}}Promise.resolve(h).catch((e=>({value:e,[u]:0}))).then((n=>{const[o,a]=N(n);t.postMessage(Object.assign(Object.assign({},o),{id:i}),a),"RELEASE"===r&&(t.removeEventListener("message",s),y(t),m in e&&"function"==typeof e[m]&&e[m]())})).catch((e=>{const[n,s]=N({value:new TypeError("Unserializable return value"),[u]:0});t.postMessage(Object.assign(Object.assign({},n),{id:i}),s)}))})),t.start&&t.start()}function y(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function g(e,t){const n=new Map;return e.addEventListener("message",(function(e){const{data:t}=e;if(!t||!t.id)return;const s=n.get(t.id);if(s)try{s(t)}finally{n.delete(t.id)}})),v(e,n,[],t)}function b(e){if(e)throw new Error("Proxy has been released and is not useable")}function E(e){return x(e,new Map,{type:"RELEASE"}).then((()=>{y(e)}))}const M=new WeakMap,$="FinalizationRegistry"in globalThis&&new FinalizationRegistry((e=>{const t=(M.get(e)||0)-1;M.set(e,t),0===t&&E(e)}));function v(e,t,n=[],s=function(){}){let o=!1;const i=new Proxy(s,{get(s,r){if(b(o),r===h)return()=>{!function(e){$&&$.unregister(e)}(i),E(e),t.clear(),o=!0};if("then"===r){if(0===n.length)return{then:()=>i};const s=x(e,t,{type:"GET",path:n.map((e=>e.toString()))}).then(S);return s.then.bind(s)}return v(e,t,[...n,r])},set(s,i,r){b(o);const[a,l]=N(r);return x(e,t,{type:"SET",path:[...n,i].map((e=>e.toString())),value:a},l).then(S)},apply(s,i,r){b(o);const a=n[n.length-1];if(a===d)return x(e,t,{type:"ENDPOINT"}).then(S);if("bind"===a)return v(e,t,n.slice(0,-1));const[l,h]=w(r);return x(e,t,{type:"APPLY",path:n.map((e=>e.toString())),argumentList:l},h).then(S)},construct(s,i){b(o);const[r,a]=w(i);return x(e,t,{type:"CONSTRUCT",path:n.map((e=>e.toString())),argumentList:r},a).then(S)}});return function(e,t){const n=(M.get(t)||0)+1;M.set(t,n),$&&$.register(e,t,e)}(i,e),i}function w(e){const t=e.map(N);return[t.map((e=>e[0])),(n=t.map((e=>e[1])),Array.prototype.concat.apply([],n))];var n}const C=new WeakMap;function N(e){for(const[t,n]of f)if(n.canHandle(e)){const[s,o]=n.serialize(e);return[{type:"HANDLER",name:t,value:s},o]}return[{type:"RAW",value:e},C.get(e)||[]]}function S(e){switch(e.type){case"HANDLER":return f.get(e.name).deserialize(e.value);case"RAW":return e.value}}function x(e,t,n,s){return new Promise((o=>{const i=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");t.set(i,o),e.start&&e.start(),e.postMessage(Object.assign({id:i},n),s)}))}exports.FEAScriptModel=class{constructor(){this.solverConfig=null,this.meshConfig={},this.boundaryConditions={},this.solverMethod="lusolve",s("FEAScriptModel instance created")}setSolverConfig(e){this.solverConfig=e,n(`Solver config set to: ${e}`)}setMeshConfig(e){this.meshConfig=e,n(`Mesh config set with dimensions: ${e.meshDimension}`)}addBoundaryCondition(e,t){this.boundaryConditions[e]=t,n(`Boundary condition added for boundary: ${e}, type: ${t[0]}`)}setSolverMethod(e){this.solverMethod=e,n(`Solver method set to: ${e}`)}solve(){if(!this.solverConfig||!this.meshConfig||!this.boundaryConditions){const e="Solver config, mesh config, and boundary conditions must be set before solving.";throw console.error(e),new Error(e)}let t=[],o=[],l=[],d={};if(s("Beginning matrix assembly..."),console.time("assemblyMatrices"),"solidHeatTransferScript"===this.solverConfig&&(s(`Using solver: ${this.solverConfig}`),({jacobianMatrix:t,residualVector:o,nodesCoordinates:d}=function(t,o){s("Starting solid heat transfer matrix assembly...");const{meshDimension:l,numElementsX:d,numElementsY:h,maxX:m,maxY:u,elementOrder:c,parsedMesh:f}=t;n("Generating mesh...");const p=new r({numElementsX:d,numElementsY:h,maxX:m,maxY:u,meshDimension:l,elementOrder:c,parsedMesh:f}).generateMesh();let y,g,b=p.nodesXCoordinates,E=p.nodesYCoordinates,M=p.totalNodesX,$=p.totalNodesY,v=p.nodalNumbering,w=p.boundaryElements;null!=f?(y=v.length,g=b.length,n(`Using parsed mesh with ${y} elements and ${g} nodes`)):(y=d*("2D"===l?h:1),g=M*("2D"===l?$:1),n(`Using mesh generated from geometry with ${y} elements and ${g} nodes`));let C,N,S,x,D,O,A,F=[],T=[],k=[],X=[],P=[],R=[],Y=[],W=[],I=[],j=[];for(let e=0;e{console.error("FEAScriptWorker: Worker error:",e)};const e=g(this.worker);this.feaWorker=await new e,this.isReady=!0}catch(e){throw console.error("Failed to initialize worker",e),e}}async _ensureReady(){return this.isReady?Promise.resolve():new Promise(((e,t)=>{let n=0;const s=()=>{n++,this.isReady?e():n>=50?t(new Error("Timeout waiting for worker to be ready")):setTimeout(s,1e3)};s()}))}async setSolverConfig(e){return await this._ensureReady(),s(`FEAScriptWorker: Setting solver config to: ${e}`),this.feaWorker.setSolverConfig(e)}async setMeshConfig(e){return await this._ensureReady(),s("FEAScriptWorker: Setting mesh config"),this.feaWorker.setMeshConfig(e)}async addBoundaryCondition(e,t){return await this._ensureReady(),s(`FEAScriptWorker: Adding boundary condition for boundary: ${e}`),this.feaWorker.addBoundaryCondition(e,t)}async setSolverMethod(e){return await this._ensureReady(),s(`FEAScriptWorker: Setting solver method to: ${e}`),this.feaWorker.setSolverMethod(e)}async solve(){await this._ensureReady(),s("FEAScriptWorker: Requesting solution from worker...");const e=performance.now(),t=await this.feaWorker.solve();return s(`FEAScriptWorker: Solution completed in ${((performance.now()-e)/1e3).toFixed(2)}s`),t}async getModelInfo(){return await this._ensureReady(),this.feaWorker.getModelInfo()}async ping(){return await this._ensureReady(),this.feaWorker.ping()}terminate(){this.worker&&(this.worker.terminate(),this.worker=null,this.feaWorker=null,this.isReady=!1)}},exports.VERSION="0.1.1",exports.importGmshQuadTri=async e=>{let t={nodesXCoordinates:[],nodesYCoordinates:[],nodalNumbering:{quadElements:[],triangleElements:[]},boundaryElements:[],boundaryConditions:[],boundaryNodePairs:{},gmshV:0,ascii:!1,fltBytes:"8",totalNodesX:0,totalNodesY:0,physicalPropMap:[],elementTypes:{}},s=(await e.text()).split("\n").map((e=>e.trim())).filter((e=>""!==e&&" "!==e)),o="",i=0,r=0,a=0,l=0,d={numNodes:0},h=0,m=[],u=0,c=0,f=0,p={dim:0,tag:0,elementType:0,numElements:0},y=0,g={};for(;i""!==e));if("meshFormat"===o)t.gmshV=parseFloat(n[0]),t.ascii="0"===n[1],t.fltBytes=n[2];else if("physicalNames"===o){if(n.length>=3){if(!/^\d+$/.test(n[0])){i++;continue}const e=parseInt(n[0],10),s=parseInt(n[1],10);let o=n.slice(2).join(" ");o=o.replace(/^"|"$/g,""),t.physicalPropMap.push({tag:s,dimension:e,name:o})}}else if("nodes"===o){if(0===r){r=parseInt(n[0],10),a=parseInt(n[1],10),t.nodesXCoordinates=new Array(a).fill(0),t.nodesYCoordinates=new Array(a).fill(0),i++;continue}if(lparseInt(e,10)));if(1===p.elementType||8===p.elementType){const n=p.tag;g[n]||(g[n]=[]),g[n].push(e),t.boundaryNodePairs[n]||(t.boundaryNodePairs[n]=[]),t.boundaryNodePairs[n].push(e)}else 2===p.elementType?t.nodalNumbering.triangleElements.push(e):(3===p.elementType||10===p.elementType)&&t.nodalNumbering.quadElements.push(e);y++,y===p.numElements&&(f++,p={numElements:0})}}i++}return t.physicalPropMap.forEach((e=>{if(1===e.dimension){const n=g[e.tag]||[];n.length>0&&t.boundaryConditions.push({name:e.name,tag:e.tag,nodes:n})}})),n(`Parsed boundary node pairs by physical tag: ${JSON.stringify(t.boundaryNodePairs)}. These pairs will be used to identify boundary elements in the mesh.`),t},exports.logSystem=function(e){"basic"!==e&&"debug"!==e?(console.log("%c[WARN] Invalid log level: "+e+". Using basic instead.","color: #FFC107; font-weight: bold;"),t="basic"):(t=e,s(`Log level set to: ${e}`))},exports.plotSolution=function(e,t,n,s,o,i,r="structured"){const{nodesXCoordinates:a,nodesYCoordinates:l}=t;if("1D"===s&&"line"===o){let t;t=e.length>0&&Array.isArray(e[0])?e.map((e=>e[0])):e;let s=Array.from(a),o={x:s,y:t,mode:"lines",type:"scatter",line:{color:"rgb(219, 64, 82)",width:2},name:"Solution"},r=Math.min(window.innerWidth,700),l=Math.max(...s),d=r/l,h={title:`line plot - ${n}`,width:Math.max(d*l,400),height:350,xaxis:{title:"x"},yaxis:{title:"Solution"},margin:{l:70,r:40,t:50,b:50}};Plotly.newPlot(i,[o],h,{responsive:!0})}else if("2D"===s&&"contour"===o){const t="structured"===r,s=new Set(a).size,d=new Set(l).size;let h=Array.isArray(e[0])?e.map((e=>e[0])):e,m=Math.min(window.innerWidth,700),u=Math.max(...a),c=Math.max(...l)/u,f=Math.min(m,600),p={title:`${o} plot - ${n}`,width:f,height:f*c*.8,xaxis:{title:"x"},yaxis:{title:"y"},margin:{l:50,r:50,t:50,b:50},hovermode:"closest"};if(t){const t=s,n=d;math.reshape(Array.from(a),[t,n]);let o=math.reshape(Array.from(l),[t,n]),r=math.reshape(Array.from(e),[t,n]),h=math.transpose(r),m=[];for(let e=0;e | |\n // 0 --- 1 0 --- 2\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[3]; // 3 -> 1\n feaScriptNodes[2] = gmshNodes[1]; // 1 -> 2\n feaScriptNodes[3] = gmshNodes[2]; // 2 -> 3\n } else if (gmshNodes.length === 9) {\n // Mapping for quadratic quad elements (9 nodes)\n // GMSH: FEAScript:\n // 3--6--2 2--5--8\n // | | | |\n // 7 8 5 --> 1 4 7\n // | | | |\n // 0--4--1 0--3--6\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[7]; // 7 -> 1\n feaScriptNodes[2] = gmshNodes[3]; // 3 -> 2\n feaScriptNodes[3] = gmshNodes[4]; // 4 -> 3\n feaScriptNodes[4] = gmshNodes[8]; // 8 -> 4\n feaScriptNodes[5] = gmshNodes[6]; // 6 -> 5\n feaScriptNodes[6] = gmshNodes[1]; // 1 -> 6\n feaScriptNodes[7] = gmshNodes[5]; // 5 -> 7\n feaScriptNodes[8] = gmshNodes[2]; // 2 -> 8\n }\n\n mappedNodalNumbering.push(feaScriptNodes);\n }\n\n this.parsedMesh.nodalNumbering = mappedNodalNumbering;\n } else if (this.parsedMesh.elementTypes[2]) {\n }\n\n debugLog(\n \"Nodal numbering after mapping from GMSH to FEAScript format: \" +\n JSON.stringify(this.parsedMesh.nodalNumbering)\n );\n\n // Process boundary elements if they exist and if physical property mapping exists\n if (this.parsedMesh.physicalPropMap && this.parsedMesh.boundaryElements) {\n // Check if boundary elements need to be processed\n if (\n Array.isArray(this.parsedMesh.boundaryElements) &&\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n // Create a new array without the empty first element\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n\n // If boundary node pairs exist but boundary elements haven't been processed\n if (this.parsedMesh.boundaryNodePairs && !this.parsedMesh.boundaryElementsProcessed) {\n // Reset boundary elements array\n this.parsedMesh.boundaryElements = [];\n\n // Process each physical property from the Gmsh file\n this.parsedMesh.physicalPropMap.forEach((prop) => {\n // Only process 1D physical entities (boundary lines)\n if (prop.dimension === 1) {\n // Get all node pairs for this boundary\n const boundaryNodePairs = this.parsedMesh.boundaryNodePairs[prop.tag] || [];\n\n if (boundaryNodePairs.length > 0) {\n // Initialize array for this boundary tag\n if (!this.parsedMesh.boundaryElements[prop.tag]) {\n this.parsedMesh.boundaryElements[prop.tag] = [];\n }\n\n // For each boundary line segment (defined by a pair of nodes)\n boundaryNodePairs.forEach((nodesPair) => {\n const node1 = nodesPair[0]; // First node in the pair\n const node2 = nodesPair[1]; // Second node in the pair\n\n debugLog(\n `Processing boundary node pair: [${node1}, ${node2}] for boundary ${prop.tag} (${\n prop.name || \"unnamed\"\n })`\n );\n\n // Search through all elements to find which one contains both nodes\n let foundElement = false;\n\n // Loop through all elements in the mesh\n for (let elemIdx = 0; elemIdx < this.parsedMesh.nodalNumbering.length; elemIdx++) {\n const elemNodes = this.parsedMesh.nodalNumbering[elemIdx];\n\n // For linear quadrilateral linear elements (4 nodes)\n if (elemNodes.length === 4) {\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript linear quadrilateral numbering:\n // 1 --- 3\n // | |\n // 0 --- 2\n\n if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0)\n ) {\n side = 0; // Bottom side\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0)\n ) {\n side = 1; // Left side\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 1 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 1)\n ) {\n side = 2; // Top side\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 2)\n ) {\n side = 3; // Right side\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n } else if (elemNodes.length === 9) {\n // For quadratic quadrilateral elements (9 nodes)\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript quadratic quadrilateral numbering:\n // 2--5--8\n // | |\n // 1 4 7\n // | |\n // 0--3--6\n\n if (\n (node1Index === 0 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 0) ||\n (node1Index === 3 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 3)\n ) {\n side = 0; // Bottom side (nodes 0, 3, 6)\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0) ||\n (node1Index === 1 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 1)\n ) {\n side = 1; // Left side (nodes 0, 1, 2)\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 5) ||\n (node1Index === 5 && node2Index === 2) ||\n (node1Index === 5 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 5)\n ) {\n side = 2; // Top side (nodes 2, 5, 8)\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 6 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 7) ||\n (node1Index === 7 && node2Index === 6) ||\n (node1Index === 7 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 7)\n ) {\n side = 3; // Right side (nodes 6, 7, 8)\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n }\n }\n\n if (!foundElement) {\n errorLog(\n `Could not find element containing boundary nodes ${node1} and ${node2}. Boundary may be incomplete.`\n );\n }\n });\n }\n }\n });\n\n // Mark as processed\n this.parsedMesh.boundaryElementsProcessed = true;\n\n // Fix boundary elements array - remove undefined entries\n if (\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n }\n }\n }\n }\n\n debugLog(\"Processed boundary elements by tag: \" + JSON.stringify(this.parsedMesh.boundaryElements));\n\n return this.parsedMesh;\n } else {\n // Validate required geometry parameters based on mesh dimension\n if (this.meshDimension === \"1D\") {\n if (this.numElementsX === null || this.maxX === null) {\n errorLog(\"numElementsX and maxX are required parameters when generating a 1D mesh from geometry\");\n }\n } else if (this.meshDimension === \"2D\") {\n if (\n this.numElementsX === null ||\n this.maxX === null ||\n this.numElementsY === null ||\n this.maxY === null\n ) {\n errorLog(\n \"numElementsX, maxX, numElementsY, and maxY are required parameters when generating a 2D mesh from geometry\"\n );\n }\n }\n\n // Generate mesh based on dimension\n return this.generateMeshFromGeometry();\n }\n }\n\n /**\n * Function to generate a structured mesh based on the geometry configuration\n * @returns {object} An object containing the coordinates of nodes,\n * total number of nodes, nodal numbering (NOP) array, and boundary elements\n */\n generateMeshFromGeometry() {\n let nodesXCoordinates = [];\n let nodesYCoordinates = [];\n const xStart = 0;\n const yStart = 0;\n let totalNodesX, totalNodesY, deltaX, deltaY;\n\n if (this.meshDimension === \"1D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX;\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX / 2;\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n null, // numElementsY (not used in 1D)\n totalNodesX,\n null, // totalNodesY (not used in 1D)\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n\n // Return x coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n totalNodesX,\n nodalNumbering,\n boundaryElements,\n };\n } else if (this.meshDimension === \"2D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n totalNodesY = this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + nodeIndexY * deltaY;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + nodeIndexX * deltaX;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + nodeIndexY * deltaY;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n totalNodesY = 2 * this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + (nodeIndexY * deltaY) / 2;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + (nodeIndexX * deltaX) / 2;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + (nodeIndexY * deltaY) / 2;\n }\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n this.numElementsY,\n totalNodesX,\n totalNodesY,\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n debugLog(\"Generated node Y coordinates: \" + JSON.stringify(nodesYCoordinates));\n\n // Return x and y coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n nodesYCoordinates,\n totalNodesX,\n totalNodesY,\n nodalNumbering,\n boundaryElements,\n };\n }\n }\n\n /**\n * Function to find the elements that belong to each boundary of a domain\n * @returns {array} An array containing arrays of elements and their adjacent boundary side for each boundary\n * Each element in the array is of the form [elementIndex, side], where 'side' indicates which side\n * of the reference element is in contact with the physical boundary:\n *\n * For 1D domains (line segments):\n * 0 - Left node of reference element (maps to physical left endpoint)\n * 1 - Right node of reference element (maps to physical right endpoint)\n *\n * For 2D domains (rectangular):\n * 0 - Bottom side of reference element (maps to physical bottom boundary)\n * 1 - Left side of reference element (maps to physical left boundary)\n * 2 - Top side of reference element (maps to physical top boundary)\n * 3 - Right side of reference element (maps to physical right boundary)\n */\n findBoundaryElements() {\n const boundaryElements = [];\n const maxSides = this.meshDimension === \"1D\" ? 2 : 4; // Number of element sides based on mesh dimension\n for (let sideIndex = 0; sideIndex < maxSides; sideIndex++) {\n boundaryElements.push([]);\n }\n\n if (this.meshDimension === \"1D\") {\n // Left boundary (element 0, side 0)\n boundaryElements[0].push([0, 0]);\n\n // Right boundary (last element, side 1)\n boundaryElements[1].push([this.numElementsX - 1, 1]);\n } else if (this.meshDimension === \"2D\") {\n for (let elementIndexX = 0; elementIndexX < this.numElementsX; elementIndexX++) {\n for (let elementIndexY = 0; elementIndexY < this.numElementsY; elementIndexY++) {\n const elementIndex = elementIndexX * this.numElementsY + elementIndexY;\n\n // Bottom boundary\n if (elementIndexY === 0) {\n boundaryElements[0].push([elementIndex, 0]);\n }\n\n // Left boundary\n if (elementIndexX === 0) {\n boundaryElements[1].push([elementIndex, 1]);\n }\n\n // Top boundary\n if (elementIndexY === this.numElementsY - 1) {\n boundaryElements[2].push([elementIndex, 2]);\n }\n\n // Right boundary\n if (elementIndexX === this.numElementsX - 1) {\n boundaryElements[3].push([elementIndex, 3]);\n }\n }\n }\n }\n\n debugLog(\"Identified boundary elements by side: \" + JSON.stringify(boundaryElements));\n return boundaryElements;\n }\n\n /**\n * Function to generate the nodal numbering (NOP) array for a structured mesh\n * This array represents the connectivity between elements and their corresponding nodes\n * @param {number} numElementsX - Number of elements along the x-axis\n * @param {number} [numElementsY] - Number of elements along the y-axis (optional for 1D)\n * @param {number} totalNodesX - Total number of nodes along the x-axis\n * @param {number} [totalNodesY] - Total number of nodes along the y-axis (optional for 1D)\n * @param {string} elementOrder - The order of elements, either 'linear' or 'quadratic'\n * @returns {array} NOP - A two-dimensional array which represents the element-to-node connectivity for the entire mesh\n */\n generateNodalNumbering(numElementsX, numElementsY, totalNodesX, totalNodesY, elementOrder) {\n let elementIndex = 0;\n let nop = [];\n\n if (this.meshDimension === \"1D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear 1D elements with the following nodes representation:\n *\n * 1 --- 2\n *\n */\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 2; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic 1D elements with the following nodes representation:\n *\n * 1--2--3\n *\n */\n let columnCounter = 0;\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 3; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex + columnCounter;\n }\n columnCounter += 1;\n }\n }\n } else if (this.meshDimension === \"2D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear rectangular elements with the following nodes representation:\n *\n * 1 --- 3\n * | |\n * 0 --- 2\n *\n */\n let rowCounter = 0;\n let columnCounter = 2;\n for (let elementIndex = 0; elementIndex < numElementsX * numElementsY; elementIndex++) {\n rowCounter += 1;\n nop[elementIndex] = [];\n nop[elementIndex][0] = elementIndex + columnCounter - 1;\n nop[elementIndex][1] = elementIndex + columnCounter;\n nop[elementIndex][2] = elementIndex + columnCounter + numElementsY;\n nop[elementIndex][3] = elementIndex + columnCounter + numElementsY + 1;\n if (rowCounter === numElementsY) {\n columnCounter += 1;\n rowCounter = 0;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic rectangular elements with the following nodes representation:\n *\n * 2--5--8\n * | |\n * 1 4 7\n * | |\n * 0--3--6\n *\n */\n for (let elementIndexX = 1; elementIndexX <= numElementsX; elementIndexX++) {\n for (let elementIndexY = 1; elementIndexY <= numElementsY; elementIndexY++) {\n nop[elementIndex] = [];\n for (let nodeIndex1 = 1; nodeIndex1 <= 3; nodeIndex1++) {\n let nodeIndex2 = 3 * nodeIndex1 - 2;\n nop[elementIndex][nodeIndex2 - 1] =\n totalNodesY * (2 * elementIndexX + nodeIndex1 - 3) + 2 * elementIndexY - 1;\n nop[elementIndex][nodeIndex2] = nop[elementIndex][nodeIndex2 - 1] + 1;\n nop[elementIndex][nodeIndex2 + 1] = nop[elementIndex][nodeIndex2 - 1] + 2;\n }\n elementIndex = elementIndex + 1;\n }\n }\n }\n }\n\n return nop;\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to handle thermal boundary conditions application\n */\nexport class ThermalBoundaryConditions {\n /**\n * Constructor to initialize the ThermalBoundaryConditions class\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @param {array} boundaryElements - Array containing elements that belong to each boundary\n * @param {array} nop - Nodal numbering (NOP) array representing the connectivity between elements and nodes\n * @param {string} meshDimension - The dimension of the mesh (e.g., \"2D\")\n * @param {string} elementOrder - The order of elements (e.g., \"linear\", \"quadratic\")\n */\n constructor(boundaryConditions, boundaryElements, nop, meshDimension, elementOrder) {\n this.boundaryConditions = boundaryConditions;\n this.boundaryElements = boundaryElements;\n this.nop = nop;\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n }\n\n /**\n * Function to impose constant temperature boundary conditions (Dirichlet type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n */\n imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix) {\n basicLog(\"Applying constant temperature boundary conditions (Dirichlet type)\");\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 1: [1], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 2: [2], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0, 2], // Nodes at the bottom side of the reference element\n 1: [0, 1], // Nodes at the left side of the reference element\n 2: [1, 3], // Nodes at the top side of the reference element\n 3: [2, 3], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0, 3, 6], // Nodes at the bottom side of the reference element\n 1: [0, 1, 2], // Nodes at the left side of the reference element\n 2: [2, 5, 8], // Nodes at the top side of the reference element\n 3: [6, 7, 8], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n }\n }\n\n /**\n * Function to impose convection boundary conditions (Robin type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n * @param {array} gaussPoints - Array of Gauss points for numerical integration\n * @param {array} gaussWeights - Array of Gauss weights for numerical integration\n * @param {array} nodesXCoordinates - Array of x-coordinates of nodes\n * @param {array} nodesYCoordinates - Array of y-coordinates of nodes\n * @param {object} basisFunctionsData - Object containing basis functions and their derivatives\n */\n imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n ) {\n basicLog(\"Applying convection boundary conditions (Robin type)\");\n // Extract convection parameters from boundary conditions\n let convectionHeatTranfCoeff = [];\n let convectionExtTemp = [];\n Object.keys(this.boundaryConditions).forEach((key) => {\n const boundaryCondition = this.boundaryConditions[key];\n if (boundaryCondition[0] === \"convection\") {\n convectionHeatTranfCoeff[key] = boundaryCondition[1];\n convectionExtTemp[key] = boundaryCondition[2];\n }\n });\n\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n let nodeIndex;\n if (this.elementOrder === \"linear\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 1;\n }\n } else if (this.elementOrder === \"quadratic\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 2;\n }\n }\n\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n residualVector[globalNodeIndex] += -convectionCoeff * extTemp;\n jacobianMatrix[globalNodeIndex][globalNodeIndex] += convectionCoeff;\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 2;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 0;\n lastNodeIndex = 2;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 1;\n firstNodeIndex = 1;\n lastNodeIndex = 4;\n nodeIncrement = 2;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 2;\n lastNodeIndex = 4;\n nodeIncrement = 1;\n }\n\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[0] * tangentVectorLength * basisFunction[localNodeIndex] * convectionCoeff * extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[0] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n for (let gaussPointIndex = 0; gaussPointIndex < 3; gaussPointIndex++) {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 7;\n nodeIncrement = 3;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 1;\n firstNodeIndex = 2;\n lastNodeIndex = 9;\n nodeIncrement = 3;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 6;\n lastNodeIndex = 9;\n nodeIncrement = 1;\n }\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n convectionCoeff *\n extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n }\n }\n });\n }\n });\n }\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nconst proxyMarker = Symbol(\"Comlink.proxy\");\nconst createEndpoint = Symbol(\"Comlink.endpoint\");\nconst releaseProxy = Symbol(\"Comlink.releaseProxy\");\nconst finalizer = Symbol(\"Comlink.finalizer\");\nconst throwMarker = Symbol(\"Comlink.thrown\");\nconst isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n/**\n * Internal transfer handle to handle objects marked to proxy.\n */\nconst proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n};\n/**\n * Internal transfer handler to handle thrown exceptions.\n */\nconst throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n};\n/**\n * Allows customizing the serialization of certain values.\n */\nconst transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n]);\nfunction isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n}\nfunction expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n}\nfunction isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n}\nfunction closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n}\nfunction wrap(ep, target) {\n const pendingListeners = new Map();\n ep.addEventListener(\"message\", function handleMessage(ev) {\n const { data } = ev;\n if (!data || !data.id) {\n return;\n }\n const resolver = pendingListeners.get(data.id);\n if (!resolver) {\n return;\n }\n try {\n resolver(data);\n }\n finally {\n pendingListeners.delete(data.id);\n }\n });\n return createProxy(ep, pendingListeners, [], target);\n}\nfunction throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n}\nfunction releaseEndpoint(ep) {\n return requestResponseMessage(ep, new Map(), {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n}\nconst proxyCounter = new WeakMap();\nconst proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\nfunction registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n}\nfunction unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n}\nfunction createProxy(ep, pendingListeners, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n pendingListeners.clear();\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, pendingListeners, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, pendingListeners, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, pendingListeners, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, pendingListeners, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n}\nfunction myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n}\nfunction processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n}\nconst transferCache = new WeakMap();\nfunction transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n}\nfunction proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n}\nfunction windowEndpoint(w, context = globalThis, targetOrigin = \"*\") {\n return {\n postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),\n addEventListener: context.addEventListener.bind(context),\n removeEventListener: context.removeEventListener.bind(context),\n };\n}\nfunction toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n}\nfunction fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n}\nfunction requestResponseMessage(ep, pendingListeners, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n pendingListeners.set(id, resolve);\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n}\nfunction generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n}\n\nexport { createEndpoint, expose, finalizer, proxy, proxyMarker, releaseProxy, transfer, transferHandlers, windowEndpoint, wrap };\n//# sourceMappingURL=comlink.mjs.map\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { jacobiMethod } from \"./methods/jacobiMethodScript.js\";\nimport { assembleSolidHeatTransferMat } from \"./solvers/solidHeatTransferScript.js\";\nimport { basicLog, debugLog, errorLog } from \"./utilities/loggingScript.js\";\n\n/**\n * Class to implement finite element analysis in JavaScript\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing the solution vector and additional mesh information\n */\nexport class FEAScriptModel {\n constructor() {\n this.solverConfig = null;\n this.meshConfig = {};\n this.boundaryConditions = {};\n this.solverMethod = \"lusolve\"; // Default solver method\n basicLog(\"FEAScriptModel instance created\");\n }\n\n setSolverConfig(solverConfig) {\n this.solverConfig = solverConfig;\n debugLog(`Solver config set to: ${solverConfig}`);\n }\n\n setMeshConfig(meshConfig) {\n this.meshConfig = meshConfig;\n debugLog(\n `Mesh config set with dimensions: ${meshConfig.meshDimension}`\n );\n }\n\n addBoundaryCondition(boundaryKey, condition) {\n this.boundaryConditions[boundaryKey] = condition;\n debugLog(`Boundary condition added for boundary: ${boundaryKey}, type: ${condition[0]}`);\n }\n\n setSolverMethod(solverMethod) {\n this.solverMethod = solverMethod;\n debugLog(`Solver method set to: ${solverMethod}`);\n }\n\n solve() {\n if (!this.solverConfig || !this.meshConfig || !this.boundaryConditions) {\n const error = \"Solver config, mesh config, and boundary conditions must be set before solving.\";\n console.error(error);\n throw new Error(error);\n }\n\n let jacobianMatrix = [];\n let residualVector = [];\n let solutionVector = [];\n let nodesCoordinates = {};\n\n // Assembly matrices\n basicLog(\"Beginning matrix assembly...\");\n console.time(\"assemblyMatrices\");\n if (this.solverConfig === \"solidHeatTransferScript\") {\n basicLog(`Using solver: ${this.solverConfig}`);\n ({ jacobianMatrix, residualVector, nodesCoordinates } = assembleSolidHeatTransferMat(\n this.meshConfig,\n this.boundaryConditions\n ));\n }\n console.timeEnd(\"assemblyMatrices\");\n basicLog(\"Matrix assembly completed\");\n\n // System solving\n basicLog(`Solving system using ${this.solverMethod}...`);\n console.time(\"systemSolving\");\n if (this.solverMethod === \"lusolve\") {\n solutionVector = math.lusolve(jacobianMatrix, residualVector);\n } else if (this.solverMethod === \"jacobi\") {\n // Create initial guess of zeros\n const initialGuess = new Array(residualVector.length).fill(0);\n // Call Jacobi method with desired max iterations and tolerance\n const jacobiResult = jacobiMethod(jacobianMatrix, residualVector, initialGuess, 1000, 1e-6);\n\n // Log convergence information\n if (jacobiResult.converged) {\n debugLog(`Jacobi method converged in ${jacobiResult.iterations} iterations`);\n } else {\n debugLog(`Jacobi method did not converge after ${jacobiResult.iterations} iterations`);\n }\n\n solutionVector = jacobiResult.solution;\n }\n console.timeEnd(\"systemSolving\");\n basicLog(\"System solved successfully\");\n\n return { solutionVector, nodesCoordinates };\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { numericalIntegration } from \"../methods/numericalIntegrationScript.js\";\nimport { basisFunctions } from \"../mesh/basisFunctionsScript.js\";\nimport { meshGeneration } from \"../mesh/meshGenerationScript.js\";\nimport { ThermalBoundaryConditions } from \"./thermalBoundaryConditionsScript.js\";\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to assemble the solid heat transfer matrix\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing:\n * - jacobianMatrix: The assembled Jacobian matrix\n * - residualVector: The assembled residual vector\n * - nodesCoordinates: Object containing x and y coordinates of nodes\n */\nexport function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {\n basicLog(\"Starting solid heat transfer matrix assembly...\");\n\n // Extract mesh details from the configuration object\n const {\n meshDimension, // The dimension of the mesh\n numElementsX, // Number of elements in x-direction\n numElementsY, // Number of elements in y-direction (only for 2D)\n maxX, // Max x-coordinate (m) of the domain\n maxY, // Max y-coordinate (m) of the domain (only for 2D)\n elementOrder, // The order of elements\n parsedMesh, // The pre-parsed mesh data (if available)\n } = meshConfig;\n\n // Create a new instance of the meshGeneration class\n debugLog(\"Generating mesh...\");\n const meshGenerationData = new meshGeneration({\n numElementsX,\n numElementsY,\n maxX,\n maxY,\n meshDimension,\n elementOrder,\n parsedMesh, // Pass the parsed mesh to the mesh generator\n });\n\n // Generate the mesh\n const nodesCoordinatesAndNumbering = meshGenerationData.generateMesh();\n\n // Extract nodes coordinates and nodal numbering (NOP) from the mesh data\n let nodesXCoordinates = nodesCoordinatesAndNumbering.nodesXCoordinates;\n let nodesYCoordinates = nodesCoordinatesAndNumbering.nodesYCoordinates;\n let totalNodesX = nodesCoordinatesAndNumbering.totalNodesX;\n let totalNodesY = nodesCoordinatesAndNumbering.totalNodesY;\n let nop = nodesCoordinatesAndNumbering.nodalNumbering;\n let boundaryElements = nodesCoordinatesAndNumbering.boundaryElements;\n\n // Check the mesh type\n const isParsedMesh = parsedMesh !== undefined && parsedMesh !== null;\n\n // Calculate totalElements and totalNodes based on mesh type\n let totalElements, totalNodes;\n\n if (isParsedMesh) {\n totalElements = nop.length; // Number of elements is the length of the nodal numbering array\n totalNodes = nodesXCoordinates.length; // Number of nodes is the length of the coordinates array\n\n // Debug log for mesh size\n debugLog(`Using parsed mesh with ${totalElements} elements and ${totalNodes} nodes`);\n } else {\n // For structured mesh, calculate based on dimensions\n totalElements = numElementsX * (meshDimension === \"2D\" ? numElementsY : 1);\n totalNodes = totalNodesX * (meshDimension === \"2D\" ? totalNodesY : 1);\n // Debug log for mesh size\n debugLog(`Using mesh generated from geometry with ${totalElements} elements and ${totalNodes} nodes`);\n }\n\n // Initialize variables for matrix assembly\n let localToGlobalMap = []; // Maps local element node indices to global mesh node indices\n let gaussPoints = []; // Gauss points\n let gaussWeights = []; // Gauss weights\n let basisFunction = []; // Basis functions\n let basisFunctionDerivKsi = []; // Derivatives of basis functions with respect to ksi\n let basisFunctionDerivEta = []; // Derivatives of basis functions with respect to eta (only for 2D)\n let basisFunctionDerivX = []; // The x-derivative of the basis function\n let basisFunctionDerivY = []; // The y-derivative of the basis function (only for 2D)\n let residualVector = []; // Galerkin residuals\n let jacobianMatrix = []; // Jacobian matrix\n let xCoordinates; // x-coordinate (physical coordinates)\n let yCoordinates; // y-coordinate (physical coordinates) (only for 2D)\n let ksiDerivX; // ksi-derivative of xCoordinates\n let etaDerivX; // eta-derivative of xCoordinates (ksi and eta are natural coordinates that vary within a reference element) (only for 2D)\n let ksiDerivY; // ksi-derivative of yCoordinates (only for 2D)\n let etaDerivY; // eta-derivative of yCoordinates (only for 2D)\n let detJacobian; // The jacobian of the isoparametric mapping\n\n // Initialize jacobianMatrix and residualVector arrays\n for (let nodeIndex = 0; nodeIndex < totalNodes; nodeIndex++) {\n residualVector[nodeIndex] = 0;\n jacobianMatrix.push([]);\n for (let colIndex = 0; colIndex < totalNodes; colIndex++) {\n jacobianMatrix[nodeIndex][colIndex] = 0;\n }\n }\n\n // Initialize the basisFunctions class\n const basisFunctionsData = new basisFunctions({\n meshDimension,\n elementOrder,\n });\n\n // Initialize the numericalIntegration class\n const numIntegrationData = new numericalIntegration({\n meshDimension,\n elementOrder,\n });\n\n // Calculate Gauss points and weights\n let gaussPointsAndWeights = numIntegrationData.getGaussPointsAndWeights();\n gaussPoints = gaussPointsAndWeights.gaussPoints;\n gaussWeights = gaussPointsAndWeights.gaussWeights;\n\n // Determine the number of nodes in the reference element based on the first element in the nop array\n const numNodes = nop[0].length;\n\n // Matrix assembly\n for (let elementIndex = 0; elementIndex < totalElements; elementIndex++) {\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n // Subtract 1 from nop in order to start numbering from 0\n localToGlobalMap[localNodeIndex] = nop[elementIndex][localNodeIndex] - 1;\n }\n\n // Loop over Gauss points\n for (let gaussPointIndex1 = 0; gaussPointIndex1 < gaussPoints.length; gaussPointIndex1++) {\n // 1D solid heat transfer\n if (meshDimension === \"1D\") {\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n xCoordinates = 0;\n ksiDerivX = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates += nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n detJacobian = ksiDerivX;\n }\n\n // Compute x-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] = basisFunctionDerivKsi[localNodeIndex] / detJacobian; // The x-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2]);\n }\n }\n // 2D solid heat transfer\n } else if (meshDimension === \"2D\") {\n for (let gaussPointIndex2 = 0; gaussPointIndex2 < gaussPoints.length; gaussPointIndex2++) {\n // Initialise variables for isoparametric mapping\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1],\n gaussPoints[gaussPointIndex2]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n xCoordinates = 0;\n yCoordinates = 0;\n ksiDerivX = 0;\n etaDerivX = 0;\n ksiDerivY = 0;\n etaDerivY = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n yCoordinates +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n ksiDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n detJacobian = meshDimension === \"2D\" ? ksiDerivX * etaDerivY - etaDerivX * ksiDerivY : ksiDerivX;\n }\n\n // Compute x-derivative and y-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] =\n (etaDerivY * basisFunctionDerivKsi[localNodeIndex] -\n ksiDerivY * basisFunctionDerivEta[localNodeIndex]) /\n detJacobian; // The x-derivative of the n basis function\n basisFunctionDerivY[localNodeIndex] =\n (ksiDerivX * basisFunctionDerivEta[localNodeIndex] -\n etaDerivX * basisFunctionDerivKsi[localNodeIndex]) /\n detJacobian; // The y-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n gaussWeights[gaussPointIndex2] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2] +\n basisFunctionDerivY[localNodeIndex1] * basisFunctionDerivY[localNodeIndex2]);\n }\n }\n }\n }\n }\n }\n\n // Create an instance of ThermalBoundaryConditions\n debugLog(\"Applying thermal boundary conditions...\");\n const thermalBoundaryConditions = new ThermalBoundaryConditions(\n boundaryConditions,\n boundaryElements,\n nop,\n meshDimension,\n elementOrder\n );\n\n // Impose Convection boundary conditions\n thermalBoundaryConditions.imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n );\n debugLog(\"Convection boundary conditions applied\");\n\n // Impose ConstantTemp boundary conditions\n thermalBoundaryConditions.imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix);\n debugLog(\"Constant temperature boundary conditions applied\");\n\n basicLog(\"Solid heat transfer matrix assembly completed\");\n\n return {\n jacobianMatrix,\n residualVector,\n nodesCoordinates: {\n nodesXCoordinates,\n nodesYCoordinates,\n },\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to solve a system of linear equations using the Jacobi iterative method\n * @param {array} A - The coefficient matrix (must be square)\n * @param {array} b - The right-hand side vector\n * @param {array} x0 - Initial guess for solution vector\n * @param {number} [maxIterations=100] - Maximum number of iterations\n * @param {number} [tolerance=1e-7] - Convergence tolerance\n * @returns {object} An object containing:\n * - solution: The solution vector\n * - iterations: The number of iterations performed\n * - converged: Boolean indicating whether the method converged\n */\nexport function jacobiMethod(A, b, x0, maxIterations = 100, tolerance = 1e-7) {\n const n = A.length; // Size of the square matrix\n let x = [...x0]; // Current solution (starts with initial guess)\n let xNew = new Array(n); // Next iteration's solution\n\n for (let iteration = 0; iteration < maxIterations; iteration++) {\n // Perform one iteration\n for (let i = 0; i < n; i++) {\n let sum = 0;\n // Calculate sum of A[i][j] * x[j] for j ≠ i\n for (let j = 0; j < n; j++) {\n if (j !== i) {\n sum += A[i][j] * x[j];\n }\n }\n // Update xNew[i] using the Jacobi formula\n xNew[i] = (b[i] - sum) / A[i][i];\n }\n\n // Check convergence\n let maxDiff = 0;\n for (let i = 0; i < n; i++) {\n maxDiff = Math.max(maxDiff, Math.abs(xNew[i] - x[i]));\n }\n\n // Update x for next iteration\n x = [...xNew];\n\n // Successfully converged if maxDiff is less than tolerance\n if (maxDiff < tolerance) {\n return {\n solution: x,\n iterations: iteration + 1,\n converged: true,\n };\n }\n }\n\n // maxIterations were reached without convergence\n return {\n solution: x,\n iterations: maxIterations,\n converged: false,\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// External imports\nimport * as Comlink from \"../vendor/comlink.mjs\";\n\n// Internal imports\nimport { basicLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to facilitate communication with web workers for FEAScript operations\n */\nexport class FEAScriptWorker {\n /**\n * Constructor to initialize the FEAScriptWorker class\n * Sets up the worker and initializes the workerWrapper.\n */\n constructor() {\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n\n this._initWorker();\n }\n\n /**\n * Function to initialize the web worker and wrap it using Comlink.\n * @private\n * @throws Will throw an error if the worker fails to initialize.\n */\n async _initWorker() {\n try {\n this.worker = new Worker(new URL(\"./wrapperScript.js\", import.meta.url), {\n type: \"module\",\n });\n\n this.worker.onerror = (event) => {\n console.error(\"FEAScriptWorker: Worker error:\", event);\n };\n const workerWrapper = Comlink.wrap(this.worker);\n\n this.feaWorker = await new workerWrapper();\n\n this.isReady = true;\n } catch (error) {\n console.error(\"Failed to initialize worker\", error);\n throw error;\n }\n }\n\n /**\n * Function to ensure that the worker is ready before performing any operations.\n * @private\n * @returns {Promise} Resolves when the worker is ready.\n * @throws Will throw an error if the worker is not ready within the timeout period.\n */\n async _ensureReady() {\n if (this.isReady) return Promise.resolve();\n\n return new Promise((resolve, reject) => {\n let attempts = 0;\n const maxAttempts = 50; // 5 seconds max\n\n const checkReady = () => {\n attempts++;\n if (this.isReady) {\n resolve();\n } else if (attempts >= maxAttempts) {\n reject(new Error(\"Timeout waiting for worker to be ready\"));\n } else {\n setTimeout(checkReady, 1000);\n }\n };\n checkReady();\n });\n }\n\n /**\n * Function to set the solver configuration in the worker.\n * @param {string} solverConfig - The solver configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setSolverConfig(solverConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver config to: ${solverConfig}`);\n return this.feaWorker.setSolverConfig(solverConfig);\n }\n\n /**\n * Sets the mesh configuration in the worker.\n * @param {object} meshConfig - The mesh configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setMeshConfig(meshConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting mesh config`);\n return this.feaWorker.setMeshConfig(meshConfig);\n }\n\n /**\n * Adds a boundary condition to the worker.\n * @param {string} boundaryKey - The key identifying the boundary.\n * @param {array} condition - The boundary condition to add.\n * @returns {Promise} Resolves when the boundary condition is added.\n */\n async addBoundaryCondition(boundaryKey, condition) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Adding boundary condition for boundary: ${boundaryKey}`);\n return this.feaWorker.addBoundaryCondition(boundaryKey, condition);\n }\n\n /**\n * Sets the solver method in the worker.\n * @param {string} solverMethod - The solver method to set.\n * @returns {Promise} Resolves when the solver method is set.\n */\n async setSolverMethod(solverMethod) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver method to: ${solverMethod}`);\n return this.feaWorker.setSolverMethod(solverMethod);\n }\n\n /**\n * Requests the worker to solve the problem.\n * @returns {Promise} Resolves with the solution result.\n */\n async solve() {\n await this._ensureReady();\n basicLog(\"FEAScriptWorker: Requesting solution from worker...\");\n\n const startTime = performance.now();\n const result = await this.feaWorker.solve();\n const endTime = performance.now();\n\n basicLog(`FEAScriptWorker: Solution completed in ${((endTime - startTime) / 1000).toFixed(2)}s`);\n return result;\n }\n\n /**\n * Retrieves model information from the worker.\n * @returns {Promise} Resolves with the model information.\n */\n async getModelInfo() {\n await this._ensureReady();\n return this.feaWorker.getModelInfo();\n }\n\n /**\n * Sends a ping request to the worker to check its availability.\n * @returns {Promise} Resolves if the worker responds.\n */\n async ping() {\n await this._ensureReady();\n return this.feaWorker.ping();\n }\n\n /**\n * Terminates the worker and cleans up resources.\n */\n terminate() {\n if (this.worker) {\n this.worker.terminate();\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n }\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\nexport { FEAScriptModel } from \"./FEAScript.js\";\nexport { importGmshQuadTri } from \"./readers/gmshReaderScript.js\";\nexport { logSystem, printVersion } from \"./utilities/loggingScript.js\";\nexport { plotSolution } from \"./visualization/plotSolutionScript.js\";\nexport { FEAScriptWorker } from \"./workers/workerScript.js\";\nexport const VERSION = \"0.1.1\";","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to import mesh data from Gmsh format containing quadrilateral and triangular elements\n * @param {File} file - The Gmsh file to be parsed (.msh version 4.1)\n * @returns {object} The parsed mesh data including node coordinates, element connectivity, and boundary conditions\n */\nconst importGmshQuadTri = async (file) => {\n let result = {\n nodesXCoordinates: [],\n nodesYCoordinates: [],\n nodalNumbering: {\n quadElements: [],\n triangleElements: [],\n },\n boundaryElements: [],\n boundaryConditions: [],\n boundaryNodePairs: {}, // Store boundary node pairs for processing in meshGenerationScript\n gmshV: 0,\n ascii: false,\n fltBytes: \"8\",\n totalNodesX: 0,\n totalNodesY: 0,\n physicalPropMap: [],\n elementTypes: {},\n };\n\n let content = await file.text();\n let lines = content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\" && line !== \" \");\n\n let section = \"\";\n let lineIndex = 0;\n\n let nodeEntityBlocks = 0;\n let totalNodes = 0;\n let nodeBlocksProcessed = 0;\n let currentNodeBlock = { numNodes: 0 };\n let nodeTagsCollected = 0;\n let nodeTags = [];\n let nodeCoordinatesCollected = 0;\n\n let elementEntityBlocks = 0;\n let totalElements = 0;\n let elementBlocksProcessed = 0;\n let currentElementBlock = {\n dim: 0,\n tag: 0,\n elementType: 0,\n numElements: 0,\n };\n let elementsProcessedInBlock = 0;\n\n let boundaryElementsByTag = {};\n\n while (lineIndex < lines.length) {\n const line = lines[lineIndex];\n\n if (line === \"$MeshFormat\") {\n section = \"meshFormat\";\n lineIndex++;\n continue;\n } else if (line === \"$EndMeshFormat\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$PhysicalNames\") {\n section = \"physicalNames\";\n lineIndex++;\n continue;\n } else if (line === \"$EndPhysicalNames\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Entities\") {\n section = \"entities\";\n lineIndex++;\n continue;\n } else if (line === \"$EndEntities\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Nodes\") {\n section = \"nodes\";\n lineIndex++;\n continue;\n } else if (line === \"$EndNodes\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Elements\") {\n section = \"elements\";\n lineIndex++;\n continue;\n } else if (line === \"$EndElements\") {\n section = \"\";\n lineIndex++;\n continue;\n }\n\n const parts = line.split(/\\s+/).filter((part) => part !== \"\");\n\n if (section === \"meshFormat\") {\n result.gmshV = parseFloat(parts[0]);\n result.ascii = parts[1] === \"0\";\n result.fltBytes = parts[2];\n } else if (section === \"physicalNames\") {\n if (parts.length >= 3) {\n if (!/^\\d+$/.test(parts[0])) {\n lineIndex++;\n continue;\n }\n\n const dimension = parseInt(parts[0], 10);\n const tag = parseInt(parts[1], 10);\n let name = parts.slice(2).join(\" \");\n name = name.replace(/^\"|\"$/g, \"\");\n\n result.physicalPropMap.push({\n tag,\n dimension,\n name,\n });\n }\n } else if (section === \"nodes\") {\n if (nodeEntityBlocks === 0) {\n nodeEntityBlocks = parseInt(parts[0], 10);\n totalNodes = parseInt(parts[1], 10);\n result.nodesXCoordinates = new Array(totalNodes).fill(0);\n result.nodesYCoordinates = new Array(totalNodes).fill(0);\n lineIndex++;\n continue;\n }\n\n if (nodeBlocksProcessed < nodeEntityBlocks && currentNodeBlock.numNodes === 0) {\n currentNodeBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n parametric: parseInt(parts[2], 10),\n numNodes: parseInt(parts[3], 10),\n };\n\n nodeTags = [];\n nodeTagsCollected = 0;\n nodeCoordinatesCollected = 0;\n\n lineIndex++;\n continue;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n for (let i = 0; i < parts.length && nodeTagsCollected < currentNodeBlock.numNodes; i++) {\n nodeTags.push(parseInt(parts[i], 10));\n nodeTagsCollected++;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n lineIndex++;\n continue;\n }\n\n lineIndex++;\n continue;\n }\n\n if (nodeCoordinatesCollected < currentNodeBlock.numNodes) {\n const nodeTag = nodeTags[nodeCoordinatesCollected] - 1;\n const x = parseFloat(parts[0]);\n const y = parseFloat(parts[1]);\n\n result.nodesXCoordinates[nodeTag] = x;\n result.nodesYCoordinates[nodeTag] = y;\n result.totalNodesX++;\n result.totalNodesY++;\n\n nodeCoordinatesCollected++;\n\n if (nodeCoordinatesCollected === currentNodeBlock.numNodes) {\n nodeBlocksProcessed++;\n currentNodeBlock = { numNodes: 0 };\n }\n }\n } else if (section === \"elements\") {\n if (elementEntityBlocks === 0) {\n elementEntityBlocks = parseInt(parts[0], 10);\n totalElements = parseInt(parts[1], 10);\n lineIndex++;\n continue;\n }\n\n if (elementBlocksProcessed < elementEntityBlocks && currentElementBlock.numElements === 0) {\n currentElementBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n elementType: parseInt(parts[2], 10),\n numElements: parseInt(parts[3], 10),\n };\n\n result.elementTypes[currentElementBlock.elementType] =\n (result.elementTypes[currentElementBlock.elementType] || 0) + currentElementBlock.numElements;\n\n elementsProcessedInBlock = 0;\n lineIndex++;\n continue;\n }\n\n if (elementsProcessedInBlock < currentElementBlock.numElements) {\n const elementTag = parseInt(parts[0], 10);\n const nodeIndices = parts.slice(1).map((idx) => parseInt(idx, 10));\n\n if (currentElementBlock.elementType === 1 || currentElementBlock.elementType === 8) {\n const physicalTag = currentElementBlock.tag;\n\n if (!boundaryElementsByTag[physicalTag]) {\n boundaryElementsByTag[physicalTag] = [];\n }\n\n boundaryElementsByTag[physicalTag].push(nodeIndices);\n\n // Store boundary node pairs for later processing in meshGenerationScript\n if (!result.boundaryNodePairs[physicalTag]) {\n result.boundaryNodePairs[physicalTag] = [];\n }\n result.boundaryNodePairs[physicalTag].push(nodeIndices);\n } else if (currentElementBlock.elementType === 2) {\n // Linear triangle elements (3 nodes)\n result.nodalNumbering.triangleElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 3) {\n // Linear quadrilateral elements (4 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 10) {\n // Quadratic quadrilateral elements (9 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n }\n\n elementsProcessedInBlock++;\n\n if (elementsProcessedInBlock === currentElementBlock.numElements) {\n elementBlocksProcessed++;\n currentElementBlock = { numElements: 0 };\n }\n }\n }\n\n lineIndex++;\n }\n\n // Store boundary conditions information\n result.physicalPropMap.forEach((prop) => {\n if (prop.dimension === 1) {\n const boundaryNodes = boundaryElementsByTag[prop.tag] || [];\n\n if (boundaryNodes.length > 0) {\n result.boundaryConditions.push({\n name: prop.name,\n tag: prop.tag,\n nodes: boundaryNodes,\n });\n }\n }\n });\n\n debugLog(\n `Parsed boundary node pairs by physical tag: ${JSON.stringify(\n result.boundaryNodePairs\n )}. These pairs will be used to identify boundary elements in the mesh.`\n );\n\n return result;\n};\n\nexport { importGmshQuadTri };\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to create plots of the solution vector\n * @param {*} solutionVector - The computed solution vector\n * @param {*} nodesCoordinates - Object containing x and y coordinates for the nodes\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {string} meshDimension - The dimension of the solution\n * @param {string} plotType - The type of plot\n * @param {string} plotDivId - The id of the div where the plot will be rendered\n * @param {string} [meshType=\"structured\"] - Type of mesh: \"structured\" or \"unstructured\"\n */\nexport function plotSolution(\n solutionVector,\n nodesCoordinates,\n solverConfig,\n meshDimension,\n plotType,\n plotDivId,\n meshType = \"structured\"\n) {\n const { nodesXCoordinates, nodesYCoordinates } = nodesCoordinates;\n\n if (meshDimension === \"1D\" && plotType === \"line\") {\n // Check if solutionVector is a nested array\n let yData;\n if (solutionVector.length > 0 && Array.isArray(solutionVector[0])) {\n yData = solutionVector.map((arr) => arr[0]);\n } else {\n yData = solutionVector;\n }\n let xData = Array.from(nodesXCoordinates);\n\n let lineData = {\n x: xData,\n y: yData,\n mode: \"lines\",\n type: \"scatter\",\n line: { color: \"rgb(219, 64, 82)\", width: 2 },\n name: \"Solution\",\n };\n\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxPlotWidth = Math.max(...xData);\n let zoomFactor = maxWindowWidth / maxPlotWidth;\n let plotWidth = Math.max(zoomFactor * maxPlotWidth, 400);\n let plotHeight = 350;\n\n let layout = {\n title: `line plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"Solution\" },\n margin: { l: 70, r: 40, t: 50, b: 50 },\n };\n\n Plotly.newPlot(plotDivId, [lineData], layout, { responsive: true });\n } else if (meshDimension === \"2D\" && plotType === \"contour\") {\n // Use the user-provided mesh type\n const isStructured = meshType === \"structured\";\n \n // For auto-detection (if needed)\n const uniqueXCoords = new Set(nodesXCoordinates).size;\n const uniqueYCoords = new Set(nodesYCoordinates).size;\n \n // Extract scalar values from solution vector\n let zValues = Array.isArray(solutionVector[0]) \n ? solutionVector.map(val => val[0]) \n : solutionVector;\n \n // Common sizing parameters for both plot types\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxX = Math.max(...nodesXCoordinates);\n let maxY = Math.max(...nodesYCoordinates);\n let aspectRatio = maxY / maxX;\n let plotWidth = Math.min(maxWindowWidth, 600);\n let plotHeight = plotWidth * aspectRatio * 0.8; // Slightly reduce height for better appearance\n \n // Common layout properties\n let layout = {\n title: `${plotType} plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"y\" },\n margin: { l: 50, r: 50, t: 50, b: 50 },\n hovermode: 'closest'\n };\n \n if (isStructured) {\n // Calculate the number of nodes along the x-axis and y-axis\n const numNodesX = uniqueXCoords;\n const numNodesY = uniqueYCoords;\n\n // Reshape the nodesXCoordinates and nodesYCoordinates arrays to match the grid dimensions\n let reshapedXCoordinates = math.reshape(Array.from(nodesXCoordinates), [numNodesX, numNodesY]);\n let reshapedYCoordinates = math.reshape(Array.from(nodesYCoordinates), [numNodesX, numNodesY]);\n\n // Reshape the solution array to match the grid dimensions\n let reshapedSolution = math.reshape(Array.from(solutionVector), [numNodesX, numNodesY]);\n\n // Transpose the reshapedSolution array to get column-wise data\n let transposedSolution = math.transpose(reshapedSolution);\n\n // Create an array for x-coordinates used in the contour plot\n let reshapedXForPlot = [];\n for (let i = 0; i < numNodesX * numNodesY; i += numNodesY) {\n let xValue = nodesXCoordinates[i];\n reshapedXForPlot.push(xValue);\n }\n\n // Create the data structure for the contour plot\n let contourData = {\n z: transposedSolution,\n type: \"contour\",\n contours: {\n coloring: \"heatmap\",\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n x: reshapedXForPlot,\n y: reshapedYCoordinates[0],\n name: 'Solution Field'\n };\n\n // Create the plot using Plotly\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n } else {\n // Create an interpolated contour plot for the unstructured mesh\n let contourData = {\n x: nodesXCoordinates,\n y: nodesYCoordinates,\n z: zValues,\n type: 'contour',\n contours: {\n coloring: 'heatmap',\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n name: 'Solution Field'\n };\n \n // Create the plot using only the contour fill\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n }\n }\n}\n"],"names":["numericalIntegration","constructor","meshDimension","elementOrder","this","getGaussPointsAndWeights","gaussPoints","gaussWeights","Math","sqrt","currentLogLevel","debugLog","message","console","log","basicLog","errorLog","basisFunctions","getBasisFunctions","ksi","eta","basisFunction","basisFunctionDerivKsi","basisFunctionDerivEta","l1","c","l2","l3","dl1","dl2","dl3","meshGeneration","numElementsX","maxX","numElementsY","maxY","parsedMesh","generateMesh","nodalNumbering","Array","isArray","quadElements","triangleElements","JSON","stringify","elementTypes","mappedNodalNumbering","elemIdx","length","gmshNodes","feaScriptNodes","push","physicalPropMap","boundaryElements","undefined","fixedBoundaryElements","i","boundaryNodePairs","boundaryElementsProcessed","forEach","prop","dimension","tag","nodesPair","node1","node2","name","foundElement","elemNodes","includes","side","node1Index","indexOf","node2Index","join","generateMeshFromGeometry","nodesXCoordinates","nodesYCoordinates","totalNodesX","totalNodesY","deltaX","deltaY","nodeIndex","generateNodalNumbering","findBoundaryElements","nodeIndexY","nodeIndexX","nnode","maxSides","sideIndex","elementIndexX","elementIndexY","elementIndex","nop","columnCounter","rowCounter","nodeIndex1","nodeIndex2","ThermalBoundaryConditions","boundaryConditions","imposeConstantTempBoundaryConditions","residualVector","jacobianMatrix","Object","keys","boundaryKey","tempValue","globalNodeIndex","colIndex","imposeConvectionBoundaryConditions","basisFunctionsData","convectionHeatTranfCoeff","convectionExtTemp","key","boundaryCondition","convectionCoeff","extTemp","gaussPoint1","gaussPoint2","firstNodeIndex","lastNodeIndex","nodeIncrement","basisFunctionsAndDerivatives","ksiDerivX","ksiDerivY","etaDerivX","etaDerivY","numNodes","tangentVectorLength","localNodeIndex","localNodeIndex2","globalNodeIndex2","gaussPointIndex","proxyMarker","Symbol","createEndpoint","releaseProxy","finalizer","throwMarker","isObject","val","transferHandlers","Map","canHandle","serialize","obj","port1","port2","MessageChannel","expose","deserialize","port","start","wrap","value","serialized","Error","isError","stack","assign","ep","globalThis","allowedOrigins","addEventListener","callback","ev","data","origin","allowedOrigin","RegExp","test","isAllowedOrigin","warn","id","type","path","argumentList","map","fromWireValue","returnValue","parent","slice","reduce","rawValue","apply","proxy","transfers","transferCache","set","transfer","Promise","resolve","catch","then","wireValue","transferables","toWireValue","postMessage","removeEventListener","closeEndPoint","error","TypeError","endpoint","isMessagePort","close","target","pendingListeners","resolver","get","delete","createProxy","throwIfProxyReleased","isReleased","releaseEndpoint","requestResponseMessage","proxyCounter","WeakMap","proxyFinalizers","FinalizationRegistry","newCount","isProxyReleased","Proxy","_target","unregister","unregisterProxy","clear","r","p","toString","bind","_thisArg","rawArgumentList","last","processArguments","construct","register","registerProxy","processed","v","arr","prototype","concat","handler","serializedValue","msg","fill","floor","random","Number","MAX_SAFE_INTEGER","solverConfig","meshConfig","solverMethod","setSolverConfig","setMeshConfig","addBoundaryCondition","condition","setSolverMethod","solve","solutionVector","nodesCoordinates","time","nodesCoordinatesAndNumbering","totalElements","totalNodes","xCoordinates","yCoordinates","detJacobian","localToGlobalMap","basisFunctionDerivX","basisFunctionDerivY","gaussPointsAndWeights","gaussPointIndex1","localNodeIndex1","localToGlobalMap1","localToGlobalMap2","gaussPointIndex2","thermalBoundaryConditions","assembleSolidHeatTransferMat","timeEnd","math","lusolve","jacobiResult","A","b","x0","maxIterations","tolerance","n","x","xNew","iteration","sum","j","maxDiff","max","abs","solution","iterations","converged","jacobiMethod","worker","feaWorker","isReady","_initWorker","Worker","URL","document","require","__filename","href","currentScript","tagName","toUpperCase","src","baseURI","onerror","event","workerWrapper","Comlink.wrap","_ensureReady","reject","attempts","checkReady","setTimeout","startTime","performance","now","result","toFixed","getModelInfo","ping","terminate","async","file","gmshV","ascii","fltBytes","lines","text","split","line","trim","filter","section","lineIndex","nodeEntityBlocks","nodeBlocksProcessed","currentNodeBlock","nodeTagsCollected","nodeTags","nodeCoordinatesCollected","elementEntityBlocks","elementBlocksProcessed","currentElementBlock","dim","elementType","numElements","elementsProcessedInBlock","boundaryElementsByTag","parts","part","parseFloat","parseInt","replace","parametric","nodeTag","y","nodeIndices","idx","physicalTag","boundaryNodes","nodes","level","plotType","plotDivId","meshType","yData","xData","from","lineData","mode","color","width","maxWindowWidth","min","window","innerWidth","maxPlotWidth","zoomFactor","layout","title","height","xaxis","yaxis","margin","l","t","Plotly","newPlot","responsive","isStructured","uniqueXCoords","Set","size","uniqueYCoords","zValues","aspectRatio","plotWidth","hovermode","numNodesX","numNodesY","reshape","reshapedYCoordinates","reshapedSolution","transposedSolution","transpose","reshapedXForPlot","xValue","contourData","z","contours","coloring","showlabels","colorbar","commitResponse","fetch","commitData","json","latestCommitDate","Date","commit","committer","date","toLocaleString"],"mappings":"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"} \ No newline at end of file diff --git a/dist/feascript.esm.js b/dist/feascript.esm.js new file mode 100644 index 0000000..899a50b --- /dev/null +++ b/dist/feascript.esm.js @@ -0,0 +1,7 @@ +class e{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getGaussPointsAndWeights(){let e=[],t=[];return"linear"===this.elementOrder?(e[0]=.5,t[0]=1):"quadratic"===this.elementOrder&&(e[0]=(1-Math.sqrt(.6))/2,e[1]=.5,e[2]=(1+Math.sqrt(.6))/2,t[0]=5/18,t[1]=8/18,t[2]=5/18),{gaussPoints:e,gaussWeights:t}}}let t="basic";function n(e){"basic"!==e&&"debug"!==e?(console.log("%c[WARN] Invalid log level: "+e+". Using basic instead.","color: #FFC107; font-weight: bold;"),t="basic"):(t=e,o(`Log level set to: ${e}`))}function s(e){"debug"===t&&console.log("%c[DEBUG] "+e,"color: #2196F3; font-weight: bold;")}function o(e){console.log("%c[INFO] "+e,"color: #4CAF50; font-weight: bold;")}function i(e){console.log("%c[ERROR] "+e,"color: #F44336; font-weight: bold;")}async function r(){o("Fetching latest FEAScript version information...");try{const e=await fetch("https://api.github.com/repos/FEAScript/FEAScript/commits/main"),t=await e.json(),n=new Date(t.commit.committer.date).toLocaleString();return o(`Latest FEAScript update: ${n}`),n}catch(e){return i("Failed to fetch version information: "+e),"Version information unavailable"}}class a{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getBasisFunctions(e,t=null){let n=[],s=[],o=[];if("1D"===this.meshDimension)"linear"===this.elementOrder?(n[0]=1-e,n[1]=e,s[0]=-1,s[1]=1):"quadratic"===this.elementOrder&&(n[0]=1-3*e+2*e**2,n[1]=4*e-4*e**2,n[2]=2*e**2-e,s[0]=4*e-3,s[1]=4-8*e,s[2]=4*e-1);else if("2D"===this.meshDimension){if(null===t)return void i("Eta coordinate is required for 2D elements");if("linear"===this.elementOrder){function r(e){return 1-e}n[0]=r(e)*r(t),n[1]=r(e)*t,n[2]=e*r(t),n[3]=e*t,s[0]=-1*r(t),s[1]=-1*t,s[2]=1*r(t),s[3]=1*t,o[0]=-1*r(e),o[1]=1*r(e),o[2]=-1*e,o[3]=1*e}else if("quadratic"===this.elementOrder){function a(e){return 2*e**2-3*e+1}function l(e){return-4*e**2+4*e}function d(e){return 2*e**2-e}function h(e){return 4*e-3}function m(e){return-8*e+4}function u(e){return 4*e-1}n[0]=a(e)*a(t),n[1]=a(e)*l(t),n[2]=a(e)*d(t),n[3]=l(e)*a(t),n[4]=l(e)*l(t),n[5]=l(e)*d(t),n[6]=d(e)*a(t),n[7]=d(e)*l(t),n[8]=d(e)*d(t),s[0]=h(e)*a(t),s[1]=h(e)*l(t),s[2]=h(e)*d(t),s[3]=m(e)*a(t),s[4]=m(e)*l(t),s[5]=m(e)*d(t),s[6]=u(e)*a(t),s[7]=u(e)*l(t),s[8]=u(e)*d(t),o[0]=a(e)*h(t),o[1]=a(e)*m(t),o[2]=a(e)*u(t),o[3]=l(e)*h(t),o[4]=l(e)*m(t),o[5]=l(e)*u(t),o[6]=d(e)*h(t),o[7]=d(e)*m(t),o[8]=d(e)*u(t)}}return{basisFunction:n,basisFunctionDerivKsi:s,basisFunctionDerivEta:o}}}class l{constructor({numElementsX:e=null,maxX:t=null,numElementsY:n=null,maxY:s=null,meshDimension:o=null,elementOrder:i="linear",parsedMesh:r=null}){this.numElementsX=e,this.numElementsY=n,this.maxX=t,this.maxY=s,this.meshDimension=o,this.elementOrder=i,this.parsedMesh=r}generateMesh(){if(this.parsedMesh){if(this.parsedMesh.nodalNumbering&&"object"==typeof this.parsedMesh.nodalNumbering&&!Array.isArray(this.parsedMesh.nodalNumbering)){const e=this.parsedMesh.nodalNumbering.quadElements||[];if(this.parsedMesh.nodalNumbering.triangleElements,s("Initial parsed mesh nodal numbering from GMSH format: "+JSON.stringify(this.parsedMesh.nodalNumbering)),this.parsedMesh.elementTypes[3]||this.parsedMesh.elementTypes[10]){const t=[];for(let n=0;n0&&void 0===this.parsedMesh.boundaryElements[0]){const e=[];for(let t=1;t{if(1===e.dimension){const t=this.parsedMesh.boundaryNodePairs[e.tag]||[];t.length>0&&(this.parsedMesh.boundaryElements[e.tag]||(this.parsedMesh.boundaryElements[e.tag]=[]),t.forEach((t=>{const n=t[0],o=t[1];s(`Processing boundary node pair: [${n}, ${o}] for boundary ${e.tag} (${e.name||"unnamed"})`);let r=!1;for(let t=0;t0&&void 0===this.parsedMesh.boundaryElements[0])){const e=[];for(let t=1;t{if("constantTemp"===this.boundaryConditions[n][0]){const o=this.boundaryConditions[n][1];s(`Boundary ${n}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[n].forEach((([n,i])=>{if("linear"===this.elementOrder){({0:[0],1:[1]})[i].forEach((i=>{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{if("constantTemp"===this.boundaryConditions[n][0]){const o=this.boundaryConditions[n][1];s(`Boundary ${n}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[n].forEach((([n,i])=>{if("linear"===this.elementOrder){({0:[0,2],1:[0,1],2:[1,3],3:[2,3]})[i].forEach((i=>{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const t=this.boundaryConditions[e];"convection"===t[0]&&(d[e]=t[1],h[e]=t[2])})),"1D"===this.meshDimension?Object.keys(this.boundaryConditions).forEach((n=>{if("convection"===this.boundaryConditions[n][0]){const o=d[n],i=h[n];s(`Boundary ${n}: Applying convection with heat transfer coefficient h=${o} W/(m²·K) and external temperature T∞=${i} K`),this.boundaryElements[n].forEach((([n,r])=>{let a;"linear"===this.elementOrder?a=0===r?0:1:"quadratic"===this.elementOrder&&(a=0===r?0:2);const l=this.nop[n][a]-1;s(` - Applied convection boundary condition to node ${l+1} (element ${n+1}, local node ${a+1})`),e[l]+=-o*i,t[l][l]+=o}))}})):"2D"===this.meshDimension&&Object.keys(this.boundaryConditions).forEach((o=>{if("convection"===this.boundaryConditions[o][0]){const m=d[o],u=h[o];s(`Boundary ${o}: Applying convection with heat transfer coefficient h=${m} W/(m²·K) and external temperature T∞=${u} K`),this.boundaryElements[o].forEach((([o,d])=>{if("linear"===this.elementOrder){let h,c,f,p,y;0===d?(h=n[0],c=0,f=0,p=3,y=2):1===d?(h=0,c=n[0],f=0,p=2,y=1):2===d?(h=n[0],c=1,f=1,p=4,y=2):3===d&&(h=1,c=n[0],f=2,p=4,y=1);let g=l.getBasisFunctions(h,c),b=g.basisFunction,E=g.basisFunctionDerivKsi,M=g.basisFunctionDerivEta,$=0,v=0,w=0,C=0;const N=this.nop[o].length;for(let e=0;e{let t={nodesXCoordinates:[],nodesYCoordinates:[],nodalNumbering:{quadElements:[],triangleElements:[]},boundaryElements:[],boundaryConditions:[],boundaryNodePairs:{},gmshV:0,ascii:!1,fltBytes:"8",totalNodesX:0,totalNodesY:0,physicalPropMap:[],elementTypes:{}},n=(await e.text()).split("\n").map((e=>e.trim())).filter((e=>""!==e&&" "!==e)),o="",i=0,r=0,a=0,l=0,d={numNodes:0},h=0,m=[],u=0,c=0,f=0,p={dim:0,tag:0,elementType:0,numElements:0},y=0,g={};for(;i""!==e));if("meshFormat"===o)t.gmshV=parseFloat(s[0]),t.ascii="0"===s[1],t.fltBytes=s[2];else if("physicalNames"===o){if(s.length>=3){if(!/^\d+$/.test(s[0])){i++;continue}const e=parseInt(s[0],10),n=parseInt(s[1],10);let o=s.slice(2).join(" ");o=o.replace(/^"|"$/g,""),t.physicalPropMap.push({tag:n,dimension:e,name:o})}}else if("nodes"===o){if(0===r){r=parseInt(s[0],10),a=parseInt(s[1],10),t.nodesXCoordinates=new Array(a).fill(0),t.nodesYCoordinates=new Array(a).fill(0),i++;continue}if(lparseInt(e,10)));if(1===p.elementType||8===p.elementType){const n=p.tag;g[n]||(g[n]=[]),g[n].push(e),t.boundaryNodePairs[n]||(t.boundaryNodePairs[n]=[]),t.boundaryNodePairs[n].push(e)}else 2===p.elementType?t.nodalNumbering.triangleElements.push(e):(3===p.elementType||10===p.elementType)&&t.nodalNumbering.quadElements.push(e);y++,y===p.numElements&&(f++,p={numElements:0})}}i++}return t.physicalPropMap.forEach((e=>{if(1===e.dimension){const n=g[e.tag]||[];n.length>0&&t.boundaryConditions.push({name:e.name,tag:e.tag,nodes:n})}})),s(`Parsed boundary node pairs by physical tag: ${JSON.stringify(t.boundaryNodePairs)}. These pairs will be used to identify boundary elements in the mesh.`),t};function u(e,t,n,s,o,i,r="structured"){const{nodesXCoordinates:a,nodesYCoordinates:l}=t;if("1D"===s&&"line"===o){let t;t=e.length>0&&Array.isArray(e[0])?e.map((e=>e[0])):e;let s=Array.from(a),o={x:s,y:t,mode:"lines",type:"scatter",line:{color:"rgb(219, 64, 82)",width:2},name:"Solution"},r=Math.min(window.innerWidth,700),l=Math.max(...s),d=r/l,h={title:`line plot - ${n}`,width:Math.max(d*l,400),height:350,xaxis:{title:"x"},yaxis:{title:"Solution"},margin:{l:70,r:40,t:50,b:50}};Plotly.newPlot(i,[o],h,{responsive:!0})}else if("2D"===s&&"contour"===o){const t="structured"===r,s=new Set(a).size,d=new Set(l).size;let h=Array.isArray(e[0])?e.map((e=>e[0])):e,m=Math.min(window.innerWidth,700),u=Math.max(...a),c=Math.max(...l)/u,f=Math.min(m,600),p={title:`${o} plot - ${n}`,width:f,height:f*c*.8,xaxis:{title:"x"},yaxis:{title:"y"},margin:{l:50,r:50,t:50,b:50},hovermode:"closest"};if(t){const t=s,n=d;math.reshape(Array.from(a),[t,n]);let o=math.reshape(Array.from(l),[t,n]),r=math.reshape(Array.from(e),[t,n]),h=math.transpose(r),m=[];for(let e=0;e"object"==typeof e&&null!==e||"function"==typeof e,E=new Map([["proxy",{canHandle:e=>b(e)&&e[c],serialize(e){const{port1:t,port2:n}=new MessageChannel;return M(e,t),[n,[n]]},deserialize:e=>(e.start(),v(e))}],["throw",{canHandle:e=>b(e)&&g in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function M(e,t=globalThis,n=["*"]){t.addEventListener("message",(function s(o){if(!o||!o.data)return;if(!function(e,t){for(const n of e){if(t===n||"*"===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}return!1}(n,o.origin))return void console.warn(`Invalid origin '${o.origin}' for comlink proxy`);const{id:i,type:r,path:a}=Object.assign({path:[]},o.data),l=(o.data.argumentList||[]).map(F);let d;try{const t=a.slice(0,-1).reduce(((e,t)=>e[t]),e),n=a.reduce(((e,t)=>e[t]),e);switch(r){case"GET":d=n;break;case"SET":t[a.slice(-1)[0]]=F(o.data.value),d=!0;break;case"APPLY":d=n.apply(t,l);break;case"CONSTRUCT":d=function(e){return Object.assign(e,{[c]:!0})}(new n(...l));break;case"ENDPOINT":{const{port1:t,port2:n}=new MessageChannel;M(e,n),d=function(e,t){return x.set(e,t),e}(t,[t])}break;case"RELEASE":d=void 0;break;default:return}}catch(e){d={value:e,[g]:0}}Promise.resolve(d).catch((e=>({value:e,[g]:0}))).then((n=>{const[o,a]=A(n);t.postMessage(Object.assign(Object.assign({},o),{id:i}),a),"RELEASE"===r&&(t.removeEventListener("message",s),$(t),y in e&&"function"==typeof e[y]&&e[y]())})).catch((e=>{const[n,s]=A({value:new TypeError("Unserializable return value"),[g]:0});t.postMessage(Object.assign(Object.assign({},n),{id:i}),s)}))})),t.start&&t.start()}function $(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function v(e,t){const n=new Map;return e.addEventListener("message",(function(e){const{data:t}=e;if(!t||!t.id)return;const s=n.get(t.id);if(s)try{s(t)}finally{n.delete(t.id)}})),D(e,n,[],t)}function w(e){if(e)throw new Error("Proxy has been released and is not useable")}function C(e){return T(e,new Map,{type:"RELEASE"}).then((()=>{$(e)}))}const N=new WeakMap,S="FinalizationRegistry"in globalThis&&new FinalizationRegistry((e=>{const t=(N.get(e)||0)-1;N.set(e,t),0===t&&C(e)}));function D(e,t,n=[],s=function(){}){let o=!1;const i=new Proxy(s,{get(s,r){if(w(o),r===p)return()=>{!function(e){S&&S.unregister(e)}(i),C(e),t.clear(),o=!0};if("then"===r){if(0===n.length)return{then:()=>i};const s=T(e,t,{type:"GET",path:n.map((e=>e.toString()))}).then(F);return s.then.bind(s)}return D(e,t,[...n,r])},set(s,i,r){w(o);const[a,l]=A(r);return T(e,t,{type:"SET",path:[...n,i].map((e=>e.toString())),value:a},l).then(F)},apply(s,i,r){w(o);const a=n[n.length-1];if(a===f)return T(e,t,{type:"ENDPOINT"}).then(F);if("bind"===a)return D(e,t,n.slice(0,-1));const[l,d]=O(r);return T(e,t,{type:"APPLY",path:n.map((e=>e.toString())),argumentList:l},d).then(F)},construct(s,i){w(o);const[r,a]=O(i);return T(e,t,{type:"CONSTRUCT",path:n.map((e=>e.toString())),argumentList:r},a).then(F)}});return function(e,t){const n=(N.get(t)||0)+1;N.set(t,n),S&&S.register(e,t,e)}(i,e),i}function O(e){const t=e.map(A);return[t.map((e=>e[0])),(n=t.map((e=>e[1])),Array.prototype.concat.apply([],n))];var n}const x=new WeakMap;function A(e){for(const[t,n]of E)if(n.canHandle(e)){const[s,o]=n.serialize(e);return[{type:"HANDLER",name:t,value:s},o]}return[{type:"RAW",value:e},x.get(e)||[]]}function F(e){switch(e.type){case"HANDLER":return E.get(e.name).deserialize(e.value);case"RAW":return e.value}}function T(e,t,n,s){return new Promise((o=>{const i=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");t.set(i,o),e.start&&e.start(),e.postMessage(Object.assign({id:i},n),s)}))}class k{constructor(){this.worker=null,this.feaWorker=null,this.isReady=!1,this._initWorker()}async _initWorker(){try{this.worker=new Worker(new URL("./wrapperScript.js",import.meta.url),{type:"module"}),this.worker.onerror=e=>{console.error("FEAScriptWorker: Worker error:",e)};const e=v(this.worker);this.feaWorker=await new e,this.isReady=!0}catch(e){throw console.error("Failed to initialize worker",e),e}}async _ensureReady(){return this.isReady?Promise.resolve():new Promise(((e,t)=>{let n=0;const s=()=>{n++,this.isReady?e():n>=50?t(new Error("Timeout waiting for worker to be ready")):setTimeout(s,1e3)};s()}))}async setSolverConfig(e){return await this._ensureReady(),o(`FEAScriptWorker: Setting solver config to: ${e}`),this.feaWorker.setSolverConfig(e)}async setMeshConfig(e){return await this._ensureReady(),o("FEAScriptWorker: Setting mesh config"),this.feaWorker.setMeshConfig(e)}async addBoundaryCondition(e,t){return await this._ensureReady(),o(`FEAScriptWorker: Adding boundary condition for boundary: ${e}`),this.feaWorker.addBoundaryCondition(e,t)}async setSolverMethod(e){return await this._ensureReady(),o(`FEAScriptWorker: Setting solver method to: ${e}`),this.feaWorker.setSolverMethod(e)}async solve(){await this._ensureReady(),o("FEAScriptWorker: Requesting solution from worker...");const e=performance.now(),t=await this.feaWorker.solve();return o(`FEAScriptWorker: Solution completed in ${((performance.now()-e)/1e3).toFixed(2)}s`),t}async getModelInfo(){return await this._ensureReady(),this.feaWorker.getModelInfo()}async ping(){return await this._ensureReady(),this.feaWorker.ping()}terminate(){this.worker&&(this.worker.terminate(),this.worker=null,this.feaWorker=null,this.isReady=!1)}}const X="0.1.1";export{h as FEAScriptModel,k as FEAScriptWorker,X as VERSION,m as importGmshQuadTri,n as logSystem,u as plotSolution,r as printVersion}; +//# sourceMappingURL=feascript.esm.js.map diff --git a/dist/feascript.esm.js.map b/dist/feascript.esm.js.map new file mode 100644 index 0000000..ed35053 --- /dev/null +++ b/dist/feascript.esm.js.map @@ -0,0 +1 @@ +{"version":3,"file":"feascript.esm.js","sources":["../src/methods/numericalIntegrationScript.js","../src/utilities/loggingScript.js","../src/mesh/basisFunctionsScript.js","../src/mesh/meshGenerationScript.js","../src/solvers/thermalBoundaryConditionsScript.js","../src/FEAScript.js","../src/solvers/solidHeatTransferScript.js","../src/methods/jacobiMethodScript.js","../src/readers/gmshReaderScript.js","../src/visualization/plotSolutionScript.js","../src/vendor/comlink.mjs","../src/workers/workerScript.js","../src/index.js"],"sourcesContent":["// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Class to handle numerical integration using Gauss quadrature\n */\nexport class numericalIntegration {\n /**\n * Constructor to initialize the numericalIntegration class\n * @param {string} meshDimension - The dimension of the mesh\n * @param {string} elementOrder - The order of elements\n */\n constructor({ meshDimension, elementOrder }) {\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n }\n\n /**\n * Function to return Gauss points and weights based on element configuration\n * @returns {object} An object containing:\n * - gaussPoints: Array of Gauss points\n * - gaussWeights: Array of Gauss weights\n */\n getGaussPointsAndWeights() {\n let gaussPoints = []; // Gauss points\n let gaussWeights = []; // Gauss weights\n\n if (this.elementOrder === \"linear\") {\n // For linear elements, use 1-point Gauss quadrature\n gaussPoints[0] = 0.5;\n gaussWeights[0] = 1;\n } else if (this.elementOrder === \"quadratic\") {\n // For quadratic elements, use 3-point Gauss quadrature\n gaussPoints[0] = (1 - Math.sqrt(3 / 5)) / 2;\n gaussPoints[1] = 0.5;\n gaussPoints[2] = (1 + Math.sqrt(3 / 5)) / 2;\n gaussWeights[0] = 5 / 18;\n gaussWeights[1] = 8 / 18;\n gaussWeights[2] = 5 / 18;\n }\n\n return { gaussPoints, gaussWeights };\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Global logging level\nlet currentLogLevel = \"basic\";\n\n/**\n * Function to set the logging system level\n * @param {string} level - Logging level (basic, debug)\n */\nexport function logSystem(level) {\n if (level !== \"basic\" && level !== \"debug\") {\n console.log(\n \"%c[WARN] Invalid log level: \" + level + \". Using basic instead.\",\n \"color: #FFC107; font-weight: bold;\"\n ); // Yellow for warnings\n currentLogLevel = \"basic\";\n } else {\n currentLogLevel = level;\n basicLog(`Log level set to: ${level}`);\n }\n}\n\n/**\n * Function to log debug messages - only logs if level is 'debug'\n * @param {string} message - Message to log\n */\nexport function debugLog(message) {\n if (currentLogLevel === \"debug\") {\n console.log(\"%c[DEBUG] \" + message, \"color: #2196F3; font-weight: bold;\"); // Blue color for debug\n }\n}\n\n/**\n * Function to log basic information - always logs\n * @param {string} message - Message to log\n */\nexport function basicLog(message) {\n console.log(\"%c[INFO] \" + message, \"color: #4CAF50; font-weight: bold;\"); // Green color for basic info\n}\n\n/**\n * Function to log error messages\n * @param {string} message - Message to log\n */\nexport function errorLog(message) {\n console.log(\"%c[ERROR] \" + message, \"color: #F44336; font-weight: bold;\"); // Red color for errors\n}\n\n/**\n * Function to handle version information and fetch the latest update date and release from GitHub\n */\nexport async function printVersion() {\n basicLog(\"Fetching latest FEAScript version information...\");\n try {\n const commitResponse = await fetch(\"https://api.github.com/repos/FEAScript/FEAScript/commits/main\");\n const commitData = await commitResponse.json();\n const latestCommitDate = new Date(commitData.commit.committer.date).toLocaleString();\n basicLog(`Latest FEAScript update: ${latestCommitDate}`);\n return latestCommitDate;\n } catch (error) {\n errorLog(\"Failed to fetch version information: \" + error);\n return \"Version information unavailable\";\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to handle basis functions and their derivatives based on element configuration\n */\nexport class basisFunctions {\n /**\n * Constructor to initialize the basisFunctions class\n * @param {string} meshDimension - The dimension of the mesh\n * @param {string} elementOrder - The order of elements\n */\n constructor({ meshDimension, elementOrder }) {\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n }\n\n /**\n * Function to calculate basis functions and their derivatives based on the dimension and order\n * @param {number} ksi - Natural coordinate (for both 1D and 2D)\n * @param {number} [eta] - Second natural coordinate (only for 2D elements)\n * @returns {object} An object containing:\n * - basisFunction: Array of evaluated basis functions\n * - basisFunctionDerivKsi: Array of derivatives of basis functions with respect to ksi\n * - basisFunctionDerivEta: Array of derivatives of basis functions with respect to eta (only for 2D elements)\n */\n getBasisFunctions(ksi, eta = null) {\n let basisFunction = [];\n let basisFunctionDerivKsi = [];\n let basisFunctionDerivEta = [];\n\n if (this.meshDimension === \"1D\") {\n if (this.elementOrder === \"linear\") {\n // Linear basis functions for 1D elements\n basisFunction[0] = 1 - ksi;\n basisFunction[1] = ksi;\n\n // Derivatives of basis functions with respect to ksi\n basisFunctionDerivKsi[0] = -1;\n basisFunctionDerivKsi[1] = 1;\n } else if (this.elementOrder === \"quadratic\") {\n // Quadratic basis functions for 1D elements\n basisFunction[0] = 1 - 3 * ksi + 2 * ksi ** 2;\n basisFunction[1] = 4 * ksi - 4 * ksi ** 2;\n basisFunction[2] = -ksi + 2 * ksi ** 2;\n\n // Derivatives of basis functions with respect to ksi\n basisFunctionDerivKsi[0] = -3 + 4 * ksi;\n basisFunctionDerivKsi[1] = 4 - 8 * ksi;\n basisFunctionDerivKsi[2] = -1 + 4 * ksi;\n }\n } else if (this.meshDimension === \"2D\") {\n if (eta === null) {\n errorLog(\"Eta coordinate is required for 2D elements\");\n return;\n }\n\n if (this.elementOrder === \"linear\") {\n // Linear basis functions for 2D elements\n function l1(c) {\n return 1 - c;\n }\n function l2(c) {\n return c;\n }\n function dl1() {\n return -1;\n }\n function dl2() {\n return 1;\n }\n\n // Evaluate basis functions at (ksi, eta)\n basisFunction[0] = l1(ksi) * l1(eta);\n basisFunction[1] = l1(ksi) * l2(eta);\n basisFunction[2] = l2(ksi) * l1(eta);\n basisFunction[3] = l2(ksi) * l2(eta);\n\n // Derivatives with respect to ksi\n basisFunctionDerivKsi[0] = dl1() * l1(eta);\n basisFunctionDerivKsi[1] = dl1() * l2(eta);\n basisFunctionDerivKsi[2] = dl2() * l1(eta);\n basisFunctionDerivKsi[3] = dl2() * l2(eta);\n\n // Derivatives with respect to eta\n basisFunctionDerivEta[0] = l1(ksi) * dl1();\n basisFunctionDerivEta[1] = l1(ksi) * dl2();\n basisFunctionDerivEta[2] = l2(ksi) * dl1();\n basisFunctionDerivEta[3] = l2(ksi) * dl2();\n } else if (this.elementOrder === \"quadratic\") {\n // Quadratic basis functions for 2D elements\n function l1(c) {\n return 2 * c ** 2 - 3 * c + 1;\n }\n function l2(c) {\n return -4 * c ** 2 + 4 * c;\n }\n function l3(c) {\n return 2 * c ** 2 - c;\n }\n function dl1(c) {\n return 4 * c - 3;\n }\n function dl2(c) {\n return -8 * c + 4;\n }\n function dl3(c) {\n return 4 * c - 1;\n }\n\n // Evaluate basis functions at (ksi, eta)\n basisFunction[0] = l1(ksi) * l1(eta);\n basisFunction[1] = l1(ksi) * l2(eta);\n basisFunction[2] = l1(ksi) * l3(eta);\n basisFunction[3] = l2(ksi) * l1(eta);\n basisFunction[4] = l2(ksi) * l2(eta);\n basisFunction[5] = l2(ksi) * l3(eta);\n basisFunction[6] = l3(ksi) * l1(eta);\n basisFunction[7] = l3(ksi) * l2(eta);\n basisFunction[8] = l3(ksi) * l3(eta);\n\n // Derivatives with respect to ksi\n basisFunctionDerivKsi[0] = dl1(ksi) * l1(eta);\n basisFunctionDerivKsi[1] = dl1(ksi) * l2(eta);\n basisFunctionDerivKsi[2] = dl1(ksi) * l3(eta);\n basisFunctionDerivKsi[3] = dl2(ksi) * l1(eta);\n basisFunctionDerivKsi[4] = dl2(ksi) * l2(eta);\n basisFunctionDerivKsi[5] = dl2(ksi) * l3(eta);\n basisFunctionDerivKsi[6] = dl3(ksi) * l1(eta);\n basisFunctionDerivKsi[7] = dl3(ksi) * l2(eta);\n basisFunctionDerivKsi[8] = dl3(ksi) * l3(eta);\n\n // Derivatives with respect to eta\n basisFunctionDerivEta[0] = l1(ksi) * dl1(eta);\n basisFunctionDerivEta[1] = l1(ksi) * dl2(eta);\n basisFunctionDerivEta[2] = l1(ksi) * dl3(eta);\n basisFunctionDerivEta[3] = l2(ksi) * dl1(eta);\n basisFunctionDerivEta[4] = l2(ksi) * dl2(eta);\n basisFunctionDerivEta[5] = l2(ksi) * dl3(eta);\n basisFunctionDerivEta[6] = l3(ksi) * dl1(eta);\n basisFunctionDerivEta[7] = l3(ksi) * dl2(eta);\n basisFunctionDerivEta[8] = l3(ksi) * dl3(eta);\n }\n }\n\n return { basisFunction, basisFunctionDerivKsi, basisFunctionDerivEta };\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to handle the generation of structured finite element meshes\n */\nexport class meshGeneration {\n /**\n * Constructor to initialize the meshGeneration class\n * @param {object} config - Configuration object for the mesh\n * @param {number} [config.numElementsX] - Number of elements along the x-axis (required for geometry-based mesh)\n * @param {number} [config.maxX] - Maximum x-coordinate of the mesh (required for geometry-based mesh)\n * @param {number} [config.numElementsY=1] - Number of elements along the y-axis (for 1D meshes)\n * @param {number} [config.maxY=0] - Maximum y-coordinate of the mesh (for 1D meshes)\n * @param {string} [config.meshDimension='2D'] - The dimension of the mesh, either 1D or 2D\n * @param {string} [config.elementOrder='linear'] - The order of elements, either 'linear' or 'quadratic'\n * @param {object} [config.parsedMesh=null] - Optional pre-parsed mesh data\n */\n constructor({\n numElementsX = null,\n maxX = null,\n numElementsY = null,\n maxY = null,\n meshDimension = null,\n elementOrder = \"linear\",\n parsedMesh = null,\n }) {\n this.numElementsX = numElementsX;\n this.numElementsY = numElementsY;\n this.maxX = maxX;\n this.maxY = maxY;\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n this.parsedMesh = parsedMesh;\n }\n\n /**\n * Function to generate the mesh based on the dimension or use a pre-parsed mesh\n * @returns {object} The generated mesh containing node coordinates and total nodes\n */\n generateMesh() {\n // If pre-parsed mesh data is provided, use it directly\n if (this.parsedMesh) {\n // Process the nodalNumbering from gmshReader format to the format expected by the solver\n if (this.parsedMesh.nodalNumbering) {\n if (\n typeof this.parsedMesh.nodalNumbering === \"object\" &&\n !Array.isArray(this.parsedMesh.nodalNumbering)\n ) {\n // Store the nodal numbering structure before converting\n const quadElements = this.parsedMesh.nodalNumbering.quadElements || [];\n const triangleElements = this.parsedMesh.nodalNumbering.triangleElements || [];\n\n debugLog(\n \"Initial parsed mesh nodal numbering from GMSH format: \" +\n JSON.stringify(this.parsedMesh.nodalNumbering)\n );\n\n // Check if it has quadElements or triangleElements structure from gmshReader\n if (this.parsedMesh.elementTypes[3] || this.parsedMesh.elementTypes[10]) {\n // Map nodal numbering from GMSH format to FEAScript format for quad elements\n const mappedNodalNumbering = [];\n\n for (let elemIdx = 0; elemIdx < quadElements.length; elemIdx++) {\n const gmshNodes = quadElements[elemIdx];\n const feaScriptNodes = new Array(gmshNodes.length);\n\n // Check for element type based on number of nodes\n if (gmshNodes.length === 4) {\n // Simple mapping for linear quad elements (4 nodes)\n // GMSH: FEAScript:\n // 3 --- 2 1 --- 3\n // | | --> | |\n // 0 --- 1 0 --- 2\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[3]; // 3 -> 1\n feaScriptNodes[2] = gmshNodes[1]; // 1 -> 2\n feaScriptNodes[3] = gmshNodes[2]; // 2 -> 3\n } else if (gmshNodes.length === 9) {\n // Mapping for quadratic quad elements (9 nodes)\n // GMSH: FEAScript:\n // 3--6--2 2--5--8\n // | | | |\n // 7 8 5 --> 1 4 7\n // | | | |\n // 0--4--1 0--3--6\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[7]; // 7 -> 1\n feaScriptNodes[2] = gmshNodes[3]; // 3 -> 2\n feaScriptNodes[3] = gmshNodes[4]; // 4 -> 3\n feaScriptNodes[4] = gmshNodes[8]; // 8 -> 4\n feaScriptNodes[5] = gmshNodes[6]; // 6 -> 5\n feaScriptNodes[6] = gmshNodes[1]; // 1 -> 6\n feaScriptNodes[7] = gmshNodes[5]; // 5 -> 7\n feaScriptNodes[8] = gmshNodes[2]; // 2 -> 8\n }\n\n mappedNodalNumbering.push(feaScriptNodes);\n }\n\n this.parsedMesh.nodalNumbering = mappedNodalNumbering;\n } else if (this.parsedMesh.elementTypes[2]) {\n }\n\n debugLog(\n \"Nodal numbering after mapping from GMSH to FEAScript format: \" +\n JSON.stringify(this.parsedMesh.nodalNumbering)\n );\n\n // Process boundary elements if they exist and if physical property mapping exists\n if (this.parsedMesh.physicalPropMap && this.parsedMesh.boundaryElements) {\n // Check if boundary elements need to be processed\n if (\n Array.isArray(this.parsedMesh.boundaryElements) &&\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n // Create a new array without the empty first element\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n\n // If boundary node pairs exist but boundary elements haven't been processed\n if (this.parsedMesh.boundaryNodePairs && !this.parsedMesh.boundaryElementsProcessed) {\n // Reset boundary elements array\n this.parsedMesh.boundaryElements = [];\n\n // Process each physical property from the Gmsh file\n this.parsedMesh.physicalPropMap.forEach((prop) => {\n // Only process 1D physical entities (boundary lines)\n if (prop.dimension === 1) {\n // Get all node pairs for this boundary\n const boundaryNodePairs = this.parsedMesh.boundaryNodePairs[prop.tag] || [];\n\n if (boundaryNodePairs.length > 0) {\n // Initialize array for this boundary tag\n if (!this.parsedMesh.boundaryElements[prop.tag]) {\n this.parsedMesh.boundaryElements[prop.tag] = [];\n }\n\n // For each boundary line segment (defined by a pair of nodes)\n boundaryNodePairs.forEach((nodesPair) => {\n const node1 = nodesPair[0]; // First node in the pair\n const node2 = nodesPair[1]; // Second node in the pair\n\n debugLog(\n `Processing boundary node pair: [${node1}, ${node2}] for boundary ${prop.tag} (${\n prop.name || \"unnamed\"\n })`\n );\n\n // Search through all elements to find which one contains both nodes\n let foundElement = false;\n\n // Loop through all elements in the mesh\n for (let elemIdx = 0; elemIdx < this.parsedMesh.nodalNumbering.length; elemIdx++) {\n const elemNodes = this.parsedMesh.nodalNumbering[elemIdx];\n\n // For linear quadrilateral linear elements (4 nodes)\n if (elemNodes.length === 4) {\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript linear quadrilateral numbering:\n // 1 --- 3\n // | |\n // 0 --- 2\n\n if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0)\n ) {\n side = 0; // Bottom side\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0)\n ) {\n side = 1; // Left side\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 1 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 1)\n ) {\n side = 2; // Top side\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 2)\n ) {\n side = 3; // Right side\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n } else if (elemNodes.length === 9) {\n // For quadratic quadrilateral elements (9 nodes)\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript quadratic quadrilateral numbering:\n // 2--5--8\n // | |\n // 1 4 7\n // | |\n // 0--3--6\n\n if (\n (node1Index === 0 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 0) ||\n (node1Index === 3 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 3)\n ) {\n side = 0; // Bottom side (nodes 0, 3, 6)\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0) ||\n (node1Index === 1 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 1)\n ) {\n side = 1; // Left side (nodes 0, 1, 2)\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 5) ||\n (node1Index === 5 && node2Index === 2) ||\n (node1Index === 5 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 5)\n ) {\n side = 2; // Top side (nodes 2, 5, 8)\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 6 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 7) ||\n (node1Index === 7 && node2Index === 6) ||\n (node1Index === 7 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 7)\n ) {\n side = 3; // Right side (nodes 6, 7, 8)\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n }\n }\n\n if (!foundElement) {\n errorLog(\n `Could not find element containing boundary nodes ${node1} and ${node2}. Boundary may be incomplete.`\n );\n }\n });\n }\n }\n });\n\n // Mark as processed\n this.parsedMesh.boundaryElementsProcessed = true;\n\n // Fix boundary elements array - remove undefined entries\n if (\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n }\n }\n }\n }\n\n debugLog(\"Processed boundary elements by tag: \" + JSON.stringify(this.parsedMesh.boundaryElements));\n\n return this.parsedMesh;\n } else {\n // Validate required geometry parameters based on mesh dimension\n if (this.meshDimension === \"1D\") {\n if (this.numElementsX === null || this.maxX === null) {\n errorLog(\"numElementsX and maxX are required parameters when generating a 1D mesh from geometry\");\n }\n } else if (this.meshDimension === \"2D\") {\n if (\n this.numElementsX === null ||\n this.maxX === null ||\n this.numElementsY === null ||\n this.maxY === null\n ) {\n errorLog(\n \"numElementsX, maxX, numElementsY, and maxY are required parameters when generating a 2D mesh from geometry\"\n );\n }\n }\n\n // Generate mesh based on dimension\n return this.generateMeshFromGeometry();\n }\n }\n\n /**\n * Function to generate a structured mesh based on the geometry configuration\n * @returns {object} An object containing the coordinates of nodes,\n * total number of nodes, nodal numbering (NOP) array, and boundary elements\n */\n generateMeshFromGeometry() {\n let nodesXCoordinates = [];\n let nodesYCoordinates = [];\n const xStart = 0;\n const yStart = 0;\n let totalNodesX, totalNodesY, deltaX, deltaY;\n\n if (this.meshDimension === \"1D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX;\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX / 2;\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n null, // numElementsY (not used in 1D)\n totalNodesX,\n null, // totalNodesY (not used in 1D)\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n\n // Return x coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n totalNodesX,\n nodalNumbering,\n boundaryElements,\n };\n } else if (this.meshDimension === \"2D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n totalNodesY = this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + nodeIndexY * deltaY;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + nodeIndexX * deltaX;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + nodeIndexY * deltaY;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n totalNodesY = 2 * this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + (nodeIndexY * deltaY) / 2;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + (nodeIndexX * deltaX) / 2;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + (nodeIndexY * deltaY) / 2;\n }\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n this.numElementsY,\n totalNodesX,\n totalNodesY,\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n debugLog(\"Generated node Y coordinates: \" + JSON.stringify(nodesYCoordinates));\n\n // Return x and y coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n nodesYCoordinates,\n totalNodesX,\n totalNodesY,\n nodalNumbering,\n boundaryElements,\n };\n }\n }\n\n /**\n * Function to find the elements that belong to each boundary of a domain\n * @returns {array} An array containing arrays of elements and their adjacent boundary side for each boundary\n * Each element in the array is of the form [elementIndex, side], where 'side' indicates which side\n * of the reference element is in contact with the physical boundary:\n *\n * For 1D domains (line segments):\n * 0 - Left node of reference element (maps to physical left endpoint)\n * 1 - Right node of reference element (maps to physical right endpoint)\n *\n * For 2D domains (rectangular):\n * 0 - Bottom side of reference element (maps to physical bottom boundary)\n * 1 - Left side of reference element (maps to physical left boundary)\n * 2 - Top side of reference element (maps to physical top boundary)\n * 3 - Right side of reference element (maps to physical right boundary)\n */\n findBoundaryElements() {\n const boundaryElements = [];\n const maxSides = this.meshDimension === \"1D\" ? 2 : 4; // Number of element sides based on mesh dimension\n for (let sideIndex = 0; sideIndex < maxSides; sideIndex++) {\n boundaryElements.push([]);\n }\n\n if (this.meshDimension === \"1D\") {\n // Left boundary (element 0, side 0)\n boundaryElements[0].push([0, 0]);\n\n // Right boundary (last element, side 1)\n boundaryElements[1].push([this.numElementsX - 1, 1]);\n } else if (this.meshDimension === \"2D\") {\n for (let elementIndexX = 0; elementIndexX < this.numElementsX; elementIndexX++) {\n for (let elementIndexY = 0; elementIndexY < this.numElementsY; elementIndexY++) {\n const elementIndex = elementIndexX * this.numElementsY + elementIndexY;\n\n // Bottom boundary\n if (elementIndexY === 0) {\n boundaryElements[0].push([elementIndex, 0]);\n }\n\n // Left boundary\n if (elementIndexX === 0) {\n boundaryElements[1].push([elementIndex, 1]);\n }\n\n // Top boundary\n if (elementIndexY === this.numElementsY - 1) {\n boundaryElements[2].push([elementIndex, 2]);\n }\n\n // Right boundary\n if (elementIndexX === this.numElementsX - 1) {\n boundaryElements[3].push([elementIndex, 3]);\n }\n }\n }\n }\n\n debugLog(\"Identified boundary elements by side: \" + JSON.stringify(boundaryElements));\n return boundaryElements;\n }\n\n /**\n * Function to generate the nodal numbering (NOP) array for a structured mesh\n * This array represents the connectivity between elements and their corresponding nodes\n * @param {number} numElementsX - Number of elements along the x-axis\n * @param {number} [numElementsY] - Number of elements along the y-axis (optional for 1D)\n * @param {number} totalNodesX - Total number of nodes along the x-axis\n * @param {number} [totalNodesY] - Total number of nodes along the y-axis (optional for 1D)\n * @param {string} elementOrder - The order of elements, either 'linear' or 'quadratic'\n * @returns {array} NOP - A two-dimensional array which represents the element-to-node connectivity for the entire mesh\n */\n generateNodalNumbering(numElementsX, numElementsY, totalNodesX, totalNodesY, elementOrder) {\n let elementIndex = 0;\n let nop = [];\n\n if (this.meshDimension === \"1D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear 1D elements with the following nodes representation:\n *\n * 1 --- 2\n *\n */\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 2; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic 1D elements with the following nodes representation:\n *\n * 1--2--3\n *\n */\n let columnCounter = 0;\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 3; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex + columnCounter;\n }\n columnCounter += 1;\n }\n }\n } else if (this.meshDimension === \"2D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear rectangular elements with the following nodes representation:\n *\n * 1 --- 3\n * | |\n * 0 --- 2\n *\n */\n let rowCounter = 0;\n let columnCounter = 2;\n for (let elementIndex = 0; elementIndex < numElementsX * numElementsY; elementIndex++) {\n rowCounter += 1;\n nop[elementIndex] = [];\n nop[elementIndex][0] = elementIndex + columnCounter - 1;\n nop[elementIndex][1] = elementIndex + columnCounter;\n nop[elementIndex][2] = elementIndex + columnCounter + numElementsY;\n nop[elementIndex][3] = elementIndex + columnCounter + numElementsY + 1;\n if (rowCounter === numElementsY) {\n columnCounter += 1;\n rowCounter = 0;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic rectangular elements with the following nodes representation:\n *\n * 2--5--8\n * | |\n * 1 4 7\n * | |\n * 0--3--6\n *\n */\n for (let elementIndexX = 1; elementIndexX <= numElementsX; elementIndexX++) {\n for (let elementIndexY = 1; elementIndexY <= numElementsY; elementIndexY++) {\n nop[elementIndex] = [];\n for (let nodeIndex1 = 1; nodeIndex1 <= 3; nodeIndex1++) {\n let nodeIndex2 = 3 * nodeIndex1 - 2;\n nop[elementIndex][nodeIndex2 - 1] =\n totalNodesY * (2 * elementIndexX + nodeIndex1 - 3) + 2 * elementIndexY - 1;\n nop[elementIndex][nodeIndex2] = nop[elementIndex][nodeIndex2 - 1] + 1;\n nop[elementIndex][nodeIndex2 + 1] = nop[elementIndex][nodeIndex2 - 1] + 2;\n }\n elementIndex = elementIndex + 1;\n }\n }\n }\n }\n\n return nop;\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to handle thermal boundary conditions application\n */\nexport class ThermalBoundaryConditions {\n /**\n * Constructor to initialize the ThermalBoundaryConditions class\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @param {array} boundaryElements - Array containing elements that belong to each boundary\n * @param {array} nop - Nodal numbering (NOP) array representing the connectivity between elements and nodes\n * @param {string} meshDimension - The dimension of the mesh (e.g., \"2D\")\n * @param {string} elementOrder - The order of elements (e.g., \"linear\", \"quadratic\")\n */\n constructor(boundaryConditions, boundaryElements, nop, meshDimension, elementOrder) {\n this.boundaryConditions = boundaryConditions;\n this.boundaryElements = boundaryElements;\n this.nop = nop;\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n }\n\n /**\n * Function to impose constant temperature boundary conditions (Dirichlet type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n */\n imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix) {\n basicLog(\"Applying constant temperature boundary conditions (Dirichlet type)\");\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 1: [1], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 2: [2], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0, 2], // Nodes at the bottom side of the reference element\n 1: [0, 1], // Nodes at the left side of the reference element\n 2: [1, 3], // Nodes at the top side of the reference element\n 3: [2, 3], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0, 3, 6], // Nodes at the bottom side of the reference element\n 1: [0, 1, 2], // Nodes at the left side of the reference element\n 2: [2, 5, 8], // Nodes at the top side of the reference element\n 3: [6, 7, 8], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n }\n }\n\n /**\n * Function to impose convection boundary conditions (Robin type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n * @param {array} gaussPoints - Array of Gauss points for numerical integration\n * @param {array} gaussWeights - Array of Gauss weights for numerical integration\n * @param {array} nodesXCoordinates - Array of x-coordinates of nodes\n * @param {array} nodesYCoordinates - Array of y-coordinates of nodes\n * @param {object} basisFunctionsData - Object containing basis functions and their derivatives\n */\n imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n ) {\n basicLog(\"Applying convection boundary conditions (Robin type)\");\n // Extract convection parameters from boundary conditions\n let convectionHeatTranfCoeff = [];\n let convectionExtTemp = [];\n Object.keys(this.boundaryConditions).forEach((key) => {\n const boundaryCondition = this.boundaryConditions[key];\n if (boundaryCondition[0] === \"convection\") {\n convectionHeatTranfCoeff[key] = boundaryCondition[1];\n convectionExtTemp[key] = boundaryCondition[2];\n }\n });\n\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n let nodeIndex;\n if (this.elementOrder === \"linear\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 1;\n }\n } else if (this.elementOrder === \"quadratic\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 2;\n }\n }\n\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n residualVector[globalNodeIndex] += -convectionCoeff * extTemp;\n jacobianMatrix[globalNodeIndex][globalNodeIndex] += convectionCoeff;\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 2;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 0;\n lastNodeIndex = 2;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 1;\n firstNodeIndex = 1;\n lastNodeIndex = 4;\n nodeIncrement = 2;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 2;\n lastNodeIndex = 4;\n nodeIncrement = 1;\n }\n\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[0] * tangentVectorLength * basisFunction[localNodeIndex] * convectionCoeff * extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[0] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n for (let gaussPointIndex = 0; gaussPointIndex < 3; gaussPointIndex++) {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 7;\n nodeIncrement = 3;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 1;\n firstNodeIndex = 2;\n lastNodeIndex = 9;\n nodeIncrement = 3;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 6;\n lastNodeIndex = 9;\n nodeIncrement = 1;\n }\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n convectionCoeff *\n extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n }\n }\n });\n }\n });\n }\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { jacobiMethod } from \"./methods/jacobiMethodScript.js\";\nimport { assembleSolidHeatTransferMat } from \"./solvers/solidHeatTransferScript.js\";\nimport { basicLog, debugLog, errorLog } from \"./utilities/loggingScript.js\";\n\n/**\n * Class to implement finite element analysis in JavaScript\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing the solution vector and additional mesh information\n */\nexport class FEAScriptModel {\n constructor() {\n this.solverConfig = null;\n this.meshConfig = {};\n this.boundaryConditions = {};\n this.solverMethod = \"lusolve\"; // Default solver method\n basicLog(\"FEAScriptModel instance created\");\n }\n\n setSolverConfig(solverConfig) {\n this.solverConfig = solverConfig;\n debugLog(`Solver config set to: ${solverConfig}`);\n }\n\n setMeshConfig(meshConfig) {\n this.meshConfig = meshConfig;\n debugLog(\n `Mesh config set with dimensions: ${meshConfig.meshDimension}`\n );\n }\n\n addBoundaryCondition(boundaryKey, condition) {\n this.boundaryConditions[boundaryKey] = condition;\n debugLog(`Boundary condition added for boundary: ${boundaryKey}, type: ${condition[0]}`);\n }\n\n setSolverMethod(solverMethod) {\n this.solverMethod = solverMethod;\n debugLog(`Solver method set to: ${solverMethod}`);\n }\n\n solve() {\n if (!this.solverConfig || !this.meshConfig || !this.boundaryConditions) {\n const error = \"Solver config, mesh config, and boundary conditions must be set before solving.\";\n console.error(error);\n throw new Error(error);\n }\n\n let jacobianMatrix = [];\n let residualVector = [];\n let solutionVector = [];\n let nodesCoordinates = {};\n\n // Assembly matrices\n basicLog(\"Beginning matrix assembly...\");\n console.time(\"assemblyMatrices\");\n if (this.solverConfig === \"solidHeatTransferScript\") {\n basicLog(`Using solver: ${this.solverConfig}`);\n ({ jacobianMatrix, residualVector, nodesCoordinates } = assembleSolidHeatTransferMat(\n this.meshConfig,\n this.boundaryConditions\n ));\n }\n console.timeEnd(\"assemblyMatrices\");\n basicLog(\"Matrix assembly completed\");\n\n // System solving\n basicLog(`Solving system using ${this.solverMethod}...`);\n console.time(\"systemSolving\");\n if (this.solverMethod === \"lusolve\") {\n solutionVector = math.lusolve(jacobianMatrix, residualVector);\n } else if (this.solverMethod === \"jacobi\") {\n // Create initial guess of zeros\n const initialGuess = new Array(residualVector.length).fill(0);\n // Call Jacobi method with desired max iterations and tolerance\n const jacobiResult = jacobiMethod(jacobianMatrix, residualVector, initialGuess, 1000, 1e-6);\n\n // Log convergence information\n if (jacobiResult.converged) {\n debugLog(`Jacobi method converged in ${jacobiResult.iterations} iterations`);\n } else {\n debugLog(`Jacobi method did not converge after ${jacobiResult.iterations} iterations`);\n }\n\n solutionVector = jacobiResult.solution;\n }\n console.timeEnd(\"systemSolving\");\n basicLog(\"System solved successfully\");\n\n return { solutionVector, nodesCoordinates };\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { numericalIntegration } from \"../methods/numericalIntegrationScript.js\";\nimport { basisFunctions } from \"../mesh/basisFunctionsScript.js\";\nimport { meshGeneration } from \"../mesh/meshGenerationScript.js\";\nimport { ThermalBoundaryConditions } from \"./thermalBoundaryConditionsScript.js\";\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to assemble the solid heat transfer matrix\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing:\n * - jacobianMatrix: The assembled Jacobian matrix\n * - residualVector: The assembled residual vector\n * - nodesCoordinates: Object containing x and y coordinates of nodes\n */\nexport function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {\n basicLog(\"Starting solid heat transfer matrix assembly...\");\n\n // Extract mesh details from the configuration object\n const {\n meshDimension, // The dimension of the mesh\n numElementsX, // Number of elements in x-direction\n numElementsY, // Number of elements in y-direction (only for 2D)\n maxX, // Max x-coordinate (m) of the domain\n maxY, // Max y-coordinate (m) of the domain (only for 2D)\n elementOrder, // The order of elements\n parsedMesh, // The pre-parsed mesh data (if available)\n } = meshConfig;\n\n // Create a new instance of the meshGeneration class\n debugLog(\"Generating mesh...\");\n const meshGenerationData = new meshGeneration({\n numElementsX,\n numElementsY,\n maxX,\n maxY,\n meshDimension,\n elementOrder,\n parsedMesh, // Pass the parsed mesh to the mesh generator\n });\n\n // Generate the mesh\n const nodesCoordinatesAndNumbering = meshGenerationData.generateMesh();\n\n // Extract nodes coordinates and nodal numbering (NOP) from the mesh data\n let nodesXCoordinates = nodesCoordinatesAndNumbering.nodesXCoordinates;\n let nodesYCoordinates = nodesCoordinatesAndNumbering.nodesYCoordinates;\n let totalNodesX = nodesCoordinatesAndNumbering.totalNodesX;\n let totalNodesY = nodesCoordinatesAndNumbering.totalNodesY;\n let nop = nodesCoordinatesAndNumbering.nodalNumbering;\n let boundaryElements = nodesCoordinatesAndNumbering.boundaryElements;\n\n // Check the mesh type\n const isParsedMesh = parsedMesh !== undefined && parsedMesh !== null;\n\n // Calculate totalElements and totalNodes based on mesh type\n let totalElements, totalNodes;\n\n if (isParsedMesh) {\n totalElements = nop.length; // Number of elements is the length of the nodal numbering array\n totalNodes = nodesXCoordinates.length; // Number of nodes is the length of the coordinates array\n\n // Debug log for mesh size\n debugLog(`Using parsed mesh with ${totalElements} elements and ${totalNodes} nodes`);\n } else {\n // For structured mesh, calculate based on dimensions\n totalElements = numElementsX * (meshDimension === \"2D\" ? numElementsY : 1);\n totalNodes = totalNodesX * (meshDimension === \"2D\" ? totalNodesY : 1);\n // Debug log for mesh size\n debugLog(`Using mesh generated from geometry with ${totalElements} elements and ${totalNodes} nodes`);\n }\n\n // Initialize variables for matrix assembly\n let localToGlobalMap = []; // Maps local element node indices to global mesh node indices\n let gaussPoints = []; // Gauss points\n let gaussWeights = []; // Gauss weights\n let basisFunction = []; // Basis functions\n let basisFunctionDerivKsi = []; // Derivatives of basis functions with respect to ksi\n let basisFunctionDerivEta = []; // Derivatives of basis functions with respect to eta (only for 2D)\n let basisFunctionDerivX = []; // The x-derivative of the basis function\n let basisFunctionDerivY = []; // The y-derivative of the basis function (only for 2D)\n let residualVector = []; // Galerkin residuals\n let jacobianMatrix = []; // Jacobian matrix\n let xCoordinates; // x-coordinate (physical coordinates)\n let yCoordinates; // y-coordinate (physical coordinates) (only for 2D)\n let ksiDerivX; // ksi-derivative of xCoordinates\n let etaDerivX; // eta-derivative of xCoordinates (ksi and eta are natural coordinates that vary within a reference element) (only for 2D)\n let ksiDerivY; // ksi-derivative of yCoordinates (only for 2D)\n let etaDerivY; // eta-derivative of yCoordinates (only for 2D)\n let detJacobian; // The jacobian of the isoparametric mapping\n\n // Initialize jacobianMatrix and residualVector arrays\n for (let nodeIndex = 0; nodeIndex < totalNodes; nodeIndex++) {\n residualVector[nodeIndex] = 0;\n jacobianMatrix.push([]);\n for (let colIndex = 0; colIndex < totalNodes; colIndex++) {\n jacobianMatrix[nodeIndex][colIndex] = 0;\n }\n }\n\n // Initialize the basisFunctions class\n const basisFunctionsData = new basisFunctions({\n meshDimension,\n elementOrder,\n });\n\n // Initialize the numericalIntegration class\n const numIntegrationData = new numericalIntegration({\n meshDimension,\n elementOrder,\n });\n\n // Calculate Gauss points and weights\n let gaussPointsAndWeights = numIntegrationData.getGaussPointsAndWeights();\n gaussPoints = gaussPointsAndWeights.gaussPoints;\n gaussWeights = gaussPointsAndWeights.gaussWeights;\n\n // Determine the number of nodes in the reference element based on the first element in the nop array\n const numNodes = nop[0].length;\n\n // Matrix assembly\n for (let elementIndex = 0; elementIndex < totalElements; elementIndex++) {\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n // Subtract 1 from nop in order to start numbering from 0\n localToGlobalMap[localNodeIndex] = nop[elementIndex][localNodeIndex] - 1;\n }\n\n // Loop over Gauss points\n for (let gaussPointIndex1 = 0; gaussPointIndex1 < gaussPoints.length; gaussPointIndex1++) {\n // 1D solid heat transfer\n if (meshDimension === \"1D\") {\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n xCoordinates = 0;\n ksiDerivX = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates += nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n detJacobian = ksiDerivX;\n }\n\n // Compute x-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] = basisFunctionDerivKsi[localNodeIndex] / detJacobian; // The x-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2]);\n }\n }\n // 2D solid heat transfer\n } else if (meshDimension === \"2D\") {\n for (let gaussPointIndex2 = 0; gaussPointIndex2 < gaussPoints.length; gaussPointIndex2++) {\n // Initialise variables for isoparametric mapping\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1],\n gaussPoints[gaussPointIndex2]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n xCoordinates = 0;\n yCoordinates = 0;\n ksiDerivX = 0;\n etaDerivX = 0;\n ksiDerivY = 0;\n etaDerivY = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n yCoordinates +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n ksiDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n detJacobian = meshDimension === \"2D\" ? ksiDerivX * etaDerivY - etaDerivX * ksiDerivY : ksiDerivX;\n }\n\n // Compute x-derivative and y-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] =\n (etaDerivY * basisFunctionDerivKsi[localNodeIndex] -\n ksiDerivY * basisFunctionDerivEta[localNodeIndex]) /\n detJacobian; // The x-derivative of the n basis function\n basisFunctionDerivY[localNodeIndex] =\n (ksiDerivX * basisFunctionDerivEta[localNodeIndex] -\n etaDerivX * basisFunctionDerivKsi[localNodeIndex]) /\n detJacobian; // The y-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n gaussWeights[gaussPointIndex2] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2] +\n basisFunctionDerivY[localNodeIndex1] * basisFunctionDerivY[localNodeIndex2]);\n }\n }\n }\n }\n }\n }\n\n // Create an instance of ThermalBoundaryConditions\n debugLog(\"Applying thermal boundary conditions...\");\n const thermalBoundaryConditions = new ThermalBoundaryConditions(\n boundaryConditions,\n boundaryElements,\n nop,\n meshDimension,\n elementOrder\n );\n\n // Impose Convection boundary conditions\n thermalBoundaryConditions.imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n );\n debugLog(\"Convection boundary conditions applied\");\n\n // Impose ConstantTemp boundary conditions\n thermalBoundaryConditions.imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix);\n debugLog(\"Constant temperature boundary conditions applied\");\n\n basicLog(\"Solid heat transfer matrix assembly completed\");\n\n return {\n jacobianMatrix,\n residualVector,\n nodesCoordinates: {\n nodesXCoordinates,\n nodesYCoordinates,\n },\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to solve a system of linear equations using the Jacobi iterative method\n * @param {array} A - The coefficient matrix (must be square)\n * @param {array} b - The right-hand side vector\n * @param {array} x0 - Initial guess for solution vector\n * @param {number} [maxIterations=100] - Maximum number of iterations\n * @param {number} [tolerance=1e-7] - Convergence tolerance\n * @returns {object} An object containing:\n * - solution: The solution vector\n * - iterations: The number of iterations performed\n * - converged: Boolean indicating whether the method converged\n */\nexport function jacobiMethod(A, b, x0, maxIterations = 100, tolerance = 1e-7) {\n const n = A.length; // Size of the square matrix\n let x = [...x0]; // Current solution (starts with initial guess)\n let xNew = new Array(n); // Next iteration's solution\n\n for (let iteration = 0; iteration < maxIterations; iteration++) {\n // Perform one iteration\n for (let i = 0; i < n; i++) {\n let sum = 0;\n // Calculate sum of A[i][j] * x[j] for j ≠ i\n for (let j = 0; j < n; j++) {\n if (j !== i) {\n sum += A[i][j] * x[j];\n }\n }\n // Update xNew[i] using the Jacobi formula\n xNew[i] = (b[i] - sum) / A[i][i];\n }\n\n // Check convergence\n let maxDiff = 0;\n for (let i = 0; i < n; i++) {\n maxDiff = Math.max(maxDiff, Math.abs(xNew[i] - x[i]));\n }\n\n // Update x for next iteration\n x = [...xNew];\n\n // Successfully converged if maxDiff is less than tolerance\n if (maxDiff < tolerance) {\n return {\n solution: x,\n iterations: iteration + 1,\n converged: true,\n };\n }\n }\n\n // maxIterations were reached without convergence\n return {\n solution: x,\n iterations: maxIterations,\n converged: false,\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to import mesh data from Gmsh format containing quadrilateral and triangular elements\n * @param {File} file - The Gmsh file to be parsed (.msh version 4.1)\n * @returns {object} The parsed mesh data including node coordinates, element connectivity, and boundary conditions\n */\nconst importGmshQuadTri = async (file) => {\n let result = {\n nodesXCoordinates: [],\n nodesYCoordinates: [],\n nodalNumbering: {\n quadElements: [],\n triangleElements: [],\n },\n boundaryElements: [],\n boundaryConditions: [],\n boundaryNodePairs: {}, // Store boundary node pairs for processing in meshGenerationScript\n gmshV: 0,\n ascii: false,\n fltBytes: \"8\",\n totalNodesX: 0,\n totalNodesY: 0,\n physicalPropMap: [],\n elementTypes: {},\n };\n\n let content = await file.text();\n let lines = content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\" && line !== \" \");\n\n let section = \"\";\n let lineIndex = 0;\n\n let nodeEntityBlocks = 0;\n let totalNodes = 0;\n let nodeBlocksProcessed = 0;\n let currentNodeBlock = { numNodes: 0 };\n let nodeTagsCollected = 0;\n let nodeTags = [];\n let nodeCoordinatesCollected = 0;\n\n let elementEntityBlocks = 0;\n let totalElements = 0;\n let elementBlocksProcessed = 0;\n let currentElementBlock = {\n dim: 0,\n tag: 0,\n elementType: 0,\n numElements: 0,\n };\n let elementsProcessedInBlock = 0;\n\n let boundaryElementsByTag = {};\n\n while (lineIndex < lines.length) {\n const line = lines[lineIndex];\n\n if (line === \"$MeshFormat\") {\n section = \"meshFormat\";\n lineIndex++;\n continue;\n } else if (line === \"$EndMeshFormat\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$PhysicalNames\") {\n section = \"physicalNames\";\n lineIndex++;\n continue;\n } else if (line === \"$EndPhysicalNames\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Entities\") {\n section = \"entities\";\n lineIndex++;\n continue;\n } else if (line === \"$EndEntities\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Nodes\") {\n section = \"nodes\";\n lineIndex++;\n continue;\n } else if (line === \"$EndNodes\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Elements\") {\n section = \"elements\";\n lineIndex++;\n continue;\n } else if (line === \"$EndElements\") {\n section = \"\";\n lineIndex++;\n continue;\n }\n\n const parts = line.split(/\\s+/).filter((part) => part !== \"\");\n\n if (section === \"meshFormat\") {\n result.gmshV = parseFloat(parts[0]);\n result.ascii = parts[1] === \"0\";\n result.fltBytes = parts[2];\n } else if (section === \"physicalNames\") {\n if (parts.length >= 3) {\n if (!/^\\d+$/.test(parts[0])) {\n lineIndex++;\n continue;\n }\n\n const dimension = parseInt(parts[0], 10);\n const tag = parseInt(parts[1], 10);\n let name = parts.slice(2).join(\" \");\n name = name.replace(/^\"|\"$/g, \"\");\n\n result.physicalPropMap.push({\n tag,\n dimension,\n name,\n });\n }\n } else if (section === \"nodes\") {\n if (nodeEntityBlocks === 0) {\n nodeEntityBlocks = parseInt(parts[0], 10);\n totalNodes = parseInt(parts[1], 10);\n result.nodesXCoordinates = new Array(totalNodes).fill(0);\n result.nodesYCoordinates = new Array(totalNodes).fill(0);\n lineIndex++;\n continue;\n }\n\n if (nodeBlocksProcessed < nodeEntityBlocks && currentNodeBlock.numNodes === 0) {\n currentNodeBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n parametric: parseInt(parts[2], 10),\n numNodes: parseInt(parts[3], 10),\n };\n\n nodeTags = [];\n nodeTagsCollected = 0;\n nodeCoordinatesCollected = 0;\n\n lineIndex++;\n continue;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n for (let i = 0; i < parts.length && nodeTagsCollected < currentNodeBlock.numNodes; i++) {\n nodeTags.push(parseInt(parts[i], 10));\n nodeTagsCollected++;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n lineIndex++;\n continue;\n }\n\n lineIndex++;\n continue;\n }\n\n if (nodeCoordinatesCollected < currentNodeBlock.numNodes) {\n const nodeTag = nodeTags[nodeCoordinatesCollected] - 1;\n const x = parseFloat(parts[0]);\n const y = parseFloat(parts[1]);\n\n result.nodesXCoordinates[nodeTag] = x;\n result.nodesYCoordinates[nodeTag] = y;\n result.totalNodesX++;\n result.totalNodesY++;\n\n nodeCoordinatesCollected++;\n\n if (nodeCoordinatesCollected === currentNodeBlock.numNodes) {\n nodeBlocksProcessed++;\n currentNodeBlock = { numNodes: 0 };\n }\n }\n } else if (section === \"elements\") {\n if (elementEntityBlocks === 0) {\n elementEntityBlocks = parseInt(parts[0], 10);\n totalElements = parseInt(parts[1], 10);\n lineIndex++;\n continue;\n }\n\n if (elementBlocksProcessed < elementEntityBlocks && currentElementBlock.numElements === 0) {\n currentElementBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n elementType: parseInt(parts[2], 10),\n numElements: parseInt(parts[3], 10),\n };\n\n result.elementTypes[currentElementBlock.elementType] =\n (result.elementTypes[currentElementBlock.elementType] || 0) + currentElementBlock.numElements;\n\n elementsProcessedInBlock = 0;\n lineIndex++;\n continue;\n }\n\n if (elementsProcessedInBlock < currentElementBlock.numElements) {\n const elementTag = parseInt(parts[0], 10);\n const nodeIndices = parts.slice(1).map((idx) => parseInt(idx, 10));\n\n if (currentElementBlock.elementType === 1 || currentElementBlock.elementType === 8) {\n const physicalTag = currentElementBlock.tag;\n\n if (!boundaryElementsByTag[physicalTag]) {\n boundaryElementsByTag[physicalTag] = [];\n }\n\n boundaryElementsByTag[physicalTag].push(nodeIndices);\n\n // Store boundary node pairs for later processing in meshGenerationScript\n if (!result.boundaryNodePairs[physicalTag]) {\n result.boundaryNodePairs[physicalTag] = [];\n }\n result.boundaryNodePairs[physicalTag].push(nodeIndices);\n } else if (currentElementBlock.elementType === 2) {\n // Linear triangle elements (3 nodes)\n result.nodalNumbering.triangleElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 3) {\n // Linear quadrilateral elements (4 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 10) {\n // Quadratic quadrilateral elements (9 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n }\n\n elementsProcessedInBlock++;\n\n if (elementsProcessedInBlock === currentElementBlock.numElements) {\n elementBlocksProcessed++;\n currentElementBlock = { numElements: 0 };\n }\n }\n }\n\n lineIndex++;\n }\n\n // Store boundary conditions information\n result.physicalPropMap.forEach((prop) => {\n if (prop.dimension === 1) {\n const boundaryNodes = boundaryElementsByTag[prop.tag] || [];\n\n if (boundaryNodes.length > 0) {\n result.boundaryConditions.push({\n name: prop.name,\n tag: prop.tag,\n nodes: boundaryNodes,\n });\n }\n }\n });\n\n debugLog(\n `Parsed boundary node pairs by physical tag: ${JSON.stringify(\n result.boundaryNodePairs\n )}. These pairs will be used to identify boundary elements in the mesh.`\n );\n\n return result;\n};\n\nexport { importGmshQuadTri };\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to create plots of the solution vector\n * @param {*} solutionVector - The computed solution vector\n * @param {*} nodesCoordinates - Object containing x and y coordinates for the nodes\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {string} meshDimension - The dimension of the solution\n * @param {string} plotType - The type of plot\n * @param {string} plotDivId - The id of the div where the plot will be rendered\n * @param {string} [meshType=\"structured\"] - Type of mesh: \"structured\" or \"unstructured\"\n */\nexport function plotSolution(\n solutionVector,\n nodesCoordinates,\n solverConfig,\n meshDimension,\n plotType,\n plotDivId,\n meshType = \"structured\"\n) {\n const { nodesXCoordinates, nodesYCoordinates } = nodesCoordinates;\n\n if (meshDimension === \"1D\" && plotType === \"line\") {\n // Check if solutionVector is a nested array\n let yData;\n if (solutionVector.length > 0 && Array.isArray(solutionVector[0])) {\n yData = solutionVector.map((arr) => arr[0]);\n } else {\n yData = solutionVector;\n }\n let xData = Array.from(nodesXCoordinates);\n\n let lineData = {\n x: xData,\n y: yData,\n mode: \"lines\",\n type: \"scatter\",\n line: { color: \"rgb(219, 64, 82)\", width: 2 },\n name: \"Solution\",\n };\n\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxPlotWidth = Math.max(...xData);\n let zoomFactor = maxWindowWidth / maxPlotWidth;\n let plotWidth = Math.max(zoomFactor * maxPlotWidth, 400);\n let plotHeight = 350;\n\n let layout = {\n title: `line plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"Solution\" },\n margin: { l: 70, r: 40, t: 50, b: 50 },\n };\n\n Plotly.newPlot(plotDivId, [lineData], layout, { responsive: true });\n } else if (meshDimension === \"2D\" && plotType === \"contour\") {\n // Use the user-provided mesh type\n const isStructured = meshType === \"structured\";\n \n // For auto-detection (if needed)\n const uniqueXCoords = new Set(nodesXCoordinates).size;\n const uniqueYCoords = new Set(nodesYCoordinates).size;\n \n // Extract scalar values from solution vector\n let zValues = Array.isArray(solutionVector[0]) \n ? solutionVector.map(val => val[0]) \n : solutionVector;\n \n // Common sizing parameters for both plot types\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxX = Math.max(...nodesXCoordinates);\n let maxY = Math.max(...nodesYCoordinates);\n let aspectRatio = maxY / maxX;\n let plotWidth = Math.min(maxWindowWidth, 600);\n let plotHeight = plotWidth * aspectRatio * 0.8; // Slightly reduce height for better appearance\n \n // Common layout properties\n let layout = {\n title: `${plotType} plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"y\" },\n margin: { l: 50, r: 50, t: 50, b: 50 },\n hovermode: 'closest'\n };\n \n if (isStructured) {\n // Calculate the number of nodes along the x-axis and y-axis\n const numNodesX = uniqueXCoords;\n const numNodesY = uniqueYCoords;\n\n // Reshape the nodesXCoordinates and nodesYCoordinates arrays to match the grid dimensions\n let reshapedXCoordinates = math.reshape(Array.from(nodesXCoordinates), [numNodesX, numNodesY]);\n let reshapedYCoordinates = math.reshape(Array.from(nodesYCoordinates), [numNodesX, numNodesY]);\n\n // Reshape the solution array to match the grid dimensions\n let reshapedSolution = math.reshape(Array.from(solutionVector), [numNodesX, numNodesY]);\n\n // Transpose the reshapedSolution array to get column-wise data\n let transposedSolution = math.transpose(reshapedSolution);\n\n // Create an array for x-coordinates used in the contour plot\n let reshapedXForPlot = [];\n for (let i = 0; i < numNodesX * numNodesY; i += numNodesY) {\n let xValue = nodesXCoordinates[i];\n reshapedXForPlot.push(xValue);\n }\n\n // Create the data structure for the contour plot\n let contourData = {\n z: transposedSolution,\n type: \"contour\",\n contours: {\n coloring: \"heatmap\",\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n x: reshapedXForPlot,\n y: reshapedYCoordinates[0],\n name: 'Solution Field'\n };\n\n // Create the plot using Plotly\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n } else {\n // Create an interpolated contour plot for the unstructured mesh\n let contourData = {\n x: nodesXCoordinates,\n y: nodesYCoordinates,\n z: zValues,\n type: 'contour',\n contours: {\n coloring: 'heatmap',\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n name: 'Solution Field'\n };\n \n // Create the plot using only the contour fill\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n }\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nconst proxyMarker = Symbol(\"Comlink.proxy\");\nconst createEndpoint = Symbol(\"Comlink.endpoint\");\nconst releaseProxy = Symbol(\"Comlink.releaseProxy\");\nconst finalizer = Symbol(\"Comlink.finalizer\");\nconst throwMarker = Symbol(\"Comlink.thrown\");\nconst isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n/**\n * Internal transfer handle to handle objects marked to proxy.\n */\nconst proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n};\n/**\n * Internal transfer handler to handle thrown exceptions.\n */\nconst throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n};\n/**\n * Allows customizing the serialization of certain values.\n */\nconst transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n]);\nfunction isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n}\nfunction expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n}\nfunction isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n}\nfunction closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n}\nfunction wrap(ep, target) {\n const pendingListeners = new Map();\n ep.addEventListener(\"message\", function handleMessage(ev) {\n const { data } = ev;\n if (!data || !data.id) {\n return;\n }\n const resolver = pendingListeners.get(data.id);\n if (!resolver) {\n return;\n }\n try {\n resolver(data);\n }\n finally {\n pendingListeners.delete(data.id);\n }\n });\n return createProxy(ep, pendingListeners, [], target);\n}\nfunction throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n}\nfunction releaseEndpoint(ep) {\n return requestResponseMessage(ep, new Map(), {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n}\nconst proxyCounter = new WeakMap();\nconst proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\nfunction registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n}\nfunction unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n}\nfunction createProxy(ep, pendingListeners, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n pendingListeners.clear();\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, pendingListeners, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, pendingListeners, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, pendingListeners, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, pendingListeners, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n}\nfunction myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n}\nfunction processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n}\nconst transferCache = new WeakMap();\nfunction transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n}\nfunction proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n}\nfunction windowEndpoint(w, context = globalThis, targetOrigin = \"*\") {\n return {\n postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),\n addEventListener: context.addEventListener.bind(context),\n removeEventListener: context.removeEventListener.bind(context),\n };\n}\nfunction toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n}\nfunction fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n}\nfunction requestResponseMessage(ep, pendingListeners, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n pendingListeners.set(id, resolve);\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n}\nfunction generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n}\n\nexport { createEndpoint, expose, finalizer, proxy, proxyMarker, releaseProxy, transfer, transferHandlers, windowEndpoint, wrap };\n//# sourceMappingURL=comlink.mjs.map\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// External imports\nimport * as Comlink from \"../vendor/comlink.mjs\";\n\n// Internal imports\nimport { basicLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to facilitate communication with web workers for FEAScript operations\n */\nexport class FEAScriptWorker {\n /**\n * Constructor to initialize the FEAScriptWorker class\n * Sets up the worker and initializes the workerWrapper.\n */\n constructor() {\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n\n this._initWorker();\n }\n\n /**\n * Function to initialize the web worker and wrap it using Comlink.\n * @private\n * @throws Will throw an error if the worker fails to initialize.\n */\n async _initWorker() {\n try {\n this.worker = new Worker(new URL(\"./wrapperScript.js\", import.meta.url), {\n type: \"module\",\n });\n\n this.worker.onerror = (event) => {\n console.error(\"FEAScriptWorker: Worker error:\", event);\n };\n const workerWrapper = Comlink.wrap(this.worker);\n\n this.feaWorker = await new workerWrapper();\n\n this.isReady = true;\n } catch (error) {\n console.error(\"Failed to initialize worker\", error);\n throw error;\n }\n }\n\n /**\n * Function to ensure that the worker is ready before performing any operations.\n * @private\n * @returns {Promise} Resolves when the worker is ready.\n * @throws Will throw an error if the worker is not ready within the timeout period.\n */\n async _ensureReady() {\n if (this.isReady) return Promise.resolve();\n\n return new Promise((resolve, reject) => {\n let attempts = 0;\n const maxAttempts = 50; // 5 seconds max\n\n const checkReady = () => {\n attempts++;\n if (this.isReady) {\n resolve();\n } else if (attempts >= maxAttempts) {\n reject(new Error(\"Timeout waiting for worker to be ready\"));\n } else {\n setTimeout(checkReady, 1000);\n }\n };\n checkReady();\n });\n }\n\n /**\n * Function to set the solver configuration in the worker.\n * @param {string} solverConfig - The solver configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setSolverConfig(solverConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver config to: ${solverConfig}`);\n return this.feaWorker.setSolverConfig(solverConfig);\n }\n\n /**\n * Sets the mesh configuration in the worker.\n * @param {object} meshConfig - The mesh configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setMeshConfig(meshConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting mesh config`);\n return this.feaWorker.setMeshConfig(meshConfig);\n }\n\n /**\n * Adds a boundary condition to the worker.\n * @param {string} boundaryKey - The key identifying the boundary.\n * @param {array} condition - The boundary condition to add.\n * @returns {Promise} Resolves when the boundary condition is added.\n */\n async addBoundaryCondition(boundaryKey, condition) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Adding boundary condition for boundary: ${boundaryKey}`);\n return this.feaWorker.addBoundaryCondition(boundaryKey, condition);\n }\n\n /**\n * Sets the solver method in the worker.\n * @param {string} solverMethod - The solver method to set.\n * @returns {Promise} Resolves when the solver method is set.\n */\n async setSolverMethod(solverMethod) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver method to: ${solverMethod}`);\n return this.feaWorker.setSolverMethod(solverMethod);\n }\n\n /**\n * Requests the worker to solve the problem.\n * @returns {Promise} Resolves with the solution result.\n */\n async solve() {\n await this._ensureReady();\n basicLog(\"FEAScriptWorker: Requesting solution from worker...\");\n\n const startTime = performance.now();\n const result = await this.feaWorker.solve();\n const endTime = performance.now();\n\n basicLog(`FEAScriptWorker: Solution completed in ${((endTime - startTime) / 1000).toFixed(2)}s`);\n return result;\n }\n\n /**\n * Retrieves model information from the worker.\n * @returns {Promise} Resolves with the model information.\n */\n async getModelInfo() {\n await this._ensureReady();\n return this.feaWorker.getModelInfo();\n }\n\n /**\n * Sends a ping request to the worker to check its availability.\n * @returns {Promise} Resolves if the worker responds.\n */\n async ping() {\n await this._ensureReady();\n return this.feaWorker.ping();\n }\n\n /**\n * Terminates the worker and cleans up resources.\n */\n terminate() {\n if (this.worker) {\n this.worker.terminate();\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n }\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\nexport { FEAScriptModel } from \"./FEAScript.js\";\nexport { importGmshQuadTri } from \"./readers/gmshReaderScript.js\";\nexport { logSystem, printVersion } from \"./utilities/loggingScript.js\";\nexport { plotSolution } from \"./visualization/plotSolutionScript.js\";\nexport { FEAScriptWorker } from \"./workers/workerScript.js\";\nexport const VERSION = \"0.1.1\";"],"names":["numericalIntegration","constructor","meshDimension","elementOrder","this","getGaussPointsAndWeights","gaussPoints","gaussWeights","Math","sqrt","currentLogLevel","logSystem","level","console","log","basicLog","debugLog","message","errorLog","async","printVersion","commitResponse","fetch","commitData","json","latestCommitDate","Date","commit","committer","date","toLocaleString","error","basisFunctions","getBasisFunctions","ksi","eta","basisFunction","basisFunctionDerivKsi","basisFunctionDerivEta","l1","c","l2","l3","dl1","dl2","dl3","meshGeneration","numElementsX","maxX","numElementsY","maxY","parsedMesh","generateMesh","nodalNumbering","Array","isArray","quadElements","triangleElements","JSON","stringify","elementTypes","mappedNodalNumbering","elemIdx","length","gmshNodes","feaScriptNodes","push","physicalPropMap","boundaryElements","undefined","fixedBoundaryElements","i","boundaryNodePairs","boundaryElementsProcessed","forEach","prop","dimension","tag","nodesPair","node1","node2","name","foundElement","elemNodes","includes","side","node1Index","indexOf","node2Index","join","generateMeshFromGeometry","nodesXCoordinates","nodesYCoordinates","totalNodesX","totalNodesY","deltaX","deltaY","nodeIndex","generateNodalNumbering","findBoundaryElements","nodeIndexY","nodeIndexX","nnode","maxSides","sideIndex","elementIndexX","elementIndexY","elementIndex","nop","columnCounter","rowCounter","nodeIndex1","nodeIndex2","ThermalBoundaryConditions","boundaryConditions","imposeConstantTempBoundaryConditions","residualVector","jacobianMatrix","Object","keys","boundaryKey","tempValue","globalNodeIndex","colIndex","imposeConvectionBoundaryConditions","basisFunctionsData","convectionHeatTranfCoeff","convectionExtTemp","key","boundaryCondition","convectionCoeff","extTemp","gaussPoint1","gaussPoint2","firstNodeIndex","lastNodeIndex","nodeIncrement","basisFunctionsAndDerivatives","ksiDerivX","ksiDerivY","etaDerivX","etaDerivY","numNodes","tangentVectorLength","localNodeIndex","localNodeIndex2","globalNodeIndex2","gaussPointIndex","FEAScriptModel","solverConfig","meshConfig","solverMethod","setSolverConfig","setMeshConfig","addBoundaryCondition","condition","setSolverMethod","solve","Error","solutionVector","nodesCoordinates","time","nodesCoordinatesAndNumbering","totalElements","totalNodes","xCoordinates","yCoordinates","detJacobian","localToGlobalMap","basisFunctionDerivX","basisFunctionDerivY","gaussPointsAndWeights","gaussPointIndex1","localNodeIndex1","localToGlobalMap1","localToGlobalMap2","gaussPointIndex2","thermalBoundaryConditions","assembleSolidHeatTransferMat","timeEnd","math","lusolve","jacobiResult","A","b","x0","maxIterations","tolerance","n","x","xNew","iteration","sum","j","maxDiff","max","abs","solution","iterations","converged","jacobiMethod","fill","importGmshQuadTri","file","result","gmshV","ascii","fltBytes","lines","text","split","map","line","trim","filter","section","lineIndex","nodeEntityBlocks","nodeBlocksProcessed","currentNodeBlock","nodeTagsCollected","nodeTags","nodeCoordinatesCollected","elementEntityBlocks","elementBlocksProcessed","currentElementBlock","dim","elementType","numElements","elementsProcessedInBlock","boundaryElementsByTag","parts","part","parseFloat","test","parseInt","slice","replace","parametric","nodeTag","y","nodeIndices","idx","physicalTag","boundaryNodes","nodes","plotSolution","plotType","plotDivId","meshType","yData","arr","xData","from","lineData","mode","type","color","width","maxWindowWidth","min","window","innerWidth","maxPlotWidth","zoomFactor","layout","title","height","xaxis","yaxis","margin","l","r","t","Plotly","newPlot","responsive","isStructured","uniqueXCoords","Set","size","uniqueYCoords","zValues","val","aspectRatio","plotWidth","hovermode","numNodesX","numNodesY","reshape","reshapedYCoordinates","reshapedSolution","transposedSolution","transpose","reshapedXForPlot","xValue","contourData","z","contours","coloring","showlabels","colorbar","proxyMarker","Symbol","createEndpoint","releaseProxy","finalizer","throwMarker","isObject","transferHandlers","Map","canHandle","serialize","obj","port1","port2","MessageChannel","expose","deserialize","port","start","wrap","value","serialized","isError","stack","assign","ep","globalThis","allowedOrigins","addEventListener","callback","ev","data","origin","allowedOrigin","RegExp","isAllowedOrigin","warn","id","path","argumentList","fromWireValue","returnValue","parent","reduce","rawValue","apply","proxy","transfers","transferCache","set","transfer","Promise","resolve","catch","then","wireValue","transferables","toWireValue","postMessage","removeEventListener","closeEndPoint","TypeError","endpoint","isMessagePort","close","target","pendingListeners","resolver","get","delete","createProxy","throwIfProxyReleased","isReleased","releaseEndpoint","requestResponseMessage","proxyCounter","WeakMap","proxyFinalizers","FinalizationRegistry","newCount","isProxyReleased","Proxy","_target","unregister","unregisterProxy","clear","p","toString","bind","_thisArg","rawArgumentList","last","processArguments","construct","register","registerProxy","processed","v","prototype","concat","handler","serializedValue","msg","floor","random","Number","MAX_SAFE_INTEGER","FEAScriptWorker","worker","feaWorker","isReady","_initWorker","Worker","URL","url","onerror","event","workerWrapper","Comlink.wrap","_ensureReady","reject","attempts","checkReady","setTimeout","startTime","performance","now","toFixed","getModelInfo","ping","terminate","VERSION"],"mappings":"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"} \ No newline at end of file diff --git a/dist/feascript.umd.js b/dist/feascript.umd.js new file mode 100644 index 0000000..1a0e0a3 --- /dev/null +++ b/dist/feascript.umd.js @@ -0,0 +1,8 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).FEAScript={})}(this,(function(e){"use strict";class t{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getGaussPointsAndWeights(){let e=[],t=[];return"linear"===this.elementOrder?(e[0]=.5,t[0]=1):"quadratic"===this.elementOrder&&(e[0]=(1-Math.sqrt(.6))/2,e[1]=.5,e[2]=(1+Math.sqrt(.6))/2,t[0]=5/18,t[1]=8/18,t[2]=5/18),{gaussPoints:e,gaussWeights:t}}}let n="basic";function s(e){"debug"===n&&console.log("%c[DEBUG] "+e,"color: #2196F3; font-weight: bold;")}function o(e){console.log("%c[INFO] "+e,"color: #4CAF50; font-weight: bold;")}function i(e){console.log("%c[ERROR] "+e,"color: #F44336; font-weight: bold;")}class r{constructor({meshDimension:e,elementOrder:t}){this.meshDimension=e,this.elementOrder=t}getBasisFunctions(e,t=null){let n=[],s=[],o=[];if("1D"===this.meshDimension)"linear"===this.elementOrder?(n[0]=1-e,n[1]=e,s[0]=-1,s[1]=1):"quadratic"===this.elementOrder&&(n[0]=1-3*e+2*e**2,n[1]=4*e-4*e**2,n[2]=2*e**2-e,s[0]=4*e-3,s[1]=4-8*e,s[2]=4*e-1);else if("2D"===this.meshDimension){if(null===t)return void i("Eta coordinate is required for 2D elements");if("linear"===this.elementOrder){function r(e){return 1-e}n[0]=r(e)*r(t),n[1]=r(e)*t,n[2]=e*r(t),n[3]=e*t,s[0]=-1*r(t),s[1]=-1*t,s[2]=1*r(t),s[3]=1*t,o[0]=-1*r(e),o[1]=1*r(e),o[2]=-1*e,o[3]=1*e}else if("quadratic"===this.elementOrder){function a(e){return 2*e**2-3*e+1}function l(e){return-4*e**2+4*e}function d(e){return 2*e**2-e}function h(e){return 4*e-3}function m(e){return-8*e+4}function u(e){return 4*e-1}n[0]=a(e)*a(t),n[1]=a(e)*l(t),n[2]=a(e)*d(t),n[3]=l(e)*a(t),n[4]=l(e)*l(t),n[5]=l(e)*d(t),n[6]=d(e)*a(t),n[7]=d(e)*l(t),n[8]=d(e)*d(t),s[0]=h(e)*a(t),s[1]=h(e)*l(t),s[2]=h(e)*d(t),s[3]=m(e)*a(t),s[4]=m(e)*l(t),s[5]=m(e)*d(t),s[6]=u(e)*a(t),s[7]=u(e)*l(t),s[8]=u(e)*d(t),o[0]=a(e)*h(t),o[1]=a(e)*m(t),o[2]=a(e)*u(t),o[3]=l(e)*h(t),o[4]=l(e)*m(t),o[5]=l(e)*u(t),o[6]=d(e)*h(t),o[7]=d(e)*m(t),o[8]=d(e)*u(t)}}return{basisFunction:n,basisFunctionDerivKsi:s,basisFunctionDerivEta:o}}}class a{constructor({numElementsX:e=null,maxX:t=null,numElementsY:n=null,maxY:s=null,meshDimension:o=null,elementOrder:i="linear",parsedMesh:r=null}){this.numElementsX=e,this.numElementsY=n,this.maxX=t,this.maxY=s,this.meshDimension=o,this.elementOrder=i,this.parsedMesh=r}generateMesh(){if(this.parsedMesh){if(this.parsedMesh.nodalNumbering&&"object"==typeof this.parsedMesh.nodalNumbering&&!Array.isArray(this.parsedMesh.nodalNumbering)){const e=this.parsedMesh.nodalNumbering.quadElements||[];if(this.parsedMesh.nodalNumbering.triangleElements,s("Initial parsed mesh nodal numbering from GMSH format: "+JSON.stringify(this.parsedMesh.nodalNumbering)),this.parsedMesh.elementTypes[3]||this.parsedMesh.elementTypes[10]){const t=[];for(let n=0;n0&&void 0===this.parsedMesh.boundaryElements[0]){const e=[];for(let t=1;t{if(1===e.dimension){const t=this.parsedMesh.boundaryNodePairs[e.tag]||[];t.length>0&&(this.parsedMesh.boundaryElements[e.tag]||(this.parsedMesh.boundaryElements[e.tag]=[]),t.forEach((t=>{const n=t[0],o=t[1];s(`Processing boundary node pair: [${n}, ${o}] for boundary ${e.tag} (${e.name||"unnamed"})`);let r=!1;for(let t=0;t0&&void 0===this.parsedMesh.boundaryElements[0])){const e=[];for(let t=1;t{if("constantTemp"===this.boundaryConditions[n][0]){const o=this.boundaryConditions[n][1];s(`Boundary ${n}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[n].forEach((([n,i])=>{if("linear"===this.elementOrder){({0:[0],1:[1]})[i].forEach((i=>{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{if("constantTemp"===this.boundaryConditions[n][0]){const o=this.boundaryConditions[n][1];s(`Boundary ${n}: Applying constant temperature of ${o} K (Dirichlet condition)`),this.boundaryElements[n].forEach((([n,i])=>{if("linear"===this.elementOrder){({0:[0,2],1:[0,1],2:[1,3],3:[2,3]})[i].forEach((i=>{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const r=this.nop[n][i]-1;s(` - Applied fixed temperature to node ${r+1} (element ${n+1}, local node ${i+1})`),e[r]=o;for(let n=0;n{const t=this.boundaryConditions[e];"convection"===t[0]&&(d[e]=t[1],h[e]=t[2])})),"1D"===this.meshDimension?Object.keys(this.boundaryConditions).forEach((n=>{if("convection"===this.boundaryConditions[n][0]){const o=d[n],i=h[n];s(`Boundary ${n}: Applying convection with heat transfer coefficient h=${o} W/(m²·K) and external temperature T∞=${i} K`),this.boundaryElements[n].forEach((([n,r])=>{let a;"linear"===this.elementOrder?a=0===r?0:1:"quadratic"===this.elementOrder&&(a=0===r?0:2);const l=this.nop[n][a]-1;s(` - Applied convection boundary condition to node ${l+1} (element ${n+1}, local node ${a+1})`),e[l]+=-o*i,t[l][l]+=o}))}})):"2D"===this.meshDimension&&Object.keys(this.boundaryConditions).forEach((o=>{if("convection"===this.boundaryConditions[o][0]){const m=d[o],u=h[o];s(`Boundary ${o}: Applying convection with heat transfer coefficient h=${m} W/(m²·K) and external temperature T∞=${u} K`),this.boundaryElements[o].forEach((([o,d])=>{if("linear"===this.elementOrder){let h,c,f,p,y;0===d?(h=n[0],c=0,f=0,p=3,y=2):1===d?(h=0,c=n[0],f=0,p=2,y=1):2===d?(h=n[0],c=1,f=1,p=4,y=2):3===d&&(h=1,c=n[0],f=2,p=4,y=1);let g=l.getBasisFunctions(h,c),b=g.basisFunction,E=g.basisFunctionDerivKsi,M=g.basisFunctionDerivEta,$=0,v=0,w=0,C=0;const S=this.nop[o].length;for(let e=0;e"object"==typeof e&&null!==e||"function"==typeof e,p=new Map([["proxy",{canHandle:e=>f(e)&&e[d],serialize(e){const{port1:t,port2:n}=new MessageChannel;return y(e,t),[n,[n]]},deserialize:e=>(e.start(),b(e))}],["throw",{canHandle:e=>f(e)&&c in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function y(e,t=globalThis,n=["*"]){t.addEventListener("message",(function s(o){if(!o||!o.data)return;if(!function(e,t){for(const n of e){if(t===n||"*"===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}return!1}(n,o.origin))return void console.warn(`Invalid origin '${o.origin}' for comlink proxy`);const{id:i,type:r,path:a}=Object.assign({path:[]},o.data),l=(o.data.argumentList||[]).map(D);let h;try{const t=a.slice(0,-1).reduce(((e,t)=>e[t]),e),n=a.reduce(((e,t)=>e[t]),e);switch(r){case"GET":h=n;break;case"SET":t[a.slice(-1)[0]]=D(o.data.value),h=!0;break;case"APPLY":h=n.apply(t,l);break;case"CONSTRUCT":h=function(e){return Object.assign(e,{[d]:!0})}(new n(...l));break;case"ENDPOINT":{const{port1:t,port2:n}=new MessageChannel;y(e,n),h=function(e,t){return S.set(e,t),e}(t,[t])}break;case"RELEASE":h=void 0;break;default:return}}catch(e){h={value:e,[c]:0}}Promise.resolve(h).catch((e=>({value:e,[c]:0}))).then((n=>{const[o,a]=N(n);t.postMessage(Object.assign(Object.assign({},o),{id:i}),a),"RELEASE"===r&&(t.removeEventListener("message",s),g(t),u in e&&"function"==typeof e[u]&&e[u]())})).catch((e=>{const[n,s]=N({value:new TypeError("Unserializable return value"),[c]:0});t.postMessage(Object.assign(Object.assign({},n),{id:i}),s)}))})),t.start&&t.start()}function g(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function b(e,t){const n=new Map;return e.addEventListener("message",(function(e){const{data:t}=e;if(!t||!t.id)return;const s=n.get(t.id);if(s)try{s(t)}finally{n.delete(t.id)}})),w(e,n,[],t)}function E(e){if(e)throw new Error("Proxy has been released and is not useable")}function M(e){return O(e,new Map,{type:"RELEASE"}).then((()=>{g(e)}))}const $=new WeakMap,v="FinalizationRegistry"in globalThis&&new FinalizationRegistry((e=>{const t=($.get(e)||0)-1;$.set(e,t),0===t&&M(e)}));function w(e,t,n=[],s=function(){}){let o=!1;const i=new Proxy(s,{get(s,r){if(E(o),r===m)return()=>{!function(e){v&&v.unregister(e)}(i),M(e),t.clear(),o=!0};if("then"===r){if(0===n.length)return{then:()=>i};const s=O(e,t,{type:"GET",path:n.map((e=>e.toString()))}).then(D);return s.then.bind(s)}return w(e,t,[...n,r])},set(s,i,r){E(o);const[a,l]=N(r);return O(e,t,{type:"SET",path:[...n,i].map((e=>e.toString())),value:a},l).then(D)},apply(s,i,r){E(o);const a=n[n.length-1];if(a===h)return O(e,t,{type:"ENDPOINT"}).then(D);if("bind"===a)return w(e,t,n.slice(0,-1));const[l,d]=C(r);return O(e,t,{type:"APPLY",path:n.map((e=>e.toString())),argumentList:l},d).then(D)},construct(s,i){E(o);const[r,a]=C(i);return O(e,t,{type:"CONSTRUCT",path:n.map((e=>e.toString())),argumentList:r},a).then(D)}});return function(e,t){const n=($.get(t)||0)+1;$.set(t,n),v&&v.register(e,t,e)}(i,e),i}function C(e){const t=e.map(N);return[t.map((e=>e[0])),(n=t.map((e=>e[1])),Array.prototype.concat.apply([],n))];var n}const S=new WeakMap;function N(e){for(const[t,n]of p)if(n.canHandle(e)){const[s,o]=n.serialize(e);return[{type:"HANDLER",name:t,value:s},o]}return[{type:"RAW",value:e},S.get(e)||[]]}function D(e){switch(e.type){case"HANDLER":return p.get(e.name).deserialize(e.value);case"RAW":return e.value}}function O(e,t,n,s){return new Promise((o=>{const i=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");t.set(i,o),e.start&&e.start(),e.postMessage(Object.assign({id:i},n),s)}))}e.FEAScriptModel=class{constructor(){this.solverConfig=null,this.meshConfig={},this.boundaryConditions={},this.solverMethod="lusolve",o("FEAScriptModel instance created")}setSolverConfig(e){this.solverConfig=e,s(`Solver config set to: ${e}`)}setMeshConfig(e){this.meshConfig=e,s(`Mesh config set with dimensions: ${e.meshDimension}`)}addBoundaryCondition(e,t){this.boundaryConditions[e]=t,s(`Boundary condition added for boundary: ${e}, type: ${t[0]}`)}setSolverMethod(e){this.solverMethod=e,s(`Solver method set to: ${e}`)}solve(){if(!this.solverConfig||!this.meshConfig||!this.boundaryConditions){const e="Solver config, mesh config, and boundary conditions must be set before solving.";throw console.error(e),new Error(e)}let e=[],n=[],i=[],d={};if(o("Beginning matrix assembly..."),console.time("assemblyMatrices"),"solidHeatTransferScript"===this.solverConfig&&(o(`Using solver: ${this.solverConfig}`),({jacobianMatrix:e,residualVector:n,nodesCoordinates:d}=function(e,n){o("Starting solid heat transfer matrix assembly...");const{meshDimension:i,numElementsX:d,numElementsY:h,maxX:m,maxY:u,elementOrder:c,parsedMesh:f}=e;s("Generating mesh...");const p=new a({numElementsX:d,numElementsY:h,maxX:m,maxY:u,meshDimension:i,elementOrder:c,parsedMesh:f}).generateMesh();let y,g,b=p.nodesXCoordinates,E=p.nodesYCoordinates,M=p.totalNodesX,$=p.totalNodesY,v=p.nodalNumbering,w=p.boundaryElements;null!=f?(y=v.length,g=b.length,s(`Using parsed mesh with ${y} elements and ${g} nodes`)):(y=d*("2D"===i?h:1),g=M*("2D"===i?$:1),s(`Using mesh generated from geometry with ${y} elements and ${g} nodes`));let C,S,N,D,O,x,A,F=[],T=[],k=[],X=[],P=[],R=[],Y=[],W=[],I=[],j=[];for(let e=0;e{console.error("FEAScriptWorker: Worker error:",e)};const e=b(this.worker);this.feaWorker=await new e,this.isReady=!0}catch(e){throw console.error("Failed to initialize worker",e),e}}async _ensureReady(){return this.isReady?Promise.resolve():new Promise(((e,t)=>{let n=0;const s=()=>{n++,this.isReady?e():n>=50?t(new Error("Timeout waiting for worker to be ready")):setTimeout(s,1e3)};s()}))}async setSolverConfig(e){return await this._ensureReady(),o(`FEAScriptWorker: Setting solver config to: ${e}`),this.feaWorker.setSolverConfig(e)}async setMeshConfig(e){return await this._ensureReady(),o("FEAScriptWorker: Setting mesh config"),this.feaWorker.setMeshConfig(e)}async addBoundaryCondition(e,t){return await this._ensureReady(),o(`FEAScriptWorker: Adding boundary condition for boundary: ${e}`),this.feaWorker.addBoundaryCondition(e,t)}async setSolverMethod(e){return await this._ensureReady(),o(`FEAScriptWorker: Setting solver method to: ${e}`),this.feaWorker.setSolverMethod(e)}async solve(){await this._ensureReady(),o("FEAScriptWorker: Requesting solution from worker...");const e=performance.now(),t=await this.feaWorker.solve();return o(`FEAScriptWorker: Solution completed in ${((performance.now()-e)/1e3).toFixed(2)}s`),t}async getModelInfo(){return await this._ensureReady(),this.feaWorker.getModelInfo()}async ping(){return await this._ensureReady(),this.feaWorker.ping()}terminate(){this.worker&&(this.worker.terminate(),this.worker=null,this.feaWorker=null,this.isReady=!1)}},e.VERSION="0.1.1",e.importGmshQuadTri=async e=>{let t={nodesXCoordinates:[],nodesYCoordinates:[],nodalNumbering:{quadElements:[],triangleElements:[]},boundaryElements:[],boundaryConditions:[],boundaryNodePairs:{},gmshV:0,ascii:!1,fltBytes:"8",totalNodesX:0,totalNodesY:0,physicalPropMap:[],elementTypes:{}},n=(await e.text()).split("\n").map((e=>e.trim())).filter((e=>""!==e&&" "!==e)),o="",i=0,r=0,a=0,l=0,d={numNodes:0},h=0,m=[],u=0,c=0,f=0,p={dim:0,tag:0,elementType:0,numElements:0},y=0,g={};for(;i""!==e));if("meshFormat"===o)t.gmshV=parseFloat(s[0]),t.ascii="0"===s[1],t.fltBytes=s[2];else if("physicalNames"===o){if(s.length>=3){if(!/^\d+$/.test(s[0])){i++;continue}const e=parseInt(s[0],10),n=parseInt(s[1],10);let o=s.slice(2).join(" ");o=o.replace(/^"|"$/g,""),t.physicalPropMap.push({tag:n,dimension:e,name:o})}}else if("nodes"===o){if(0===r){r=parseInt(s[0],10),a=parseInt(s[1],10),t.nodesXCoordinates=new Array(a).fill(0),t.nodesYCoordinates=new Array(a).fill(0),i++;continue}if(lparseInt(e,10)));if(1===p.elementType||8===p.elementType){const n=p.tag;g[n]||(g[n]=[]),g[n].push(e),t.boundaryNodePairs[n]||(t.boundaryNodePairs[n]=[]),t.boundaryNodePairs[n].push(e)}else 2===p.elementType?t.nodalNumbering.triangleElements.push(e):(3===p.elementType||10===p.elementType)&&t.nodalNumbering.quadElements.push(e);y++,y===p.numElements&&(f++,p={numElements:0})}}i++}return t.physicalPropMap.forEach((e=>{if(1===e.dimension){const n=g[e.tag]||[];n.length>0&&t.boundaryConditions.push({name:e.name,tag:e.tag,nodes:n})}})),s(`Parsed boundary node pairs by physical tag: ${JSON.stringify(t.boundaryNodePairs)}. These pairs will be used to identify boundary elements in the mesh.`),t},e.logSystem=function(e){"basic"!==e&&"debug"!==e?(console.log("%c[WARN] Invalid log level: "+e+". Using basic instead.","color: #FFC107; font-weight: bold;"),n="basic"):(n=e,o(`Log level set to: ${e}`))},e.plotSolution=function(e,t,n,s,o,i,r="structured"){const{nodesXCoordinates:a,nodesYCoordinates:l}=t;if("1D"===s&&"line"===o){let t;t=e.length>0&&Array.isArray(e[0])?e.map((e=>e[0])):e;let s=Array.from(a),o={x:s,y:t,mode:"lines",type:"scatter",line:{color:"rgb(219, 64, 82)",width:2},name:"Solution"},r=Math.min(window.innerWidth,700),l=Math.max(...s),d=r/l,h={title:`line plot - ${n}`,width:Math.max(d*l,400),height:350,xaxis:{title:"x"},yaxis:{title:"Solution"},margin:{l:70,r:40,t:50,b:50}};Plotly.newPlot(i,[o],h,{responsive:!0})}else if("2D"===s&&"contour"===o){const t="structured"===r,s=new Set(a).size,d=new Set(l).size;let h=Array.isArray(e[0])?e.map((e=>e[0])):e,m=Math.min(window.innerWidth,700),u=Math.max(...a),c=Math.max(...l)/u,f=Math.min(m,600),p={title:`${o} plot - ${n}`,width:f,height:f*c*.8,xaxis:{title:"x"},yaxis:{title:"y"},margin:{l:50,r:50,t:50,b:50},hovermode:"closest"};if(t){const t=s,n=d;math.reshape(Array.from(a),[t,n]);let o=math.reshape(Array.from(l),[t,n]),r=math.reshape(Array.from(e),[t,n]),h=math.transpose(r),m=[];for(let e=0;e | |\n // 0 --- 1 0 --- 2\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[3]; // 3 -> 1\n feaScriptNodes[2] = gmshNodes[1]; // 1 -> 2\n feaScriptNodes[3] = gmshNodes[2]; // 2 -> 3\n } else if (gmshNodes.length === 9) {\n // Mapping for quadratic quad elements (9 nodes)\n // GMSH: FEAScript:\n // 3--6--2 2--5--8\n // | | | |\n // 7 8 5 --> 1 4 7\n // | | | |\n // 0--4--1 0--3--6\n\n feaScriptNodes[0] = gmshNodes[0]; // 0 -> 0\n feaScriptNodes[1] = gmshNodes[7]; // 7 -> 1\n feaScriptNodes[2] = gmshNodes[3]; // 3 -> 2\n feaScriptNodes[3] = gmshNodes[4]; // 4 -> 3\n feaScriptNodes[4] = gmshNodes[8]; // 8 -> 4\n feaScriptNodes[5] = gmshNodes[6]; // 6 -> 5\n feaScriptNodes[6] = gmshNodes[1]; // 1 -> 6\n feaScriptNodes[7] = gmshNodes[5]; // 5 -> 7\n feaScriptNodes[8] = gmshNodes[2]; // 2 -> 8\n }\n\n mappedNodalNumbering.push(feaScriptNodes);\n }\n\n this.parsedMesh.nodalNumbering = mappedNodalNumbering;\n } else if (this.parsedMesh.elementTypes[2]) {\n }\n\n debugLog(\n \"Nodal numbering after mapping from GMSH to FEAScript format: \" +\n JSON.stringify(this.parsedMesh.nodalNumbering)\n );\n\n // Process boundary elements if they exist and if physical property mapping exists\n if (this.parsedMesh.physicalPropMap && this.parsedMesh.boundaryElements) {\n // Check if boundary elements need to be processed\n if (\n Array.isArray(this.parsedMesh.boundaryElements) &&\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n // Create a new array without the empty first element\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n\n // If boundary node pairs exist but boundary elements haven't been processed\n if (this.parsedMesh.boundaryNodePairs && !this.parsedMesh.boundaryElementsProcessed) {\n // Reset boundary elements array\n this.parsedMesh.boundaryElements = [];\n\n // Process each physical property from the Gmsh file\n this.parsedMesh.physicalPropMap.forEach((prop) => {\n // Only process 1D physical entities (boundary lines)\n if (prop.dimension === 1) {\n // Get all node pairs for this boundary\n const boundaryNodePairs = this.parsedMesh.boundaryNodePairs[prop.tag] || [];\n\n if (boundaryNodePairs.length > 0) {\n // Initialize array for this boundary tag\n if (!this.parsedMesh.boundaryElements[prop.tag]) {\n this.parsedMesh.boundaryElements[prop.tag] = [];\n }\n\n // For each boundary line segment (defined by a pair of nodes)\n boundaryNodePairs.forEach((nodesPair) => {\n const node1 = nodesPair[0]; // First node in the pair\n const node2 = nodesPair[1]; // Second node in the pair\n\n debugLog(\n `Processing boundary node pair: [${node1}, ${node2}] for boundary ${prop.tag} (${\n prop.name || \"unnamed\"\n })`\n );\n\n // Search through all elements to find which one contains both nodes\n let foundElement = false;\n\n // Loop through all elements in the mesh\n for (let elemIdx = 0; elemIdx < this.parsedMesh.nodalNumbering.length; elemIdx++) {\n const elemNodes = this.parsedMesh.nodalNumbering[elemIdx];\n\n // For linear quadrilateral linear elements (4 nodes)\n if (elemNodes.length === 4) {\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript linear quadrilateral numbering:\n // 1 --- 3\n // | |\n // 0 --- 2\n\n if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0)\n ) {\n side = 0; // Bottom side\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0)\n ) {\n side = 1; // Left side\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 1 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 1)\n ) {\n side = 2; // Top side\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 2)\n ) {\n side = 3; // Right side\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n } else if (elemNodes.length === 9) {\n // For quadratic quadrilateral elements (9 nodes)\n // Check if both boundary nodes are in this element\n if (elemNodes.includes(node1) && elemNodes.includes(node2)) {\n // Find which side of the element these nodes form\n let side;\n\n const node1Index = elemNodes.indexOf(node1);\n const node2Index = elemNodes.indexOf(node2);\n\n debugLog(\n ` Found element ${elemIdx} containing boundary nodes. Element nodes: [${elemNodes.join(\n \", \"\n )}]`\n );\n debugLog(\n ` Node ${node1} is at index ${node1Index}, Node ${node2} is at index ${node2Index} in the element`\n );\n\n // Based on FEAScript quadratic quadrilateral numbering:\n // 2--5--8\n // | |\n // 1 4 7\n // | |\n // 0--3--6\n\n if (\n (node1Index === 0 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 3) ||\n (node1Index === 3 && node2Index === 0) ||\n (node1Index === 3 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 3)\n ) {\n side = 0; // Bottom side (nodes 0, 3, 6)\n debugLog(` These nodes form the BOTTOM side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 0 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 0) ||\n (node1Index === 0 && node2Index === 1) ||\n (node1Index === 1 && node2Index === 0) ||\n (node1Index === 1 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 1)\n ) {\n side = 1; // Left side (nodes 0, 1, 2)\n debugLog(` These nodes form the LEFT side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 2 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 2) ||\n (node1Index === 2 && node2Index === 5) ||\n (node1Index === 5 && node2Index === 2) ||\n (node1Index === 5 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 5)\n ) {\n side = 2; // Top side (nodes 2, 5, 8)\n debugLog(` These nodes form the TOP side (${side}) of element ${elemIdx}`);\n } else if (\n (node1Index === 6 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 6) ||\n (node1Index === 6 && node2Index === 7) ||\n (node1Index === 7 && node2Index === 6) ||\n (node1Index === 7 && node2Index === 8) ||\n (node1Index === 8 && node2Index === 7)\n ) {\n side = 3; // Right side (nodes 6, 7, 8)\n debugLog(` These nodes form the RIGHT side (${side}) of element ${elemIdx}`);\n }\n\n // Add the element and side to the boundary elements array\n this.parsedMesh.boundaryElements[prop.tag].push([elemIdx, side]);\n debugLog(\n ` Added element-side pair [${elemIdx}, ${side}] to boundary tag ${prop.tag}`\n );\n foundElement = true;\n break;\n }\n }\n }\n\n if (!foundElement) {\n errorLog(\n `Could not find element containing boundary nodes ${node1} and ${node2}. Boundary may be incomplete.`\n );\n }\n });\n }\n }\n });\n\n // Mark as processed\n this.parsedMesh.boundaryElementsProcessed = true;\n\n // Fix boundary elements array - remove undefined entries\n if (\n this.parsedMesh.boundaryElements.length > 0 &&\n this.parsedMesh.boundaryElements[0] === undefined\n ) {\n const fixedBoundaryElements = [];\n for (let i = 1; i < this.parsedMesh.boundaryElements.length; i++) {\n if (this.parsedMesh.boundaryElements[i]) {\n fixedBoundaryElements.push(this.parsedMesh.boundaryElements[i]);\n }\n }\n this.parsedMesh.boundaryElements = fixedBoundaryElements;\n }\n }\n }\n }\n }\n\n debugLog(\"Processed boundary elements by tag: \" + JSON.stringify(this.parsedMesh.boundaryElements));\n\n return this.parsedMesh;\n } else {\n // Validate required geometry parameters based on mesh dimension\n if (this.meshDimension === \"1D\") {\n if (this.numElementsX === null || this.maxX === null) {\n errorLog(\"numElementsX and maxX are required parameters when generating a 1D mesh from geometry\");\n }\n } else if (this.meshDimension === \"2D\") {\n if (\n this.numElementsX === null ||\n this.maxX === null ||\n this.numElementsY === null ||\n this.maxY === null\n ) {\n errorLog(\n \"numElementsX, maxX, numElementsY, and maxY are required parameters when generating a 2D mesh from geometry\"\n );\n }\n }\n\n // Generate mesh based on dimension\n return this.generateMeshFromGeometry();\n }\n }\n\n /**\n * Function to generate a structured mesh based on the geometry configuration\n * @returns {object} An object containing the coordinates of nodes,\n * total number of nodes, nodal numbering (NOP) array, and boundary elements\n */\n generateMeshFromGeometry() {\n let nodesXCoordinates = [];\n let nodesYCoordinates = [];\n const xStart = 0;\n const yStart = 0;\n let totalNodesX, totalNodesY, deltaX, deltaY;\n\n if (this.meshDimension === \"1D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX;\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n\n nodesXCoordinates[0] = xStart;\n for (let nodeIndex = 1; nodeIndex < totalNodesX; nodeIndex++) {\n nodesXCoordinates[nodeIndex] = nodesXCoordinates[nodeIndex - 1] + deltaX / 2;\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n null, // numElementsY (not used in 1D)\n totalNodesX,\n null, // totalNodesY (not used in 1D)\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n\n // Return x coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n totalNodesX,\n nodalNumbering,\n boundaryElements,\n };\n } else if (this.meshDimension === \"2D\") {\n if (this.elementOrder === \"linear\") {\n totalNodesX = this.numElementsX + 1;\n totalNodesY = this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + nodeIndexY * deltaY;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + nodeIndexX * deltaX;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + nodeIndexY * deltaY;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n totalNodesX = 2 * this.numElementsX + 1;\n totalNodesY = 2 * this.numElementsY + 1;\n deltaX = (this.maxX - xStart) / this.numElementsX;\n deltaY = (this.maxY - yStart) / this.numElementsY;\n\n nodesXCoordinates[0] = xStart;\n nodesYCoordinates[0] = yStart;\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nodeIndexY] = nodesXCoordinates[0];\n nodesYCoordinates[nodeIndexY] = nodesYCoordinates[0] + (nodeIndexY * deltaY) / 2;\n }\n for (let nodeIndexX = 1; nodeIndexX < totalNodesX; nodeIndexX++) {\n const nnode = nodeIndexX * totalNodesY;\n nodesXCoordinates[nnode] = nodesXCoordinates[0] + (nodeIndexX * deltaX) / 2;\n nodesYCoordinates[nnode] = nodesYCoordinates[0];\n for (let nodeIndexY = 1; nodeIndexY < totalNodesY; nodeIndexY++) {\n nodesXCoordinates[nnode + nodeIndexY] = nodesXCoordinates[nnode];\n nodesYCoordinates[nnode + nodeIndexY] = nodesYCoordinates[nnode] + (nodeIndexY * deltaY) / 2;\n }\n }\n }\n // Generate nodal numbering (NOP) array\n const nodalNumbering = this.generateNodalNumbering(\n this.numElementsX,\n this.numElementsY,\n totalNodesX,\n totalNodesY,\n this.elementOrder\n );\n // Find boundary elements\n const boundaryElements = this.findBoundaryElements();\n\n debugLog(\"Generated node X coordinates: \" + JSON.stringify(nodesXCoordinates));\n debugLog(\"Generated node Y coordinates: \" + JSON.stringify(nodesYCoordinates));\n\n // Return x and y coordinates of nodes, total nodes, NOP array, and boundary elements\n return {\n nodesXCoordinates,\n nodesYCoordinates,\n totalNodesX,\n totalNodesY,\n nodalNumbering,\n boundaryElements,\n };\n }\n }\n\n /**\n * Function to find the elements that belong to each boundary of a domain\n * @returns {array} An array containing arrays of elements and their adjacent boundary side for each boundary\n * Each element in the array is of the form [elementIndex, side], where 'side' indicates which side\n * of the reference element is in contact with the physical boundary:\n *\n * For 1D domains (line segments):\n * 0 - Left node of reference element (maps to physical left endpoint)\n * 1 - Right node of reference element (maps to physical right endpoint)\n *\n * For 2D domains (rectangular):\n * 0 - Bottom side of reference element (maps to physical bottom boundary)\n * 1 - Left side of reference element (maps to physical left boundary)\n * 2 - Top side of reference element (maps to physical top boundary)\n * 3 - Right side of reference element (maps to physical right boundary)\n */\n findBoundaryElements() {\n const boundaryElements = [];\n const maxSides = this.meshDimension === \"1D\" ? 2 : 4; // Number of element sides based on mesh dimension\n for (let sideIndex = 0; sideIndex < maxSides; sideIndex++) {\n boundaryElements.push([]);\n }\n\n if (this.meshDimension === \"1D\") {\n // Left boundary (element 0, side 0)\n boundaryElements[0].push([0, 0]);\n\n // Right boundary (last element, side 1)\n boundaryElements[1].push([this.numElementsX - 1, 1]);\n } else if (this.meshDimension === \"2D\") {\n for (let elementIndexX = 0; elementIndexX < this.numElementsX; elementIndexX++) {\n for (let elementIndexY = 0; elementIndexY < this.numElementsY; elementIndexY++) {\n const elementIndex = elementIndexX * this.numElementsY + elementIndexY;\n\n // Bottom boundary\n if (elementIndexY === 0) {\n boundaryElements[0].push([elementIndex, 0]);\n }\n\n // Left boundary\n if (elementIndexX === 0) {\n boundaryElements[1].push([elementIndex, 1]);\n }\n\n // Top boundary\n if (elementIndexY === this.numElementsY - 1) {\n boundaryElements[2].push([elementIndex, 2]);\n }\n\n // Right boundary\n if (elementIndexX === this.numElementsX - 1) {\n boundaryElements[3].push([elementIndex, 3]);\n }\n }\n }\n }\n\n debugLog(\"Identified boundary elements by side: \" + JSON.stringify(boundaryElements));\n return boundaryElements;\n }\n\n /**\n * Function to generate the nodal numbering (NOP) array for a structured mesh\n * This array represents the connectivity between elements and their corresponding nodes\n * @param {number} numElementsX - Number of elements along the x-axis\n * @param {number} [numElementsY] - Number of elements along the y-axis (optional for 1D)\n * @param {number} totalNodesX - Total number of nodes along the x-axis\n * @param {number} [totalNodesY] - Total number of nodes along the y-axis (optional for 1D)\n * @param {string} elementOrder - The order of elements, either 'linear' or 'quadratic'\n * @returns {array} NOP - A two-dimensional array which represents the element-to-node connectivity for the entire mesh\n */\n generateNodalNumbering(numElementsX, numElementsY, totalNodesX, totalNodesY, elementOrder) {\n let elementIndex = 0;\n let nop = [];\n\n if (this.meshDimension === \"1D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear 1D elements with the following nodes representation:\n *\n * 1 --- 2\n *\n */\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 2; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic 1D elements with the following nodes representation:\n *\n * 1--2--3\n *\n */\n let columnCounter = 0;\n for (let elementIndex = 0; elementIndex < numElementsX; elementIndex++) {\n nop[elementIndex] = [];\n for (let nodeIndex = 1; nodeIndex <= 3; nodeIndex++) {\n nop[elementIndex][nodeIndex - 1] = elementIndex + nodeIndex + columnCounter;\n }\n columnCounter += 1;\n }\n }\n } else if (this.meshDimension === \"2D\") {\n if (elementOrder === \"linear\") {\n /**\n * Linear rectangular elements with the following nodes representation:\n *\n * 1 --- 3\n * | |\n * 0 --- 2\n *\n */\n let rowCounter = 0;\n let columnCounter = 2;\n for (let elementIndex = 0; elementIndex < numElementsX * numElementsY; elementIndex++) {\n rowCounter += 1;\n nop[elementIndex] = [];\n nop[elementIndex][0] = elementIndex + columnCounter - 1;\n nop[elementIndex][1] = elementIndex + columnCounter;\n nop[elementIndex][2] = elementIndex + columnCounter + numElementsY;\n nop[elementIndex][3] = elementIndex + columnCounter + numElementsY + 1;\n if (rowCounter === numElementsY) {\n columnCounter += 1;\n rowCounter = 0;\n }\n }\n } else if (elementOrder === \"quadratic\") {\n /**\n * Quadratic rectangular elements with the following nodes representation:\n *\n * 2--5--8\n * | |\n * 1 4 7\n * | |\n * 0--3--6\n *\n */\n for (let elementIndexX = 1; elementIndexX <= numElementsX; elementIndexX++) {\n for (let elementIndexY = 1; elementIndexY <= numElementsY; elementIndexY++) {\n nop[elementIndex] = [];\n for (let nodeIndex1 = 1; nodeIndex1 <= 3; nodeIndex1++) {\n let nodeIndex2 = 3 * nodeIndex1 - 2;\n nop[elementIndex][nodeIndex2 - 1] =\n totalNodesY * (2 * elementIndexX + nodeIndex1 - 3) + 2 * elementIndexY - 1;\n nop[elementIndex][nodeIndex2] = nop[elementIndex][nodeIndex2 - 1] + 1;\n nop[elementIndex][nodeIndex2 + 1] = nop[elementIndex][nodeIndex2 - 1] + 2;\n }\n elementIndex = elementIndex + 1;\n }\n }\n }\n }\n\n return nop;\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to handle thermal boundary conditions application\n */\nexport class ThermalBoundaryConditions {\n /**\n * Constructor to initialize the ThermalBoundaryConditions class\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @param {array} boundaryElements - Array containing elements that belong to each boundary\n * @param {array} nop - Nodal numbering (NOP) array representing the connectivity between elements and nodes\n * @param {string} meshDimension - The dimension of the mesh (e.g., \"2D\")\n * @param {string} elementOrder - The order of elements (e.g., \"linear\", \"quadratic\")\n */\n constructor(boundaryConditions, boundaryElements, nop, meshDimension, elementOrder) {\n this.boundaryConditions = boundaryConditions;\n this.boundaryElements = boundaryElements;\n this.nop = nop;\n this.meshDimension = meshDimension;\n this.elementOrder = elementOrder;\n }\n\n /**\n * Function to impose constant temperature boundary conditions (Dirichlet type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n */\n imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix) {\n basicLog(\"Applying constant temperature boundary conditions (Dirichlet type)\");\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 1: [1], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0], // Node at the left side of the reference element\n 2: [2], // Node at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"constantTemp\") {\n const tempValue = this.boundaryConditions[boundaryKey][1];\n debugLog(\n `Boundary ${boundaryKey}: Applying constant temperature of ${tempValue} K (Dirichlet condition)`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n const boundarySides = {\n 0: [0, 2], // Nodes at the bottom side of the reference element\n 1: [0, 1], // Nodes at the left side of the reference element\n 2: [1, 3], // Nodes at the top side of the reference element\n 3: [2, 3], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n } else if (this.elementOrder === \"quadratic\") {\n const boundarySides = {\n 0: [0, 3, 6], // Nodes at the bottom side of the reference element\n 1: [0, 1, 2], // Nodes at the left side of the reference element\n 2: [2, 5, 8], // Nodes at the top side of the reference element\n 3: [6, 7, 8], // Nodes at the right side of the reference element\n };\n boundarySides[side].forEach((nodeIndex) => {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied fixed temperature to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n // Set the residual vector to the ConstantTemp value\n residualVector[globalNodeIndex] = tempValue;\n // Set the Jacobian matrix row to zero\n for (let colIndex = 0; colIndex < residualVector.length; colIndex++) {\n jacobianMatrix[globalNodeIndex][colIndex] = 0;\n }\n // Set the diagonal entry of the Jacobian matrix to one\n jacobianMatrix[globalNodeIndex][globalNodeIndex] = 1;\n });\n }\n });\n }\n });\n }\n }\n\n /**\n * Function to impose convection boundary conditions (Robin type)\n * @param {array} residualVector - The residual vector to be modified\n * @param {array} jacobianMatrix - The Jacobian matrix to be modified\n * @param {array} gaussPoints - Array of Gauss points for numerical integration\n * @param {array} gaussWeights - Array of Gauss weights for numerical integration\n * @param {array} nodesXCoordinates - Array of x-coordinates of nodes\n * @param {array} nodesYCoordinates - Array of y-coordinates of nodes\n * @param {object} basisFunctionsData - Object containing basis functions and their derivatives\n */\n imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n ) {\n basicLog(\"Applying convection boundary conditions (Robin type)\");\n // Extract convection parameters from boundary conditions\n let convectionHeatTranfCoeff = [];\n let convectionExtTemp = [];\n Object.keys(this.boundaryConditions).forEach((key) => {\n const boundaryCondition = this.boundaryConditions[key];\n if (boundaryCondition[0] === \"convection\") {\n convectionHeatTranfCoeff[key] = boundaryCondition[1];\n convectionExtTemp[key] = boundaryCondition[2];\n }\n });\n\n if (this.meshDimension === \"1D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n let nodeIndex;\n if (this.elementOrder === \"linear\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 1;\n }\n } else if (this.elementOrder === \"quadratic\") {\n if (side === 0) {\n // Node at the left side of the reference element\n nodeIndex = 0;\n } else {\n // Node at the right side of the reference element\n nodeIndex = 2;\n }\n }\n\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${nodeIndex + 1})`\n );\n residualVector[globalNodeIndex] += -convectionCoeff * extTemp;\n jacobianMatrix[globalNodeIndex][globalNodeIndex] += convectionCoeff;\n });\n }\n });\n } else if (this.meshDimension === \"2D\") {\n Object.keys(this.boundaryConditions).forEach((boundaryKey) => {\n if (this.boundaryConditions[boundaryKey][0] === \"convection\") {\n const convectionCoeff = convectionHeatTranfCoeff[boundaryKey];\n const extTemp = convectionExtTemp[boundaryKey];\n debugLog(\n `Boundary ${boundaryKey}: Applying convection with heat transfer coefficient h=${convectionCoeff} W/(m²·K) and external temperature T∞=${extTemp} K`\n );\n this.boundaryElements[boundaryKey].forEach(([elementIndex, side]) => {\n if (this.elementOrder === \"linear\") {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 2;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 0;\n lastNodeIndex = 2;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[0];\n gaussPoint2 = 1;\n firstNodeIndex = 1;\n lastNodeIndex = 4;\n nodeIncrement = 2;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[0];\n firstNodeIndex = 2;\n lastNodeIndex = 4;\n nodeIncrement = 1;\n }\n\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[0] * tangentVectorLength * basisFunction[localNodeIndex] * convectionCoeff * extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[0] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n } else if (this.elementOrder === \"quadratic\") {\n for (let gaussPointIndex = 0; gaussPointIndex < 3; gaussPointIndex++) {\n let gaussPoint1, gaussPoint2, firstNodeIndex, lastNodeIndex, nodeIncrement;\n if (side === 0) {\n // Nodes at the bottom side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 0;\n firstNodeIndex = 0;\n lastNodeIndex = 7;\n nodeIncrement = 3;\n } else if (side === 1) {\n // Nodes at the left side of the reference element\n gaussPoint1 = 0;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 0;\n lastNodeIndex = 3;\n nodeIncrement = 1;\n } else if (side === 2) {\n // Nodes at the top side of the reference element\n gaussPoint1 = gaussPoints[gaussPointIndex];\n gaussPoint2 = 1;\n firstNodeIndex = 2;\n lastNodeIndex = 9;\n nodeIncrement = 3;\n } else if (side === 3) {\n // Nodes at the right side of the reference element\n gaussPoint1 = 1;\n gaussPoint2 = gaussPoints[gaussPointIndex];\n firstNodeIndex = 6;\n lastNodeIndex = 9;\n nodeIncrement = 1;\n }\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoint1,\n gaussPoint2\n );\n let basisFunction = basisFunctionsAndDerivatives.basisFunction;\n let basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n let basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n\n let ksiDerivX = 0;\n let ksiDerivY = 0;\n let etaDerivX = 0;\n let etaDerivY = 0;\n const numNodes = this.nop[elementIndex].length;\n for (let nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {\n const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;\n\n // For boundaries along Ksi (horizontal), use Ksi derivatives\n if (side === 0 || side === 2) {\n ksiDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n ksiDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivKsi[nodeIndex];\n }\n // For boundaries along Eta (vertical), use Eta derivatives\n else if (side === 1 || side === 3) {\n etaDerivX += nodesXCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n etaDerivY += nodesYCoordinates[globalNodeIndex] * basisFunctionDerivEta[nodeIndex];\n }\n }\n\n // Compute the length of tangent vector\n const tangentVectorLength =\n side === 0 || side === 2\n ? Math.sqrt(ksiDerivX ** 2 + ksiDerivY ** 2)\n : Math.sqrt(etaDerivX ** 2 + etaDerivY ** 2);\n\n for (\n let localNodeIndex = firstNodeIndex;\n localNodeIndex < lastNodeIndex;\n localNodeIndex += nodeIncrement\n ) {\n let globalNodeIndex = this.nop[elementIndex][localNodeIndex] - 1;\n debugLog(\n ` - Applied convection boundary condition to node ${globalNodeIndex + 1} (element ${\n elementIndex + 1\n }, local node ${localNodeIndex + 1})`\n );\n\n // Apply boundary condition with proper Jacobian for all sides\n residualVector[globalNodeIndex] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n convectionCoeff *\n extTemp;\n\n for (\n let localNodeIndex2 = firstNodeIndex;\n localNodeIndex2 < lastNodeIndex;\n localNodeIndex2 += nodeIncrement\n ) {\n let globalNodeIndex2 = this.nop[elementIndex][localNodeIndex2] - 1;\n jacobianMatrix[globalNodeIndex][globalNodeIndex2] +=\n -gaussWeights[gaussPointIndex] *\n tangentVectorLength *\n basisFunction[localNodeIndex] *\n basisFunction[localNodeIndex2] *\n convectionCoeff;\n }\n }\n }\n }\n });\n }\n });\n }\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nconst proxyMarker = Symbol(\"Comlink.proxy\");\nconst createEndpoint = Symbol(\"Comlink.endpoint\");\nconst releaseProxy = Symbol(\"Comlink.releaseProxy\");\nconst finalizer = Symbol(\"Comlink.finalizer\");\nconst throwMarker = Symbol(\"Comlink.thrown\");\nconst isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n/**\n * Internal transfer handle to handle objects marked to proxy.\n */\nconst proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n};\n/**\n * Internal transfer handler to handle thrown exceptions.\n */\nconst throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n};\n/**\n * Allows customizing the serialization of certain values.\n */\nconst transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n]);\nfunction isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n}\nfunction expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n}\nfunction isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n}\nfunction closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n}\nfunction wrap(ep, target) {\n const pendingListeners = new Map();\n ep.addEventListener(\"message\", function handleMessage(ev) {\n const { data } = ev;\n if (!data || !data.id) {\n return;\n }\n const resolver = pendingListeners.get(data.id);\n if (!resolver) {\n return;\n }\n try {\n resolver(data);\n }\n finally {\n pendingListeners.delete(data.id);\n }\n });\n return createProxy(ep, pendingListeners, [], target);\n}\nfunction throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n}\nfunction releaseEndpoint(ep) {\n return requestResponseMessage(ep, new Map(), {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n}\nconst proxyCounter = new WeakMap();\nconst proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\nfunction registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n}\nfunction unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n}\nfunction createProxy(ep, pendingListeners, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n pendingListeners.clear();\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, pendingListeners, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, pendingListeners, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, pendingListeners, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, pendingListeners, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n}\nfunction myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n}\nfunction processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n}\nconst transferCache = new WeakMap();\nfunction transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n}\nfunction proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n}\nfunction windowEndpoint(w, context = globalThis, targetOrigin = \"*\") {\n return {\n postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),\n addEventListener: context.addEventListener.bind(context),\n removeEventListener: context.removeEventListener.bind(context),\n };\n}\nfunction toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n}\nfunction fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n}\nfunction requestResponseMessage(ep, pendingListeners, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n pendingListeners.set(id, resolve);\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n}\nfunction generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n}\n\nexport { createEndpoint, expose, finalizer, proxy, proxyMarker, releaseProxy, transfer, transferHandlers, windowEndpoint, wrap };\n//# sourceMappingURL=comlink.mjs.map\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { jacobiMethod } from \"./methods/jacobiMethodScript.js\";\nimport { assembleSolidHeatTransferMat } from \"./solvers/solidHeatTransferScript.js\";\nimport { basicLog, debugLog, errorLog } from \"./utilities/loggingScript.js\";\n\n/**\n * Class to implement finite element analysis in JavaScript\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing the solution vector and additional mesh information\n */\nexport class FEAScriptModel {\n constructor() {\n this.solverConfig = null;\n this.meshConfig = {};\n this.boundaryConditions = {};\n this.solverMethod = \"lusolve\"; // Default solver method\n basicLog(\"FEAScriptModel instance created\");\n }\n\n setSolverConfig(solverConfig) {\n this.solverConfig = solverConfig;\n debugLog(`Solver config set to: ${solverConfig}`);\n }\n\n setMeshConfig(meshConfig) {\n this.meshConfig = meshConfig;\n debugLog(\n `Mesh config set with dimensions: ${meshConfig.meshDimension}`\n );\n }\n\n addBoundaryCondition(boundaryKey, condition) {\n this.boundaryConditions[boundaryKey] = condition;\n debugLog(`Boundary condition added for boundary: ${boundaryKey}, type: ${condition[0]}`);\n }\n\n setSolverMethod(solverMethod) {\n this.solverMethod = solverMethod;\n debugLog(`Solver method set to: ${solverMethod}`);\n }\n\n solve() {\n if (!this.solverConfig || !this.meshConfig || !this.boundaryConditions) {\n const error = \"Solver config, mesh config, and boundary conditions must be set before solving.\";\n console.error(error);\n throw new Error(error);\n }\n\n let jacobianMatrix = [];\n let residualVector = [];\n let solutionVector = [];\n let nodesCoordinates = {};\n\n // Assembly matrices\n basicLog(\"Beginning matrix assembly...\");\n console.time(\"assemblyMatrices\");\n if (this.solverConfig === \"solidHeatTransferScript\") {\n basicLog(`Using solver: ${this.solverConfig}`);\n ({ jacobianMatrix, residualVector, nodesCoordinates } = assembleSolidHeatTransferMat(\n this.meshConfig,\n this.boundaryConditions\n ));\n }\n console.timeEnd(\"assemblyMatrices\");\n basicLog(\"Matrix assembly completed\");\n\n // System solving\n basicLog(`Solving system using ${this.solverMethod}...`);\n console.time(\"systemSolving\");\n if (this.solverMethod === \"lusolve\") {\n solutionVector = math.lusolve(jacobianMatrix, residualVector);\n } else if (this.solverMethod === \"jacobi\") {\n // Create initial guess of zeros\n const initialGuess = new Array(residualVector.length).fill(0);\n // Call Jacobi method with desired max iterations and tolerance\n const jacobiResult = jacobiMethod(jacobianMatrix, residualVector, initialGuess, 1000, 1e-6);\n\n // Log convergence information\n if (jacobiResult.converged) {\n debugLog(`Jacobi method converged in ${jacobiResult.iterations} iterations`);\n } else {\n debugLog(`Jacobi method did not converge after ${jacobiResult.iterations} iterations`);\n }\n\n solutionVector = jacobiResult.solution;\n }\n console.timeEnd(\"systemSolving\");\n basicLog(\"System solved successfully\");\n\n return { solutionVector, nodesCoordinates };\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { numericalIntegration } from \"../methods/numericalIntegrationScript.js\";\nimport { basisFunctions } from \"../mesh/basisFunctionsScript.js\";\nimport { meshGeneration } from \"../mesh/meshGenerationScript.js\";\nimport { ThermalBoundaryConditions } from \"./thermalBoundaryConditionsScript.js\";\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to assemble the solid heat transfer matrix\n * @param {object} meshConfig - Object containing computational mesh details\n * @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis\n * @returns {object} An object containing:\n * - jacobianMatrix: The assembled Jacobian matrix\n * - residualVector: The assembled residual vector\n * - nodesCoordinates: Object containing x and y coordinates of nodes\n */\nexport function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {\n basicLog(\"Starting solid heat transfer matrix assembly...\");\n\n // Extract mesh details from the configuration object\n const {\n meshDimension, // The dimension of the mesh\n numElementsX, // Number of elements in x-direction\n numElementsY, // Number of elements in y-direction (only for 2D)\n maxX, // Max x-coordinate (m) of the domain\n maxY, // Max y-coordinate (m) of the domain (only for 2D)\n elementOrder, // The order of elements\n parsedMesh, // The pre-parsed mesh data (if available)\n } = meshConfig;\n\n // Create a new instance of the meshGeneration class\n debugLog(\"Generating mesh...\");\n const meshGenerationData = new meshGeneration({\n numElementsX,\n numElementsY,\n maxX,\n maxY,\n meshDimension,\n elementOrder,\n parsedMesh, // Pass the parsed mesh to the mesh generator\n });\n\n // Generate the mesh\n const nodesCoordinatesAndNumbering = meshGenerationData.generateMesh();\n\n // Extract nodes coordinates and nodal numbering (NOP) from the mesh data\n let nodesXCoordinates = nodesCoordinatesAndNumbering.nodesXCoordinates;\n let nodesYCoordinates = nodesCoordinatesAndNumbering.nodesYCoordinates;\n let totalNodesX = nodesCoordinatesAndNumbering.totalNodesX;\n let totalNodesY = nodesCoordinatesAndNumbering.totalNodesY;\n let nop = nodesCoordinatesAndNumbering.nodalNumbering;\n let boundaryElements = nodesCoordinatesAndNumbering.boundaryElements;\n\n // Check the mesh type\n const isParsedMesh = parsedMesh !== undefined && parsedMesh !== null;\n\n // Calculate totalElements and totalNodes based on mesh type\n let totalElements, totalNodes;\n\n if (isParsedMesh) {\n totalElements = nop.length; // Number of elements is the length of the nodal numbering array\n totalNodes = nodesXCoordinates.length; // Number of nodes is the length of the coordinates array\n\n // Debug log for mesh size\n debugLog(`Using parsed mesh with ${totalElements} elements and ${totalNodes} nodes`);\n } else {\n // For structured mesh, calculate based on dimensions\n totalElements = numElementsX * (meshDimension === \"2D\" ? numElementsY : 1);\n totalNodes = totalNodesX * (meshDimension === \"2D\" ? totalNodesY : 1);\n // Debug log for mesh size\n debugLog(`Using mesh generated from geometry with ${totalElements} elements and ${totalNodes} nodes`);\n }\n\n // Initialize variables for matrix assembly\n let localToGlobalMap = []; // Maps local element node indices to global mesh node indices\n let gaussPoints = []; // Gauss points\n let gaussWeights = []; // Gauss weights\n let basisFunction = []; // Basis functions\n let basisFunctionDerivKsi = []; // Derivatives of basis functions with respect to ksi\n let basisFunctionDerivEta = []; // Derivatives of basis functions with respect to eta (only for 2D)\n let basisFunctionDerivX = []; // The x-derivative of the basis function\n let basisFunctionDerivY = []; // The y-derivative of the basis function (only for 2D)\n let residualVector = []; // Galerkin residuals\n let jacobianMatrix = []; // Jacobian matrix\n let xCoordinates; // x-coordinate (physical coordinates)\n let yCoordinates; // y-coordinate (physical coordinates) (only for 2D)\n let ksiDerivX; // ksi-derivative of xCoordinates\n let etaDerivX; // eta-derivative of xCoordinates (ksi and eta are natural coordinates that vary within a reference element) (only for 2D)\n let ksiDerivY; // ksi-derivative of yCoordinates (only for 2D)\n let etaDerivY; // eta-derivative of yCoordinates (only for 2D)\n let detJacobian; // The jacobian of the isoparametric mapping\n\n // Initialize jacobianMatrix and residualVector arrays\n for (let nodeIndex = 0; nodeIndex < totalNodes; nodeIndex++) {\n residualVector[nodeIndex] = 0;\n jacobianMatrix.push([]);\n for (let colIndex = 0; colIndex < totalNodes; colIndex++) {\n jacobianMatrix[nodeIndex][colIndex] = 0;\n }\n }\n\n // Initialize the basisFunctions class\n const basisFunctionsData = new basisFunctions({\n meshDimension,\n elementOrder,\n });\n\n // Initialize the numericalIntegration class\n const numIntegrationData = new numericalIntegration({\n meshDimension,\n elementOrder,\n });\n\n // Calculate Gauss points and weights\n let gaussPointsAndWeights = numIntegrationData.getGaussPointsAndWeights();\n gaussPoints = gaussPointsAndWeights.gaussPoints;\n gaussWeights = gaussPointsAndWeights.gaussWeights;\n\n // Determine the number of nodes in the reference element based on the first element in the nop array\n const numNodes = nop[0].length;\n\n // Matrix assembly\n for (let elementIndex = 0; elementIndex < totalElements; elementIndex++) {\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n // Subtract 1 from nop in order to start numbering from 0\n localToGlobalMap[localNodeIndex] = nop[elementIndex][localNodeIndex] - 1;\n }\n\n // Loop over Gauss points\n for (let gaussPointIndex1 = 0; gaussPointIndex1 < gaussPoints.length; gaussPointIndex1++) {\n // 1D solid heat transfer\n if (meshDimension === \"1D\") {\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n xCoordinates = 0;\n ksiDerivX = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates += nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n detJacobian = ksiDerivX;\n }\n\n // Compute x-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] = basisFunctionDerivKsi[localNodeIndex] / detJacobian; // The x-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2]);\n }\n }\n // 2D solid heat transfer\n } else if (meshDimension === \"2D\") {\n for (let gaussPointIndex2 = 0; gaussPointIndex2 < gaussPoints.length; gaussPointIndex2++) {\n // Initialise variables for isoparametric mapping\n let basisFunctionsAndDerivatives = basisFunctionsData.getBasisFunctions(\n gaussPoints[gaussPointIndex1],\n gaussPoints[gaussPointIndex2]\n );\n basisFunction = basisFunctionsAndDerivatives.basisFunction;\n basisFunctionDerivKsi = basisFunctionsAndDerivatives.basisFunctionDerivKsi;\n basisFunctionDerivEta = basisFunctionsAndDerivatives.basisFunctionDerivEta;\n xCoordinates = 0;\n yCoordinates = 0;\n ksiDerivX = 0;\n etaDerivX = 0;\n ksiDerivY = 0;\n etaDerivY = 0;\n detJacobian = 0;\n\n // Isoparametric mapping\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n xCoordinates +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n yCoordinates +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunction[localNodeIndex];\n ksiDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivX +=\n nodesXCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n ksiDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivKsi[localNodeIndex];\n etaDerivY +=\n nodesYCoordinates[localToGlobalMap[localNodeIndex]] * basisFunctionDerivEta[localNodeIndex];\n detJacobian = meshDimension === \"2D\" ? ksiDerivX * etaDerivY - etaDerivX * ksiDerivY : ksiDerivX;\n }\n\n // Compute x-derivative and y-derivative of basis functions\n for (let localNodeIndex = 0; localNodeIndex < numNodes; localNodeIndex++) {\n basisFunctionDerivX[localNodeIndex] =\n (etaDerivY * basisFunctionDerivKsi[localNodeIndex] -\n ksiDerivY * basisFunctionDerivEta[localNodeIndex]) /\n detJacobian; // The x-derivative of the n basis function\n basisFunctionDerivY[localNodeIndex] =\n (ksiDerivX * basisFunctionDerivEta[localNodeIndex] -\n etaDerivX * basisFunctionDerivKsi[localNodeIndex]) /\n detJacobian; // The y-derivative of the n basis function\n }\n\n // Computation of Galerkin's residuals and Jacobian matrix\n for (let localNodeIndex1 = 0; localNodeIndex1 < numNodes; localNodeIndex1++) {\n let localToGlobalMap1 = localToGlobalMap[localNodeIndex1];\n // residualVector is zero for this case\n\n for (let localNodeIndex2 = 0; localNodeIndex2 < numNodes; localNodeIndex2++) {\n let localToGlobalMap2 = localToGlobalMap[localNodeIndex2];\n jacobianMatrix[localToGlobalMap1][localToGlobalMap2] +=\n -gaussWeights[gaussPointIndex1] *\n gaussWeights[gaussPointIndex2] *\n detJacobian *\n (basisFunctionDerivX[localNodeIndex1] * basisFunctionDerivX[localNodeIndex2] +\n basisFunctionDerivY[localNodeIndex1] * basisFunctionDerivY[localNodeIndex2]);\n }\n }\n }\n }\n }\n }\n\n // Create an instance of ThermalBoundaryConditions\n debugLog(\"Applying thermal boundary conditions...\");\n const thermalBoundaryConditions = new ThermalBoundaryConditions(\n boundaryConditions,\n boundaryElements,\n nop,\n meshDimension,\n elementOrder\n );\n\n // Impose Convection boundary conditions\n thermalBoundaryConditions.imposeConvectionBoundaryConditions(\n residualVector,\n jacobianMatrix,\n gaussPoints,\n gaussWeights,\n nodesXCoordinates,\n nodesYCoordinates,\n basisFunctionsData\n );\n debugLog(\"Convection boundary conditions applied\");\n\n // Impose ConstantTemp boundary conditions\n thermalBoundaryConditions.imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix);\n debugLog(\"Constant temperature boundary conditions applied\");\n\n basicLog(\"Solid heat transfer matrix assembly completed\");\n\n return {\n jacobianMatrix,\n residualVector,\n nodesCoordinates: {\n nodesXCoordinates,\n nodesYCoordinates,\n },\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to solve a system of linear equations using the Jacobi iterative method\n * @param {array} A - The coefficient matrix (must be square)\n * @param {array} b - The right-hand side vector\n * @param {array} x0 - Initial guess for solution vector\n * @param {number} [maxIterations=100] - Maximum number of iterations\n * @param {number} [tolerance=1e-7] - Convergence tolerance\n * @returns {object} An object containing:\n * - solution: The solution vector\n * - iterations: The number of iterations performed\n * - converged: Boolean indicating whether the method converged\n */\nexport function jacobiMethod(A, b, x0, maxIterations = 100, tolerance = 1e-7) {\n const n = A.length; // Size of the square matrix\n let x = [...x0]; // Current solution (starts with initial guess)\n let xNew = new Array(n); // Next iteration's solution\n\n for (let iteration = 0; iteration < maxIterations; iteration++) {\n // Perform one iteration\n for (let i = 0; i < n; i++) {\n let sum = 0;\n // Calculate sum of A[i][j] * x[j] for j ≠ i\n for (let j = 0; j < n; j++) {\n if (j !== i) {\n sum += A[i][j] * x[j];\n }\n }\n // Update xNew[i] using the Jacobi formula\n xNew[i] = (b[i] - sum) / A[i][i];\n }\n\n // Check convergence\n let maxDiff = 0;\n for (let i = 0; i < n; i++) {\n maxDiff = Math.max(maxDiff, Math.abs(xNew[i] - x[i]));\n }\n\n // Update x for next iteration\n x = [...xNew];\n\n // Successfully converged if maxDiff is less than tolerance\n if (maxDiff < tolerance) {\n return {\n solution: x,\n iterations: iteration + 1,\n converged: true,\n };\n }\n }\n\n // maxIterations were reached without convergence\n return {\n solution: x,\n iterations: maxIterations,\n converged: false,\n };\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// External imports\nimport * as Comlink from \"../vendor/comlink.mjs\";\n\n// Internal imports\nimport { basicLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Class to facilitate communication with web workers for FEAScript operations\n */\nexport class FEAScriptWorker {\n /**\n * Constructor to initialize the FEAScriptWorker class\n * Sets up the worker and initializes the workerWrapper.\n */\n constructor() {\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n\n this._initWorker();\n }\n\n /**\n * Function to initialize the web worker and wrap it using Comlink.\n * @private\n * @throws Will throw an error if the worker fails to initialize.\n */\n async _initWorker() {\n try {\n this.worker = new Worker(new URL(\"./wrapperScript.js\", import.meta.url), {\n type: \"module\",\n });\n\n this.worker.onerror = (event) => {\n console.error(\"FEAScriptWorker: Worker error:\", event);\n };\n const workerWrapper = Comlink.wrap(this.worker);\n\n this.feaWorker = await new workerWrapper();\n\n this.isReady = true;\n } catch (error) {\n console.error(\"Failed to initialize worker\", error);\n throw error;\n }\n }\n\n /**\n * Function to ensure that the worker is ready before performing any operations.\n * @private\n * @returns {Promise} Resolves when the worker is ready.\n * @throws Will throw an error if the worker is not ready within the timeout period.\n */\n async _ensureReady() {\n if (this.isReady) return Promise.resolve();\n\n return new Promise((resolve, reject) => {\n let attempts = 0;\n const maxAttempts = 50; // 5 seconds max\n\n const checkReady = () => {\n attempts++;\n if (this.isReady) {\n resolve();\n } else if (attempts >= maxAttempts) {\n reject(new Error(\"Timeout waiting for worker to be ready\"));\n } else {\n setTimeout(checkReady, 1000);\n }\n };\n checkReady();\n });\n }\n\n /**\n * Function to set the solver configuration in the worker.\n * @param {string} solverConfig - The solver configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setSolverConfig(solverConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver config to: ${solverConfig}`);\n return this.feaWorker.setSolverConfig(solverConfig);\n }\n\n /**\n * Sets the mesh configuration in the worker.\n * @param {object} meshConfig - The mesh configuration to set.\n * @returns {Promise} Resolves when the configuration is set.\n */\n async setMeshConfig(meshConfig) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting mesh config`);\n return this.feaWorker.setMeshConfig(meshConfig);\n }\n\n /**\n * Adds a boundary condition to the worker.\n * @param {string} boundaryKey - The key identifying the boundary.\n * @param {array} condition - The boundary condition to add.\n * @returns {Promise} Resolves when the boundary condition is added.\n */\n async addBoundaryCondition(boundaryKey, condition) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Adding boundary condition for boundary: ${boundaryKey}`);\n return this.feaWorker.addBoundaryCondition(boundaryKey, condition);\n }\n\n /**\n * Sets the solver method in the worker.\n * @param {string} solverMethod - The solver method to set.\n * @returns {Promise} Resolves when the solver method is set.\n */\n async setSolverMethod(solverMethod) {\n await this._ensureReady();\n basicLog(`FEAScriptWorker: Setting solver method to: ${solverMethod}`);\n return this.feaWorker.setSolverMethod(solverMethod);\n }\n\n /**\n * Requests the worker to solve the problem.\n * @returns {Promise} Resolves with the solution result.\n */\n async solve() {\n await this._ensureReady();\n basicLog(\"FEAScriptWorker: Requesting solution from worker...\");\n\n const startTime = performance.now();\n const result = await this.feaWorker.solve();\n const endTime = performance.now();\n\n basicLog(`FEAScriptWorker: Solution completed in ${((endTime - startTime) / 1000).toFixed(2)}s`);\n return result;\n }\n\n /**\n * Retrieves model information from the worker.\n * @returns {Promise} Resolves with the model information.\n */\n async getModelInfo() {\n await this._ensureReady();\n return this.feaWorker.getModelInfo();\n }\n\n /**\n * Sends a ping request to the worker to check its availability.\n * @returns {Promise} Resolves if the worker responds.\n */\n async ping() {\n await this._ensureReady();\n return this.feaWorker.ping();\n }\n\n /**\n * Terminates the worker and cleans up resources.\n */\n terminate() {\n if (this.worker) {\n this.worker.terminate();\n this.worker = null;\n this.feaWorker = null;\n this.isReady = false;\n }\n }\n}\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\nexport { FEAScriptModel } from \"./FEAScript.js\";\nexport { importGmshQuadTri } from \"./readers/gmshReaderScript.js\";\nexport { logSystem, printVersion } from \"./utilities/loggingScript.js\";\nexport { plotSolution } from \"./visualization/plotSolutionScript.js\";\nexport { FEAScriptWorker } from \"./workers/workerScript.js\";\nexport const VERSION = \"0.1.1\";","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n// Internal imports\nimport { basicLog, debugLog, errorLog } from \"../utilities/loggingScript.js\";\n\n/**\n * Function to import mesh data from Gmsh format containing quadrilateral and triangular elements\n * @param {File} file - The Gmsh file to be parsed (.msh version 4.1)\n * @returns {object} The parsed mesh data including node coordinates, element connectivity, and boundary conditions\n */\nconst importGmshQuadTri = async (file) => {\n let result = {\n nodesXCoordinates: [],\n nodesYCoordinates: [],\n nodalNumbering: {\n quadElements: [],\n triangleElements: [],\n },\n boundaryElements: [],\n boundaryConditions: [],\n boundaryNodePairs: {}, // Store boundary node pairs for processing in meshGenerationScript\n gmshV: 0,\n ascii: false,\n fltBytes: \"8\",\n totalNodesX: 0,\n totalNodesY: 0,\n physicalPropMap: [],\n elementTypes: {},\n };\n\n let content = await file.text();\n let lines = content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\" && line !== \" \");\n\n let section = \"\";\n let lineIndex = 0;\n\n let nodeEntityBlocks = 0;\n let totalNodes = 0;\n let nodeBlocksProcessed = 0;\n let currentNodeBlock = { numNodes: 0 };\n let nodeTagsCollected = 0;\n let nodeTags = [];\n let nodeCoordinatesCollected = 0;\n\n let elementEntityBlocks = 0;\n let totalElements = 0;\n let elementBlocksProcessed = 0;\n let currentElementBlock = {\n dim: 0,\n tag: 0,\n elementType: 0,\n numElements: 0,\n };\n let elementsProcessedInBlock = 0;\n\n let boundaryElementsByTag = {};\n\n while (lineIndex < lines.length) {\n const line = lines[lineIndex];\n\n if (line === \"$MeshFormat\") {\n section = \"meshFormat\";\n lineIndex++;\n continue;\n } else if (line === \"$EndMeshFormat\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$PhysicalNames\") {\n section = \"physicalNames\";\n lineIndex++;\n continue;\n } else if (line === \"$EndPhysicalNames\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Entities\") {\n section = \"entities\";\n lineIndex++;\n continue;\n } else if (line === \"$EndEntities\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Nodes\") {\n section = \"nodes\";\n lineIndex++;\n continue;\n } else if (line === \"$EndNodes\") {\n section = \"\";\n lineIndex++;\n continue;\n } else if (line === \"$Elements\") {\n section = \"elements\";\n lineIndex++;\n continue;\n } else if (line === \"$EndElements\") {\n section = \"\";\n lineIndex++;\n continue;\n }\n\n const parts = line.split(/\\s+/).filter((part) => part !== \"\");\n\n if (section === \"meshFormat\") {\n result.gmshV = parseFloat(parts[0]);\n result.ascii = parts[1] === \"0\";\n result.fltBytes = parts[2];\n } else if (section === \"physicalNames\") {\n if (parts.length >= 3) {\n if (!/^\\d+$/.test(parts[0])) {\n lineIndex++;\n continue;\n }\n\n const dimension = parseInt(parts[0], 10);\n const tag = parseInt(parts[1], 10);\n let name = parts.slice(2).join(\" \");\n name = name.replace(/^\"|\"$/g, \"\");\n\n result.physicalPropMap.push({\n tag,\n dimension,\n name,\n });\n }\n } else if (section === \"nodes\") {\n if (nodeEntityBlocks === 0) {\n nodeEntityBlocks = parseInt(parts[0], 10);\n totalNodes = parseInt(parts[1], 10);\n result.nodesXCoordinates = new Array(totalNodes).fill(0);\n result.nodesYCoordinates = new Array(totalNodes).fill(0);\n lineIndex++;\n continue;\n }\n\n if (nodeBlocksProcessed < nodeEntityBlocks && currentNodeBlock.numNodes === 0) {\n currentNodeBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n parametric: parseInt(parts[2], 10),\n numNodes: parseInt(parts[3], 10),\n };\n\n nodeTags = [];\n nodeTagsCollected = 0;\n nodeCoordinatesCollected = 0;\n\n lineIndex++;\n continue;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n for (let i = 0; i < parts.length && nodeTagsCollected < currentNodeBlock.numNodes; i++) {\n nodeTags.push(parseInt(parts[i], 10));\n nodeTagsCollected++;\n }\n\n if (nodeTagsCollected < currentNodeBlock.numNodes) {\n lineIndex++;\n continue;\n }\n\n lineIndex++;\n continue;\n }\n\n if (nodeCoordinatesCollected < currentNodeBlock.numNodes) {\n const nodeTag = nodeTags[nodeCoordinatesCollected] - 1;\n const x = parseFloat(parts[0]);\n const y = parseFloat(parts[1]);\n\n result.nodesXCoordinates[nodeTag] = x;\n result.nodesYCoordinates[nodeTag] = y;\n result.totalNodesX++;\n result.totalNodesY++;\n\n nodeCoordinatesCollected++;\n\n if (nodeCoordinatesCollected === currentNodeBlock.numNodes) {\n nodeBlocksProcessed++;\n currentNodeBlock = { numNodes: 0 };\n }\n }\n } else if (section === \"elements\") {\n if (elementEntityBlocks === 0) {\n elementEntityBlocks = parseInt(parts[0], 10);\n totalElements = parseInt(parts[1], 10);\n lineIndex++;\n continue;\n }\n\n if (elementBlocksProcessed < elementEntityBlocks && currentElementBlock.numElements === 0) {\n currentElementBlock = {\n dim: parseInt(parts[0], 10),\n tag: parseInt(parts[1], 10),\n elementType: parseInt(parts[2], 10),\n numElements: parseInt(parts[3], 10),\n };\n\n result.elementTypes[currentElementBlock.elementType] =\n (result.elementTypes[currentElementBlock.elementType] || 0) + currentElementBlock.numElements;\n\n elementsProcessedInBlock = 0;\n lineIndex++;\n continue;\n }\n\n if (elementsProcessedInBlock < currentElementBlock.numElements) {\n const elementTag = parseInt(parts[0], 10);\n const nodeIndices = parts.slice(1).map((idx) => parseInt(idx, 10));\n\n if (currentElementBlock.elementType === 1 || currentElementBlock.elementType === 8) {\n const physicalTag = currentElementBlock.tag;\n\n if (!boundaryElementsByTag[physicalTag]) {\n boundaryElementsByTag[physicalTag] = [];\n }\n\n boundaryElementsByTag[physicalTag].push(nodeIndices);\n\n // Store boundary node pairs for later processing in meshGenerationScript\n if (!result.boundaryNodePairs[physicalTag]) {\n result.boundaryNodePairs[physicalTag] = [];\n }\n result.boundaryNodePairs[physicalTag].push(nodeIndices);\n } else if (currentElementBlock.elementType === 2) {\n // Linear triangle elements (3 nodes)\n result.nodalNumbering.triangleElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 3) {\n // Linear quadrilateral elements (4 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n } else if (currentElementBlock.elementType === 10) {\n // Quadratic quadrilateral elements (9 nodes)\n result.nodalNumbering.quadElements.push(nodeIndices);\n }\n\n elementsProcessedInBlock++;\n\n if (elementsProcessedInBlock === currentElementBlock.numElements) {\n elementBlocksProcessed++;\n currentElementBlock = { numElements: 0 };\n }\n }\n }\n\n lineIndex++;\n }\n\n // Store boundary conditions information\n result.physicalPropMap.forEach((prop) => {\n if (prop.dimension === 1) {\n const boundaryNodes = boundaryElementsByTag[prop.tag] || [];\n\n if (boundaryNodes.length > 0) {\n result.boundaryConditions.push({\n name: prop.name,\n tag: prop.tag,\n nodes: boundaryNodes,\n });\n }\n }\n });\n\n debugLog(\n `Parsed boundary node pairs by physical tag: ${JSON.stringify(\n result.boundaryNodePairs\n )}. These pairs will be used to identify boundary elements in the mesh.`\n );\n\n return result;\n};\n\nexport { importGmshQuadTri };\n","// ______ ______ _____ _ _ //\n// | ____| ____| /\\ / ____| (_) | | //\n// | |__ | |__ / \\ | (___ ___ ____ _ ____ | |_ //\n// | __| | __| / /\\ \\ \\___ \\ / __| __| | _ \\| __| //\n// | | | |____ / ____ \\ ____) | (__| | | | |_) | | //\n// |_| |______/_/ \\_\\_____/ \\___|_| |_| __/| | //\n// | | | | //\n// |_| | |_ //\n// Website: https://feascript.com/ \\__| //\n\n/**\n * Function to create plots of the solution vector\n * @param {*} solutionVector - The computed solution vector\n * @param {*} nodesCoordinates - Object containing x and y coordinates for the nodes\n * @param {string} solverConfig - Parameter specifying the type of solver\n * @param {string} meshDimension - The dimension of the solution\n * @param {string} plotType - The type of plot\n * @param {string} plotDivId - The id of the div where the plot will be rendered\n * @param {string} [meshType=\"structured\"] - Type of mesh: \"structured\" or \"unstructured\"\n */\nexport function plotSolution(\n solutionVector,\n nodesCoordinates,\n solverConfig,\n meshDimension,\n plotType,\n plotDivId,\n meshType = \"structured\"\n) {\n const { nodesXCoordinates, nodesYCoordinates } = nodesCoordinates;\n\n if (meshDimension === \"1D\" && plotType === \"line\") {\n // Check if solutionVector is a nested array\n let yData;\n if (solutionVector.length > 0 && Array.isArray(solutionVector[0])) {\n yData = solutionVector.map((arr) => arr[0]);\n } else {\n yData = solutionVector;\n }\n let xData = Array.from(nodesXCoordinates);\n\n let lineData = {\n x: xData,\n y: yData,\n mode: \"lines\",\n type: \"scatter\",\n line: { color: \"rgb(219, 64, 82)\", width: 2 },\n name: \"Solution\",\n };\n\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxPlotWidth = Math.max(...xData);\n let zoomFactor = maxWindowWidth / maxPlotWidth;\n let plotWidth = Math.max(zoomFactor * maxPlotWidth, 400);\n let plotHeight = 350;\n\n let layout = {\n title: `line plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"Solution\" },\n margin: { l: 70, r: 40, t: 50, b: 50 },\n };\n\n Plotly.newPlot(plotDivId, [lineData], layout, { responsive: true });\n } else if (meshDimension === \"2D\" && plotType === \"contour\") {\n // Use the user-provided mesh type\n const isStructured = meshType === \"structured\";\n \n // For auto-detection (if needed)\n const uniqueXCoords = new Set(nodesXCoordinates).size;\n const uniqueYCoords = new Set(nodesYCoordinates).size;\n \n // Extract scalar values from solution vector\n let zValues = Array.isArray(solutionVector[0]) \n ? solutionVector.map(val => val[0]) \n : solutionVector;\n \n // Common sizing parameters for both plot types\n let maxWindowWidth = Math.min(window.innerWidth, 700);\n let maxX = Math.max(...nodesXCoordinates);\n let maxY = Math.max(...nodesYCoordinates);\n let aspectRatio = maxY / maxX;\n let plotWidth = Math.min(maxWindowWidth, 600);\n let plotHeight = plotWidth * aspectRatio * 0.8; // Slightly reduce height for better appearance\n \n // Common layout properties\n let layout = {\n title: `${plotType} plot - ${solverConfig}`,\n width: plotWidth,\n height: plotHeight,\n xaxis: { title: \"x\" },\n yaxis: { title: \"y\" },\n margin: { l: 50, r: 50, t: 50, b: 50 },\n hovermode: 'closest'\n };\n \n if (isStructured) {\n // Calculate the number of nodes along the x-axis and y-axis\n const numNodesX = uniqueXCoords;\n const numNodesY = uniqueYCoords;\n\n // Reshape the nodesXCoordinates and nodesYCoordinates arrays to match the grid dimensions\n let reshapedXCoordinates = math.reshape(Array.from(nodesXCoordinates), [numNodesX, numNodesY]);\n let reshapedYCoordinates = math.reshape(Array.from(nodesYCoordinates), [numNodesX, numNodesY]);\n\n // Reshape the solution array to match the grid dimensions\n let reshapedSolution = math.reshape(Array.from(solutionVector), [numNodesX, numNodesY]);\n\n // Transpose the reshapedSolution array to get column-wise data\n let transposedSolution = math.transpose(reshapedSolution);\n\n // Create an array for x-coordinates used in the contour plot\n let reshapedXForPlot = [];\n for (let i = 0; i < numNodesX * numNodesY; i += numNodesY) {\n let xValue = nodesXCoordinates[i];\n reshapedXForPlot.push(xValue);\n }\n\n // Create the data structure for the contour plot\n let contourData = {\n z: transposedSolution,\n type: \"contour\",\n contours: {\n coloring: \"heatmap\",\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n x: reshapedXForPlot,\n y: reshapedYCoordinates[0],\n name: 'Solution Field'\n };\n\n // Create the plot using Plotly\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n } else {\n // Create an interpolated contour plot for the unstructured mesh\n let contourData = {\n x: nodesXCoordinates,\n y: nodesYCoordinates,\n z: zValues,\n type: 'contour',\n contours: {\n coloring: 'heatmap',\n showlabels: false\n },\n //colorscale: 'Viridis',\n colorbar: {\n title: 'Solution'\n },\n name: 'Solution Field'\n };\n \n // Create the plot using only the contour fill\n Plotly.newPlot(plotDivId, [contourData], layout, { responsive: true });\n }\n }\n}\n"],"names":["numericalIntegration","constructor","meshDimension","elementOrder","this","getGaussPointsAndWeights","gaussPoints","gaussWeights","Math","sqrt","currentLogLevel","debugLog","message","console","log","basicLog","errorLog","basisFunctions","getBasisFunctions","ksi","eta","basisFunction","basisFunctionDerivKsi","basisFunctionDerivEta","l1","c","l2","l3","dl1","dl2","dl3","meshGeneration","numElementsX","maxX","numElementsY","maxY","parsedMesh","generateMesh","nodalNumbering","Array","isArray","quadElements","triangleElements","JSON","stringify","elementTypes","mappedNodalNumbering","elemIdx","length","gmshNodes","feaScriptNodes","push","physicalPropMap","boundaryElements","undefined","fixedBoundaryElements","i","boundaryNodePairs","boundaryElementsProcessed","forEach","prop","dimension","tag","nodesPair","node1","node2","name","foundElement","elemNodes","includes","side","node1Index","indexOf","node2Index","join","generateMeshFromGeometry","nodesXCoordinates","nodesYCoordinates","totalNodesX","totalNodesY","deltaX","deltaY","nodeIndex","generateNodalNumbering","findBoundaryElements","nodeIndexY","nodeIndexX","nnode","maxSides","sideIndex","elementIndexX","elementIndexY","elementIndex","nop","columnCounter","rowCounter","nodeIndex1","nodeIndex2","ThermalBoundaryConditions","boundaryConditions","imposeConstantTempBoundaryConditions","residualVector","jacobianMatrix","Object","keys","boundaryKey","tempValue","globalNodeIndex","colIndex","imposeConvectionBoundaryConditions","basisFunctionsData","convectionHeatTranfCoeff","convectionExtTemp","key","boundaryCondition","convectionCoeff","extTemp","gaussPoint1","gaussPoint2","firstNodeIndex","lastNodeIndex","nodeIncrement","basisFunctionsAndDerivatives","ksiDerivX","ksiDerivY","etaDerivX","etaDerivY","numNodes","tangentVectorLength","localNodeIndex","localNodeIndex2","globalNodeIndex2","gaussPointIndex","proxyMarker","Symbol","createEndpoint","releaseProxy","finalizer","throwMarker","isObject","val","transferHandlers","Map","canHandle","serialize","obj","port1","port2","MessageChannel","expose","deserialize","port","start","wrap","value","serialized","Error","isError","stack","assign","ep","globalThis","allowedOrigins","addEventListener","callback","ev","data","origin","allowedOrigin","RegExp","test","isAllowedOrigin","warn","id","type","path","argumentList","map","fromWireValue","returnValue","parent","slice","reduce","rawValue","apply","proxy","transfers","transferCache","set","transfer","Promise","resolve","catch","then","wireValue","transferables","toWireValue","postMessage","removeEventListener","closeEndPoint","error","TypeError","endpoint","isMessagePort","close","target","pendingListeners","resolver","get","delete","createProxy","throwIfProxyReleased","isReleased","releaseEndpoint","requestResponseMessage","proxyCounter","WeakMap","proxyFinalizers","FinalizationRegistry","newCount","isProxyReleased","Proxy","_target","unregister","unregisterProxy","clear","r","p","toString","bind","_thisArg","rawArgumentList","last","processArguments","construct","register","registerProxy","processed","v","arr","prototype","concat","handler","serializedValue","msg","fill","floor","random","Number","MAX_SAFE_INTEGER","solverConfig","meshConfig","solverMethod","setSolverConfig","setMeshConfig","addBoundaryCondition","condition","setSolverMethod","solve","solutionVector","nodesCoordinates","time","nodesCoordinatesAndNumbering","totalElements","totalNodes","xCoordinates","yCoordinates","detJacobian","localToGlobalMap","basisFunctionDerivX","basisFunctionDerivY","gaussPointsAndWeights","gaussPointIndex1","localNodeIndex1","localToGlobalMap1","localToGlobalMap2","gaussPointIndex2","thermalBoundaryConditions","assembleSolidHeatTransferMat","timeEnd","math","lusolve","jacobiResult","A","b","x0","maxIterations","tolerance","n","x","xNew","iteration","sum","j","maxDiff","max","abs","solution","iterations","converged","jacobiMethod","worker","feaWorker","isReady","_initWorker","Worker","URL","document","location","require","__filename","href","currentScript","tagName","toUpperCase","src","baseURI","onerror","event","workerWrapper","Comlink.wrap","_ensureReady","reject","attempts","checkReady","setTimeout","startTime","performance","now","result","toFixed","getModelInfo","ping","terminate","async","file","gmshV","ascii","fltBytes","lines","text","split","line","trim","filter","section","lineIndex","nodeEntityBlocks","nodeBlocksProcessed","currentNodeBlock","nodeTagsCollected","nodeTags","nodeCoordinatesCollected","elementEntityBlocks","elementBlocksProcessed","currentElementBlock","dim","elementType","numElements","elementsProcessedInBlock","boundaryElementsByTag","parts","part","parseFloat","parseInt","replace","parametric","nodeTag","y","nodeIndices","idx","physicalTag","boundaryNodes","nodes","level","plotType","plotDivId","meshType","yData","xData","from","lineData","mode","color","width","maxWindowWidth","min","window","innerWidth","maxPlotWidth","zoomFactor","layout","title","height","xaxis","yaxis","margin","l","t","Plotly","newPlot","responsive","isStructured","uniqueXCoords","Set","size","uniqueYCoords","zValues","aspectRatio","plotWidth","hovermode","numNodesX","numNodesY","reshape","reshapedYCoordinates","reshapedSolution","transposedSolution","transpose","reshapedXForPlot","xValue","contourData","z","contours","coloring","showlabels","colorbar","commitResponse","fetch","commitData","json","latestCommitDate","Date","commit","committer","date","toLocaleString"],"mappings":"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"} \ No newline at end of file diff --git a/feascript-0.1.1.tgz b/feascript-0.1.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..aa2d2604109e0ef78132fcfb85e2fa79fc76f7e9 GIT binary patch literal 141436 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 z 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

!@Nv}u{KI#7tN}%k!471to5mynIE{SB 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

!zmB!C{!mqYbMIMLm0 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 H0L%&i&^77` literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..21f115f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4525 @@ +{ + "name": "feascript", + "version": "0.1.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "feascript", + "version": "0.1.1", + "license": "MIT", + "devDependencies": { + "@rollup/plugin-commonjs": "^28.0.3", + "@rollup/plugin-node-resolve": "^16.0.1", + "@types/estree": "^1.0.7", + "mathjs": "^11.12.0", + "rollup": "^2.79.2", + "rollup-plugin-terser": "^7.0.2", + "rollup-plugin-typescript2": "^0.36.0", + "typescript": "^5.8.3" + }, + "peerDependencies": { + "mathjs": "^11.12.0", + "plotly.js": "^2.27.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz", + "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@choojs/findup": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@choojs/findup/-/findup-0.2.1.tgz", + "integrity": "sha512-YstAqNb0MCN8PjdLCDfRsBcGVRN41f3vgLvaI0IrIcBp4AqILRSS0DeWNGkicC+f/zRIPJLc+9RURVSepwvfBw==", + "license": "MIT", + "peer": true, + "dependencies": { + "commander": "^2.15.1" + }, + "bin": { + "findup": "bin/findup.js" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mapbox/geojson-rewind": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz", + "integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", + "license": "ISC", + "peer": true, + "dependencies": { + "get-stream": "^6.0.1", + "minimist": "^1.2.6" + }, + "bin": { + "geojson-rewind": "geojson-rewind" + } + }, + "node_modules/@mapbox/geojson-types": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-types/-/geojson-types-1.0.2.tgz", + "integrity": "sha512-e9EBqHHv3EORHrSfbR9DqecPNn+AmuAoQxV6aL8Xu30bJMJR1o8PZLZzpk1Wq7/NfCbuhmakHTPYRhoqLsXRnw==", + "license": "ISC", + "peer": true + }, + "node_modules/@mapbox/jsonlint-lines-primitives": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", + "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@mapbox/mapbox-gl-supported": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz", + "integrity": "sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg==", + "license": "BSD-3-Clause", + "peer": true, + "peerDependencies": { + "mapbox-gl": ">=0.32.1 <2.0.0" + } + }, + "node_modules/@mapbox/point-geometry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", + "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==", + "license": "ISC", + "peer": true + }, + "node_modules/@mapbox/tiny-sdf": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.2.5.tgz", + "integrity": "sha512-cD8A/zJlm6fdJOk6DqPUV8mcpyJkRz2x2R+/fYcWDYG3oWbG7/L7Yl/WqQ1VZCjnL9OTIMAn6c+BC5Eru4sQEw==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/@mapbox/unitbezier": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz", + "integrity": "sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/@mapbox/vector-tile": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", + "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "@mapbox/point-geometry": "~0.1.0" + } + }, + "node_modules/@mapbox/whoots-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", + "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-20.4.0.tgz", + "integrity": "sha512-AzBy3095fTFPjDjmWpR2w6HVRAZJ6hQZUCwk5Plz6EyfnfuQW1odeW5i2Ai47Y6TBA2hQnC+azscjBSALpaWgw==", + "license": "ISC", + "peer": true, + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "~2.0.2", + "@mapbox/unitbezier": "^0.0.1", + "json-stringify-pretty-compact": "^4.0.0", + "minimist": "^1.2.8", + "quickselect": "^2.0.0", + "rw": "^1.3.3", + "tinyqueue": "^3.0.0" + }, + "bin": { + "gl-style-format": "dist/gl-style-format.mjs", + "gl-style-migrate": "dist/gl-style-migrate.mjs", + "gl-style-validate": "dist/gl-style-validate.mjs" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec/node_modules/@mapbox/unitbezier": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/@maplibre/maplibre-gl-style-spec/node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "license": "ISC", + "peer": true + }, + "node_modules/@plotly/d3": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@plotly/d3/-/d3-3.8.2.tgz", + "integrity": "sha512-wvsNmh1GYjyJfyEBPKJLTMzgf2c2bEbSIL50lmqVUi+o1NHaLPi1Lb4v7VxXXJn043BhNyrxUrWI85Q+zmjOVA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@plotly/d3-sankey": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@plotly/d3-sankey/-/d3-sankey-0.7.2.tgz", + "integrity": "sha512-2jdVos1N3mMp3QW0k2q1ph7Gd6j5PY1YihBrwpkFnKqO+cqtZq3AdEYUeSGXMeLsBDQYiqTVcihYfk8vr5tqhw==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "d3-array": "1", + "d3-collection": "1", + "d3-shape": "^1.2.0" + } + }, + "node_modules/@plotly/d3-sankey-circular": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@plotly/d3-sankey-circular/-/d3-sankey-circular-0.33.1.tgz", + "integrity": "sha512-FgBV1HEvCr3DV7RHhDsPXyryknucxtfnLwPtCKKxdolKyTFYoLX/ibEfX39iFYIL7DYbVeRtP43dbFcrHNE+KQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "d3-array": "^1.2.1", + "d3-collection": "^1.0.4", + "d3-shape": "^1.2.0", + "elementary-circuits-directed-graph": "^1.0.4" + } + }, + "node_modules/@plotly/mapbox-gl": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/@plotly/mapbox-gl/-/mapbox-gl-1.13.4.tgz", + "integrity": "sha512-sR3/Pe5LqT/fhYgp4rT4aSFf1rTsxMbGiH6Hojc7PH36ny5Bn17iVFUjpzycafETURuFbLZUfjODO8LvSI+5zQ==", + "license": "SEE LICENSE IN LICENSE.txt", + "peer": true, + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.2", + "@mapbox/geojson-types": "^1.0.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/mapbox-gl-supported": "^1.5.0", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^1.1.1", + "@mapbox/unitbezier": "^0.0.0", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "csscolorparser": "~1.0.3", + "earcut": "^2.2.2", + "geojson-vt": "^3.2.1", + "gl-matrix": "^3.2.1", + "grid-index": "^1.1.0", + "murmurhash-js": "^1.0.0", + "pbf": "^3.2.1", + "potpack": "^1.0.1", + "quickselect": "^2.0.0", + "rw": "^1.3.3", + "supercluster": "^7.1.0", + "tinyqueue": "^2.0.3", + "vt-pbf": "^3.1.1" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/@plotly/point-cluster": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@plotly/point-cluster/-/point-cluster-3.1.9.tgz", + "integrity": "sha512-MwaI6g9scKf68Orpr1pHZ597pYx9uP8UEFXLPbsCmuw3a84obwz6pnMXGc90VhgDNeNiLEdlmuK7CPo+5PIxXw==", + "license": "MIT", + "peer": true, + "dependencies": { + "array-bounds": "^1.0.1", + "binary-search-bounds": "^2.0.4", + "clamp": "^1.0.1", + "defined": "^1.0.0", + "dtype": "^2.0.0", + "flatten-vertex-data": "^1.0.2", + "is-obj": "^1.0.1", + "math-log2": "^1.0.1", + "parse-rect": "^1.2.0", + "pick-by-alias": "^1.2.0" + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "28.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.3.tgz", + "integrity": "sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.2.0", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.1.tgz", + "integrity": "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@turf/area": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/area/-/area-7.2.0.tgz", + "integrity": "sha512-zuTTdQ4eoTI9nSSjerIy4QwgvxqwJVciQJ8tOPuMHbXJ9N/dNjI7bU8tasjhxas/Cx3NE9NxVHtNpYHL0FSzoA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@turf/helpers": "^7.2.0", + "@turf/meta": "^7.2.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/bbox": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-7.2.0.tgz", + "integrity": "sha512-wzHEjCXlYZiDludDbXkpBSmv8Zu6tPGLmJ1sXQ6qDwpLE1Ew3mcWqt8AaxfTP5QwDNQa3sf2vvgTEzNbPQkCiA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@turf/helpers": "^7.2.0", + "@turf/meta": "^7.2.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/centroid": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/centroid/-/centroid-7.2.0.tgz", + "integrity": "sha512-yJqDSw25T7P48au5KjvYqbDVZ7qVnipziVfZ9aSo7P2/jTE7d4BP21w0/XLi3T/9bry/t9PR1GDDDQljN4KfDw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@turf/helpers": "^7.2.0", + "@turf/meta": "^7.2.0", + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/helpers": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-7.2.0.tgz", + "integrity": "sha512-cXo7bKNZoa7aC7ydLmUR02oB3IgDe7MxiPuRz3cCtYQHn+BJ6h1tihmamYDWWUlPHgSNF0i3ATc4WmDECZafKw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/meta": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-7.2.0.tgz", + "integrity": "sha512-igzTdHsQc8TV1RhPuOLVo74Px/hyPrVgVOTgjWQZzt3J9BVseCdpfY/0cJBdlSRI4S/yTmmHl7gAqjhpYH5Yaw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@turf/helpers": "^7.2.0", + "@types/geojson": "^7946.0.10" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "license": "MIT" + }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/geojson-vt": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz", + "integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/mapbox__point-geometry": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", + "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/mapbox__vector-tile": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", + "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/geojson": "*", + "@types/mapbox__point-geometry": "*", + "@types/pbf": "*" + } + }, + "node_modules/@types/node": { + "version": "22.15.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz", + "integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/pbf": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", + "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/supercluster": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0", + "peer": true + }, + "node_modules/abs-svg-path": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz", + "integrity": "sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==", + "license": "MIT", + "peer": true + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/almost-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/almost-equal/-/almost-equal-1.1.0.tgz", + "integrity": "sha512-0V/PkoculFl5+0Lp47JoxUcO0xSxhIBvm+BxHdD/OgXNmdRpRHCFnKVuUoWyS9EzQP+otSGv0m9Lb4yVkQBn2A==", + "license": "MIT", + "peer": true + }, + "node_modules/array-bounds": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-bounds/-/array-bounds-1.0.1.tgz", + "integrity": "sha512-8wdW3ZGk6UjMPJx/glyEt0sLzzwAE1bhToPsO1W2pbpR2gULyxe3BjSiuJFheP50T/GgODVPz2fuMUmIywt8cQ==", + "license": "MIT", + "peer": true + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-normalize": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array-normalize/-/array-normalize-1.1.4.tgz", + "integrity": "sha512-fCp0wKFLjvSPmCn4F5Tiw4M3lpMZoHlCjfcs7nNzuj3vqQQ1/a8cgB9DXcpDSn18c+coLnaW7rqfcYCvKbyJXg==", + "license": "MIT", + "peer": true, + "dependencies": { + "array-bounds": "^1.0.0" + } + }, + "node_modules/array-range": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-range/-/array-range-1.0.1.tgz", + "integrity": "sha512-shdaI1zT3CVNL2hnx9c0JMc0ZogGaxDs5e85akgHWKYa0yVbIyp06Ind3dVkTj/uuFrzaHBOyqFzo+VV6aXgtA==", + "license": "MIT", + "peer": true + }, + "node_modules/array-rearrange": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/array-rearrange/-/array-rearrange-2.2.2.tgz", + "integrity": "sha512-UfobP5N12Qm4Qu4fwLDIi2v6+wZsSf6snYSxAMeKhrh37YGnNWZPRmVEKc/2wfms53TLQnzfpG8wCx2Y/6NG1w==", + "license": "MIT", + "peer": true + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/binary-search-bounds": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-2.0.5.tgz", + "integrity": "sha512-H0ea4Fd3lS1+sTEB2TgcLoK21lLhwEJzlQv3IN47pJS976Gx4zoWe0ak3q+uYh60ppQxg9F16Ri4tS1sfD4+jA==", + "license": "MIT", + "peer": true + }, + "node_modules/bit-twiddle": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", + "integrity": "sha512-B9UhK0DKFZhoTFcfvAzhqsjStvGJp9vYWf3+6SNTtdSQnvIgfkHbgHrg/e4+TH71N2GDu8tpmCVoyfrL1d7ntA==", + "license": "MIT", + "peer": true + }, + "node_modules/bitmap-sdf": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bitmap-sdf/-/bitmap-sdf-1.0.4.tgz", + "integrity": "sha512-1G3U4n5JE6RAiALMxu0p1XmeZkTeCwGKykzsLTCqVzfSDaN6S7fKnkIkfejogz+iwqBWc0UYAIKnKHNN7pSfDg==", + "license": "MIT", + "peer": true + }, + "node_modules/bl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", + "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "license": "MIT", + "peer": true, + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/browserslist": { + "version": "4.24.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz", + "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001716", + "electron-to-chromium": "^1.5.149", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001718", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", + "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0", + "peer": true + }, + "node_modules/canvas-fit": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/canvas-fit/-/canvas-fit-1.5.0.tgz", + "integrity": "sha512-onIcjRpz69/Hx5bB5HGbYKUF2uC6QT6Gp+pfpGm3A7mPfcluSLV5v4Zu+oflDUwLdUw0rLIBhUbi0v8hM4FJQQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "element-size": "^1.1.1" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clamp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/clamp/-/clamp-1.0.1.tgz", + "integrity": "sha512-kgMuFyE78OC6Dyu3Dy7vcx4uy97EIbVxJB/B0eJ3bUNAkwdNcxYzgKltnyADiYwsR7SEqkkUPsEUT//OVS6XMA==", + "license": "MIT", + "peer": true + }, + "node_modules/color-alpha": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/color-alpha/-/color-alpha-1.0.4.tgz", + "integrity": "sha512-lr8/t5NPozTSqli+duAN+x+no/2WaKTeWvxhHGN+aXT6AJ8vPlzLa7UriyjWak0pSC2jHol9JgjBYnnHsGha9A==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-parse": "^1.3.8" + } + }, + "node_modules/color-alpha/node_modules/color-parse": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/color-parse/-/color-parse-1.4.3.tgz", + "integrity": "sha512-BADfVl/FHkQkyo8sRBwMYBqemqsgnu7JZAwUgvBvuwwuNUZAhSvLTbsEErS5bQXzOjDR0dWzJ4vXN2Q+QoPx0A==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "^1.0.0" + } + }, + "node_modules/color-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/color-id/-/color-id-1.1.0.tgz", + "integrity": "sha512-2iRtAn6dC/6/G7bBIo0uupVrIne1NsQJvJxZOBCzQOfk7jRq97feaDZ3RdzuHakRXXnHGNwglto3pqtRx1sX0g==", + "license": "MIT", + "peer": true, + "dependencies": { + "clamp": "^1.0.1" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT", + "peer": true + }, + "node_modules/color-normalize": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/color-normalize/-/color-normalize-1.5.0.tgz", + "integrity": "sha512-rUT/HDXMr6RFffrR53oX3HGWkDOP9goSAQGBkUaAYKjOE2JxozccdGyufageWDlInRAjm/jYPrf/Y38oa+7obw==", + "license": "MIT", + "peer": true, + "dependencies": { + "clamp": "^1.0.1", + "color-rgba": "^2.1.1", + "dtype": "^2.0.0" + } + }, + "node_modules/color-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/color-parse/-/color-parse-2.0.0.tgz", + "integrity": "sha512-g2Z+QnWsdHLppAbrpcFWo629kLOnOPtpxYV69GCqm92gqSgyXbzlfyN3MXs0412fPBkFmiuS+rXposgBgBa6Kg==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "^1.0.0" + } + }, + "node_modules/color-rgba": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/color-rgba/-/color-rgba-2.1.1.tgz", + "integrity": "sha512-VaX97wsqrMwLSOR6H7rU1Doa2zyVdmShabKrPEIFywLlHoibgD3QW9Dw6fSqM4+H/LfjprDNAUUW31qEQcGzNw==", + "license": "MIT", + "peer": true, + "dependencies": { + "clamp": "^1.0.1", + "color-parse": "^1.3.8", + "color-space": "^1.14.6" + } + }, + "node_modules/color-rgba/node_modules/color-parse": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/color-parse/-/color-parse-1.4.3.tgz", + "integrity": "sha512-BADfVl/FHkQkyo8sRBwMYBqemqsgnu7JZAwUgvBvuwwuNUZAhSvLTbsEErS5bQXzOjDR0dWzJ4vXN2Q+QoPx0A==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "^1.0.0" + } + }, + "node_modules/color-space": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/color-space/-/color-space-1.16.0.tgz", + "integrity": "sha512-A6WMiFzunQ8KEPFmj02OnnoUnqhmSaHaZ/0LVFcPTdlvm8+3aMJ5x1HRHy3bDHPkovkf4sS0f4wsVvwk71fKkg==", + "license": "MIT", + "peer": true, + "dependencies": { + "hsluv": "^0.0.3", + "mumath": "^3.3.4" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/complex.js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.2.tgz", + "integrity": "sha512-qtx7HRhPGSCBtGiST4/WGHuW+zeaND/6Ld+db6PbrulIB1i2Ev/2UPiqcmpQNPSyfBKraC0EOvOKCB5dGZKt3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT", + "peer": true + }, + "node_modules/country-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/country-regex/-/country-regex-1.1.0.tgz", + "integrity": "sha512-iSPlClZP8vX7MC3/u6s3lrDuoQyhQukh5LyABJ3hvfzbQ3Yyayd4fp04zjLnfi267B/B2FkumcWWgrbban7sSA==", + "license": "MIT", + "peer": true + }, + "node_modules/css-font": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-font/-/css-font-1.2.0.tgz", + "integrity": "sha512-V4U4Wps4dPDACJ4WpgofJ2RT5Yqwe1lEH6wlOOaIxMi0gTjdIijsc5FmxQlZ7ZZyKQkkutqqvULOp07l9c7ssA==", + "license": "MIT", + "peer": true, + "dependencies": { + "css-font-size-keywords": "^1.0.0", + "css-font-stretch-keywords": "^1.0.1", + "css-font-style-keywords": "^1.0.1", + "css-font-weight-keywords": "^1.0.0", + "css-global-keywords": "^1.0.1", + "css-system-font-keywords": "^1.0.0", + "pick-by-alias": "^1.2.0", + "string-split-by": "^1.0.0", + "unquote": "^1.1.0" + } + }, + "node_modules/css-font-size-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-font-size-keywords/-/css-font-size-keywords-1.0.0.tgz", + "integrity": "sha512-Q+svMDbMlelgCfH/RVDKtTDaf5021O486ZThQPIpahnIjUkMUslC+WuOQSWTgGSrNCH08Y7tYNEmmy0hkfMI8Q==", + "license": "MIT", + "peer": true + }, + "node_modules/css-font-stretch-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-font-stretch-keywords/-/css-font-stretch-keywords-1.0.1.tgz", + "integrity": "sha512-KmugPO2BNqoyp9zmBIUGwt58UQSfyk1X5DbOlkb2pckDXFSAfjsD5wenb88fNrD6fvS+vu90a/tsPpb9vb0SLg==", + "license": "MIT", + "peer": true + }, + "node_modules/css-font-style-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-font-style-keywords/-/css-font-style-keywords-1.0.1.tgz", + "integrity": "sha512-0Fn0aTpcDktnR1RzaBYorIxQily85M2KXRpzmxQPgh8pxUN9Fcn00I8u9I3grNr1QXVgCl9T5Imx0ZwKU973Vg==", + "license": "MIT", + "peer": true + }, + "node_modules/css-font-weight-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-font-weight-keywords/-/css-font-weight-keywords-1.0.0.tgz", + "integrity": "sha512-5So8/NH+oDD+EzsnF4iaG4ZFHQ3vaViePkL1ZbZ5iC/KrsCY+WHq/lvOgrtmuOQ9pBBZ1ADGpaf+A4lj1Z9eYA==", + "license": "MIT", + "peer": true + }, + "node_modules/css-global-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-global-keywords/-/css-global-keywords-1.0.1.tgz", + "integrity": "sha512-X1xgQhkZ9n94WDwntqst5D/FKkmiU0GlJSFZSV3kLvyJ1WC5VeyoXDOuleUD+SIuH9C7W05is++0Woh0CGfKjQ==", + "license": "MIT", + "peer": true + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "license": "MIT", + "peer": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-system-font-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-system-font-keywords/-/css-system-font-keywords-1.0.0.tgz", + "integrity": "sha512-1umTtVd/fXS25ftfjB71eASCrYhilmEsvDEI6wG/QplnmlfmVM5HkZ/ZX46DT5K3eblFPgLUHt5BRCb0YXkSFA==", + "license": "MIT", + "peer": true + }, + "node_modules/csscolorparser": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", + "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==", + "license": "MIT", + "peer": true + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "peer": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "license": "ISC", + "peer": true, + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-collection": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", + "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz", + "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-force": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz", + "integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-quadtree": "1", + "d3-timer": "1" + } + }, + "node_modules/d3-format": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", + "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-geo": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.12.1.tgz", + "integrity": "sha512-XG4d1c/UJSEX9NfU02KwBL6BYPj8YKHxgBEw5om2ZnTRSbIcego6dhHwcxuSR3clxh0EpE38os1DVPOmnYtTPg==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "d3-array": "1" + } + }, + "node_modules/d3-geo-projection": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/d3-geo-projection/-/d3-geo-projection-2.9.0.tgz", + "integrity": "sha512-ZULvK/zBn87of5rWAfFMc9mJOipeSo57O+BBitsKIXmU4rTVAnX1kSsJkE0R+TxY8pGNoM1nbyRRE7GYHhdOEQ==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "commander": "2", + "d3-array": "1", + "d3-geo": "^1.12.0", + "resolve": "^1.1.10" + }, + "bin": { + "geo2svg": "bin/geo2svg", + "geograticule": "bin/geograticule", + "geoproject": "bin/geoproject", + "geoquantize": "bin/geoquantize", + "geostitch": "bin/geostitch" + } + }, + "node_modules/d3-hierarchy": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz", + "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "peer": true, + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-quadtree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz", + "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", + "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/d3-time-format": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.3.0.tgz", + "integrity": "sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "d3-time": "1" + } + }, + "node_modules/d3-timer": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz", + "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-kerning": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-kerning/-/detect-kerning-2.1.2.tgz", + "integrity": "sha512-I3JIbrnKPAntNLl1I6TpSQQdQ4AutYzv/sKMFKbepawV/hlH0GmYKhUoOEMd4xqaUHT+Bm0f4127lh5qs1m1tw==", + "license": "MIT", + "peer": true + }, + "node_modules/draw-svg-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/draw-svg-path/-/draw-svg-path-1.0.0.tgz", + "integrity": "sha512-P8j3IHxcgRMcY6sDzr0QvJDLzBnJJqpTG33UZ2Pvp8rw0apCHhJCWqYprqrXjrgHnJ6tuhP1iTJSAodPDHxwkg==", + "license": "MIT", + "peer": true, + "dependencies": { + "abs-svg-path": "~0.1.1", + "normalize-svg-path": "~0.1.0" + } + }, + "node_modules/dtype": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dtype/-/dtype-2.0.0.tgz", + "integrity": "sha512-s2YVcLKdFGS0hpFqJaTwscsyt0E8nNFdmo73Ocd81xNPj4URI4rj6D60A+vFMIw7BXWlb4yRkEwfBqcZzPGiZg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/dup": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dup/-/dup-1.0.0.tgz", + "integrity": "sha512-Bz5jxMMC0wgp23Zm15ip1x8IhYRqJvF3nFC0UInJUDkN1z4uNPk9jTnfCUJXbOGiQ1JbXLQsiV41Fb+HXcj5BA==", + "license": "MIT", + "peer": true + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "license": "MIT", + "peer": true, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/earcut": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==", + "license": "ISC", + "peer": true + }, + "node_modules/electron-to-chromium": { + "version": "1.5.155", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.155.tgz", + "integrity": "sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng==", + "license": "ISC", + "peer": true + }, + "node_modules/element-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/element-size/-/element-size-1.1.1.tgz", + "integrity": "sha512-eaN+GMOq/Q+BIWy0ybsgpcYImjGIdNLyjLFJU4XsLHXYQao5jCNb36GyN6C2qwmDDYSfIBmKpPpr4VnBdLCsPQ==", + "license": "MIT", + "peer": true + }, + "node_modules/elementary-circuits-directed-graph": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/elementary-circuits-directed-graph/-/elementary-circuits-directed-graph-1.3.1.tgz", + "integrity": "sha512-ZEiB5qkn2adYmpXGnJKkxT8uJHlW/mxmBpmeqawEHzPxh9HkLD4/1mFYX5l0On+f6rcPIt8/EWlRU2Vo3fX6dQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "strongly-connected-components": "^1.0.1" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT", + "peer": true + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "hasInstallScript": true, + "license": "ISC", + "peer": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "license": "MIT", + "peer": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "license": "ISC", + "peer": true, + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "license": "ISC", + "peer": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==", + "dev": true, + "license": "MIT" + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "license": "ISC", + "peer": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "license": "MIT", + "peer": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "license": "ISC", + "peer": true, + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/falafel": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.2.5.tgz", + "integrity": "sha512-HuC1qF9iTnHDnML9YZAdCDQwT0yKl/U55K4XSUXqGAA2GLoafFgWRqdAbhWJxXaYD4pyoVxAJ8wH670jMpI9DQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "acorn": "^7.1.1", + "isarray": "^2.0.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/falafel/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT", + "peer": true + }, + "node_modules/fast-isnumeric": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fast-isnumeric/-/fast-isnumeric-1.1.4.tgz", + "integrity": "sha512-1mM8qOr2LYz8zGaUdmiqRDiuue00Dxjgcb1NQR7TnhLVh6sQyngP9xvLo7Sl7LZpP/sk5eb+bcyWXw530NTBZw==", + "license": "MIT", + "peer": true, + "dependencies": { + "is-string-blank": "^1.0.1" + } + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flatten-vertex-data": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten-vertex-data/-/flatten-vertex-data-1.0.2.tgz", + "integrity": "sha512-BvCBFK2NZqerFTdMDgqfHBwxYWnxeCkwONsw6PvBMcUXqo8U/KDWwmXhqx1x2kLIg7DqIsJfOaJFOmlua3Lxuw==", + "license": "MIT", + "peer": true, + "dependencies": { + "dtype": "^2.0.0" + } + }, + "node_modules/font-atlas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/font-atlas/-/font-atlas-2.1.0.tgz", + "integrity": "sha512-kP3AmvX+HJpW4w3d+PiPR2X6E1yvsBXt2yhuCw+yReO9F1WYhvZwx3c95DGZGwg9xYzDGrgJYa885xmVA+28Cg==", + "license": "MIT", + "peer": true, + "dependencies": { + "css-font": "^1.0.0" + } + }, + "node_modules/font-measure": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/font-measure/-/font-measure-1.2.2.tgz", + "integrity": "sha512-mRLEpdrWzKe9hbfaF3Qpr06TAjquuBVP5cHy4b3hyeNdjc9i0PO6HniGsX5vjL5OWv7+Bd++NiooNpT/s8BvIA==", + "license": "MIT", + "peer": true, + "dependencies": { + "css-font": "^1.2.0" + } + }, + "node_modules/fraction.js": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz", + "integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "license": "MIT", + "peer": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/geojson-vt": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz", + "integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==", + "license": "ISC", + "peer": true + }, + "node_modules/get-canvas-context": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-canvas-context/-/get-canvas-context-1.0.2.tgz", + "integrity": "sha512-LnpfLf/TNzr9zVOGiIY6aKCz8EKuXmlYNV7CM2pUjBa/B+c2I15tS7KLySep75+FuerJdmArvJLcsAXWEy2H0A==", + "license": "MIT", + "peer": true + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gl-mat4": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gl-mat4/-/gl-mat4-1.2.0.tgz", + "integrity": "sha512-sT5C0pwB1/e9G9AvAoLsoaJtbMGjfd/jfxo8jMCKqYYEnjZuFvqV5rehqar0538EmssjdDeiEWnKyBSTw7quoA==", + "license": "Zlib", + "peer": true + }, + "node_modules/gl-matrix": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", + "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==", + "license": "MIT", + "peer": true + }, + "node_modules/gl-text": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gl-text/-/gl-text-1.4.0.tgz", + "integrity": "sha512-o47+XBqLCj1efmuNyCHt7/UEJmB9l66ql7pnobD6p+sgmBUdzfMZXIF0zD2+KRfpd99DJN+QXdvTFAGCKCVSmQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "bit-twiddle": "^1.0.2", + "color-normalize": "^1.5.0", + "css-font": "^1.2.0", + "detect-kerning": "^2.1.2", + "es6-weak-map": "^2.0.3", + "flatten-vertex-data": "^1.0.2", + "font-atlas": "^2.1.0", + "font-measure": "^1.2.2", + "gl-util": "^3.1.2", + "is-plain-obj": "^1.1.0", + "object-assign": "^4.1.1", + "parse-rect": "^1.2.0", + "parse-unit": "^1.0.1", + "pick-by-alias": "^1.2.0", + "regl": "^2.0.0", + "to-px": "^1.0.1", + "typedarray-pool": "^1.1.0" + } + }, + "node_modules/gl-util": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/gl-util/-/gl-util-3.1.3.tgz", + "integrity": "sha512-dvRTggw5MSkJnCbh74jZzSoTOGnVYK+Bt+Ckqm39CVcl6+zSsxqWk4lr5NKhkqXHL6qvZAU9h17ZF8mIskY9mA==", + "license": "MIT", + "peer": true, + "dependencies": { + "is-browser": "^2.0.1", + "is-firefox": "^1.0.3", + "is-plain-obj": "^1.1.0", + "number-is-integer": "^1.0.1", + "object-assign": "^4.1.0", + "pick-by-alias": "^1.2.0", + "weak-map": "^1.0.5" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/global-prefix": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-4.0.0.tgz", + "integrity": "sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ini": "^4.1.3", + "kind-of": "^6.0.3", + "which": "^4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/glsl-inject-defines": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/glsl-inject-defines/-/glsl-inject-defines-1.0.3.tgz", + "integrity": "sha512-W49jIhuDtF6w+7wCMcClk27a2hq8znvHtlGnrYkSWEr8tHe9eA2dcnohlcAmxLYBSpSSdzOkRdyPTrx9fw49+A==", + "license": "MIT", + "peer": true, + "dependencies": { + "glsl-token-inject-block": "^1.0.0", + "glsl-token-string": "^1.0.1", + "glsl-tokenizer": "^2.0.2" + } + }, + "node_modules/glsl-resolve": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/glsl-resolve/-/glsl-resolve-0.0.1.tgz", + "integrity": "sha512-xxFNsfnhZTK9NBhzJjSBGX6IOqYpvBHxxmo+4vapiljyGNCY0Bekzn0firQkQrazK59c1hYxMDxYS8MDlhw4gA==", + "license": "MIT", + "peer": true, + "dependencies": { + "resolve": "^0.6.1", + "xtend": "^2.1.2" + } + }, + "node_modules/glsl-resolve/node_modules/resolve": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz", + "integrity": "sha512-UHBY3viPlJKf85YijDUcikKX6tmF4SokIDp518ZDVT92JNDcG5uKIthaT/owt3Sar0lwtOafsQuwrg22/v2Dwg==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-resolve/node_modules/xtend": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.2.0.tgz", + "integrity": "sha512-SLt5uylT+4aoXxXuwtQp5ZnMMzhDb1Xkg4pEqc00WUJCQifPfV9Ub1VrNhp9kXkrjZD2I2Hl8WnjP37jzZLPZw==", + "peer": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/glsl-token-assignments": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/glsl-token-assignments/-/glsl-token-assignments-2.0.2.tgz", + "integrity": "sha512-OwXrxixCyHzzA0U2g4btSNAyB2Dx8XrztY5aVUCjRSh4/D0WoJn8Qdps7Xub3sz6zE73W3szLrmWtQ7QMpeHEQ==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-defines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glsl-token-defines/-/glsl-token-defines-1.0.0.tgz", + "integrity": "sha512-Vb5QMVeLjmOwvvOJuPNg3vnRlffscq2/qvIuTpMzuO/7s5kT+63iL6Dfo2FYLWbzuiycWpbC0/KV0biqFwHxaQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "glsl-tokenizer": "^2.0.0" + } + }, + "node_modules/glsl-token-depth": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/glsl-token-depth/-/glsl-token-depth-1.1.2.tgz", + "integrity": "sha512-eQnIBLc7vFf8axF9aoi/xW37LSWd2hCQr/3sZui8aBJnksq9C7zMeUYHVJWMhFzXrBU7fgIqni4EhXVW4/krpg==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-descope": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glsl-token-descope/-/glsl-token-descope-1.0.2.tgz", + "integrity": "sha512-kS2PTWkvi/YOeicVjXGgX5j7+8N7e56srNDEHDTVZ1dcESmbmpmgrnpjPcjxJjMxh56mSXYoFdZqb90gXkGjQw==", + "license": "MIT", + "peer": true, + "dependencies": { + "glsl-token-assignments": "^2.0.0", + "glsl-token-depth": "^1.1.0", + "glsl-token-properties": "^1.0.0", + "glsl-token-scope": "^1.1.0" + } + }, + "node_modules/glsl-token-inject-block": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/glsl-token-inject-block/-/glsl-token-inject-block-1.1.0.tgz", + "integrity": "sha512-q/m+ukdUBuHCOtLhSr0uFb/qYQr4/oKrPSdIK2C4TD+qLaJvqM9wfXIF/OOBjuSA3pUoYHurVRNao6LTVVUPWA==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-properties": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/glsl-token-properties/-/glsl-token-properties-1.0.1.tgz", + "integrity": "sha512-dSeW1cOIzbuUoYH0y+nxzwK9S9O3wsjttkq5ij9ZGw0OS41BirKJzzH48VLm8qLg+au6b0sINxGC0IrGwtQUcA==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-scope": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/glsl-token-scope/-/glsl-token-scope-1.1.2.tgz", + "integrity": "sha512-YKyOMk1B/tz9BwYUdfDoHvMIYTGtVv2vbDSLh94PT4+f87z21FVdou1KNKgF+nECBTo0fJ20dpm0B1vZB1Q03A==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/glsl-token-string/-/glsl-token-string-1.0.1.tgz", + "integrity": "sha512-1mtQ47Uxd47wrovl+T6RshKGkRRCYWhnELmkEcUAPALWGTFe2XZpH3r45XAwL2B6v+l0KNsCnoaZCSnhzKEksg==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-token-whitespace-trim": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glsl-token-whitespace-trim/-/glsl-token-whitespace-trim-1.0.0.tgz", + "integrity": "sha512-ZJtsPut/aDaUdLUNtmBYhaCmhIjpKNg7IgZSfX5wFReMc2vnj8zok+gB/3Quqs0TsBSX/fGnqUUYZDqyuc2xLQ==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-tokenizer": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz", + "integrity": "sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA==", + "license": "MIT", + "peer": true, + "dependencies": { + "through2": "^0.6.3" + } + }, + "node_modules/glsl-tokenizer/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-tokenizer/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "license": "MIT", + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/glsl-tokenizer/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT", + "peer": true + }, + "node_modules/glsl-tokenizer/node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==", + "license": "MIT", + "peer": true, + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/glslify": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glslify/-/glslify-7.1.1.tgz", + "integrity": "sha512-bud98CJ6kGZcP9Yxcsi7Iz647wuDz3oN+IZsjCRi5X1PI7t/xPKeL0mOwXJjo+CRZMqvq0CkSJiywCcY7kVYog==", + "license": "MIT", + "peer": true, + "dependencies": { + "bl": "^2.2.1", + "concat-stream": "^1.5.2", + "duplexify": "^3.4.5", + "falafel": "^2.1.0", + "from2": "^2.3.0", + "glsl-resolve": "0.0.1", + "glsl-token-whitespace-trim": "^1.0.0", + "glslify-bundle": "^5.0.0", + "glslify-deps": "^1.2.5", + "minimist": "^1.2.5", + "resolve": "^1.1.5", + "stack-trace": "0.0.9", + "static-eval": "^2.0.5", + "through2": "^2.0.1", + "xtend": "^4.0.0" + }, + "bin": { + "glslify": "bin.js" + } + }, + "node_modules/glslify-bundle": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glslify-bundle/-/glslify-bundle-5.1.1.tgz", + "integrity": "sha512-plaAOQPv62M1r3OsWf2UbjN0hUYAB7Aph5bfH58VxJZJhloRNbxOL9tl/7H71K7OLJoSJ2ZqWOKk3ttQ6wy24A==", + "license": "MIT", + "peer": true, + "dependencies": { + "glsl-inject-defines": "^1.0.1", + "glsl-token-defines": "^1.0.0", + "glsl-token-depth": "^1.1.1", + "glsl-token-descope": "^1.0.2", + "glsl-token-scope": "^1.1.1", + "glsl-token-string": "^1.0.1", + "glsl-token-whitespace-trim": "^1.0.0", + "glsl-tokenizer": "^2.0.2", + "murmurhash-js": "^1.0.0", + "shallow-copy": "0.0.1" + } + }, + "node_modules/glslify-deps": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/glslify-deps/-/glslify-deps-1.3.2.tgz", + "integrity": "sha512-7S7IkHWygJRjcawveXQjRXLO2FTjijPDYC7QfZyAQanY+yGLCFHYnPtsGT9bdyHiwPTw/5a1m1M9hamT2aBpag==", + "license": "ISC", + "peer": true, + "dependencies": { + "@choojs/findup": "^0.2.0", + "events": "^3.2.0", + "glsl-resolve": "0.0.1", + "glsl-tokenizer": "^2.0.0", + "graceful-fs": "^4.1.2", + "inherits": "^2.0.1", + "map-limit": "0.0.1", + "resolve": "^1.0.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/grid-index": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.1.0.tgz", + "integrity": "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==", + "license": "ISC", + "peer": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-hover": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-hover/-/has-hover-1.0.1.tgz", + "integrity": "sha512-0G6w7LnlcpyDzpeGUTuT0CEw05+QlMuGVk1IHNAlHrGJITGodjZu3x8BNDUMfKJSZXNB2ZAclqc1bvrd+uUpfg==", + "license": "MIT", + "peer": true, + "dependencies": { + "is-browser": "^2.0.1" + } + }, + "node_modules/has-passive-events": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-passive-events/-/has-passive-events-1.0.0.tgz", + "integrity": "sha512-2vSj6IeIsgvsRMyeQ0JaCX5Q3lX4zMn5HpoVc7MEhQ6pv8Iq9rsXjsp+E5ZwaT7T0xhMT0KmU8gtt1EFVdbJiw==", + "license": "MIT", + "peer": true, + "dependencies": { + "is-browser": "^2.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hsluv": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/hsluv/-/hsluv-0.0.3.tgz", + "integrity": "sha512-08iL2VyCRbkQKBySkSh6m8zMUa3sADAxGVWs3Z1aPcUkTJeK0ETG4Fc27tEmQBGUAXZjIsXOZqBvacuVNSC/fQ==", + "license": "MIT", + "peer": true + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "license": "ISC", + "peer": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC", + "peer": true + }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "license": "ISC", + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/is-browser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-browser/-/is-browser-2.1.0.tgz", + "integrity": "sha512-F5rTJxDQ2sW81fcfOR1GnCXT6sVJC104fCyfj+mjpwNEwaPYSn5fte5jiHmBg3DHsIoL/l8Kvw5VN5SsTRcRFQ==", + "license": "MIT", + "peer": true + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-firefox": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-firefox/-/is-firefox-1.0.3.tgz", + "integrity": "sha512-6Q9ITjvWIm0Xdqv+5U12wgOKEM2KoBw4Y926m0OFkvlCxnbG94HKAsVz8w3fWcfAS5YA2fJORXX1dLrkprCCxA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-iexplorer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-iexplorer/-/is-iexplorer-1.0.0.tgz", + "integrity": "sha512-YeLzceuwg3K6O0MLM3UyUUjKAlyULetwryFp1mHy1I5PfArK0AEqlfa+MR4gkJjcbuJXoDJCvXbyqZVf5CR2Sg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-mobile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-mobile/-/is-mobile-4.0.0.tgz", + "integrity": "sha512-mlcHZA84t1qLSuWkt2v0I2l61PYdyQDt4aG1mLIXF5FDMm4+haBCxCPYSr/uwqQNRk1MiTizn0ypEuRAOLRAew==", + "license": "MIT", + "peer": true + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-string-blank": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-string-blank/-/is-string-blank-1.0.1.tgz", + "integrity": "sha512-9H+ZBCVs3L9OYqv8nuUAzpcT9OTgMD1yAWrG7ihlnibdkbtB850heAmYWxHuXc4CHy4lKeK69tN+ny1K7gBIrw==", + "license": "MIT", + "peer": true + }, + "node_modules/is-svg-path": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-svg-path/-/is-svg-path-1.0.2.tgz", + "integrity": "sha512-Lj4vePmqpPR1ZnRctHv8ltSh1OrSxHkhUkd7wi+VQdcdP15/KvQFyk7LhNuM7ZW0EVbJz8kZLVmL9quLrfq4Kg==", + "license": "MIT", + "peer": true + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT", + "peer": true + }, + "node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT", + "peer": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT", + "peer": true + }, + "node_modules/json-stringify-pretty-compact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", + "license": "MIT", + "peer": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==", + "license": "ISC", + "peer": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT", + "peer": true + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/map-limit": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/map-limit/-/map-limit-0.0.1.tgz", + "integrity": "sha512-pJpcfLPnIF/Sk3taPW21G/RQsEEirGaFpCW3oXRwH9dnFHPHNGjNyvh++rdmC2fNqEaTw2MhYJraoJWAHx8kEg==", + "license": "MIT", + "peer": true, + "dependencies": { + "once": "~1.3.0" + } + }, + "node_modules/map-limit/node_modules/once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==", + "license": "ISC", + "peer": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/mapbox-gl": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-1.13.3.tgz", + "integrity": "sha512-p8lJFEiqmEQlyv+DQxFAOG/XPWN0Wp7j/Psq93Zywz7qt9CcUKFYDBOoOEKzqe6gudHVJY8/Bhqw6VDpX2lSBg==", + "license": "SEE LICENSE IN LICENSE.txt", + "peer": true, + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.2", + "@mapbox/geojson-types": "^1.0.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/mapbox-gl-supported": "^1.5.0", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^1.1.1", + "@mapbox/unitbezier": "^0.0.0", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "csscolorparser": "~1.0.3", + "earcut": "^2.2.2", + "geojson-vt": "^3.2.1", + "gl-matrix": "^3.2.1", + "grid-index": "^1.1.0", + "murmurhash-js": "^1.0.0", + "pbf": "^3.2.1", + "potpack": "^1.0.1", + "quickselect": "^2.0.0", + "rw": "^1.3.3", + "supercluster": "^7.1.0", + "tinyqueue": "^2.0.3", + "vt-pbf": "^3.1.1" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/maplibre-gl": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.7.1.tgz", + "integrity": "sha512-lgL7XpIwsgICiL82ITplfS7IGwrB1OJIw/pCvprDp2dhmSSEBgmPzYRvwYYYvJGJD7fxUv1Tvpih4nZ6VrLuaA==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^2.0.6", + "@mapbox/unitbezier": "^0.0.1", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "@maplibre/maplibre-gl-style-spec": "^20.3.1", + "@types/geojson": "^7946.0.14", + "@types/geojson-vt": "3.2.5", + "@types/mapbox__point-geometry": "^0.1.4", + "@types/mapbox__vector-tile": "^1.3.4", + "@types/pbf": "^3.0.5", + "@types/supercluster": "^7.1.3", + "earcut": "^3.0.0", + "geojson-vt": "^4.0.2", + "gl-matrix": "^3.4.3", + "global-prefix": "^4.0.0", + "kdbush": "^4.0.2", + "murmurhash-js": "^1.0.0", + "pbf": "^3.3.0", + "potpack": "^2.0.0", + "quickselect": "^3.0.0", + "supercluster": "^8.0.1", + "tinyqueue": "^3.0.0", + "vt-pbf": "^3.1.3" + }, + "engines": { + "node": ">=16.14.0", + "npm": ">=8.1.0" + }, + "funding": { + "url": "https://github.com/maplibre/maplibre-gl-js?sponsor=1" + } + }, + "node_modules/maplibre-gl/node_modules/@mapbox/tiny-sdf": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz", + "integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/@mapbox/unitbezier": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/earcut": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.1.tgz", + "integrity": "sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw==", + "license": "ISC", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/geojson-vt": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz", + "integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==", + "license": "ISC", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/potpack": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz", + "integrity": "sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==", + "license": "ISC", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/quickselect": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", + "license": "ISC", + "peer": true + }, + "node_modules/maplibre-gl/node_modules/supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "license": "ISC", + "peer": true, + "dependencies": { + "kdbush": "^4.0.2" + } + }, + "node_modules/maplibre-gl/node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "license": "ISC", + "peer": true + }, + "node_modules/math-log2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-log2/-/math-log2-1.0.1.tgz", + "integrity": "sha512-9W0yGtkaMAkf74XGYVy4Dqw3YUMnTNB2eeiw9aQbUl4A3KmuCEHTt2DgAB07ENzOYAjsYSAYufkAq0Zd+jU7zA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mathjs": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-11.12.0.tgz", + "integrity": "sha512-UGhVw8rS1AyedyI55DGz9q1qZ0p98kyKPyc9vherBkoueLntPfKtPBh14x+V4cdUWK0NZV2TBwqRFlvadscSuw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.23.2", + "complex.js": "^2.1.1", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "4.3.4", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.1.1" + }, + "bin": { + "mathjs": "bin/cli.js" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mouse-change": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/mouse-change/-/mouse-change-1.4.0.tgz", + "integrity": "sha512-vpN0s+zLL2ykyyUDh+fayu9Xkor5v/zRD9jhSqjRS1cJTGS0+oakVZzNm5n19JvvEj0you+MXlYTpNxUDQUjkQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "mouse-event": "^1.0.0" + } + }, + "node_modules/mouse-event": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/mouse-event/-/mouse-event-1.0.5.tgz", + "integrity": "sha512-ItUxtL2IkeSKSp9cyaX2JLUuKk2uMoxBg4bbOWVd29+CskYJR9BGsUqtXenNzKbnDshvupjUewDIYVrOB6NmGw==", + "license": "MIT", + "peer": true + }, + "node_modules/mouse-event-offset": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mouse-event-offset/-/mouse-event-offset-3.0.2.tgz", + "integrity": "sha512-s9sqOs5B1Ykox3Xo8b3Ss2IQju4UwlW6LSR+Q5FXWpprJ5fzMLefIIItr3PH8RwzfGy6gxs/4GAmiNuZScE25w==", + "license": "MIT", + "peer": true + }, + "node_modules/mouse-wheel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mouse-wheel/-/mouse-wheel-1.2.0.tgz", + "integrity": "sha512-+OfYBiUOCTWcTECES49neZwL5AoGkXE+lFjIvzwNCnYRlso+EnfvovcBxGoyQ0yQt806eSPjS675K0EwWknXmw==", + "license": "MIT", + "peer": true, + "dependencies": { + "right-now": "^1.0.0", + "signum": "^1.0.0", + "to-px": "^1.0.1" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT", + "peer": true + }, + "node_modules/mumath": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/mumath/-/mumath-3.3.4.tgz", + "integrity": "sha512-VAFIOG6rsxoc7q/IaY3jdjmrsuX9f15KlRLYTHmixASBZkZEKC1IFqE2BC5CdhXmK6WLM1Re33z//AGmeRI6FA==", + "deprecated": "Redundant dependency in your project.", + "license": "Unlicense", + "peer": true, + "dependencies": { + "almost-equal": "^1.1.0" + } + }, + "node_modules/murmurhash-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==", + "license": "MIT", + "peer": true + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg==", + "license": "MIT", + "peer": true + }, + "node_modules/needle": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", + "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT", + "peer": true + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "license": "ISC", + "peer": true + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "license": "MIT", + "peer": true + }, + "node_modules/normalize-svg-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-0.1.0.tgz", + "integrity": "sha512-1/kmYej2iedi5+ROxkRESL/pI02pkg0OBnaR4hJkSIX6+ORzepwbuUXfrdZaPjysTsJInj0Rj5NuX027+dMBvA==", + "license": "MIT", + "peer": true + }, + "node_modules/number-is-integer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-integer/-/number-is-integer-1.0.1.tgz", + "integrity": "sha512-Dq3iuiFBkrbmuQjGFFF3zckXNCQoSD37/SdSbgcBailUx6knDvDwb5CympBgcoWHy36sfS12u74MHYkXyHq6bg==", + "license": "MIT", + "peer": true, + "dependencies": { + "is-finite": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "peer": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parenthesis": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/parenthesis/-/parenthesis-3.1.8.tgz", + "integrity": "sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw==", + "license": "MIT", + "peer": true + }, + "node_modules/parse-rect": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parse-rect/-/parse-rect-1.2.0.tgz", + "integrity": "sha512-4QZ6KYbnE6RTwg9E0HpLchUM9EZt6DnDxajFZZDSV4p/12ZJEvPO702DZpGvRYEPo00yKDys7jASi+/w7aO8LA==", + "license": "MIT", + "peer": true, + "dependencies": { + "pick-by-alias": "^1.2.0" + } + }, + "node_modules/parse-svg-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz", + "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==", + "license": "MIT", + "peer": true + }, + "node_modules/parse-unit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-unit/-/parse-unit-1.0.1.tgz", + "integrity": "sha512-hrqldJHokR3Qj88EIlV/kAyAi/G5R2+R56TBANxNMy0uPlYcttx0jnMW6Yx5KsKPSbC3KddM/7qQm3+0wEXKxg==", + "license": "MIT", + "peer": true + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/pbf": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.3.0.tgz", + "integrity": "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT", + "peer": true + }, + "node_modules/pick-by-alias": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pick-by-alias/-/pick-by-alias-1.2.0.tgz", + "integrity": "sha512-ESj2+eBxhGrcA1azgHs7lARG5+5iLakc/6nlfbpjcLl00HuuUOIuORhYXN4D1HfvMSKuVtFQjAlnwi1JHEeDIw==", + "license": "MIT", + "peer": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/plotly.js": { + "version": "2.35.3", + "resolved": "https://registry.npmjs.org/plotly.js/-/plotly.js-2.35.3.tgz", + "integrity": "sha512-7RaC6FxmCUhpD6H4MpD+QLUu3hCn76I11rotRefrh3m1iDvWqGnVqVk9dSaKmRAhFD3vsNsYea0OxnR1rc2IzQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@plotly/d3": "3.8.2", + "@plotly/d3-sankey": "0.7.2", + "@plotly/d3-sankey-circular": "0.33.1", + "@plotly/mapbox-gl": "1.13.4", + "@turf/area": "^7.1.0", + "@turf/bbox": "^7.1.0", + "@turf/centroid": "^7.1.0", + "base64-arraybuffer": "^1.0.2", + "canvas-fit": "^1.5.0", + "color-alpha": "1.0.4", + "color-normalize": "1.5.0", + "color-parse": "2.0.0", + "color-rgba": "2.1.1", + "country-regex": "^1.1.0", + "css-loader": "^7.1.2", + "d3-force": "^1.2.1", + "d3-format": "^1.4.5", + "d3-geo": "^1.12.1", + "d3-geo-projection": "^2.9.0", + "d3-hierarchy": "^1.1.9", + "d3-interpolate": "^3.0.1", + "d3-time": "^1.1.0", + "d3-time-format": "^2.2.3", + "fast-isnumeric": "^1.1.4", + "gl-mat4": "^1.2.0", + "gl-text": "^1.4.0", + "has-hover": "^1.0.1", + "has-passive-events": "^1.0.0", + "is-mobile": "^4.0.0", + "maplibre-gl": "^4.5.2", + "mouse-change": "^1.4.0", + "mouse-event-offset": "^3.0.2", + "mouse-wheel": "^1.2.0", + "native-promise-only": "^0.8.1", + "parse-svg-path": "^0.1.2", + "point-in-polygon": "^1.1.0", + "polybooljs": "^1.2.2", + "probe-image-size": "^7.2.3", + "regl": "npm:@plotly/regl@^2.1.2", + "regl-error2d": "^2.0.12", + "regl-line2d": "^3.1.3", + "regl-scatter2d": "^3.3.1", + "regl-splom": "^1.0.14", + "strongly-connected-components": "^1.0.1", + "style-loader": "^4.0.0", + "superscript-text": "^1.0.0", + "svg-path-sdf": "^1.1.3", + "tinycolor2": "^1.4.2", + "to-px": "1.0.1", + "topojson-client": "^3.1.0", + "webgl-context": "^2.2.0", + "world-calendars": "^1.0.3" + } + }, + "node_modules/point-in-polygon": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.1.0.tgz", + "integrity": "sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw==", + "license": "MIT", + "peer": true + }, + "node_modules/polybooljs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/polybooljs/-/polybooljs-1.2.2.tgz", + "integrity": "sha512-ziHW/02J0XuNuUtmidBc6GXE8YohYydp3DWPWXYsd7O721TjcmN+k6ezjdwkDqep+gnWnFY+yqZHvzElra2oCg==", + "license": "MIT", + "peer": true + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "license": "ISC", + "peer": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "license": "MIT", + "peer": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "license": "ISC", + "peer": true, + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "license": "ISC", + "peer": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "peer": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT", + "peer": true + }, + "node_modules/potpack": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", + "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==", + "license": "ISC", + "peer": true + }, + "node_modules/probe-image-size": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.2.3.tgz", + "integrity": "sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==", + "license": "MIT", + "peer": true, + "dependencies": { + "lodash.merge": "^4.6.2", + "needle": "^2.5.2", + "stream-parser": "~0.3.1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT", + "peer": true + }, + "node_modules/protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==", + "license": "MIT", + "peer": true + }, + "node_modules/quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==", + "license": "ISC", + "peer": true + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "license": "MIT", + "peer": true, + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT", + "peer": true + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT", + "peer": true + }, + "node_modules/regl": { + "name": "@plotly/regl", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@plotly/regl/-/regl-2.1.2.tgz", + "integrity": "sha512-Mdk+vUACbQvjd0m/1JJjOOafmkp/EpmHjISsopEz5Av44CBq7rPC05HHNbYGKVyNUF2zmEoBS/TT0pd0SPFFyw==", + "license": "MIT", + "peer": true + }, + "node_modules/regl-error2d": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/regl-error2d/-/regl-error2d-2.0.12.tgz", + "integrity": "sha512-r7BUprZoPO9AbyqM5qlJesrSRkl+hZnVKWKsVp7YhOl/3RIpi4UDGASGJY0puQ96u5fBYw/OlqV24IGcgJ0McA==", + "license": "MIT", + "peer": true, + "dependencies": { + "array-bounds": "^1.0.1", + "color-normalize": "^1.5.0", + "flatten-vertex-data": "^1.0.2", + "object-assign": "^4.1.1", + "pick-by-alias": "^1.2.0", + "to-float32": "^1.1.0", + "update-diff": "^1.1.0" + } + }, + "node_modules/regl-line2d": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/regl-line2d/-/regl-line2d-3.1.3.tgz", + "integrity": "sha512-fkgzW+tTn4QUQLpFKsUIE0sgWdCmXAM3ctXcCgoGBZTSX5FE2A0M7aynz7nrZT5baaftLrk9te54B+MEq4QcSA==", + "license": "MIT", + "peer": true, + "dependencies": { + "array-bounds": "^1.0.1", + "array-find-index": "^1.0.2", + "array-normalize": "^1.1.4", + "color-normalize": "^1.5.0", + "earcut": "^2.1.5", + "es6-weak-map": "^2.0.3", + "flatten-vertex-data": "^1.0.2", + "object-assign": "^4.1.1", + "parse-rect": "^1.2.0", + "pick-by-alias": "^1.2.0", + "to-float32": "^1.1.0" + } + }, + "node_modules/regl-scatter2d": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/regl-scatter2d/-/regl-scatter2d-3.3.1.tgz", + "integrity": "sha512-seOmMIVwaCwemSYz/y4WE0dbSO9svNFSqtTh5RE57I7PjGo3tcUYKtH0MTSoshcAsreoqN8HoCtnn8wfHXXfKQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@plotly/point-cluster": "^3.1.9", + "array-range": "^1.0.1", + "array-rearrange": "^2.2.2", + "clamp": "^1.0.1", + "color-id": "^1.1.0", + "color-normalize": "^1.5.0", + "color-rgba": "^2.1.1", + "flatten-vertex-data": "^1.0.2", + "glslify": "^7.0.0", + "is-iexplorer": "^1.0.0", + "object-assign": "^4.1.1", + "parse-rect": "^1.2.0", + "pick-by-alias": "^1.2.0", + "to-float32": "^1.1.0", + "update-diff": "^1.1.0" + } + }, + "node_modules/regl-splom": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/regl-splom/-/regl-splom-1.0.14.tgz", + "integrity": "sha512-OiLqjmPRYbd7kDlHC6/zDf6L8lxgDC65BhC8JirhP4ykrK4x22ZyS+BnY8EUinXKDeMgmpRwCvUmk7BK4Nweuw==", + "license": "MIT", + "peer": true, + "dependencies": { + "array-bounds": "^1.0.1", + "array-range": "^1.0.1", + "color-alpha": "^1.0.4", + "flatten-vertex-data": "^1.0.2", + "parse-rect": "^1.2.0", + "pick-by-alias": "^1.2.0", + "raf": "^3.4.1", + "regl-scatter2d": "^3.2.3" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, + "node_modules/right-now": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/right-now/-/right-now-1.0.0.tgz", + "integrity": "sha512-DA8+YS+sMIVpbsuKgy+Z67L9Lxb1p05mNxRpDPNksPDEFir4vmBlUtuN9jkTGn9YMMdlBuK7XQgFiz6ws+yhSg==", + "license": "MIT", + "peer": true + }, + "node_modules/rollup": { + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "dev": true, + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-plugin-typescript2": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.36.0.tgz", + "integrity": "sha512-NB2CSQDxSe9+Oe2ahZbf+B4bh7pHwjV5L+RSYpCu7Q5ROuN94F9b6ioWwKfz3ueL3KTtmX4o2MUH2cgHDIEUsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^4.1.2", + "find-cache-dir": "^3.3.2", + "fs-extra": "^10.0.0", + "semver": "^7.5.4", + "tslib": "^2.6.2" + }, + "peerDependencies": { + "rollup": ">=1.26.3", + "typescript": ">=2.4.0" + } + }, + "node_modules/rollup-plugin-typescript2/node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/rollup-plugin-typescript2/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT", + "peer": true + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC", + "peer": true + }, + "node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shallow-copy": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", + "integrity": "sha512-b6i4ZpVuUxB9h5gfCxPiusKYkqTMOjEbBs4wMaFbkfia4yFv92UKZ6Df8WXcKbn08JNL/abvg3FnMAOfakDvUw==", + "license": "MIT", + "peer": true + }, + "node_modules/signum": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/signum/-/signum-1.0.0.tgz", + "integrity": "sha512-yodFGwcyt59XRh7w5W3jPcIQb3Bwi21suEfT7MAWnBX3iCdklJpgDgvGT9o04UonglZN5SNMfJFkHIR/jO8GHw==", + "license": "MIT", + "peer": true + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/stack-trace": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", + "integrity": "sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==", + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/static-eval": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.1.tgz", + "integrity": "sha512-MgWpQ/ZjGieSVB3eOJVs4OA2LT/q1vx98KPCTTQPzq/aLr0YUXTsgryTXr4SLfR0ZfUUCiedM9n/ABeDIyy4mA==", + "license": "MIT", + "peer": true, + "dependencies": { + "escodegen": "^2.1.0" + } + }, + "node_modules/stream-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", + "integrity": "sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "2" + } + }, + "node_modules/stream-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/stream-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT", + "peer": true + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "license": "MIT", + "peer": true + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT", + "peer": true + }, + "node_modules/string-split-by": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string-split-by/-/string-split-by-1.0.0.tgz", + "integrity": "sha512-KaJKY+hfpzNyet/emP81PJA9hTVSfxNLS9SFTWxdCnnW1/zOOwiV248+EfoX7IQFcBaOp4G5YE6xTJMF+pLg6A==", + "license": "MIT", + "peer": true, + "dependencies": { + "parenthesis": "^3.1.5" + } + }, + "node_modules/strongly-connected-components": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strongly-connected-components/-/strongly-connected-components-1.0.1.tgz", + "integrity": "sha512-i0TFx4wPcO0FwX+4RkLJi1MxmcTv90jNZgxMu9XRnMXMeFUY1VJlIoXpZunPUvUUqbCT1pg5PEkFqqpcaElNaA==", + "license": "MIT", + "peer": true + }, + "node_modules/style-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", + "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.27.0" + } + }, + "node_modules/supercluster": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.5.tgz", + "integrity": "sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==", + "license": "ISC", + "peer": true, + "dependencies": { + "kdbush": "^3.0.0" + } + }, + "node_modules/supercluster/node_modules/kdbush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz", + "integrity": "sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew==", + "license": "ISC", + "peer": true + }, + "node_modules/superscript-text": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/superscript-text/-/superscript-text-1.0.0.tgz", + "integrity": "sha512-gwu8l5MtRZ6koO0icVTlmN5pm7Dhh1+Xpe9O4x6ObMAsW+3jPbW14d1DsBq1F4wiI+WOFjXF35pslgec/G8yCQ==", + "license": "MIT", + "peer": true + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-arc-to-cubic-bezier": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz", + "integrity": "sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g==", + "license": "ISC", + "peer": true + }, + "node_modules/svg-path-bounds": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/svg-path-bounds/-/svg-path-bounds-1.0.2.tgz", + "integrity": "sha512-H4/uAgLWrppIC0kHsb2/dWUYSmb4GE5UqH06uqWBcg6LBjX2fu0A8+JrO2/FJPZiSsNOKZAhyFFgsLTdYUvSqQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "abs-svg-path": "^0.1.1", + "is-svg-path": "^1.0.1", + "normalize-svg-path": "^1.0.0", + "parse-svg-path": "^0.1.2" + } + }, + "node_modules/svg-path-bounds/node_modules/normalize-svg-path": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-1.1.0.tgz", + "integrity": "sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==", + "license": "MIT", + "peer": true, + "dependencies": { + "svg-arc-to-cubic-bezier": "^3.0.0" + } + }, + "node_modules/svg-path-sdf": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/svg-path-sdf/-/svg-path-sdf-1.1.3.tgz", + "integrity": "sha512-vJJjVq/R5lSr2KLfVXVAStktfcfa1pNFjFOgyJnzZFXlO/fDZ5DmM8FpnSKKzLPfEYTVeXuVBTHF296TpxuJVg==", + "license": "MIT", + "peer": true, + "dependencies": { + "bitmap-sdf": "^1.0.0", + "draw-svg-path": "^1.0.0", + "is-svg-path": "^1.0.1", + "parse-svg-path": "^0.1.2", + "svg-path-bounds": "^1.0.1" + } + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.39.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.2.tgz", + "integrity": "sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "license": "MIT", + "peer": true + }, + "node_modules/tinyqueue": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", + "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==", + "license": "ISC", + "peer": true + }, + "node_modules/to-float32": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/to-float32/-/to-float32-1.1.0.tgz", + "integrity": "sha512-keDnAusn/vc+R3iEiSDw8TOF7gPiTLdK1ArvWtYbJQiVfmRg6i/CAvbKq3uIS0vWroAC7ZecN3DjQKw3aSklUg==", + "license": "MIT", + "peer": true + }, + "node_modules/to-px": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-px/-/to-px-1.0.1.tgz", + "integrity": "sha512-2y3LjBeIZYL19e5gczp14/uRWFDtDUErJPVN3VU9a7SJO+RjGRtYR47aMN2bZgGlxvW4ZcEz2ddUPVHXcMfuXw==", + "license": "MIT", + "peer": true, + "dependencies": { + "parse-unit": "^1.0.1" + } + }, + "node_modules/topojson-client": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", + "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", + "license": "ISC", + "peer": true, + "dependencies": { + "commander": "2" + }, + "bin": { + "topo2geo": "bin/topo2geo", + "topomerge": "bin/topomerge", + "topoquantize": "bin/topoquantize" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", + "license": "ISC", + "peer": true + }, + "node_modules/typed-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz", + "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT", + "peer": true + }, + "node_modules/typedarray-pool": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typedarray-pool/-/typedarray-pool-1.2.0.tgz", + "integrity": "sha512-YTSQbzX43yvtpfRtIDAYygoYtgT+Rpjuxy9iOpczrjpXLgGoyG7aS5USJXV2d3nn8uHTeb9rXDvzS27zUg5KYQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "bit-twiddle": "^1.0.0", + "dup": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", + "license": "MIT", + "peer": true + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-diff/-/update-diff-1.1.0.tgz", + "integrity": "sha512-rCiBPiHxZwT4+sBhEbChzpO5hYHjm91kScWgdHf4Qeafs6Ba7MBl+d9GlGv72bcTZQO0sLmtQS1pHSWoCLtN/A==", + "license": "MIT", + "peer": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT", + "peer": true + }, + "node_modules/vt-pbf": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", + "integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@mapbox/point-geometry": "0.1.0", + "@mapbox/vector-tile": "^1.3.1", + "pbf": "^3.2.1" + } + }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "license": "MIT", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/weak-map": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.8.tgz", + "integrity": "sha512-lNR9aAefbGPpHO7AEnY0hCFjz1eTkWCXYvkTRrTHs9qv8zJp+SkVYpzfLIFXQQiG3tVvbNFQgVg2bQS8YGgxyw==", + "license": "Apache-2.0", + "peer": true + }, + "node_modules/webgl-context": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webgl-context/-/webgl-context-2.2.0.tgz", + "integrity": "sha512-q/fGIivtqTT7PEoF07axFIlHNk/XCPaYpq64btnepopSWvKNFkoORlQYgqDigBIuGA1ExnFd/GnSUnBNEPQY7Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "get-canvas-context": "^1.0.1" + } + }, + "node_modules/webpack": { + "version": "5.99.9", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", + "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "license": "ISC", + "peer": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/world-calendars": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/world-calendars/-/world-calendars-1.0.3.tgz", + "integrity": "sha512-sAjLZkBnsbHkHWVhrsCU5Sa/EVuf9QqgvrN8zyJ2L/F9FR9Oc6CvVK0674+PGAtmmmYQMH98tCUSO4QLQv3/TQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "object-assign": "^4.1.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC", + "peer": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..94de51e --- /dev/null +++ b/package.json @@ -0,0 +1,69 @@ +{ + "name": "feascript", + "version": "0.1.1", + "description": "A lightweight finite element simulation library built in JavaScript for browser-based physics and engineering simulations", + "main": "dist/feascript.cjs.js", + "module": "dist/feascript.esm.js", + "browser": "dist/feascript.umd.js", + "exports": { + "import": "./dist/feascript.esm.js", + "require": "./dist/feascript.cjs.js" + }, + "files": [ + "dist", + "src" + ], + "types": "dist/types/index.d.ts", + "directories": { + "example": "examples" + }, + "scripts": { + "build": "rollup -c", + "prepublishOnly": "npm run build", + "test": "echo \"No tests configured\" && exit 0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/FEAScript/FEAScript-core.git" + }, + "keywords": [ + "finite element", + "simulation", + "javascript", + "web", + "FEA", + "FEM", + "finite element analysis", + "finite element method" + ], + "author": "Nikolaos Chamakos (https://www.npmjs.com/~nikoscham)", + "contributors": [ + { + "name": "sridhar-mani", + "url": "https://www.npmjs.com/~sridhar-mani" + } + ], + "license": "MIT", + "type": "module", + "bugs": { + "url": "https://github.com/FEAScript/FEAScript-core/issues" + }, + "homepage": "https://github.com/FEAScript/FEAScript-core#readme", + "publishConfig": { + "access": "public" + }, + "peerDependencies": { + "mathjs": "^11.12.0", + "plotly.js": "^2.27.0" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^28.0.3", + "@rollup/plugin-node-resolve": "^16.0.1", + "@types/estree": "^1.0.7", + "mathjs": "^11.12.0", + "rollup": "^2.79.2", + "rollup-plugin-terser": "^7.0.2", + "rollup-plugin-typescript2": "^0.36.0", + "typescript": "^5.8.3" + } +} diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..445e8b3 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,39 @@ +import resolve from "@rollup/plugin-node-resolve"; +import commonjs from "@rollup/plugin-commonjs"; +import { terser } from "rollup-plugin-terser"; + +export default { + input: "src/index.js", + output: [ + { + file: "dist/feascript.cjs.js", + format: "cjs", + sourcemap: true, + + }, + { + file: "dist/feascript.esm.js", + format: "esm", + sourcemap: true, + }, + { + file: "dist/feascript.umd.js", + format: "umd", + name: "FEAScript", + sourcemap: true, + globals: { + mathjs: "math", + "plotly.js": "Plotly" + }, + }, + ], + plugins: [ + resolve({ + browser: true, + preferBuiltins: false, + }), + commonjs(), + terser(), + ], + external: ["mathjs", "plotly.js"], +}; diff --git a/src/index.js b/src/index.js index 5d709fd..c836d38 100644 --- a/src/index.js +++ b/src/index.js @@ -13,3 +13,4 @@ export { importGmshQuadTri } from "./readers/gmshReaderScript.js"; export { logSystem, printVersion } from "./utilities/loggingScript.js"; export { plotSolution } from "./visualization/plotSolutionScript.js"; export { FEAScriptWorker } from "./workers/workerScript.js"; +export const VERSION = "0.1.1"; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..3107ac8 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "outDir": "./dist", + "rootDir": "./src", + "allowJs": true, + "declaration": true, + "declarationDir": "./dist/types", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "lib": [ + "ES2020", + "DOM", + "DOM.Iterable", + "WebWorker", + "ESNext.AsyncIterable" + ], + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test"] +} From eb7eeeddd5300f11c0becca48863558649069a5b Mon Sep 17 00:00:00 2001 From: nikoscham Date: Thu, 22 May 2025 15:33:27 +0300 Subject: [PATCH 6/6] Update import statements in README.md to use ESM version of FEAScript --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9c05e59..5487633 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ If you already have a package.json file, manually add `"type": "module"` to enab Add this line to your HTML or JavaScript module: ```javascript -import { FEAScriptModel, plotSolution } from "https://core.feascript.com/dist/feascript.umd.js"; +import { FEAScriptModel, plotSolution } from "https://core.feascript.com/dist/feascript.esm.js"; ``` ### Option 3: Download and Use Locally @@ -60,7 +60,7 @@ import { FEAScriptModel, plotSolution } from "https://core.feascript.com/dist/fe ```javascript // Import FEAScript library -import { FEAScriptModel, plotSolution } from "https://core.feascript.com/dist/feascript.umd.js"; +import { FEAScriptModel, plotSolution } from "https://core.feascript.com/dist/feascript.esm.js"; // Create and configure model const model = new FEAScriptModel();