diff --git a/.gitignore b/.gitignore
index a60c4d3..3961125 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,19 @@
+# Building
build/
dist/
deb_dist/
-linux/flatpak/AppDir
-linux/flatpak/repo
-linux/flatpak/build-dir
-linux/flatpak/.flatpak-builder
+assets/linux/flatpak/AppDir
+assets/linux/flatpak/repo
+assets/linux/flatpak/build-dir
+assets/linux/flatpak/.flatpak-builder
*.snap
*.spec
*.zip
+*.tar.gz
+*.spec
+*.egg-info/
+
+# Runtime data
**/**.qmlc
**/**.jsc
**/**.pyc
@@ -20,16 +26,19 @@ linux/flatpak/.flatpak-builder
.DS_Store
**/.DS_Store
**/__pycache__/
+
+# IDE Data
.ropeproject
.vscode
*.kdev4
.kdev4
-.coverage
-build
docs/html
.directory
*.lpf
*.lgg
-*.spec
-*.egg-info/
-*.tar.gz
+
+# npm
+common/node_modules
+common/coverage/
+common/.coverage
+runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/index.mjs*
diff --git a/.gitmodules b/.gitmodules
index df81e42..042c634 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
-[submodule "LogarithmPlotter/qml/eu/ad5001/MixedMenu"]
- path = LogarithmPlotter/qml/eu/ad5001/MixedMenu
+[submodule "runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/MixedMenu"]
+ path = runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/MixedMenu
url = https://git.ad5001.eu/Ad5001/MixedMenu
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs
deleted file mode 100644
index 9da3f4d..0000000
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/interface.mjs
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
- * Copyright (C) 2021-2024 Ad5001
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-export const NUMBER = 0
-export const STRING = "string"
-export const BOOLEAN = true
-export const OBJECT = {}
-export const FUNCTION = () => {
-}
-
-
-export class Interface {
- /**
- * Checks if the class to check implements the given interface.
- * Throws an error if the implementation does not conform to the interface.
- * @param {typeof Interface} interface_
- * @param {object} classToCheck
- * @return {boolean}
- */
- static check_implementation(interface_, classToCheck) {
- const properties = new interface_()
- const interfaceName = interface_.name
- const toCheckName = classToCheck.constructor.name
- for(const [property, value] of Object.entries(properties))
- if(property !== "implement") {
- console.log(classToCheck[property], value)
- if(!classToCheck.hasOwnProperty(property))
- // Check if the property exist
- throw new Error(`Property '${property}' (${typeof value}) is present in interface ${interfaceName}, but not in implementation ${toCheckName}.`)
- else if((typeof value) !== (typeof classToCheck[property]))
- // Compare the types
- throw new Error(`Property '${property}' of ${interfaceName} implementation ${toCheckName} is a '${typeof classToCheck[property]}' and not a '${typeof value}'.`)
- else if((typeof value) === "object")
- // Test type of object.
- if(value instanceof Interface)
- Interface.check_implementation(value, classToCheck[property])
- else if(value.prototype && !(classToCheck[property] instanceof value))
- throw new Error(`Property '${property}' of ${interfaceName} implementation ${toCheckName} is not '${value.constructor.name}'.`)
- }
- }
-
- /**
- * Decorator to automatically check if a class conforms to the current interface.
- * @param {object} class_
- */
- implement(class_) {
- Interface.check_implementation(this, class_)
- return class_
- }
-}
-
-
-export class SettingsInterface extends Interface {
- constructor() {
- super()
- this.width = NUMBER
- this.height = NUMBER
- this.xmin = NUMBER
- this.ymax = NUMBER
- this.xzoom = NUMBER
- this.yzoom = NUMBER
- this.xaxisstep = STRING
- this.yaxisstep = STRING
- this.xlabel = STRING
- this.ylabel = STRING
- this.linewidth = NUMBER
- this.textsize = NUMBER
- this.logscalex = BOOLEAN
- this.showxgrad = BOOLEAN
- this.showygrad = BOOLEAN
- }
-}
-
-export class CanvasInterface extends SettingsInterface {
- constructor() {
- super()
- this.imageLoaders = OBJECT
- /** @type {function(string): CanvasRenderingContext2D} */
- this.getContext = FUNCTION
- /** @type {function(rect)} */
- this.markDirty = FUNCTION
- /** @type {function(string)} */
- this.loadImage = FUNCTION
- /** @type {function()} */
- this.requestPaint = FUNCTION
- }
-}
-
-export class RootInterface extends Interface {
- constructor() {
- super()
- this.width = NUMBER
- this.height = NUMBER
- this.updateObjectsLists = FUNCTION
- }
-}
-
-export class DialogInterface extends Interface {
- constructor() {
- super()
- this.show = FUNCTION
- }
-}
-
-export class HistoryInterface extends Interface {
- constructor() {
- super()
- this.undo = FUNCTION
- this.redo = FUNCTION
- this.clear = FUNCTION
- this.addToHistory = FUNCTION
- this.unserialize = FUNCTION
- this.serialize = FUNCTION
- }
-}
\ No newline at end of file
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs
deleted file mode 100644
index 9c30991..0000000
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs
+++ /dev/null
@@ -1,174 +0,0 @@
-/**
- * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
- * Copyright (C) 2021-2024 Ad5001
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-import * as Polyfill from "../lib/expr-eval/polyfill.mjs"
-
-export const CONSTANTS = {
- "π": Math.PI,
- "pi": Math.PI,
- "inf": Infinity,
- "infinity": Infinity,
- "∞": Infinity,
- "e": Math.E
-};
-export const CONSTANTS_LIST = Object.keys(CONSTANTS);
-
-export const FUNCTIONS = {
- // The functions commented are the one either not implemented
- // in the parser, or not to be used for autocompletion.
- // Unary operators
- //'+': Number,
- //'-': (x) => -x,
- //'!'
- // Other operations
- 'length': (s) => Array.isArray(s) ? s.length : String(s).length,
- // Boolean functions
- 'not': (x) => !x,
- // Math functions
- 'abs': Math.abs,
- 'acos': Math.acos,
- 'acosh': Math.acosh,
- 'asin': Math.asin,
- 'asinh': Math.asinh,
- 'atan': Math.atan,
- 'atan2': Math.atan2,
- 'atanh': Math.atanh,
- 'cbrt': Math.cbrt,
- 'ceil': Math.ceil,
- //'clz32': Math.clz32,
- 'cos': Math.cos,
- 'cosh': Math.cosh,
- 'exp': Math.exp,
- 'expm1': Math.expm1,
- 'floor': Math.floor,
- //'fround': Math.fround,
- 'hypot': Math.hypot,
- //'imul': Math.imul,
- 'lg': Math.log10,
- 'ln': Math.log,
- 'log': Math.log,
- 'log10': Math.log10,
- 'log1p': Math.log1p,
- 'log2': Math.log2,
- 'max': Math.max,
- 'min': Math.min,
- 'pow': Math.log2,
- 'random': Math.random,
- 'round': Math.round,
- 'sign': Math.sign,
- 'sin': Math.sin,
- 'sinh': Math.sinh,
- 'sqrt': Math.sqrt,
- 'tan': Math.tan,
- 'tanh': Math.tanh,
- 'trunc': Math.trunc,
- // Functions in expr-eval, ported here.
- 'fac': Polyfill.factorial,
- 'gamma': Polyfill.gamma,
- 'Γ': Polyfill.gamma,
- 'roundTo': (x, exp) => Number(x).toFixed(exp),
- // 'map': Polyfill.arrayMap,
- // 'fold': Polyfill.arrayFold,
- // 'filter': Polyfill.arrayFilter,
- // 'indexOf': Polyfill.indexOf,
- // 'join': Polyfill.arrayJoin,
- // Integral & derivative (only here for autocomplete).
- 'integral': () => 0, // TODO: Implement
- 'derivative': () => 0,
-}
-export const FUNCTIONS_LIST = Object.keys(FUNCTIONS);
-
-export class P {
- // Parameter class.
- constructor(type, name = '', optional = false, multipleAllowed = false) {
- this.name = name
- this.type = type
- this.optional = optional
- this.multipleAllowed = multipleAllowed
- }
-
- toString() {
- let base_string = this.type
- if(this.name !== '')
- base_string = `${this.name}: ${base_string}`
- if(this.multipleAllowed)
- base_string += '...'
- if(!this.optional)
- base_string = `<${base_string}>`
- else
- base_string = `[${base_string}]`
- return base_string
- }
-}
-
-export let string = new P('string')
-export let bool = new P('bool')
-export let number = new P('number')
-export let array = new P('array')
-
-export const FUNCTIONS_USAGE = {
- 'length': [string],
- 'not': [bool],
- // Math functions
- 'abs': [number],
- 'acos': [number],
- 'acosh': [number],
- 'asin': [number],
- 'asinh': [number],
- 'atan': [number],
- 'atan2': [number],
- 'atanh': [number],
- 'cbrt': [number],
- 'ceil': [number],
- //'clz32': [number],
- 'cos': [number],
- 'cosh': [number],
- 'exp': [number],
- 'expm1': [number],
- 'floor': [number],
- //'fround': [number],
- 'hypot': [number],
- //'imul': [number],
- 'lg': [number],
- 'ln': [number],
- 'log': [number],
- 'log10': [number],
- 'log1p': [number],
- 'log2': [number],
- 'max': [number, number, new P('numbers', '', true, true)],
- 'min': [number, number, new P('numbers', '', true, true)],
- 'pow': [number, new P('number', 'exp')],
- 'random': [number, number],
- 'round': [number],
- 'sign': [number],
- 'sin': [number],
- 'sinh': [number],
- 'sqrt': [number],
- 'tan': [number],
- 'tanh': [number],
- 'trunc': [number],
- // Functions in expr-eval, ported here.
- 'fac': [number],
- 'gamma': [number],
- 'Γ': [number],
- 'roundTo': [number, new P('number')],
- // Function manipulation
- 'derivative': [new P('f'), new P('string', 'var', true), number],
- 'integral': [new P('from'), new P('to'), new P('f'), new P('string', 'var', true)],
-}
-
diff --git a/README.md b/README.md
index 8ae4d47..8002fe0 100644
--- a/README.md
+++ b/README.md
@@ -15,9 +15,19 @@
You can find more screenshots on the [app's website](https://apps.ad5001.eu/logarithmplotter/).
-## Run
+## Build & Run
-You can simply run LogarithmPlotter using `python3 run.py`.
+First, you'll need to install all the required dependencies:
+
+- [Python 3](https://python.org) with [poetry](https://python-poetry.org/), setup a virtual environment, go to the `runtime-pyside6` directory, and call
+ `poetry install`.
+- [npm](https://npmjs.com) (or [yarn](https://yarnpkg.com/)), go to the `common` directory, and run `npm install` (or `yarn install`).
+
+You can simply run LogarithmPlotter using `python3 run.py`. It automatically compiles the language files (requires
+`lrelease` to be installed and in path), and the JavaScript modules.
+
+If you do not wish do recompile the files again on every run, you can use the build script (`scripts/build.sh`) and run
+`python3 build/runtime-pyside6/LogarithmPlotter/logarithmplotter.py`.
In order to test translations, you can use the `--lang=` commandline option to force the locale.
@@ -27,26 +37,20 @@ In order to test translations, you can use the `--lang=` commandline
All scripts noted here can be found in the `scripts` directory.
-You can generate installers for LogarithmPlotter after installing all the dependencies:
-For all builds, you will need [Python 3](https://python.org) with [poetry](https://python-poetry.org/), and
-`poetry install --with packaging`.
+You can generate installers for LogarithmPlotter after installing all the dependencies.
-- Windows installer:
- - Run the `build-windows.bat` script (or `build-wine.sh` if you're cross-compiling with wine on Linux) to build an
- exe for LogarithmPlotter.
- - You also need [NSIS](https://nsis.sourceforge.io/Main_Page) (Linux users can install
- the [nsis](https://pkgs.org/download/nsis) package).
- - Run the `package-windows.bat` script (or `package-wine.sh`if you're cross-compiling on Linux). You will find a
- logarithmplotter-setup.exe installer in the dist/logarithmplotter/ folder.
+- Windows installer (crosscompiling from Linux):
+ - Run `build-wine.sh` (requires wine) to build an exe for LogarithmPlotter in build/runtime-pyside6/dist.
+ - You also need [NSIS](https://nsis.sourceforge.io/Main_Page) (the [nsis](https://pkgs.org/download/nsis) package is available on linux).
+ - Run the `package-wine.sh` script. You will find a logarithmplotter-setup.exe installer in the build/runtime-pyside6/dist/logarithmplotter/ folder.
- MacOS Archive creator installer:
- - Run the `build-macosx.sh` script to build an .app for LogarithmPlotter which can be found in the dist directory.
+ - Run the `build-macosx.sh` script to build an .app for LogarithmPlotter which can be found in the build/runtime-pyside6/dist directory.
- Run the `package-macosx.sh` script. You will find a LogarithmPlotter-v<version>-setup.dmg installer in the
- dist/ folder.
+ build/runtime-pyside6/build/pysdist/ folder.
- Linux packages:
- - To build and install the flatpak, you
- need [flatpak-builder](https://docs.flatpak.org/en/latest/flatpak-builder.html) installed.
- - To build the snap, you need [snapcraft](https://snapcraft.io) installed.
- - Run `package-linux.sh`.
+ - Run `package-deb.sh`. It will create an DSC and a DEB in build/runtime-pyside6/deb_dist/
+ - Run `scripts/build.sh` followed by `snapcraft`. It .snap file in the root directory.
+ - See [the flatpak repo](https://github.com/Ad5001/eu.ad5001.LogarithmPlotter) for instrutions on how to build the flatpak.
## Contribute
diff --git a/LogarithmPlotter/i18n/lp_de.ts b/assets/i18n/lp_de.ts
similarity index 100%
rename from LogarithmPlotter/i18n/lp_de.ts
rename to assets/i18n/lp_de.ts
diff --git a/LogarithmPlotter/i18n/lp_en.ts b/assets/i18n/lp_en.ts
similarity index 100%
rename from LogarithmPlotter/i18n/lp_en.ts
rename to assets/i18n/lp_en.ts
diff --git a/LogarithmPlotter/i18n/lp_es.ts b/assets/i18n/lp_es.ts
similarity index 100%
rename from LogarithmPlotter/i18n/lp_es.ts
rename to assets/i18n/lp_es.ts
diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/assets/i18n/lp_fr.ts
similarity index 100%
rename from LogarithmPlotter/i18n/lp_fr.ts
rename to assets/i18n/lp_fr.ts
diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/assets/i18n/lp_hu.ts
similarity index 100%
rename from LogarithmPlotter/i18n/lp_hu.ts
rename to assets/i18n/lp_hu.ts
diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/assets/i18n/lp_nb_NO.ts
similarity index 100%
rename from LogarithmPlotter/i18n/lp_nb_NO.ts
rename to assets/i18n/lp_nb_NO.ts
diff --git a/LogarithmPlotter/i18n/lp_template.ts b/assets/i18n/lp_template.ts
similarity index 100%
rename from LogarithmPlotter/i18n/lp_template.ts
rename to assets/i18n/lp_template.ts
diff --git a/LogarithmPlotter/i18n/release.sh b/assets/i18n/release.sh
similarity index 100%
rename from LogarithmPlotter/i18n/release.sh
rename to assets/i18n/release.sh
diff --git a/LogarithmPlotter/i18n/update.sh b/assets/i18n/update.sh
similarity index 80%
rename from LogarithmPlotter/i18n/update.sh
rename to assets/i18n/update.sh
index 3a01e14..8d589d5 100755
--- a/LogarithmPlotter/i18n/update.sh
+++ b/assets/i18n/update.sh
@@ -4,7 +4,7 @@
# specificities so that lupdate doesn't cry out in pain.
# See also: https://bugreports.qt.io/browse/QTBUG-123819
#
-
+
escape() {
str="$1"
str="${str//\//\\/}" # Escape slashes
@@ -19,15 +19,20 @@ replace() {
sed -i "s/${from}/${to}/g" "$file"
}
+rm ../qml/eu/ad5001/LogarithmPlotter/js/index.mjs # Remove index which should not be scanned
+
files=$(find .. -name *.mjs)
for file in $files; do
echo "Moving '$file' to '${file%.*}.js'..."
mv "$file" "${file%.*}.js"
# Replacements to make it valid js
replace "${file%.*}.js" "^import" "/*import"
+ replace "${file%.*}.js" "^export *" "/*export *"
replace "${file%.*}.js" '.mjs"$' '.mjs"*/'
replace "${file%.*}.js" "^export default" "/*export default*/"
replace "${file%.*}.js" "^export" "/*export*/"
+ replace "${file%.*}.js" "async " "/*async */"
+ replace "${file%.*}.js" "await" "/*await */"
done
echo "----------------------------"
@@ -38,7 +43,6 @@ lupdate -extensions js,qs,qml,py -recursive .. -ts lp_*.ts
for lp in *.ts; do
echo "Replacing locations in $lp..."
for file in $files; do
- echo " > Replacing for file $file..."
replace "$lp" "${file%.*}.js" "$file"
done
done
@@ -47,8 +51,11 @@ for file in $files; do
echo "Moving '${file%.*}.js' to '$file'..."
mv "${file%.*}.js" "$file"
# Resetting changes
- replace "$file" "^/*import" "import"
- replace "$file" '.mjs"*/$' '.mjs"'
- replace "$file" "^/*export default*/" "export default"
+ replace "$file" "/*await */" "await"
+ replace "$file" "/*async */" "async "
replace "$file" "^/*export*/" "export"
+ replace "$file" "^/*export default*/" "export default"
+ replace "$file" "^/*import" "import"
+ replace "$file" "^/*export" "export"
+ replace "$file" '.mjs"*/$' '.mjs"'
done
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/angle.svg b/assets/icons/common/angle.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/angle.svg
rename to assets/icons/common/angle.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/appearance.svg b/assets/icons/common/appearance.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/appearance.svg
rename to assets/icons/common/appearance.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/arrow.svg b/assets/icons/common/arrow.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/arrow.svg
rename to assets/icons/common/arrow.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg b/assets/icons/common/close.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg
rename to assets/icons/common/close.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/delete.svg b/assets/icons/common/delete.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/delete.svg
rename to assets/icons/common/delete.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/label.svg b/assets/icons/common/label.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/label.svg
rename to assets/icons/common/label.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg b/assets/icons/common/manual.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg
rename to assets/icons/common/manual.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg b/assets/icons/common/new.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg
rename to assets/icons/common/new.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/position.svg b/assets/icons/common/position.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/position.svg
rename to assets/icons/common/position.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/settings.svg b/assets/icons/common/settings.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/settings.svg
rename to assets/icons/common/settings.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/target.svg b/assets/icons/common/target.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/target.svg
rename to assets/icons/common/target.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/text.svg b/assets/icons/common/text.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/text.svg
rename to assets/icons/common/text.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/appearance.svg b/assets/icons/history/appearance.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/appearance.svg
rename to assets/icons/history/appearance.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/create.svg b/assets/icons/history/create.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/create.svg
rename to assets/icons/history/create.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg b/assets/icons/history/delete.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg
rename to assets/icons/history/delete.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/modify.svg b/assets/icons/history/modify.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/modify.svg
rename to assets/icons/history/modify.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/name.svg b/assets/icons/history/name.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/name.svg
rename to assets/icons/history/name.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/position.svg b/assets/icons/history/position.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/position.svg
rename to assets/icons/history/position.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/visibility.svg b/assets/icons/history/visibility.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/visibility.svg
rename to assets/icons/history/visibility.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/logarithmplotter.svg b/assets/icons/logarithmplotter.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/logarithmplotter.svg
rename to assets/icons/logarithmplotter.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Function.svg b/assets/icons/objects/Function.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Function.svg
rename to assets/icons/objects/Function.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Gain Bode.svg b/assets/icons/objects/Gain Bode.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Gain Bode.svg
rename to assets/icons/objects/Gain Bode.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Phase Bode.svg b/assets/icons/objects/Phase Bode.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Phase Bode.svg
rename to assets/icons/objects/Phase Bode.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Point.svg b/assets/icons/objects/Point.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Point.svg
rename to assets/icons/objects/Point.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Repartition.svg b/assets/icons/objects/Repartition.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Repartition.svg
rename to assets/icons/objects/Repartition.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Sequence.svg b/assets/icons/objects/Sequence.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Sequence.svg
rename to assets/icons/objects/Sequence.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Text.svg b/assets/icons/objects/Text.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Text.svg
rename to assets/icons/objects/Text.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/X Cursor.svg b/assets/icons/objects/X Cursor.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/X Cursor.svg
rename to assets/icons/objects/X Cursor.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg b/assets/icons/settings/color.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg
rename to assets/icons/settings/color.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Definition Domain.svg b/assets/icons/settings/custom/Definition Domain.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Definition Domain.svg
rename to assets/icons/settings/custom/Definition Domain.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Destination Domain.svg b/assets/icons/settings/custom/Destination Domain.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Destination Domain.svg
rename to assets/icons/settings/custom/Destination Domain.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Display Mode.svg b/assets/icons/settings/custom/Display Mode.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Display Mode.svg
rename to assets/icons/settings/custom/Display Mode.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Display Style.svg b/assets/icons/settings/custom/Display Style.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Display Style.svg
rename to assets/icons/settings/custom/Display Style.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Expression.svg b/assets/icons/settings/custom/Expression.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Expression.svg
rename to assets/icons/settings/custom/Expression.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Gain.svg b/assets/icons/settings/custom/Gain.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Gain.svg
rename to assets/icons/settings/custom/Gain.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Label Position.svg b/assets/icons/settings/custom/Label Position.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Label Position.svg
rename to assets/icons/settings/custom/Label Position.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Label X.svg b/assets/icons/settings/custom/Label X.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Label X.svg
rename to assets/icons/settings/custom/Label X.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Pass.svg b/assets/icons/settings/custom/Pass.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Pass.svg
rename to assets/icons/settings/custom/Pass.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Phase.svg b/assets/icons/settings/custom/Phase.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Phase.svg
rename to assets/icons/settings/custom/Phase.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Point Style.svg b/assets/icons/settings/custom/Point Style.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Point Style.svg
rename to assets/icons/settings/custom/Point Style.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Rounding.svg b/assets/icons/settings/custom/Rounding.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Rounding.svg
rename to assets/icons/settings/custom/Rounding.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Target Element.svg b/assets/icons/settings/custom/Target Element.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Target Element.svg
rename to assets/icons/settings/custom/Target Element.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Target Value Position.svg b/assets/icons/settings/custom/Target Value Position.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Target Value Position.svg
rename to assets/icons/settings/custom/Target Value Position.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Text.svg b/assets/icons/settings/custom/Text.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Text.svg
rename to assets/icons/settings/custom/Text.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Unit.svg b/assets/icons/settings/custom/Unit.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Unit.svg
rename to assets/icons/settings/custom/Unit.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/X.svg b/assets/icons/settings/custom/X.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/X.svg
rename to assets/icons/settings/custom/X.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Y.svg b/assets/icons/settings/custom/Y.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/Y.svg
rename to assets/icons/settings/custom/Y.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/ω_0.svg b/assets/icons/settings/custom/ω_0.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/ω_0.svg
rename to assets/icons/settings/custom/ω_0.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg b/assets/icons/settings/label.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg
rename to assets/icons/settings/label.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/linewidth.svg b/assets/icons/settings/linewidth.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/linewidth.svg
rename to assets/icons/settings/linewidth.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg b/assets/icons/settings/text.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg
rename to assets/icons/settings/text.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/textsize.svg b/assets/icons/settings/textsize.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/textsize.svg
rename to assets/icons/settings/textsize.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/timeline.svg b/assets/icons/settings/timeline.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/timeline.svg
rename to assets/icons/settings/timeline.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/update.svg b/assets/icons/settings/update.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/update.svg
rename to assets/icons/settings/update.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xaxisstep.svg b/assets/icons/settings/xaxisstep.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xaxisstep.svg
rename to assets/icons/settings/xaxisstep.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xlabel.svg b/assets/icons/settings/xlabel.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xlabel.svg
rename to assets/icons/settings/xlabel.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xmax.svg b/assets/icons/settings/xmax.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xmax.svg
rename to assets/icons/settings/xmax.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xmin.svg b/assets/icons/settings/xmin.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xmin.svg
rename to assets/icons/settings/xmin.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xzoom.svg b/assets/icons/settings/xzoom.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/xzoom.svg
rename to assets/icons/settings/xzoom.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/yaxisstep.svg b/assets/icons/settings/yaxisstep.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/yaxisstep.svg
rename to assets/icons/settings/yaxisstep.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ylabel.svg b/assets/icons/settings/ylabel.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ylabel.svg
rename to assets/icons/settings/ylabel.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ymax.svg b/assets/icons/settings/ymax.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ymax.svg
rename to assets/icons/settings/ymax.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ymin.svg b/assets/icons/settings/ymin.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/ymin.svg
rename to assets/icons/settings/ymin.svg
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/yzoom.svg b/assets/icons/settings/yzoom.svg
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/yzoom.svg
rename to assets/icons/settings/yzoom.svg
diff --git a/LogarithmPlotter/logarithmplotter.svg b/assets/logarithmplotter.svg
similarity index 100%
rename from LogarithmPlotter/logarithmplotter.svg
rename to assets/logarithmplotter.svg
diff --git a/logplotterfile.svg b/assets/logplotterfile.svg
similarity index 100%
rename from logplotterfile.svg
rename to assets/logplotterfile.svg
diff --git a/assets/native/linux/application-x-logarithm-plot.svg b/assets/native/linux/application-x-logarithm-plot.svg
new file mode 120000
index 0000000..4e7d218
--- /dev/null
+++ b/assets/native/linux/application-x-logarithm-plot.svg
@@ -0,0 +1 @@
+../../logplotterfile.svg
\ No newline at end of file
diff --git a/linux/debian/changelog b/assets/native/linux/debian/changelog
similarity index 100%
rename from linux/debian/changelog
rename to assets/native/linux/debian/changelog
diff --git a/linux/debian/control b/assets/native/linux/debian/control
similarity index 65%
rename from linux/debian/control
rename to assets/native/linux/debian/control
index e63e970..1df7fd8 100644
--- a/linux/debian/control
+++ b/assets/native/linux/debian/control
@@ -3,9 +3,9 @@ Source: logarithmplotter
Version: 0.6.0
Architecture: all
Maintainer: Ad5001
-Depends: python3, python3-pip, python3-pyside6-essentials (>= 6.7.0), python3-pyside6-addons (>= 6.7), texlive-latex-base, dvipng
+Depends: python3 (>= 3.9), python3-pip, python3-pyside6-essentials (>= 6.7.0), python3-pyside6-addons (>= 6.7), texlive-latex-base, dvipng
-Build-Depends: debhelper (>=11~), dh-python, dpkg-dev (>= 1.16.1~), python-setuptools, python3-all-dev (>=3.9)
+Build-Depends: debhelper (>=11~), dh-python, dpkg-dev (>= 1.16.1~), python-setuptools
Section: science
Priority: optional
Homepage: https://apps.ad5001.eu/logarithmplotter/
diff --git a/linux/debian/copyright b/assets/native/linux/debian/copyright
similarity index 100%
rename from linux/debian/copyright
rename to assets/native/linux/debian/copyright
diff --git a/assets/native/linux/debian/depends b/assets/native/linux/debian/depends
new file mode 100644
index 0000000..5b7d902
--- /dev/null
+++ b/assets/native/linux/debian/depends
@@ -0,0 +1 @@
+python3 (>= 3.9), python3-pip, python3-pyside6-essentials (>= 6.7.0), texlive-latex-base, dvipng
diff --git a/linux/debian/recommends b/assets/native/linux/debian/recommends
similarity index 100%
rename from linux/debian/recommends
rename to assets/native/linux/debian/recommends
diff --git a/linux/debian/rules b/assets/native/linux/debian/rules
similarity index 100%
rename from linux/debian/rules
rename to assets/native/linux/debian/rules
diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml
similarity index 100%
rename from linux/eu.ad5001.LogarithmPlotter.metainfo.xml
rename to assets/native/linux/eu.ad5001.LogarithmPlotter.metainfo.xml
diff --git a/linux/logarithmplotter.desktop b/assets/native/linux/logarithmplotter.desktop
similarity index 100%
rename from linux/logarithmplotter.desktop
rename to assets/native/linux/logarithmplotter.desktop
diff --git a/linux/snapcraft/launcher/launch-logarithmplotter b/assets/native/linux/snapcraft/launcher/launch-logarithmplotter
similarity index 100%
rename from linux/snapcraft/launcher/launch-logarithmplotter
rename to assets/native/linux/snapcraft/launcher/launch-logarithmplotter
diff --git a/linux/x-logarithm-plot.xml b/assets/native/linux/x-logarithm-plot.xml
similarity index 100%
rename from linux/x-logarithm-plot.xml
rename to assets/native/linux/x-logarithm-plot.xml
diff --git a/mac/Info.plist b/assets/native/mac/Info.plist
similarity index 100%
rename from mac/Info.plist
rename to assets/native/mac/Info.plist
diff --git a/mac/install-bg.png b/assets/native/mac/install-bg.png
similarity index 100%
rename from mac/install-bg.png
rename to assets/native/mac/install-bg.png
diff --git a/mac/install-bg.xcf b/assets/native/mac/install-bg.xcf
similarity index 100%
rename from mac/install-bg.xcf
rename to assets/native/mac/install-bg.xcf
diff --git a/mac/logarithmplotter.icns b/assets/native/mac/logarithmplotter.icns
similarity index 100%
rename from mac/logarithmplotter.icns
rename to assets/native/mac/logarithmplotter.icns
diff --git a/mac/logarithmplotter.iconset/icon_128x128.png b/assets/native/mac/logarithmplotter.iconset/icon_128x128.png
similarity index 100%
rename from mac/logarithmplotter.iconset/icon_128x128.png
rename to assets/native/mac/logarithmplotter.iconset/icon_128x128.png
diff --git a/mac/logarithmplotter.iconset/icon_16x16.png b/assets/native/mac/logarithmplotter.iconset/icon_16x16.png
similarity index 100%
rename from mac/logarithmplotter.iconset/icon_16x16.png
rename to assets/native/mac/logarithmplotter.iconset/icon_16x16.png
diff --git a/mac/logarithmplotter.iconset/icon_256x256.png b/assets/native/mac/logarithmplotter.iconset/icon_256x256.png
similarity index 100%
rename from mac/logarithmplotter.iconset/icon_256x256.png
rename to assets/native/mac/logarithmplotter.iconset/icon_256x256.png
diff --git a/mac/logarithmplotter.iconset/icon_32x32.png b/assets/native/mac/logarithmplotter.iconset/icon_32x32.png
similarity index 100%
rename from mac/logarithmplotter.iconset/icon_32x32.png
rename to assets/native/mac/logarithmplotter.iconset/icon_32x32.png
diff --git a/mac/logarithmplotter.iconset/icon_512x512.png b/assets/native/mac/logarithmplotter.iconset/icon_512x512.png
similarity index 100%
rename from mac/logarithmplotter.iconset/icon_512x512.png
rename to assets/native/mac/logarithmplotter.iconset/icon_512x512.png
diff --git a/mac/logarithmplotterfile.icns b/assets/native/mac/logarithmplotterfile.icns
similarity index 100%
rename from mac/logarithmplotterfile.icns
rename to assets/native/mac/logarithmplotterfile.icns
diff --git a/mac/logarithmplotterfile.iconset/icon_128x128.png b/assets/native/mac/logarithmplotterfile.iconset/icon_128x128.png
similarity index 100%
rename from mac/logarithmplotterfile.iconset/icon_128x128.png
rename to assets/native/mac/logarithmplotterfile.iconset/icon_128x128.png
diff --git a/mac/logarithmplotterfile.iconset/icon_128x128@2x.png b/assets/native/mac/logarithmplotterfile.iconset/icon_128x128@2x.png
similarity index 100%
rename from mac/logarithmplotterfile.iconset/icon_128x128@2x.png
rename to assets/native/mac/logarithmplotterfile.iconset/icon_128x128@2x.png
diff --git a/mac/logarithmplotterfile.iconset/icon_16x16.png b/assets/native/mac/logarithmplotterfile.iconset/icon_16x16.png
similarity index 100%
rename from mac/logarithmplotterfile.iconset/icon_16x16.png
rename to assets/native/mac/logarithmplotterfile.iconset/icon_16x16.png
diff --git a/mac/logarithmplotterfile.iconset/icon_16x16@2x.png b/assets/native/mac/logarithmplotterfile.iconset/icon_16x16@2x.png
similarity index 100%
rename from mac/logarithmplotterfile.iconset/icon_16x16@2x.png
rename to assets/native/mac/logarithmplotterfile.iconset/icon_16x16@2x.png
diff --git a/mac/logarithmplotterfile.iconset/icon_256x256.png b/assets/native/mac/logarithmplotterfile.iconset/icon_256x256.png
similarity index 100%
rename from mac/logarithmplotterfile.iconset/icon_256x256.png
rename to assets/native/mac/logarithmplotterfile.iconset/icon_256x256.png
diff --git a/mac/logarithmplotterfile.iconset/icon_256x256@2x.png b/assets/native/mac/logarithmplotterfile.iconset/icon_256x256@2x.png
similarity index 100%
rename from mac/logarithmplotterfile.iconset/icon_256x256@2x.png
rename to assets/native/mac/logarithmplotterfile.iconset/icon_256x256@2x.png
diff --git a/mac/logarithmplotterfile.iconset/icon_32x32.png b/assets/native/mac/logarithmplotterfile.iconset/icon_32x32.png
similarity index 100%
rename from mac/logarithmplotterfile.iconset/icon_32x32.png
rename to assets/native/mac/logarithmplotterfile.iconset/icon_32x32.png
diff --git a/mac/logarithmplotterfile.iconset/icon_32x32@2x.png b/assets/native/mac/logarithmplotterfile.iconset/icon_32x32@2x.png
similarity index 100%
rename from mac/logarithmplotterfile.iconset/icon_32x32@2x.png
rename to assets/native/mac/logarithmplotterfile.iconset/icon_32x32@2x.png
diff --git a/mac/logarithmplotterfile.iconset/icon_512x512.png b/assets/native/mac/logarithmplotterfile.iconset/icon_512x512.png
similarity index 100%
rename from mac/logarithmplotterfile.iconset/icon_512x512.png
rename to assets/native/mac/logarithmplotterfile.iconset/icon_512x512.png
diff --git a/mac/logarithmplotterfile.iconset/icon_512x512@2x.png b/assets/native/mac/logarithmplotterfile.iconset/icon_512x512@2x.png
similarity index 100%
rename from mac/logarithmplotterfile.iconset/icon_512x512@2x.png
rename to assets/native/mac/logarithmplotterfile.iconset/icon_512x512@2x.png
diff --git a/win/inst_banner.bmp b/assets/native/win/inst_banner.bmp
similarity index 100%
rename from win/inst_banner.bmp
rename to assets/native/win/inst_banner.bmp
diff --git a/win/installer.nsi b/assets/native/win/installer.nsi
similarity index 99%
rename from win/installer.nsi
rename to assets/native/win/installer.nsi
index 58261ff..ebb84c9 100644
--- a/win/installer.nsi
+++ b/assets/native/win/installer.nsi
@@ -14,7 +14,7 @@ Unicode True
!define VERSION_SHORT "0.6.0"
!define APP_VERSION "${VERSION_SHORT}.0"
!define COPYRIGHT "Ad5001 (c) 2021-2024"
-!define DESCRIPTION "Create graphs with logarithm scales."
+!define DESCRIPTION "Create graphs with logarithmic scales."
!define REG_UNINSTALL "Software\Microsoft\Windows\CurrentVersion\Uninstall\LogarithmPlotter"
!define REG_APPPATHS "Software\Microsoft\Windows\CurrentVersion\App Paths\logarithmplotter.exe"
diff --git a/win/logarithmplotter.ico b/assets/native/win/logarithmplotter.ico
similarity index 100%
rename from win/logarithmplotter.ico
rename to assets/native/win/logarithmplotter.ico
diff --git a/ci/drone.yml b/ci/drone.yml
index 60fadf8..da7d1c7 100644
--- a/ci/drone.yml
+++ b/ci/drone.yml
@@ -11,12 +11,24 @@ steps:
commands:
- git submodule update --init --recursive
+ - name: Build
+ image: node:18-bookworm
+ commands:
+ - cd common && npm install && cd ..
+ - apt update
+ - apt install -y qtchooser qttools5-dev-tools
+ # Start building
+ - bash scripts/build.sh
+ when:
+ event: [ push, tag ]
+
- name: Unit Tests
image: ad5001/ubuntu-pyside-xvfb:linux-6-latest-latex
commands:
- - apt install -y qtchooser qttools5-dev-tools
- - cd LogarithmPlotter/i18n && bash release.sh && cd ../..
- - xvfb-run bash scripts/run-tests.sh
+ - apt update
+ - apt install -y npm
+ - cd common && npm install -D && cd ..
+ - xvfb-run bash scripts/run-tests.sh --no-rebuild
when:
event: [ push, tag ]
@@ -32,7 +44,7 @@ steps:
- name: Windows build
image: ad5001/ubuntu-pyside-xvfb:wine-6-latest
commands:
- - bash scripts/build-wine.sh
+ - bash scripts/build-wine.sh --no-rebuild
- bash scripts/package-wine.sh
when:
event: [ push, tag ]
diff --git a/common/.mocharc.jsonc b/common/.mocharc.jsonc
new file mode 100644
index 0000000..56a6b31
--- /dev/null
+++ b/common/.mocharc.jsonc
@@ -0,0 +1,25 @@
+/**
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+{
+ "recursive": true,
+ "require": [
+ "esm",
+ "./test/hooks.mjs"
+ ]
+}
diff --git a/common/babel.config.json b/common/babel.config.json
new file mode 100644
index 0000000..fd63c92
--- /dev/null
+++ b/common/babel.config.json
@@ -0,0 +1,6 @@
+{
+ "presets": ["@babel/preset-env"],
+ "targets": {
+ "esmodules": true
+ }
+}
\ No newline at end of file
diff --git a/common/package-lock.json b/common/package-lock.json
new file mode 100644
index 0000000..0b60cac
--- /dev/null
+++ b/common/package-lock.json
@@ -0,0 +1,4440 @@
+{
+ "name": "logarithmplotter",
+ "version": "0.6.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "logarithmplotter",
+ "version": "0.6.0",
+ "license": "GPL-3.0-or-later",
+ "dependencies": {
+ "@babel/preset-env": "^7.25.4",
+ "@rollup/plugin-babel": "^6.0.4",
+ "@rollup/plugin-commonjs": "^28.0.0",
+ "@rollup/plugin-node-resolve": "^15.3.0",
+ "c8": "^10.1.2",
+ "rollup": "^4.22.4",
+ "rollup-plugin-cleanup": "^3.2.1"
+ },
+ "devDependencies": {
+ "@types/chai": "^5.0.0",
+ "@types/mocha": "^10.0.8",
+ "chai": "^5.1.1",
+ "chai-as-promised": "^8.0.0",
+ "esm": "^3.2.25",
+ "mocha": "^10.7.3"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
+ "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/highlight": "^7.24.7",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz",
+ "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz",
+ "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.24.7",
+ "@babel/generator": "^7.25.0",
+ "@babel/helper-compilation-targets": "^7.25.2",
+ "@babel/helper-module-transforms": "^7.25.2",
+ "@babel/helpers": "^7.25.0",
+ "@babel/parser": "^7.25.0",
+ "@babel/template": "^7.25.0",
+ "@babel/traverse": "^7.25.2",
+ "@babel/types": "^7.25.2",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
+ "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.25.6",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz",
+ "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz",
+ "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz",
+ "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.25.2",
+ "@babel/helper-validator-option": "^7.24.8",
+ "browserslist": "^4.23.1",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz",
+ "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.24.7",
+ "@babel/helper-member-expression-to-functions": "^7.24.8",
+ "@babel/helper-optimise-call-expression": "^7.24.7",
+ "@babel/helper-replace-supers": "^7.25.0",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
+ "@babel/traverse": "^7.25.4",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin": {
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz",
+ "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.24.7",
+ "regexpu-core": "^5.3.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz",
+ "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.22.6",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "debug": "^4.1.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.14.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz",
+ "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.24.8",
+ "@babel/types": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
+ "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz",
+ "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.24.7",
+ "@babel/helper-simple-access": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.24.7",
+ "@babel/traverse": "^7.25.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz",
+ "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
+ "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz",
+ "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.24.7",
+ "@babel/helper-wrap-function": "^7.25.0",
+ "@babel/traverse": "^7.25.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz",
+ "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-member-expression-to-functions": "^7.24.8",
+ "@babel/helper-optimise-call-expression": "^7.24.7",
+ "@babel/traverse": "^7.25.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
+ "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz",
+ "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
+ "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
+ "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
+ "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz",
+ "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.25.0",
+ "@babel/traverse": "^7.25.0",
+ "@babel/types": "^7.25.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz",
+ "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/template": "^7.25.0",
+ "@babel/types": "^7.25.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
+ "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.24.7",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
+ "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.25.6"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+ "version": "7.25.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz",
+ "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/traverse": "^7.25.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz",
+ "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz",
+ "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz",
+ "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
+ "@babel/plugin-transform-optional-chaining": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.13.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz",
+ "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/traverse": "^7.25.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-private-property-in-object": {
+ "version": "7.21.0-placeholder-for-preset-env.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+ "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-export-namespace-from": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+ "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-assertions": {
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz",
+ "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz",
+ "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+ "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-arrow-functions": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz",
+ "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-generator-functions": {
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz",
+ "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/helper-remap-async-to-generator": "^7.25.0",
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/traverse": "^7.25.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz",
+ "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-remap-async-to-generator": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz",
+ "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz",
+ "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-properties": {
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz",
+ "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.25.4",
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-static-block": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz",
+ "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.12.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz",
+ "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.24.7",
+ "@babel/helper-compilation-targets": "^7.25.2",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/helper-replace-supers": "^7.25.0",
+ "@babel/traverse": "^7.25.4",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-computed-properties": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz",
+ "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/template": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-destructuring": {
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz",
+ "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dotall-regex": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz",
+ "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-keys": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz",
+ "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz",
+ "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.0",
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dynamic-import": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz",
+ "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz",
+ "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-export-namespace-from": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz",
+ "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-for-of": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz",
+ "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name": {
+ "version": "7.25.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz",
+ "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.24.8",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/traverse": "^7.25.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-json-strings": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz",
+ "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/plugin-syntax-json-strings": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-literals": {
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz",
+ "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz",
+ "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-member-expression-literals": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz",
+ "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-amd": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz",
+ "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz",
+ "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.24.8",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/helper-simple-access": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-systemjs": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz",
+ "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.25.0",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/helper-validator-identifier": "^7.24.7",
+ "@babel/traverse": "^7.25.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-umd": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz",
+ "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz",
+ "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-new-target": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz",
+ "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz",
+ "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-numeric-separator": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz",
+ "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-rest-spread": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz",
+ "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-transform-parameters": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-super": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz",
+ "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-replace-supers": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-catch-binding": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz",
+ "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-chaining": {
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz",
+ "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-parameters": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz",
+ "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-methods": {
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz",
+ "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.25.4",
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-property-in-object": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz",
+ "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.24.7",
+ "@babel/helper-create-class-features-plugin": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-property-literals": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz",
+ "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regenerator": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz",
+ "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "regenerator-transform": "^0.15.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-reserved-words": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz",
+ "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-shorthand-properties": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz",
+ "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-spread": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz",
+ "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-sticky-regex": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz",
+ "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-template-literals": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz",
+ "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typeof-symbol": {
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz",
+ "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-escapes": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz",
+ "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-property-regex": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz",
+ "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-regex": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz",
+ "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-sets-regex": {
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz",
+ "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.2",
+ "@babel/helper-plugin-utils": "^7.24.8"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/preset-env": {
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz",
+ "integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.25.4",
+ "@babel/helper-compilation-targets": "^7.25.2",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/helper-validator-option": "^7.24.8",
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3",
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7",
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0",
+ "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+ "@babel/plugin-syntax-import-assertions": "^7.24.7",
+ "@babel/plugin-syntax-import-attributes": "^7.24.7",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5",
+ "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
+ "@babel/plugin-transform-arrow-functions": "^7.24.7",
+ "@babel/plugin-transform-async-generator-functions": "^7.25.4",
+ "@babel/plugin-transform-async-to-generator": "^7.24.7",
+ "@babel/plugin-transform-block-scoped-functions": "^7.24.7",
+ "@babel/plugin-transform-block-scoping": "^7.25.0",
+ "@babel/plugin-transform-class-properties": "^7.25.4",
+ "@babel/plugin-transform-class-static-block": "^7.24.7",
+ "@babel/plugin-transform-classes": "^7.25.4",
+ "@babel/plugin-transform-computed-properties": "^7.24.7",
+ "@babel/plugin-transform-destructuring": "^7.24.8",
+ "@babel/plugin-transform-dotall-regex": "^7.24.7",
+ "@babel/plugin-transform-duplicate-keys": "^7.24.7",
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0",
+ "@babel/plugin-transform-dynamic-import": "^7.24.7",
+ "@babel/plugin-transform-exponentiation-operator": "^7.24.7",
+ "@babel/plugin-transform-export-namespace-from": "^7.24.7",
+ "@babel/plugin-transform-for-of": "^7.24.7",
+ "@babel/plugin-transform-function-name": "^7.25.1",
+ "@babel/plugin-transform-json-strings": "^7.24.7",
+ "@babel/plugin-transform-literals": "^7.25.2",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
+ "@babel/plugin-transform-member-expression-literals": "^7.24.7",
+ "@babel/plugin-transform-modules-amd": "^7.24.7",
+ "@babel/plugin-transform-modules-commonjs": "^7.24.8",
+ "@babel/plugin-transform-modules-systemjs": "^7.25.0",
+ "@babel/plugin-transform-modules-umd": "^7.24.7",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
+ "@babel/plugin-transform-new-target": "^7.24.7",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
+ "@babel/plugin-transform-numeric-separator": "^7.24.7",
+ "@babel/plugin-transform-object-rest-spread": "^7.24.7",
+ "@babel/plugin-transform-object-super": "^7.24.7",
+ "@babel/plugin-transform-optional-catch-binding": "^7.24.7",
+ "@babel/plugin-transform-optional-chaining": "^7.24.8",
+ "@babel/plugin-transform-parameters": "^7.24.7",
+ "@babel/plugin-transform-private-methods": "^7.25.4",
+ "@babel/plugin-transform-private-property-in-object": "^7.24.7",
+ "@babel/plugin-transform-property-literals": "^7.24.7",
+ "@babel/plugin-transform-regenerator": "^7.24.7",
+ "@babel/plugin-transform-reserved-words": "^7.24.7",
+ "@babel/plugin-transform-shorthand-properties": "^7.24.7",
+ "@babel/plugin-transform-spread": "^7.24.7",
+ "@babel/plugin-transform-sticky-regex": "^7.24.7",
+ "@babel/plugin-transform-template-literals": "^7.24.7",
+ "@babel/plugin-transform-typeof-symbol": "^7.24.8",
+ "@babel/plugin-transform-unicode-escapes": "^7.24.7",
+ "@babel/plugin-transform-unicode-property-regex": "^7.24.7",
+ "@babel/plugin-transform-unicode-regex": "^7.24.7",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.25.4",
+ "@babel/preset-modules": "0.1.6-no-external-plugins",
+ "babel-plugin-polyfill-corejs2": "^0.4.10",
+ "babel-plugin-polyfill-corejs3": "^0.10.6",
+ "babel-plugin-polyfill-regenerator": "^0.6.1",
+ "core-js-compat": "^3.37.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-modules": {
+ "version": "0.1.6-no-external-plugins",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
+ "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/@babel/regjsgen": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz",
+ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==",
+ "license": "MIT"
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
+ "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
+ "license": "MIT",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
+ "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.24.7",
+ "@babel/parser": "^7.25.0",
+ "@babel/types": "^7.25.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
+ "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.24.7",
+ "@babel/generator": "^7.25.6",
+ "@babel/parser": "^7.25.6",
+ "@babel/template": "^7.25.0",
+ "@babel/types": "^7.25.6",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
+ "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.24.8",
+ "@babel/helper-validator-identifier": "^7.24.7",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "license": "MIT"
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "license": "MIT"
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+ "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/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/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@rollup/plugin-babel": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz",
+ "integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.18.6",
+ "@rollup/pluginutils": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0",
+ "@types/babel__core": "^7.1.9",
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/babel__core": {
+ "optional": true
+ },
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-commonjs": {
+ "version": "28.0.0",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.0.tgz",
+ "integrity": "sha512-BJcu+a+Mpq476DMXG+hevgPSl56bkUoi88dKT8t3RyUp8kGuOh+2bU8Gs7zXDlu+fyZggnJ+iOBGrb/O1SorYg==",
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "commondir": "^1.0.1",
+ "estree-walker": "^2.0.2",
+ "fdir": "^6.1.1",
+ "is-reference": "1.2.1",
+ "magic-string": "^0.30.3",
+ "picomatch": "^2.3.1"
+ },
+ "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-commonjs/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/@rollup/plugin-node-resolve": {
+ "version": "15.3.0",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz",
+ "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==",
+ "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.2",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz",
+ "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "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/@rollup/pluginutils/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz",
+ "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz",
+ "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz",
+ "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz",
+ "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz",
+ "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz",
+ "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz",
+ "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz",
+ "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz",
+ "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz",
+ "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz",
+ "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz",
+ "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz",
+ "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz",
+ "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz",
+ "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz",
+ "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@types/chai": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.0.0.tgz",
+ "integrity": "sha512-+DwhEHAaFPPdJ2ral3kNHFQXnTfscEEFsUxzD+d7nlcLrFK23JtNjH71RGasTcHb88b4vVi4mTyfpf8u2L8bdA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "license": "MIT"
+ },
+ "node_modules/@types/mocha": {
+ "version": "10.0.8",
+ "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.8.tgz",
+ "integrity": "sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/anymatch/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/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2": {
+ "version": "0.4.11",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz",
+ "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.22.6",
+ "@babel/helper-define-polyfill-provider": "^0.6.2",
+ "semver": "^6.3.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.10.6",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz",
+ "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.2",
+ "core-js-compat": "^3.38.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-regenerator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz",
+ "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/browserslist": {
+ "version": "4.23.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
+ "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
+ "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",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001646",
+ "electron-to-chromium": "^1.5.4",
+ "node-releases": "^2.0.18",
+ "update-browserslist-db": "^1.1.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/c8": {
+ "version": "10.1.2",
+ "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.2.tgz",
+ "integrity": "sha512-Qr6rj76eSshu5CgRYvktW0uM0CFY0yi4Fd5D0duDXO6sYinyopmftUiJVuzBQxQcwQLor7JWDVRP+dUfCmzgJw==",
+ "license": "ISC",
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@istanbuljs/schema": "^0.1.3",
+ "find-up": "^5.0.0",
+ "foreground-child": "^3.1.1",
+ "istanbul-lib-coverage": "^3.2.0",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-reports": "^3.1.6",
+ "test-exclude": "^7.0.1",
+ "v8-to-istanbul": "^9.0.0",
+ "yargs": "^17.7.2",
+ "yargs-parser": "^21.1.1"
+ },
+ "bin": {
+ "c8": "bin/c8.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "monocart-coverage-reports": "^2"
+ },
+ "peerDependenciesMeta": {
+ "monocart-coverage-reports": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/c8/node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/c8/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/c8/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/c8/node_modules/test-exclude": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz",
+ "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==",
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^10.4.1",
+ "minimatch": "^9.0.4"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/c8/node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/c8/node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001663",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz",
+ "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==",
+ "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"
+ },
+ "node_modules/chai": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz",
+ "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.1.1",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.1.0",
+ "pathval": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/chai-as-promised": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-8.0.0.tgz",
+ "integrity": "sha512-sMsGXTrS3FunP/wbqh/KxM8Kj/aLPXQGkNtvE5wPfSToq8wkkvBpTZo1LIiEVmC4BwkKpag+l5h/20lBMk6nUg==",
+ "dev": true,
+ "license": "WTFPL",
+ "dependencies": {
+ "check-error": "^2.0.0"
+ },
+ "peerDependencies": {
+ "chai": ">= 2.1.2 < 6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/check-error": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
+ "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "license": "MIT"
+ },
+ "node_modules/core-js-compat": {
+ "version": "3.38.1",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz",
+ "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==",
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.23.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decamelize": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/deep-eql": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/diff": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
+ "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.27",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz",
+ "integrity": "sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw==",
+ "license": "ISC"
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "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",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/esm": {
+ "version": "3.2.25",
+ "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
+ "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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==",
+ "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",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz",
+ "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+ "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/foreground-child/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "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/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-func-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
+ "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "license": "MIT"
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
+ "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "license": "ISC"
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-report/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/istanbul-lib-report/node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/istanbul-lib-report/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-report/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/js-cleanup": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/js-cleanup/-/js-cleanup-1.2.0.tgz",
+ "integrity": "sha512-JeDD0yiiSt80fXzAVa/crrS0JDPQljyBG/RpOtaSbyDq03VHa9szJWMaWOYU/bcTn412uMN2MxApXq8v79cUiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "magic-string": "^0.25.7",
+ "perf-regexes": "^1.0.1",
+ "skip-regex": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10.14.2 || >=12.0.0"
+ }
+ },
+ "node_modules/js-cleanup/node_modules/magic-string": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+ "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+ "license": "MIT",
+ "dependencies": {
+ "sourcemap-codec": "^1.4.8"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+ "license": "MIT"
+ },
+ "node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-symbols/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/log-symbols/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/log-symbols/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/log-symbols/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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/log-symbols/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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/log-symbols/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/loupe": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz",
+ "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-func-name": "^2.0.1"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.11",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz",
+ "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/mocha": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz",
+ "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^4.1.3",
+ "browser-stdout": "^1.3.1",
+ "chokidar": "^3.5.3",
+ "debug": "^4.3.5",
+ "diff": "^5.2.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-up": "^5.0.0",
+ "glob": "^8.1.0",
+ "he": "^1.2.0",
+ "js-yaml": "^4.1.0",
+ "log-symbols": "^4.1.0",
+ "minimatch": "^5.1.6",
+ "ms": "^2.1.3",
+ "serialize-javascript": "^6.0.2",
+ "strip-json-comments": "^3.1.1",
+ "supports-color": "^8.1.1",
+ "workerpool": "^6.5.1",
+ "yargs": "^16.2.0",
+ "yargs-parser": "^20.2.9",
+ "yargs-unparser": "^2.0.0"
+ },
+ "bin": {
+ "_mocha": "bin/_mocha",
+ "mocha": "bin/mocha.js"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/mocha/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mocha/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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=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"
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
+ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
+ "license": "MIT"
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "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==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "license": "BlueOak-1.0.0"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "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/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "license": "ISC"
+ },
+ "node_modules/pathval": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
+ "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.16"
+ }
+ },
+ "node_modules/perf-regexes": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/perf-regexes/-/perf-regexes-1.0.1.tgz",
+ "integrity": "sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.14"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
+ "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
+ "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==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/readdirp/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/regenerate": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+ "license": "MIT"
+ },
+ "node_modules/regenerate-unicode-properties": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
+ "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
+ "license": "MIT",
+ "dependencies": {
+ "regenerate": "^1.4.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
+ "license": "MIT"
+ },
+ "node_modules/regenerator-transform": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
+ "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.8.4"
+ }
+ },
+ "node_modules/regexpu-core": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
+ "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/regjsgen": "^0.8.0",
+ "regenerate": "^1.4.2",
+ "regenerate-unicode-properties": "^10.1.0",
+ "regjsparser": "^0.9.1",
+ "unicode-match-property-ecmascript": "^2.0.0",
+ "unicode-match-property-value-ecmascript": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regjsparser": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
+ "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "jsesc": "~0.5.0"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/regjsparser/node_modules/jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.22.4",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz",
+ "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.5"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.22.4",
+ "@rollup/rollup-android-arm64": "4.22.4",
+ "@rollup/rollup-darwin-arm64": "4.22.4",
+ "@rollup/rollup-darwin-x64": "4.22.4",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.22.4",
+ "@rollup/rollup-linux-arm-musleabihf": "4.22.4",
+ "@rollup/rollup-linux-arm64-gnu": "4.22.4",
+ "@rollup/rollup-linux-arm64-musl": "4.22.4",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4",
+ "@rollup/rollup-linux-riscv64-gnu": "4.22.4",
+ "@rollup/rollup-linux-s390x-gnu": "4.22.4",
+ "@rollup/rollup-linux-x64-gnu": "4.22.4",
+ "@rollup/rollup-linux-x64-musl": "4.22.4",
+ "@rollup/rollup-win32-arm64-msvc": "4.22.4",
+ "@rollup/rollup-win32-ia32-msvc": "4.22.4",
+ "@rollup/rollup-win32-x64-msvc": "4.22.4",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rollup-plugin-cleanup": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-cleanup/-/rollup-plugin-cleanup-3.2.1.tgz",
+ "integrity": "sha512-zuv8EhoO3TpnrU8MX8W7YxSbO4gmOR0ny06Lm3nkFfq0IVKdBUtHwhVzY1OAJyNCIAdLiyPnOrU0KnO0Fri1GQ==",
+ "license": "MIT",
+ "dependencies": {
+ "js-cleanup": "^1.2.0",
+ "rollup-pluginutils": "^2.8.2"
+ },
+ "engines": {
+ "node": "^10.14.2 || >=12.0.0"
+ },
+ "peerDependencies": {
+ "rollup": ">=2.0"
+ }
+ },
+ "node_modules/rollup-pluginutils": {
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
+ "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
+ "license": "MIT",
+ "dependencies": {
+ "estree-walker": "^0.6.1"
+ }
+ },
+ "node_modules/rollup-pluginutils/node_modules/estree-walker": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
+ "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
+ "license": "MIT"
+ },
+ "node_modules/rollup/node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "license": "MIT"
+ },
+ "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==",
+ "dev": true,
+ "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/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/skip-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz",
+ "integrity": "sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.2"
+ }
+ },
+ "node_modules/sourcemap-codec": {
+ "version": "1.4.8",
+ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+ "deprecated": "Please use @jridgewell/sourcemap-codec instead",
+ "license": "MIT"
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/unicode-canonical-property-names-ecmascript": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
+ "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+ "license": "MIT",
+ "dependencies": {
+ "unicode-canonical-property-names-ecmascript": "^2.0.0",
+ "unicode-property-aliases-ecmascript": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-value-ecmascript": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
+ "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-property-aliases-ecmascript": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
+ "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
+ "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
+ "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",
+ "dependencies": {
+ "escalade": "^3.1.2",
+ "picocolors": "^1.0.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
+ "license": "ISC",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/workerpool": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz",
+ "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/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"
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/wrap-ansi/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"
+ },
+ "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==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "license": "ISC"
+ },
+ "node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-unparser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/common/package.json b/common/package.json
new file mode 100644
index 0000000..9ef203c
--- /dev/null
+++ b/common/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "logarithmplotter",
+ "version": "0.6.0",
+ "description": "2D plotter software to make Bode plots, sequences and distribution functions.",
+ "main": "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs",
+ "scripts": {
+ "build": "rollup --config rollup.config.mjs",
+ "test": "c8 mocha test/**/*.mjs"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://git.ad5001.eu/Ad5001/LogarithmPlotter"
+ },
+ "author": "Ad5001 ",
+ "license": "GPL-3.0-or-later",
+ "dependencies": {
+ "@babel/preset-env": "^7.25.4",
+ "@rollup/plugin-babel": "^6.0.4",
+ "@rollup/plugin-commonjs": "^28.0.0",
+ "@rollup/plugin-node-resolve": "^15.3.0",
+ "c8": "^10.1.2",
+ "rollup": "^4.22.4",
+ "rollup-plugin-cleanup": "^3.2.1"
+ },
+ "devDependencies": {
+ "@types/chai": "^5.0.0",
+ "@types/mocha": "^10.0.8",
+ "chai": "^5.1.1",
+ "chai-as-promised": "^8.0.0",
+ "esm": "^3.2.25",
+ "mocha": "^10.7.3"
+ }
+}
diff --git a/common/rollup.config.mjs b/common/rollup.config.mjs
new file mode 100644
index 0000000..6a18a41
--- /dev/null
+++ b/common/rollup.config.mjs
@@ -0,0 +1,44 @@
+/**
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import { nodeResolve } from "@rollup/plugin-node-resolve"
+import commonjs from "@rollup/plugin-commonjs"
+import { babel } from "@rollup/plugin-babel"
+import cleanup from "rollup-plugin-cleanup"
+
+const src = "./src/index.mjs"
+const dest = "../build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/index.mjs"
+
+export default {
+ input: src,
+ output: {
+ file: dest,
+ compact: false,
+ sourcemap: true,
+ format: "es"
+ },
+ plugins: [
+ nodeResolve({ browser: true }),
+ commonjs(),
+ cleanup({ comments: 'some' }),
+ babel({
+ babelHelpers: "bundled"
+ }),
+ ]
+}
+
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs b/common/src/history/color.mjs
similarity index 71%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs
rename to common/src/history/color.mjs
index 067da0c..1d395ed 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs
+++ b/common/src/history/color.mjs
@@ -1,56 +1,61 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-import EditedProperty from "editproperty.mjs"
+import EditedProperty from "./editproperty.mjs"
import Objects from "../module/objects.mjs"
export default class ColorChanged extends EditedProperty {
// Action used everytime when an object's color is changed
- type(){return 'ColorChanged'}
-
- icon(){return 'appearance'}
-
-
+ type() {
+ return "ColorChanged"
+ }
+
+ icon() {
+ return "appearance"
+ }
+
constructor(targetName = "", targetType = "Point", oldColor = "black", newColor = "white") {
super(targetName, targetType, "color", oldColor, newColor)
}
-
+
export() {
return [this.targetName, this.targetType, this.previousValue, this.newValue]
}
-
- color(darkVer=false){return darkVer ? 'purple' : 'plum'}
-
+
+ color(darkVer = false) {
+ return darkVer ? "purple" : "plum"
+ }
+
getReadableString() {
return qsTranslate("color", "%1 %2's color changed from %3 to %4.")
- .arg(Objects.types[this.targetType].displayType()).arg(this.targetName)
- .arg(this.previousValue).arg(this.newValue)
+ .arg(Objects.types[this.targetType].displayType()).arg(this.targetName)
+ .arg(this.previousValue).arg(this.newValue)
}
-
+
formatColor(color) {
return `██`
}
-
+
getHTMLString() {
return qsTranslate("color", "%1 %2's color changed from %3 to %4.")
- .arg(Objects.types[this.targetType].displayType())
- .arg(' ' + this.targetName + " ")
- .arg(this.formatColor(this.previousValue)).arg(this.formatColor(this.newValue))
+ .arg(Objects.types[this.targetType].displayType())
+ .arg(" " + this.targetName + " ")
+ .arg(this.formatColor(this.previousValue)).arg(this.formatColor(this.newValue))
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/common/src/history/common.mjs
similarity index 71%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs
rename to common/src/history/common.mjs
index 41d28ce..33f9118 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs
+++ b/common/src/history/common.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -22,88 +22,90 @@ import Latex from "../module/latex.mjs"
export class Action {
/**
* Type of the action.
- *
+ *
* @returns {string}
*/
- type(){return 'Unknown'}
-
+ type() {
+ return "Unknown"
+ }
+
/**
* Icon associated with the action.
- *
+ *
* @returns {string}
*/
- icon(){return 'position'}
-
+ icon() {
+ return "position"
+ }
+
// TargetName is the name of the object that's targeted by the event.
constructor(targetName = "", targetType = "Point") {
this.targetName = targetName
this.targetType = targetType
}
-
+
/**
* Undoes the action.
*/
- undo() {}
-
+ undo() {
+ }
+
/**
* Redoes the action.
*/
- redo() {}
-
+ redo() {
+ }
+
/**
* Export the action to a serializable format.
* NOTE: These arguments will be reinputed in the constructor in this order.
- *
+ *
* @returns {string[]}
*/
export() {
return [this.targetName, this.targetType]
}
-
+
/**
- * Returns a string with the human readable description of the action.
- *
+ * Returns a string with the human-readable description of the action.
+ *
* @returns {string}
*/
getReadableString() {
- return 'Unknown action'
+ return "Unknown action"
}
-
+
/**
* Returns a string containing an HTML tag describing the icon of a type
- *
+ *
* @param {string} type - Name of the icon to put in rich text.
* @returns {string}
*/
getIconRichText(type) {
- return ``
+ return ``
}
-
+
/**
* Renders a LaTeX-formatted string to an image and wraps it in an HTML tag in a string.
- *
+ *
* @param {string} latexString - Source string of the latex.
* @returns {Promise}
*/
- renderLatexAsHtml(latexString) {
+ async renderLatexAsHtml(latexString) {
if(!Latex.enabled)
throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.")
- return new Promise(resolve => {
- let imgDepth = History.imageDepth
- Latex.requestAsyncRender(
- latexString,
- imgDepth * (History.fontSize + 2),
- History.themeTextColor
- ).then((imgData) => {
- const { source, width, height } = imgData
- resolve(``)
- })
- })
+ const imgDepth = History.imageDepth
+ const { source, width, height } = await Latex.requestAsyncRender(
+ latexString,
+ imgDepth * (History.fontSize + 2),
+ History.themeTextColor
+ )
+ return ``
}
-
+
/**
* Returns a string with the HTML-formatted description of the action.
- *
+ *
* @returns {string|Promise}
*/
getHTMLString() {
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs b/common/src/history/create.mjs
similarity index 79%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs
rename to common/src/history/create.mjs
index bd3dafd..1308d9e 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs
+++ b/common/src/history/create.mjs
@@ -1,61 +1,69 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import Objects from "../module/objects.mjs"
-import { Action } from "common.mjs"
+import { Action } from "./common.mjs"
+/**
+ * Action used for the creation of an object.
+ */
export default class CreateNewObject extends Action {
- // Action used for the creation of an object
- type(){return 'CreateNewObject'}
-
- icon(){return 'create'}
-
- color(darkVer=false){return darkVer ? 'green' : 'lime'}
-
+ type() {
+ return "CreateNewObject"
+ }
+
+ icon() {
+ return "create"
+ }
+
+ color(darkVer = false) {
+ return darkVer ? "green" : "lime"
+ }
+
constructor(targetName = "", targetType = "Point", properties = []) {
super(targetName, targetType)
this.targetProperties = properties
}
-
+
undo() {
Objects.deleteObject(this.targetName)
}
-
+
redo() {
Objects.createNewRegisteredObject(this.targetType, this.targetProperties)
Objects.currentObjectsByName[this.targetName].update()
}
-
+
export() {
return [this.targetName, this.targetType, this.targetProperties]
}
-
+
getReadableString() {
return qsTranslate("create", "New %1 %2 created.")
.arg(Objects.types[this.targetType].displayType())
.arg(this.targetName)
}
-
+
getHTMLString() {
return qsTranslate("create", "New %1 %2 created.")
- .arg(Objects.types[this.targetType].displayType())
- .arg('' + this.targetName + "")
+ .arg(Objects.types[this.targetType].displayType())
+ .arg("" + this.targetName + "")
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs b/common/src/history/delete.mjs
similarity index 89%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs
rename to common/src/history/delete.mjs
index c348c41..f9674c5 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs
+++ b/common/src/history/delete.mjs
@@ -17,13 +17,13 @@
*/
import Objects from "../module/objects.mjs"
-import CreateNewObject from "create.mjs"
+import CreateNewObject from "./create.mjs"
+/**
+ * Action used at the deletion of an object. Basically the same thing as creating a new object, except Redo & Undo are reversed.
+ */
export default class DeleteObject extends CreateNewObject {
- /**
- * Action used at the deletion of an object. Basically the same thing as creating a new object, except Redo & Undo are reversed.
- */
type(){return 'DeleteObject'}
icon(){return 'delete'}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs b/common/src/history/editproperty.mjs
similarity index 72%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs
rename to common/src/history/editproperty.mjs
index de84449..886f100 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs
+++ b/common/src/history/editproperty.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -19,17 +19,23 @@
import Objects from "../module/objects.mjs"
import Latex from "../module/latex.mjs"
import * as MathLib from "../math/index.mjs"
-import { Action } from "common.mjs"
+import { Action } from "./common.mjs"
import { DrawableObject } from "../objs/common.mjs"
+/**
+ * Action used everytime an object's property has been changed.
+ */
export default class EditedProperty extends Action {
- // Action used everytime an object's property has been changed
- type(){return 'EditedProperty'}
-
- icon(){return 'modify'}
-
- color(darkVer=false){
- return darkVer ? 'darkslateblue' : 'cyan';
+ type() {
+ return "EditedProperty"
+ }
+
+ icon() {
+ return "modify"
+ }
+
+ color(darkVer = false) {
+ return darkVer ? "darkslateblue" : "cyan"
}
/**
@@ -49,12 +55,12 @@ export default class EditedProperty extends Action {
this.newValue = newValue
this.propertyType = Objects.types[targetType].properties()[targetProperty]
if(valueIsExpressionNeedingImport) {
- if(typeof this.propertyType == 'object' && this.propertyType.type === "Expression") {
- this.previousValue = new MathLib.Expression(this.previousValue);
- this.newValue = new MathLib.Expression(this.newValue);
+ if(typeof this.propertyType == "object" && this.propertyType.type === "Expression") {
+ this.previousValue = new MathLib.Expression(this.previousValue)
+ this.newValue = new MathLib.Expression(this.newValue)
} else if(this.propertyType === "Domain") {
- this.previousValue = MathLib.parseDomain(this.previousValue);
- this.newValue = MathLib.parseDomain(this.newValue);
+ this.previousValue = MathLib.parseDomain(this.previousValue)
+ this.newValue = MathLib.parseDomain(this.newValue)
} else {
// Objects
this.previousValue = Objects.currentObjectsByName[this.previousValue] // Objects.getObjectByName(this.previousValue);
@@ -63,17 +69,17 @@ export default class EditedProperty extends Action {
}
this.setReadableValues()
}
-
+
undo() {
Objects.currentObjectsByName[this.targetName][this.targetProperty] = this.previousValue
Objects.currentObjectsByName[this.targetName].update()
}
-
+
redo() {
Objects.currentObjectsByName[this.targetName][this.targetProperty] = this.newValue
Objects.currentObjectsByName[this.targetName].update()
}
-
+
export() {
if(this.previousValue instanceof MathLib.Expression) {
return [this.targetName, this.targetType, this.targetProperty, this.previousValue.toEditableString(), this.newValue.toEditableString(), true]
@@ -83,7 +89,7 @@ export default class EditedProperty extends Action {
return [this.targetName, this.targetType, this.targetProperty, this.previousValue, this.newValue, false]
}
}
-
+
setReadableValues() {
this.prevString = ""
this.nextString = ""
@@ -93,67 +99,61 @@ export default class EditedProperty extends Action {
case "Enum":
this.prevString = this.propertyType.translatedValues[this.propertyType.values.indexOf(this.previousValue)]
this.nextString = this.propertyType.translatedValues[this.propertyType.values.indexOf(this.newValue)]
- break;
+ break
case "ObjectType":
this.prevString = this.previousValue == null ? "null" : this.previousValue.name
this.nextString = this.newValue == null ? "null" : this.newValue.name
- break;
+ break
case "List":
this.prevString = this.previousValue.join(",")
this.nextString = this.newValue.name.join(",")
- break;
+ break
case "Dict":
this.prevString = JSON.stringify(this.previousValue)
this.nextString = JSON.stringify(this.newValue)
- break;
+ break
case "Expression":
this.prevString = this.previousValue == null ? "null" : this.previousValue.toString()
this.nextString = this.newValue == null ? "null" : this.newValue.toString()
- break;
+ break
}
} else {
this.prevString = this.previousValue == null ? "null" : this.previousValue.toString()
this.nextString = this.newValue == null ? "null" : this.newValue.toString()
}
// HTML
- this.prevHTML = ' '+this.prevString+' '
- this.nextHTML = ' '+this.nextString+' '
- if(Latex.enabled && typeof this.propertyType == 'object' && this.propertyType.type === "Expression") {
+ this.prevHTML = " " + this.prevString + " "
+ this.nextHTML = " " + this.nextString + " "
+ if(Latex.enabled && typeof this.propertyType == "object" && this.propertyType.type === "Expression") {
// Store promises so that querying can wait for them to finish.
this._renderPromises = [
this.renderLatexAsHtml(this.previousValue.latexMarkup).then(prev => this.prevHTML = prev),
- this.renderLatexAsHtml(this.newValue.latexMarkup).then(next => this.nextHTML = prev)
+ this.renderLatexAsHtml(this.newValue.latexMarkup).then(next => this.nextHTML = next)
]
}
}
-
+
getReadableString() {
- return qsTranslate("editproperty", '%1 of %2 %3 changed from "%4" to "%5".')
- .arg(this.targetPropertyReadable)
- .arg(Objects.types[this.targetType].displayType())
- .arg(this.targetName).arg(this.prevString).arg(this.nextString)
+ return qsTranslate("editproperty", "%1 of %2 %3 changed from \"%4\" to \"%5\".")
+ .arg(this.targetPropertyReadable)
+ .arg(Objects.types[this.targetType].displayType())
+ .arg(this.targetName).arg(this.prevString).arg(this.nextString)
}
/**
*
* @return {Promise|string}
*/
- getHTMLString() {
- return new Promise(resolve => {
- const translation = qsTranslate("editproperty", '%1 of %2 changed from %3 to %4.')
- .arg(this.targetPropertyReadable)
- .arg(' ' + this.targetName + ' ')
- // Check if we need to wait for LaTeX HTML to be rendered.
- if(this.prevHTML !== undefined && this.nextHTML !== undefined)
- resolve(translation.arg(this.prevHTML).arg(this.nextHTML))
- else
- Promise.all(this._renderPromises).then((rendered) => {
- // Rendered are (potentially) two HTML strings which are defined during rendering
- this.prevHTML = this.prevHTML ?? rendered[0]
- this.nextHTML = this.prevHTML ?? rendered[1]
- resolve(translation.arg(this.prevHTML).arg(this.nextHTML))
- })
- })
-
+ async getHTMLString() {
+ const translation = qsTranslate("editproperty", "%1 of %2 changed from %3 to %4.")
+ .arg(this.targetPropertyReadable)
+ .arg(" " + this.targetName + " ")
+ // Check if we need to wait for LaTeX HTML to be rendered.
+ if(this.prevHTML === undefined || this.nextHTML === undefined) {
+ const [prevHTML, nextHTML] = await Promise.all(this._renderPromises)
+ this.prevHTML = this.prevHTML ?? prevHTML
+ this.nextHTML = this.nextHTML ?? nextHTML
+ }
+ return translation.arg(this.prevHTML).arg(this.nextHTML)
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/index.mjs b/common/src/history/index.mjs
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/index.mjs
rename to common/src/history/index.mjs
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs b/common/src/history/name.mjs
similarity index 94%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs
rename to common/src/history/name.mjs
index a852923..5c5b397 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs
+++ b/common/src/history/name.mjs
@@ -16,12 +16,13 @@
* along with this program. If not, see .
*/
-import EditedProperty from "editproperty.mjs"
+import EditedProperty from "./editproperty.mjs"
import Objects from "../module/objects.mjs"
-
+/**
+ * Action used everytime an object's name has been changed.
+ */
export default class NameChanged extends EditedProperty {
- // Action used everytime an object's property has been changed
type(){return 'NameChanged'}
icon(){return 'name'}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs b/common/src/history/position.mjs
similarity index 53%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs
rename to common/src/history/position.mjs
index c568615..4c1af60 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs
+++ b/common/src/history/position.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -20,44 +20,49 @@ import Objects from "../module/objects.mjs"
import Latex from "../module/latex.mjs"
import * as MathLib from "../math/index.mjs"
import { escapeHTML } from "../utils.mjs"
-import { Action } from "common.mjs"
-import { DrawableObject } from "../objs/common.mjs"
+import { Action } from "./common.mjs"
+/**
+ * Action used for objects that have a X and Y expression properties (points, texts...)
+ */
export default class EditedPosition extends Action {
- // Action used for objects that have a X and Y expression properties (points, texts...)
- type(){return 'EditedPosition'}
-
- icon(){return 'position'}
-
- color(darkVer=false){
- return darkVer ? 'seagreen' : 'lightseagreen';
+ type() {
+ return "EditedPosition"
}
-
+
+ icon() {
+ return "position"
+ }
+
+ color(darkVer = false) {
+ return darkVer ? "seagreen" : "lightseagreen"
+ }
+
constructor(targetName = "", targetType = "Point", previousXValue = "", newXValue = "", previousYValue = "", newYValue = "") {
- super(targetName, targetType)
+ super(targetName, targetType)
let imports = {
- 'previousXValue': previousXValue,
- 'previousYValue': previousYValue,
- 'newXValue': newXValue,
- 'newYValue': newYValue
+ "previousXValue": previousXValue,
+ "previousYValue": previousYValue,
+ "newXValue": newXValue,
+ "newYValue": newYValue
}
for(let name in imports)
- this[name] = (typeof imports[name]) == 'string' ? new MathLib.Expression(imports[name]) : imports[name]
+ this[name] = (typeof imports[name]) == "string" ? new MathLib.Expression(imports[name]) : imports[name]
this.setReadableValues()
}
-
+
undo() {
Objects.currentObjectsByName[this.targetName].x = this.previousXValue
Objects.currentObjectsByName[this.targetName].y = this.previousYValue
Objects.currentObjectsByName[this.targetName].update()
}
-
+
redo() {
Objects.currentObjectsByName[this.targetName].x = this.newXValue
Objects.currentObjectsByName[this.targetName].y = this.newYValue
Objects.currentObjectsByName[this.targetName].update()
}
-
+
setReadableValues() {
this.prevString = `(${this.previousXValue.toString()},${this.previousYValue.toString()})`
this.nextString = `(${this.newXValue.toString()},${this.newYValue.toString()})`
@@ -71,39 +76,34 @@ export default class EditedPosition extends Action {
this.renderLatexAsHtml(nextMarkup)
]
} else {
- this.prevHTML = ' '+escapeHTML(this.prevString)+' '
- this.nextHTML = ' '+escapeHTML(this.nextString)+' '
+ this.prevHTML = " " + escapeHTML(this.prevString) + " "
+ this.nextHTML = " " + escapeHTML(this.nextString) + " "
}
-
+
}
-
+
export() {
return [this.targetName, this.targetType,
- this.previousXValue.toEditableString(), this.newXValue.toEditableString(),
- this.previousYValue.toEditableString(), this.newYValue.toEditableString()]
+ this.previousXValue.toEditableString(), this.newXValue.toEditableString(),
+ this.previousYValue.toEditableString(), this.newYValue.toEditableString()]
}
-
+
getReadableString() {
- return qsTranslate("position", 'Position of %1 %2 set from "%3" to "%4".')
- .arg(Objects.types[this.targetType].displayType())
- .arg(this.targetName).arg(this.prevString).arg(this.nextString)
+ return qsTranslate("position", "Position of %1 %2 set from \"%3\" to \"%4\".")
+ .arg(Objects.types[this.targetType].displayType())
+ .arg(this.targetName).arg(this.prevString).arg(this.nextString)
}
-
- getHTMLString() {
- return new Promise(resolve => {
- const translation = qsTranslate("position", 'Position of %1 set from %2 to %3.')
- .arg(' ' + this.targetName + ' ')
- // Check if we need to wait for LaTeX HTML to be rendered.
- if(this.prevHTML !== undefined && this.nextHTML !== undefined)
- resolve(translation.arg(this.prevHTML).arg(this.nextHTML))
- else
- Promise.all(this._renderPromises).then((rendered) => {
- // Rendered are (potentially) two HTML strings which are defined during rendering
- this.prevHTML = this.prevHTML ?? rendered[0]
- this.nextHTML = this.nextHTML ?? rendered[1]
- resolve(translation.arg(this.prevHTML).arg(this.nextHTML))
- })
- })
-
+
+ async getHTMLString() {
+ const translation = qsTranslate("position", "Position of %1 set from %2 to %3.")
+ .arg(" " + this.targetName + " ")
+ // Check if we need to wait for LaTeX HTML to be rendered.
+ if(this.prevHTML === undefined || this.nextHTML === undefined) {
+ const [prevHTML, nextHTML] = await Promise.all(this._renderPromises)
+ this.prevHTML = this.prevHTML ?? prevHTML
+ this.nextHTML = this.nextHTML ?? nextHTML
+ }
+ return translation.arg(this.prevHTML).arg(this.nextHTML)
+
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs b/common/src/history/visibility.mjs
similarity index 67%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs
rename to common/src/history/visibility.mjs
index c04e0a4..e911c1b 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs
+++ b/common/src/history/visibility.mjs
@@ -1,55 +1,61 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-import EditedProperty from "editproperty.mjs"
+import EditedProperty from "./editproperty.mjs"
import Objects from "../module/objects.mjs"
+/**
+ * Action used when an object's shown or hidden.
+ */
export default class EditedVisibility extends EditedProperty {
- // Action used when an object's shown or hidden.
- type(){return 'EditedVisibility'}
-
- icon(){return 'visibility'}
-
- color(darkVer=false){
- return this.newValue ?
- (darkVer ? 'darkgray' : 'whitesmoke') :
- (darkVer ? 'dimgray' : 'lightgray')
+ type() {
+ return "EditedVisibility"
}
-
+
+ icon() {
+ return "visibility"
+ }
+
+ color(darkVer = false) {
+ return this.newValue ?
+ (darkVer ? "darkgray" : "whitesmoke") :
+ (darkVer ? "dimgray" : "lightgray")
+ }
+
constructor(targetName = "", targetType = "Point", newValue = true) {
super(targetName, targetType, "visible", !newValue, newValue)
}
-
+
export() {
return [this.targetName, this.targetType, this.newValue]
}
-
+
getReadableString() {
- return (this.newValue ? qsTranslate('visibility', '%1 %2 shown.') : qsTranslate('visibility', '%1 %2 hidden.'))
+ return (this.newValue ? qsTranslate("visibility", "%1 %2 shown.") : qsTranslate("visibility", "%1 %2 hidden."))
.arg(Objects.types[this.targetType].displayType())
.arg(this.targetName)
}
-
+
getHTMLString() {
- return (this.newValue ? qsTranslate('visibility', '%1 %2 shown.') : qsTranslate('visibility', '%1 %2 hidden.'))
+ return (this.newValue ? qsTranslate("visibility", "%1 %2 shown.") : qsTranslate("visibility", "%1 %2 hidden."))
.arg(Objects.types[this.targetType].displayType())
- .arg('' + this.targetName + "")
+ .arg("" + this.targetName + "")
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs b/common/src/index.mjs
similarity index 69%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs
rename to common/src/index.mjs
index 085a5c5..c19e2fe 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.mjs
+++ b/common/src/index.mjs
@@ -1,27 +1,27 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-// Loading modules in order
-import * as Objects from "./module/objects.mjs"
-import * as ExprParser from "./module/expreval.mjs"
+import js from "./lib/polyfills/js.mjs"
+
+import * as Modules from "./module/index.mjs"
import * as ObjsAutoload from "./objs/autoload.mjs"
-import * as Latex from "./module/latex.mjs"
-import * as History from "./module/history.mjs"
-import * as CanvasAPI from "./module/canvas.mjs"
-import * as IOAPI from "./module/io.mjs"
-import * as PreferencesAPI from "./module/preferences.mjs"
+
+export * as MathLib from "./math/index.mjs"
+export * as HistoryLib from "./history/index.mjs"
+export * as Parsing from "./parsing/index.mjs"
+export * as Utils from "./utils.mjs"
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs b/common/src/lib/expr-eval/expression.mjs
similarity index 99%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs
rename to common/src/lib/expr-eval/expression.mjs
index 57b4e0e..89831c7 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expression.mjs
+++ b/common/src/lib/expr-eval/expression.mjs
@@ -482,7 +482,7 @@ export class ExprEvalExpression {
/**
* Calculates the value of the expression by giving all variables and their corresponding values.
- * @param {Object} values
+ * @param {Object} values
* @returns {number}
*/
evaluate(values) {
@@ -512,8 +512,7 @@ export class ExprEvalExpression {
* as constants or functions.
* @returns {string[]}
*/
- variables(options) {
- options = options || {}
+ variables(options = {}) {
const vars = []
getSymbols(this.tokens, vars, options)
const functions = this.functions
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/instruction.mjs b/common/src/lib/expr-eval/instruction.mjs
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/instruction.mjs
rename to common/src/lib/expr-eval/instruction.mjs
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs b/common/src/lib/expr-eval/parser.mjs
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parser.mjs
rename to common/src/lib/expr-eval/parser.mjs
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parserstate.mjs b/common/src/lib/expr-eval/parserstate.mjs
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/parserstate.mjs
rename to common/src/lib/expr-eval/parserstate.mjs
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/polyfill.mjs b/common/src/lib/expr-eval/polyfill.mjs
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/polyfill.mjs
rename to common/src/lib/expr-eval/polyfill.mjs
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/tokens.mjs b/common/src/lib/expr-eval/tokens.mjs
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/tokens.mjs
rename to common/src/lib/expr-eval/tokens.mjs
diff --git a/common/src/lib/polyfills/js.mjs b/common/src/lib/polyfills/js.mjs
new file mode 100644
index 0000000..43ed375
--- /dev/null
+++ b/common/src/lib/polyfills/js.mjs
@@ -0,0 +1,126 @@
+/**
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+// JS polyfills to add because they're not implemented in the QML Scripting engine.
+// CoreJS does not work well with it (as well as doubles the compiled size), so this is preferable.
+function notPolyfilled(name) {
+ return function() { throw new Error(`${name} not polyfilled`) }
+}
+
+/**
+ * @param {number} depth
+ * @this {Array}
+ * @returns {Array}
+ */
+function arrayFlat(depth = 1) {
+ const newArray = []
+ for(const element of this) {
+ if(element instanceof Array)
+ newArray.push(...(depth > 1 ? element.flat(depth - 1) : element))
+ else
+ newArray.push(element)
+ }
+ return newArray
+}
+
+/**
+ * @param {function(any, number, Array): any} callbackFn
+ * @param {object} thisArg
+ * @this {Array}
+ * @returns {Array}
+ */
+function arrayFlatMap(callbackFn, thisArg) {
+ const newArray = []
+ for(let i = 0; i < this.length; i++) {
+ const value = callbackFn.call(thisArg ?? this, this[i], i, this)
+ if(value instanceof Array)
+ newArray.push(...value)
+ else
+ newArray.push(value)
+ }
+ return newArray
+}
+
+/**
+ * Replaces all instances of from by to.
+ * @param {string} from
+ * @param {string} to
+ * @this {string}
+ * @return {String}
+ */
+function stringReplaceAll(from, to) {
+ let str = this
+ while(str.includes(from))
+ str = str.replace(from, to)
+ return str
+}
+
+
+const polyfills = {
+ 2017: [
+ [Object, "entries", notPolyfilled("Object.entries")],
+ [Object, "values", notPolyfilled("Object.values")],
+ [Object, "getOwnPropertyDescriptors", notPolyfilled("Object.getOwnPropertyDescriptors")],
+ [String.prototype, "padStart", notPolyfilled("String.prototype.padStart")],
+ [String.prototype, "padEnd", notPolyfilled("String.prototype.padEnd")]
+ ],
+ 2018: [
+ [Promise.prototype, "finally", notPolyfilled("Object.entries")]
+ ],
+ 2019: [
+ [String.prototype, "trimStart", notPolyfilled("String.prototype.trimStart")],
+ [String.prototype, "trimEnd", notPolyfilled("String.prototype.trimEnd")],
+ [Object, "fromEntries", notPolyfilled("Object.fromEntries")],
+ [Array.prototype, "flat", arrayFlat],
+ [Array.prototype, "flatMap", arrayFlatMap]
+ ],
+ 2020: [
+ [String.prototype, "matchAll", notPolyfilled("String.prototype.matchAll")],
+ [Promise, "allSettled", notPolyfilled("Promise.allSettled")]
+ ],
+ 2021: [
+ [Promise, "any", notPolyfilled("Promise.any")],
+ [String.prototype, "replaceAll", stringReplaceAll]
+ ],
+ 2022: [
+ [Array.prototype, "at", notPolyfilled("Array.prototype.at")],
+ [String.prototype, "at", notPolyfilled("String.prototype.at")],
+ [Object, "hasOwn", notPolyfilled("Object.hasOwn")]
+ ],
+ 2023: [
+ [Array.prototype, "findLast", notPolyfilled("Array.prototype.findLast")],
+ [Array.prototype, "toReversed", notPolyfilled("Array.prototype.toReversed")],
+ [Array.prototype, "toSorted", notPolyfilled("Array.prototype.toSorted")],
+ [Array.prototype, "toSpliced", notPolyfilled("Array.prototype.toSpliced")],
+ [Array.prototype, "with", notPolyfilled("Array.prototype.with")]
+ ],
+ 2024: [
+ [Object, "groupBy", notPolyfilled("Object.groupBy")],
+ [Map, "groupBy", notPolyfilled("Map.groupBy")]
+ ]
+}
+
+// Fulfill polyfill.
+for(const [year, entries] of Object.entries(polyfills)) {
+ const defined = entries.filter(x => x[0][x[1]] !== undefined)
+ console.info(`ES${year} support: ${defined.length === entries.length} (${defined.length}/${entries.length})`)
+ // Apply polyfills
+ for(const [context, functionName, polyfill] of entries.filter(x => x[0][x[1]] === undefined)) {
+ context[functionName] = polyfill
+ }
+}
\ No newline at end of file
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs b/common/src/lib/polyfills/qt.mjs
similarity index 60%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs
rename to common/src/lib/polyfills/qt.mjs
index daefa6c..6559423 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs
+++ b/common/src/lib/polyfills/qt.mjs
@@ -18,6 +18,7 @@
// Type polyfills for IDEs.
// Never directly imported.
+// Might need to be reimplemented in other implemententations.
Modules = Modules || {}
/** @type {function(string, string): string} */
@@ -25,7 +26,7 @@ qsTranslate = qsTranslate || function(category, string) { throw new Error('qsTra
/** @type {function(string): string} */
qsTr = qsTr || function(string) { throw new Error('qsTr not implemented.'); }
/** @type {function(string, string): string} */
-QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(string, string) { throw new Error('QT_TRANSLATE_NOOP not implemented.'); }
+QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(category, string) { throw new Error('QT_TRANSLATE_NOOP not implemented.'); }
/** @type {function(string): string} */
QT_TR_NOOP = QT_TR_NOOP || function(string) { throw new Error('QT_TR_NOOP not implemented.'); }
/** @type {function(string|boolean|int): string} */
@@ -42,33 +43,4 @@ const Qt = {
rect: function(x, y, width, height) {
return {x: x, y: y, width: width, height: height};
}
-}
-
-/** Typehints for Helper. */
-const Helper = {
- /** @type {function(string): boolean} */
- getSettingBool: (setting) => true,
- /** @type {function(string): int} */
- getSettingInt: (setting) => 0,
- /** @type {function(string): string} */
- getSetting: (setting) => '',
- /** @type {function(string, boolean)} */
- setSettingBool: (setting, value) => {},
- /** @type {function(string, int)} */
- setSettingInt: (setting, value) => 0,
- /** @type {function(string, string)} */
- setSetting: (setting, value) => '',
- /** @type {function(string, string)} */
- write: (filename, data) => {},
- /** @type {function(string): string} */
- load: (filename) => '',
-}
-
-const Latex = {
- /** @type {function(string, number, string): string} */
- render: (latex_markup, font_size, color) => '',
- /** @type {function(string, number, string): string} */
- findPrerendered: (latex_markup, font_size, color) => '',
- /** @type {function(): boolean} */
- checkLatexInstallation: () => true,
-}
+}
\ No newline at end of file
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs b/common/src/math/domain.mjs
similarity index 79%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs
rename to common/src/math/domain.mjs
index 22b0154..48bf8ad 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs
+++ b/common/src/math/domain.mjs
@@ -1,57 +1,66 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-import { Expression, executeExpression } from "expression.mjs"
+import { Expression, executeExpression } from "./expression.mjs"
/**
* Main abstract domain class
* It doesn't represent any kind of domain and is meant to be extended.
*/
export class Domain {
- constructor() {}
-
+ constructor() {
+ }
+
/**
* Checks whether x is included in the domain.
* @param {number} x - The x value.
* @return {boolean} true if included, false otherwise.
*/
- includes(x) { return false }
-
+ includes(x) {
+ return false
+ }
+
/**
* Returns a string representation of the domain.
* @return {string} String representation of the domain.
*/
- toString() { return '???' }
-
+ toString() {
+ return "???"
+ }
+
/**
* Returns a new domain that is the union between this domain and another.
* @param {Domain} domain - Domain to unionise with this.
* @return {Domain} newly created domain.
*/
- union(domain) { return domain }
-
+ union(domain) {
+ return domain
+ }
+
/**
* Returns a new domain that is the intersection between this domain and another.
* @param {Domain} domain - Domain to get the interscection with this.
* @return {Domain} newly created domain.
*/
- intersection(domain) { return this }
-
+ intersection(domain) {
+ return this
+ }
+
/**
* Imports a domain from a string.
* @return {Domain} Found domain, string otherwise.
@@ -61,24 +70,20 @@ export class Domain {
case "R":
case "ℝ":
return Domain.R
- break;
case "RE":
case "R*":
case "ℝ*":
return Domain.RE
- break;
case "RP":
case "R+":
case "ℝ⁺":
case "ℝ+":
return Domain.RP
- break;
case "RM":
case "R-":
case "ℝ⁻":
case "ℝ-":
return Domain.RM
- break;
case "RPE":
case "REP":
case "R+*":
@@ -88,7 +93,6 @@ export class Domain {
case "ℝ*+":
case "ℝ+*":
return Domain.RPE
- break;
case "RME":
case "REM":
case "R-*":
@@ -98,7 +102,6 @@ export class Domain {
case "ℝ-*":
case "ℝ*-":
return Domain.RME
- break;
case "ℕ":
case "N":
case "ZP":
@@ -106,12 +109,10 @@ export class Domain {
case "ℤ⁺":
case "ℤ+":
return Domain.N
- break;
case "NLOG":
case "ℕˡᵒᵍ":
case "ℕLOG":
return Domain.NLog
- break;
case "NE":
case "NP":
case "N*":
@@ -128,17 +129,14 @@ export class Domain {
case "ℤ+*":
case "ℤ*+":
return Domain.NE
- break;
case "Z":
case "ℤ":
return Domain.Z
- break;
case "ZM":
case "Z-":
case "ℤ⁻":
case "ℤ-":
return Domain.ZM
- break;
case "ZME":
case "ZEM":
case "Z-*":
@@ -148,15 +146,12 @@ export class Domain {
case "ℤ-*":
case "ℤ*-":
return Domain.ZME
- break;
case "ZE":
case "Z*":
case "ℤ*":
return Domain.ZE
- break;
default:
- return new EmptySet()
- break;
+ return Domain.EmptySet
}
}
}
@@ -170,45 +165,57 @@ export class EmptySet extends Domain {
this.displayName = "∅"
this.latexMarkup = "\\emptyset"
}
-
- includes(x) { return false }
-
- toString() { return this.displayName }
-
- union(domain) { return domain }
-
- intersection(domain) { return this }
-
- static import(frm) { return new EmptySet() }
+
+ includes(x) {
+ return false
+ }
+
+ toString() {
+ return this.displayName
+ }
+
+ union(domain) {
+ return domain
+ }
+
+ intersection(domain) {
+ return this
+ }
+
+ static import(frm) {
+ return new EmptySet()
+ }
}
+Domain.EmptySet = new EmptySet() // To prevent use prior to declaration.
+
/**
* Domain classes for ranges (e.g ]0;3[, [1;2[ ...)
*/
export class Range extends Domain {
constructor(begin, end, openBegin, openEnd) {
super()
- if(typeof begin == 'number' || typeof begin == 'string') begin = new Expression(begin.toString())
+ if(typeof begin == "number" || typeof begin == "string") begin = new Expression(begin.toString())
this.begin = begin
- if(typeof end == 'number' || typeof end == 'string') end = new Expression(end.toString())
+ if(typeof end == "number" || typeof end == "string") end = new Expression(end.toString())
this.end = end
this.openBegin = openBegin
this.openEnd = openEnd
this.displayName = (openBegin ? "]" : "[") + begin.toString() + ";" + end.toString() + (openEnd ? "[" : "]")
this.latexMarkup = `\\mathopen${openBegin ? "]" : "["}${this.begin.latexMarkup};${this.end.latexMarkup}\\mathclose${openEnd ? "[" : "]"}`
}
-
+
includes(x) {
if(x instanceof Expression) x = x.execute()
- if(typeof x == 'string') x = executeExpression(x)
+ if(typeof x == "string") x = executeExpression(x)
return ((this.openBegin && x > this.begin.execute()) || (!this.openBegin && x >= this.begin.execute())) &&
((this.openEnd && x < this.end.execute()) || (!this.openEnd && x <= this.end.execute()))
}
-
+
toString() {
return this.displayName
}
-
+
union(domain) {
if(domain instanceof EmptySet) return this
if(domain instanceof DomainSet) return domain.union(this)
@@ -217,7 +224,7 @@ export class Range extends Domain {
if(domain instanceof MinusDomain) return new UnionDomain(this, domain)
if(domain instanceof Range) return new UnionDomain(this, domain)
}
-
+
intersection(domain) {
if(domain instanceof EmptySet) return domain
if(domain instanceof DomainSet) return domain.intersection(this)
@@ -226,11 +233,11 @@ export class Range extends Domain {
if(domain instanceof MinusDomain) return new IntersectionDomain(this, domain)
if(domain instanceof Range) return new IntersectionDomain(this, domain)
}
-
+
static import(frm) {
let openBegin = frm.trim().charAt(0) === "]"
- let openEnd = frm.trim().charAt(frm.length -1) === "["
- let [begin, end] = frm.substr(1, frm.length-2).split(";")
+ let openEnd = frm.trim().charAt(frm.length - 1) === "["
+ let [begin, end] = frm.substring(1, frm.length - 1).split(";")
return new Range(begin.trim(), end.trim(), openBegin, openEnd)
}
}
@@ -248,7 +255,7 @@ export class SpecialDomain extends Domain {
* @param {boolean} moveSupported - Only true if next and previous functions are valid.
*/
constructor(displayName, isValid, next = () => true, previous = () => true,
- moveSupported = true) {
+ moveSupported = true) {
super()
this.displayName = displayName
this.isValid = isValid
@@ -256,29 +263,29 @@ export class SpecialDomain extends Domain {
this.prevValue = previous
this.moveSupported = moveSupported
}
-
+
includes(x) {
if(x instanceof Expression) x = x.execute()
- if(typeof x == 'string') x = executeExpression(x)
+ if(typeof x == "string") x = executeExpression(x)
return this.isValid(x)
}
-
+
next(x) {
if(x instanceof Expression) x = x.execute()
- if(typeof x == 'string') x = executeExpression(x)
+ if(typeof x == "string") x = executeExpression(x)
return this.nextValue(x)
}
-
+
previous(x) {
if(x instanceof Expression) x = x.execute()
- if(typeof x == 'string') x = executeExpression(x)
+ if(typeof x == "string") x = executeExpression(x)
return this.prevValue(x)
}
-
+
toString() {
return this.displayName
}
-
+
union(domain) {
if(domain instanceof EmptySet) return this
if(domain instanceof DomainSet) return domain.union(this)
@@ -287,7 +294,7 @@ export class SpecialDomain extends Domain {
if(domain instanceof MinusDomain) return new UnionDomain(this, domain)
if(domain instanceof Range) return new UnionDomain(this, domain)
}
-
+
intersection(domain) {
if(domain instanceof EmptySet) return domain
if(domain instanceof DomainSet) return domain.intersection(this)
@@ -303,7 +310,7 @@ export class SpecialDomain extends Domain {
*/
export class DomainSet extends SpecialDomain {
constructor(values) {
- super('', x => true, x => x, true)
+ super("", () => true, x => x, true)
let newVals = {}
this.executedValues = []
for(let value of values) {
@@ -312,54 +319,54 @@ export class DomainSet extends SpecialDomain {
newVals[ex] = expr
this.executedValues.push(ex)
}
- this.executedValues.sort((a,b) => a-b)
+ this.executedValues.sort((a, b) => a - b)
this.values = this.executedValues.map(val => newVals[val])
this.displayName = "{" + this.values.join(";") + "}"
this.latexMarkup = `\\{${this.values.join(";")}\\}`
}
-
+
includes(x) {
if(x instanceof Expression) x = x.execute()
- if(typeof x == 'string') x = executeExpression(x)
+ if(typeof x == "string") x = executeExpression(x)
for(let value of this.values)
if(x === value.execute()) return true
return false
}
-
+
next(x) {
if(x instanceof Expression) x = x.execute()
- if(typeof x == 'string') x = executeExpression(x)
+ if(typeof x == "string") x = executeExpression(x)
if(x < this.executedValues[0]) return this.executedValues[0]
for(let i = 1; i < this.values.length; i++) {
- let prevValue = this.executedValues[i-1]
+ let prevValue = this.executedValues[i - 1]
let value = this.executedValues[i]
if(x >= prevValue && x < value) return value
}
return null
}
-
+
previous(x) {
if(x instanceof Expression) x = x.execute()
- if(typeof x == 'string') x = executeExpression(x)
- if(x > this.executedValues[this.executedValues.length-1])
- return this.executedValues[this.executedValues.length-1]
+ if(typeof x == "string") x = executeExpression(x)
+ if(x > this.executedValues[this.executedValues.length - 1])
+ return this.executedValues[this.executedValues.length - 1]
for(let i = 1; i < this.values.length; i++) {
- let prevValue = this.executedValues[i-1]
+ let prevValue = this.executedValues[i - 1]
let value = this.executedValues[i]
if(x > prevValue && x <= value) return prevValue
}
return null
}
-
+
toString() {
return this.displayName
}
-
+
union(domain) {
if(domain instanceof EmptySet) return this
if(domain instanceof DomainSet) {
let newValues = []
- let values = this.values.concat(domain.values).filter(function(val){
+ let values = this.values.concat(domain.values).filter(function(val) {
newValues.push(val.execute())
return newValues.indexOf(val.execute()) === newValues.length - 1
})
@@ -376,18 +383,18 @@ export class DomainSet extends SpecialDomain {
domain.openEnd = false
}
}
- if(!domain.includes(value))
+ if(!domain.includes(value))
notIncludedValues.push(this.values[i].toEditableString())
}
if(notIncludedValues.length === 0) return domain
return new UnionDomain(domain, new DomainSet(notIncludedValues))
}
-
+
intersection(domain) {
if(domain instanceof EmptySet) return domain
if(domain instanceof DomainSet) {
let domValues = domain.values.map(expr => expr.execute())
- this.values = this.values.filter(function(val){
+ this.values = this.values.filter(function(val) {
return domValues.indexOf(val.execute()) >= 0
})
return this
@@ -403,16 +410,16 @@ export class DomainSet extends SpecialDomain {
domain.openEnd = false
}
}
- if(domain.includes(value))
+ if(domain.includes(value))
includedValues.push(this.values[i].toEditableString())
}
if(includedValues.length === 0) return new EmptySet()
if(includedValues.length === this.values.length) return this
return new IntersectionDomain(domain, new DomainSet(includedValues))
}
-
+
static import(frm) {
- return new DomainSet(frm.substr(1, frm.length-2).split(";"))
+ return new DomainSet(frm.substring(1, frm.length - 1).split(";"))
}
}
@@ -427,15 +434,15 @@ export class UnionDomain extends Domain {
this.displayName = this.dom1.toString() + " ∪ " + this.dom2.toString()
this.latexMarkup = `${dom1.latexMarkup}\\cup${dom2.latexMarkup}`
}
-
+
includes(x) {
return this.dom1.includes(x) || this.dom2.includes(x)
}
-
+
toString() {
return this.displayName
}
-
+
union(domain) {
if(domain instanceof EmptySet) return this
if(domain instanceof DomainSet) return domain.union(this)
@@ -444,7 +451,7 @@ export class UnionDomain extends Domain {
if(domain instanceof IntersectionDomain) return new UnionDomain(this, domain)
if(domain instanceof MinusDomain) return new MinusDomain(this, domain)
}
-
+
intersection(domain) {
if(domain instanceof EmptySet) return domain
if(domain instanceof DomainSet) return domain.intersection(this)
@@ -452,12 +459,12 @@ export class UnionDomain extends Domain {
if(domain instanceof IntersectionDomain) return this.dom1.intersection(domain.dom1).intersection(this.dom2).intersection(domain.dom2)
if(domain instanceof MinusDomain) return new IntersectionDomain(this, domain)
}
-
+
static import(frm) {
let domains = frm.trim().split("∪")
if(domains.length === 1) domains = frm.trim().split("U") // Fallback
let dom2 = parseDomain(domains.pop())
- let dom1 = parseDomain(domains.join('∪'))
+ let dom1 = parseDomain(domains.join("∪"))
return dom1.union(dom2)
}
}
@@ -473,24 +480,24 @@ export class IntersectionDomain extends Domain {
this.displayName = dom1.toString() + " ∩ " + dom2.toString()
this.latexMarkup = `${dom1.latexMarkup}\\cap${dom2.latexMarkup}`
}
-
+
includes(x) {
return this.dom1.includes(x) && this.dom2.includes(x)
}
-
+
toString() {
return this.displayName
}
-
+
union(domain) {
if(domain instanceof EmptySet) return this
if(domain instanceof DomainSet) return domain.union(this)
if(domain instanceof Range) return domain.union(this)
- if(domain instanceof UnionDomain) return this.dom1.union(domain.dom1).union(this.dom2).union(domain.dom2)
+ if(domain instanceof UnionDomain) return this.dom1.union(domain.dom1).union(this.dom2).union(domain.dom2)
if(domain instanceof IntersectionDomain) return new UnionDomain(this, domain)
if(domain instanceof MinusDomain) return new MinusDomain(this, domain)
}
-
+
intersection(domain) {
if(domain instanceof EmptySet) return domain
if(domain instanceof DomainSet) return domain.intersection(this)
@@ -498,11 +505,11 @@ export class IntersectionDomain extends Domain {
if(domain instanceof IntersectionDomain) return new IntersectionDomain(this, domain)
if(domain instanceof MinusDomain) return new IntersectionDomain(this, domain)
}
-
+
static import(frm) {
let domains = frm.trim().split("∩")
let dom1 = parseDomain(domains.pop())
- let dom2 = parseDomain(domains.join('∩'))
+ let dom2 = parseDomain(domains.join("∩"))
return dom1.intersection(dom2)
}
}
@@ -518,20 +525,20 @@ export class MinusDomain extends Domain {
this.displayName = dom1.toString() + "∖" + dom2.toString()
this.latexMarkup = `${dom1.latexMarkup}\\setminus${dom2.latexMarkup}`
}
-
+
includes(x) {
return this.dom1.includes(x) && !this.dom2.includes(x)
}
-
+
toString() {
return this.displayName
}
-
+
static import(frm) {
let domains = frm.trim().split("∖")
if(domains.length === 1) domains = frm.trim().split("\\") // Fallback
let dom1 = parseDomain(domains.shift())
- let dom2 = parseDomain(domains.join('∪'))
+ let dom2 = parseDomain(domains.join("∪"))
return new MinusDomain(dom1, dom2)
}
}
@@ -540,53 +547,53 @@ Domain.RE = new MinusDomain("R", "{0}")
Domain.RE.displayName = "ℝ*"
Domain.RE.latexMarkup = "\\mathbb{R}^{*}"
-Domain.R = new Range(-Infinity,Infinity,true,true)
+Domain.R = new Range(-Infinity, Infinity, true, true)
Domain.R.displayName = "ℝ"
Domain.R.latexMarkup = "\\mathbb{R}"
-Domain.RP = new Range(0,Infinity,true,false)
+Domain.RP = new Range(0, Infinity, true, false)
Domain.RP.displayName = "ℝ⁺"
Domain.RP.latexMarkup = "\\mathbb{R}^{+}"
-Domain.RM = new Range(-Infinity,0,true,false)
+Domain.RM = new Range(-Infinity, 0, true, false)
Domain.RM.displayName = "ℝ⁻"
Domain.RM.latexMarkup = "\\mathbb{R}^{-}"
-Domain.RPE = new Range(0,Infinity,true,true)
+Domain.RPE = new Range(0, Infinity, true, true)
Domain.RPE.displayName = "ℝ⁺*"
Domain.RPE.latexMarkup = "\\mathbb{R}^{+*}"
-Domain.RME = new Range(-Infinity,0,true,true)
+Domain.RME = new Range(-Infinity, 0, true, true)
Domain.RME.displayName = "ℝ⁻*"
Domain.RME.latexMarkup = "\\mathbb{R}^{+*}"
-Domain.N = new SpecialDomain('ℕ', x => x%1===0 && x >= 0,
- x => Math.max(Math.floor(x)+1, 0),
- x => Math.max(Math.ceil(x)-1, 0))
+Domain.N = new SpecialDomain("ℕ", x => x % 1 === 0 && x >= 0,
+ x => Math.max(Math.floor(x) + 1, 0),
+ x => Math.max(Math.ceil(x) - 1, 0))
Domain.N.latexMarkup = "\\mathbb{N}"
-Domain.NE = new SpecialDomain('ℕ*', x => x%1===0 && x > 0,
- x => Math.max(Math.floor(x)+1, 1),
- x => Math.max(Math.ceil(x)-1, 1))
+Domain.NE = new SpecialDomain("ℕ*", x => x % 1 === 0 && x > 0,
+ x => Math.max(Math.floor(x) + 1, 1),
+ x => Math.max(Math.ceil(x) - 1, 1))
Domain.NE.latexMarkup = "\\mathbb{N}^{*}"
-Domain.Z = new SpecialDomain('ℤ', x => x%1===0, x => Math.floor(x)+1, x => Math.ceil(x)-1)
+Domain.Z = new SpecialDomain("ℤ", x => x % 1 === 0, x => Math.floor(x) + 1, x => Math.ceil(x) - 1)
Domain.Z.latexMarkup = "\\mathbb{Z}"
-Domain.ZE = new SpecialDomain('ℤ*', x => x%1===0 && x !== 0,
- x => Math.floor(x)+1 === 0 ? Math.floor(x)+2 : Math.floor(x)+1,
- x => Math.ceil(x)-1 === 0 ? Math.ceil(x)-2 : Math.ceil(x)-1)
+Domain.ZE = new SpecialDomain("ℤ*", x => x % 1 === 0 && x !== 0,
+ x => Math.floor(x) + 1 === 0 ? Math.floor(x) + 2 : Math.floor(x) + 1,
+ x => Math.ceil(x) - 1 === 0 ? Math.ceil(x) - 2 : Math.ceil(x) - 1)
Domain.ZE.latexMarkup = "\\mathbb{Z}^{*}"
-Domain.ZM = new SpecialDomain('ℤ⁻', x => x%1===0 && x <= 0,
- x => Math.min(Math.floor(x)+1, 0),
- x => Math.min(Math.ceil(x)-1, 0))
+Domain.ZM = new SpecialDomain("ℤ⁻", x => x % 1 === 0 && x <= 0,
+ x => Math.min(Math.floor(x) + 1, 0),
+ x => Math.min(Math.ceil(x) - 1, 0))
Domain.ZM.latexMarkup = "\\mathbb{Z}^{-}"
-Domain.ZME = new SpecialDomain('ℤ⁻*', x => x%1===0 && x < 0,
- x => Math.min(Math.floor(x)+1, -1),
- x => Math.min(Math.ceil(x)-1, -1))
+Domain.ZME = new SpecialDomain("ℤ⁻*", x => x % 1 === 0 && x < 0,
+ x => Math.min(Math.floor(x) + 1, -1),
+ x => Math.min(Math.ceil(x) - 1, -1))
Domain.ZME.latexMarkup = "\\mathbb{Z}^{-*}"
-Domain.NLog = new SpecialDomain('ℕˡᵒᵍ',
- x => x/Math.pow(10, x.toString().length-1) % 1 === 0 && x > 0,
- function(x) {
- let x10pow = Math.pow(10, x.toString().length-1)
- return Math.max(1, (Math.floor(x/x10pow)+1)*x10pow)
- },
- function(x) {
- let x10pow = Math.pow(10, x.toString().length-1)
- return Math.max(1, (Math.ceil(x/x10pow)-1)*x10pow)
- })
+Domain.NLog = new SpecialDomain("ℕˡᵒᵍ",
+ x => x / Math.pow(10, Math.ceil(Math.log10(x))) % 1 === 0 && x > 0,
+ function(x) {
+ let x10pow = Math.pow(10, Math.ceil(Math.log10(x)))
+ return Math.max(1, (Math.floor(x / x10pow) + 1) * x10pow)
+ },
+ function(x) {
+ let x10pow = Math.pow(10, Math.ceil(Math.log10(x)))
+ return Math.max(1, (Math.ceil(x / x10pow) - 1) * x10pow)
+ })
Domain.NLog.latexMarkup = "\\mathbb{N}^{log}"
let refedDomains = []
@@ -598,11 +605,11 @@ let refedDomains = []
* @returns {Domain} Parsed domain.
*/
export function parseDomain(domain) {
- if(!domain.includes(')') && !domain.includes('(')) return parseDomainSimple(domain)
+ if(!domain.includes(")") && !domain.includes("(")) return parseDomainSimple(domain)
let domStr
while((domStr = /\(([^)(]+)\)/.exec(domain)) !== null) {
- let dom = parseDomainSimple(domStr[1].trim());
- domain = domain.replace(domStr[0], 'D' + refedDomains.length)
+ let dom = parseDomainSimple(domStr[1].trim())
+ domain = domain.replace(domStr[0], "D" + refedDomains.length)
refedDomains.push(dom)
}
return parseDomainSimple(domain)
@@ -619,10 +626,10 @@ export function parseDomainSimple(domain) {
if(domain.includes("U") || domain.includes("∪")) return UnionDomain.import(domain)
if(domain.includes("∩")) return IntersectionDomain.import(domain)
if(domain.includes("∖") || domain.includes("\\")) return MinusDomain.import(domain)
- if(domain.charAt(0) === "{" && domain.charAt(domain.length -1) === "}") return DomainSet.import(domain)
+ if(domain.charAt(0) === "{" && domain.charAt(domain.length - 1) === "}") return DomainSet.import(domain)
if(domain.includes("]") || domain.includes("[")) return Range.import(domain)
if(["R", "ℝ", "N", "ℕ", "Z", "ℤ"].some(str => domain.toUpperCase().includes(str)))
return Domain.import(domain)
- if(domain[0] === 'D') return refedDomains[parseInt(domain.substr(1))]
+ if(domain[0] === "D") return refedDomains[parseInt(domain.substring(1))]
return new EmptySet()
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs b/common/src/math/expression.mjs
similarity index 71%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs
rename to common/src/math/expression.mjs
index 6505018..2862183 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs
+++ b/common/src/math/expression.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -37,70 +37,90 @@ export class Expression {
}
this.cached = this.isConstant()
this.cachedValue = null
- if(this.cached && this.allRequirementsFullfilled())
+ if(this.cached && this.allRequirementsFulfilled())
this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName)
this.latexMarkup = Latex.expression(this.calc.tokens)
}
+ /**
+ * Return all the variables used in calc
+ * @return {string[]}
+ */
variables() {
return this.calc.variables()
}
+ /**
+ * Checks if the current expression is constant (does not depend on a variable, be it x or n).
+ * @return {boolean}
+ */
isConstant() {
let vars = this.calc.variables()
return !vars.includes("x") && !vars.includes("n")
}
-
+
+ /**
+ * Returns the list of object names this expression is dependant on.
+ * @return {string[]}
+ */
requiredObjects() {
return this.calc.variables().filter(objName => objName !== "x" && objName !== "n")
}
-
- allRequirementsFullfilled() {
+
+ /**
+ * Checks if all the objects required for this expression are defined.
+ * @return {boolean}
+ */
+ allRequirementsFulfilled() {
return this.requiredObjects().every(objName => objName in Objects.currentObjectsByName)
}
-
+
+ /**
+ * Returns a list of names whose corresponding objects this expression is dependant on and are missing.
+ * @return {boolean}
+ */
undefinedVariables() {
return this.requiredObjects().filter(objName => !(objName in Objects.currentObjectsByName))
}
-
+
recache() {
if(this.cached)
this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName)
}
-
+
execute(x = 1) {
if(this.cached) {
if(this.cachedValue == null)
this.cachedValue = this.calc.evaluate(Objects.currentObjectsByName)
return this.cachedValue
}
- ExprParser.currentVars = Object.assign({'x': x}, Objects.currentObjectsByName)
+ ExprParser.currentVars = Object.assign({ "x": x }, Objects.currentObjectsByName)
return this.calc.evaluate(ExprParser.currentVars)
}
-
+
simplify(x) {
- let expr = this.calc.substitute('x', x).simplify()
- if(expr.evaluate() === 0) expr = '0'
+ let expr = this.calc.substitute("x", x).simplify()
+ if(expr.evaluate() === 0) expr = "0"
return new Expression(expr)
}
-
+
toEditableString() {
return this.calc.toString()
}
-
- toString(forceSign=false) {
+
+ toString(forceSign = false) {
let str = Utils.makeExpressionReadable(this.calc.toString())
if(str !== undefined && str.match(/^\d*\.\d+$/)) {
- if(str.split('.')[1].split('0').length > 7) {
+ if(str.split(".")[1].split("0").length > 7) {
// Likely rounding error
- str = parseFloat(str.substring(0, str.length-1)).toString();
+ str = parseFloat(str.substring(0, str.length - 1)).toString()
}
}
- if(str[0] !== '-' && forceSign) str = '+' + str
+ if(str[0] !== "-" && forceSign) str = "+" + str
return str
}
}
-export function executeExpression(expr){
+export function executeExpression(expr) {
return (new Expression(expr.toString())).execute()
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/index.mjs b/common/src/math/index.mjs
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/index.mjs
rename to common/src/math/index.mjs
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs b/common/src/math/sequence.mjs
similarity index 98%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs
rename to common/src/math/sequence.mjs
index d524e44..5394237 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs
+++ b/common/src/math/sequence.mjs
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import * as Expr from "expression.mjs"
+import * as Expr from "./expression.mjs"
import * as Utils from "../utils.mjs"
import Latex from "../module/latex.mjs"
import Objects from "../module/objects.mjs"
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs b/common/src/module/canvas.mjs
similarity index 99%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs
rename to common/src/module/canvas.mjs
index 04abf68..e623034 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/canvas.mjs
+++ b/common/src/module/canvas.mjs
@@ -17,7 +17,7 @@
*/
import { Module } from "./common.mjs"
-import { FUNCTION, Interface, CanvasInterface, DialogInterface } from "./interface.mjs"
+import { CanvasInterface, DialogInterface } from "./interface.mjs"
import { textsup } from "../utils.mjs"
import { Expression } from "../math/index.mjs"
import Latex from "./latex.mjs"
@@ -227,7 +227,7 @@ class CanvasAPI extends Module {
// Drawing throws an error. Generally, it's due to a new modification (or the opening of a file)
console.error(e)
console.log(e.stack)
- this._drawingErrorDialog.showDialog(objType, obj.name, e.message)
+ this._drawingErrorDialog.show(objType, obj.name, e.message)
History.undo()
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs b/common/src/module/common.mjs
similarity index 87%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs
rename to common/src/module/common.mjs
index 6902745..b757f14 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/common.mjs
+++ b/common/src/module/common.mjs
@@ -18,6 +18,9 @@
import { Interface } from "./interface.mjs"
+// Define Modules interface before they are imported.
+globalThis.Modules = globalThis.Modules || {}
+
/**
* Base class for global APIs in runtime.
*/
@@ -26,13 +29,14 @@ export class Module {
/**
*
* @param {string} name - Name of the API
- * @param {Object.} initializationParameters - List of parameters for the initialize function.
+ * @param {Object.} initializationParameters - List of parameters for the initialize function.
*/
constructor(name, initializationParameters = {}) {
console.log(`Loading module ${name}...`)
this.__name = name
this.__initializationParameters = initializationParameters
this.initialized = false
+
}
/**
@@ -42,6 +46,7 @@ export class Module {
initialize(options) {
if(this.initialized)
throw new Error(`Cannot reinitialize module ${this.__name}.`)
+ console.log(`Initializing ${this.__name}...`)
for(const [name, value] of Object.entries(this.__initializationParameters)) {
if(!options.hasOwnProperty(name))
throw new Error(`Option '${name}' of initialize of module ${this.__name} does not exist.`)
@@ -52,4 +57,4 @@ export class Module {
}
this.initialized = true
}
-}
\ No newline at end of file
+}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs b/common/src/module/expreval.mjs
similarity index 98%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs
rename to common/src/module/expreval.mjs
index cc61434..854f928 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/expreval.mjs
+++ b/common/src/module/expreval.mjs
@@ -34,7 +34,7 @@ const evalVariables = {
"false": false
}
-export class ExprParserAPI extends Module {
+class ExprParserAPI extends Module {
constructor() {
super("ExprParser")
this.currentVars = {}
@@ -55,7 +55,7 @@ export class ExprParserAPI extends Module {
* @return {function} JS function to call.
*/
parseArgumentsForFunction(args, usage1, usage2) {
- let f, target, variable
+ let f, variable
if(args.length === 1) {
// Parse object
f = args[0]
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs b/common/src/module/history.mjs
similarity index 97%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs
rename to common/src/module/history.mjs
index 09b45d6..8cd3f60 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/history.mjs
+++ b/common/src/module/history.mjs
@@ -17,7 +17,6 @@
*/
import { Module } from "./common.mjs"
-import Latex from "./latex.mjs"
import { HistoryInterface, NUMBER, STRING } from "./interface.mjs"
@@ -38,7 +37,6 @@ class HistoryAPI extends Module {
initialize({ historyObj, themeTextColor, imageDepth, fontSize }) {
super.initialize({ historyObj, themeTextColor, imageDepth, fontSize })
- console.log("Initializing history...")
this.history = historyObj
this.themeTextColor = themeTextColor
this.imageDepth = imageDepth
diff --git a/common/src/module/index.mjs b/common/src/module/index.mjs
new file mode 100644
index 0000000..fe2e8d9
--- /dev/null
+++ b/common/src/module/index.mjs
@@ -0,0 +1,35 @@
+/**
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import Objects from "./objects.mjs"
+import ExprParser from "./expreval.mjs"
+import Latex from "./latex.mjs"
+import History from "./history.mjs"
+import Canvas from "./canvas.mjs"
+import IO from "./io.mjs"
+import Preferences from "./preferences.mjs"
+
+export default {
+ Objects,
+ ExprParser,
+ Latex,
+ History,
+ Canvas,
+ IO,
+ Preferences
+}
diff --git a/common/src/module/interface.mjs b/common/src/module/interface.mjs
new file mode 100644
index 0000000..9273c8f
--- /dev/null
+++ b/common/src/module/interface.mjs
@@ -0,0 +1,187 @@
+/*!
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ *
+ * @author Ad5001
+ * @license GPL-3.0-or-later
+ * @copyright (C) 2021-2024 Ad5001
+ * @preserve
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+export const NUMBER = 0
+export const STRING = "string"
+export const BOOLEAN = true
+export const OBJECT = {}
+export const FUNCTION = () => {
+ throw new Error("Cannot call function of an interface.")
+}
+
+
+export class Interface {
+ /**
+ * Checks if the class to check implements the given interface.
+ * Throws an error if the implementation does not conform to the interface.
+ * @param {typeof Interface} interface_
+ * @param {object} classToCheck
+ * @return {boolean}
+ */
+ static check_implementation(interface_, classToCheck) {
+ const properties = new interface_()
+ const interfaceName = interface_.name
+ const toCheckName = classToCheck.constructor.name
+ for(const [property, value] of Object.entries(properties))
+ if(property !== "implement") {
+ if(classToCheck[property] === undefined)
+ // Check if the property exist
+ throw new Error(`Property '${property}' (${typeof value}) is present in interface ${interfaceName}, but not in implementation ${toCheckName}.`)
+ else if((typeof value) !== (typeof classToCheck[property]))
+ // Compare the types
+ throw new Error(`Property '${property}' of ${interfaceName} implementation ${toCheckName} is a '${typeof classToCheck[property]}' and not a '${typeof value}'.`)
+ else if((typeof value) === "object")
+ // Test type of object.
+ if(value instanceof Interface)
+ Interface.check_implementation(value, classToCheck[property])
+ else if(value.prototype && !(classToCheck[property] instanceof value))
+ throw new Error(`Property '${property}' of ${interfaceName} implementation ${toCheckName} is not '${value.constructor.name}'.`)
+ }
+ }
+}
+
+
+export class SettingsInterface extends Interface {
+ width = NUMBER
+ height = NUMBER
+ xmin = NUMBER
+ ymax = NUMBER
+ xzoom = NUMBER
+ yzoom = NUMBER
+ xaxisstep = STRING
+ yaxisstep = STRING
+ xlabel = STRING
+ ylabel = STRING
+ linewidth = NUMBER
+ textsize = NUMBER
+ logscalex = BOOLEAN
+ showxgrad = BOOLEAN
+ showygrad = BOOLEAN
+}
+
+export class CanvasInterface extends SettingsInterface {
+ imageLoaders = OBJECT
+ /** @type {function(string): CanvasRenderingContext2D} */
+ getContext = FUNCTION
+ /** @type {function(rect)} */
+ markDirty = FUNCTION
+ /** @type {function(string)} */
+ loadImage = FUNCTION
+ /** @type {function(string)} */
+ isImageLoading = FUNCTION
+ /** @type {function(string)} */
+ isImageLoaded = FUNCTION
+ /** @type {function()} */
+ requestPaint = FUNCTION
+}
+
+export class RootInterface extends Interface {
+ width = NUMBER
+ height = NUMBER
+ updateObjectsLists = FUNCTION
+}
+
+export class DialogInterface extends Interface {
+ show = FUNCTION
+}
+
+export class HistoryInterface extends Interface {
+ undo = FUNCTION
+ redo = FUNCTION
+ clear = FUNCTION
+ addToHistory = FUNCTION
+ unserialize = FUNCTION
+ serialize = FUNCTION
+}
+
+export class LatexInterface extends Interface {
+ /**
+ * @param {string} markup - LaTeX markup to render
+ * @param {number} fontSize - Font size (in pt) to render
+ * @param {string} color - Color of the text to render
+ * @returns {string} - Comma separated data of the image (source, width, height)
+ */
+ render = FUNCTION
+ /**
+ * @param {string} markup - LaTeX markup to render
+ * @param {number} fontSize - Font size (in pt) to render
+ * @param {string} color - Color of the text to render
+ * @returns {string} - Comma separated data of the image (source, width, height)
+ */
+ findPrerendered = FUNCTION
+ /**
+ * Checks if the Latex installation is valid
+ * @returns {boolean}
+ */
+ checkLatexInstallation = FUNCTION
+}
+
+export class HelperInterface extends Interface {
+ /**
+ * Gets a setting from the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin")
+ * @returns {boolean} Value of the setting
+ */
+ getSettingBool = FUNCTION
+ /**
+ * Gets a setting from the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin")
+ * @returns {number} Value of the setting
+ */
+ getSettingInt = FUNCTION
+ /**
+ * Gets a setting from the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin")
+ * @returns {string} Value of the setting
+ */
+ getSetting = FUNCTION
+ /**
+ * Sets a setting in the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin")
+ * @param {boolean} value
+ */
+ setSettingBool = FUNCTION
+ /**
+ * Sets a setting in the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin")
+ * @param {number} value
+ */
+ setSettingInt = FUNCTION
+ /**
+ * Sets a setting in the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin")
+ * @param {string} value
+ */
+ setSetting = FUNCTION
+ /**
+ * Sends data to be written
+ * @param {string} file
+ * @param {string} dataToWrite - just JSON encoded, requires the "LPFv1" mime to be added before writing
+ */
+ write = FUNCTION
+ /**
+ * Requests data to be read from a file
+ * @param {string} file
+ * @returns {string} the loaded data - just JSON encoded, requires the "LPFv1" mime to be stripped
+ */
+ load = FUNCTION
+}
\ No newline at end of file
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs b/common/src/module/io.mjs
similarity index 97%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs
rename to common/src/module/io.mjs
index 2a540a7..b6d40f5 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/io.mjs
+++ b/common/src/module/io.mjs
@@ -20,7 +20,7 @@ import { Module } from "./common.mjs"
import Objects from "./objects.mjs"
import History from "./history.mjs"
import Canvas from "./canvas.mjs"
-import { DialogInterface, FUNCTION, Interface, RootInterface, SettingsInterface } from "./interface.mjs"
+import { DialogInterface, RootInterface, SettingsInterface } from "./interface.mjs"
class IOAPI extends Module {
@@ -97,7 +97,7 @@ class IOAPI extends Module {
* Loads the diagram from a certain \c filename.
* @param {string} filename
*/
- loadDiagram(filename) {
+ async loadDiagram(filename) {
if(!this.initialized) throw new Error("Attempting loadDiagram before initialize!")
if(!History.initialized) throw new Error("Attempting loadDiagram before history is initialized!")
let basename = filename.split("/").pop()
@@ -178,4 +178,4 @@ class IOAPI extends Module {
/** @type {IOAPI} */
Modules.IO = Modules.IO || new IOAPI()
-export default Modules.IO
\ No newline at end of file
+export default Modules.IO
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs b/common/src/module/latex.mjs
similarity index 83%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs
rename to common/src/module/latex.mjs
index f2e9b0b..8740160 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/latex.mjs
+++ b/common/src/module/latex.mjs
@@ -19,8 +19,10 @@
import { Module } from "./common.mjs"
import * as Instruction from "../lib/expr-eval/instruction.mjs"
import { escapeValue } from "../lib/expr-eval/expression.mjs"
+import { HelperInterface, LatexInterface } from "./interface.mjs"
-const unicodechars = ["α", "β", "γ", "δ", "ε", "ζ", "η",
+const unicodechars = [
+ "α", "β", "γ", "δ", "ε", "ζ", "η",
"π", "θ", "κ", "λ", "μ", "ξ", "ρ",
"ς", "σ", "τ", "φ", "χ", "ψ", "ω",
"Γ", "Δ", "Θ", "Λ", "Ξ", "Π", "Σ",
@@ -30,7 +32,8 @@ const unicodechars = ["α", "β", "γ", "δ", "ε", "ζ", "η",
"⁷", "⁸", "⁹", "⁰", "₁", "₂", "₃",
"₄", "₅", "₆", "₇", "₈", "₉", "₀",
"pi", "∞"]
-const equivalchars = ["\\alpha", "\\beta", "\\gamma", "\\delta", "\\epsilon", "\\zeta", "\\eta",
+const equivalchars = [
+ "\\alpha", "\\beta", "\\gamma", "\\delta", "\\epsilon", "\\zeta", "\\eta",
"\\pi", "\\theta", "\\kappa", "\\lambda", "\\mu", "\\xi", "\\rho",
"\\sigma", "\\sigma", "\\tau", "\\phi", "\\chi", "\\psi", "\\omega",
"\\Gamma", "\\Delta", "\\Theta", "\\Lambda", "\\Xi", "\\Pi", "\\Sigma",
@@ -58,24 +61,25 @@ class LatexRenderResult {
class LatexAPI extends Module {
constructor() {
- super("Latex")
+ super("Latex", {
+ latex: LatexInterface,
+ helper: HelperInterface
+ })
/**
* true if latex has been enabled by the user, false otherwise.
*/
- this.enabled = Helper.getSettingBool("enable_latex")
+ this.enabled = false
}
/**
- * Prepares and renders a latex string into a png file.
- *
- * @param {string} markup - LaTeX markup to render.
- * @param {number} fontSize - Font size (in pt) to render.
- * @param {color} color - Color of the text to render.
- * @returns {LatexRenderResult}
+ * @param {LatexInterface} latex
+ * @param {HelperInterface} helper
*/
- renderSync(markup, fontSize, color) {
- let args = Latex.render(markup, fontSize, color).split(",")
- return new LatexRenderResult(...args)
+ initialize({ latex, helper }) {
+ super.initialize({ latex, helper })
+ this.latex = latex
+ this.helper = helper
+ this.enabled = helper.getSettingBool("enable_latex")
}
/**
@@ -84,11 +88,12 @@ class LatexAPI extends Module {
*
* @param {string} markup - LaTeX markup to render.
* @param {number} fontSize - Font size (in pt) to render.
- * @param {color} color - Color of the text to render.
+ * @param {string} color - Color of the text to render.
* @returns {LatexRenderResult|null}
*/
findPrerendered(markup, fontSize, color) {
- const data = Latex.findPrerendered(markup, fontSize, color)
+ if(!this.initialized) throw new Error("Attempting findPrerendered before initialize!")
+ const data = this.latex.findPrerendered(markup, fontSize, color)
let ret = null
if(data !== "")
ret = new LatexRenderResult(...data.split(","))
@@ -100,13 +105,13 @@ class LatexAPI extends Module {
*
* @param {string} markup - LaTeX markup to render.
* @param {number} fontSize - Font size (in pt) to render.
- * @param {color} color - Color of the text to render.
+ * @param {string} color - Color of the text to render.
* @returns {Promise}
*/
- requestAsyncRender(markup, fontSize, color) {
- return new Promise(resolve => {
- resolve(this.renderSync(markup, fontSize, color))
- })
+ async requestAsyncRender(markup, fontSize, color) {
+ if(!this.initialized) throw new Error("Attempting requestAsyncRender before initialize!")
+ let args = this.latex.render(markup, fontSize, color).split(",")
+ return new LatexRenderResult(...args)
}
/**
@@ -133,7 +138,7 @@ class LatexAPI extends Module {
if(elem[0] !== "(" && elem[elem.length - 1] !== ")" && contents.some(x => elem.indexOf(x) > 0))
return this.par(elem)
if(elem[0] === "(" && elem[elem.length - 1] === ")")
- return elem.substr(1, elem.length - 2)
+ return elem.removeEnclosure()
return elem
}
@@ -148,24 +153,24 @@ class LatexAPI extends Module {
switch(f) {
case "derivative":
if(args.length === 3)
- return "\\frac{d" + args[0].substr(1, args[0].length - 2).replace(new RegExp(args[1].substr(1, args[1].length - 2), "g"), "x") + "}{dx}"
+ return `\\frac{d${args[0].removeEnclosure().replaceAll(args[1].removeEnclosure(), "x")}}{dx}`
else
- return "\\frac{d" + args[0] + "}{dx}(x)"
+ return `\\frac{d${args[0]}}{dx}(x)`
case "integral":
if(args.length === 4)
- return "\\int\\limits_{" + args[0] + "}^{" + args[1] + "}" + args[2].substr(1, args[2].length - 2) + " d" + args[3].substr(1, args[3].length - 2)
+ return `\\int\\limits_{${args[0]}}^{${args[1]}}${args[2].removeEnclosure()} d${args[3].removeEnclosure()}`
else
- return "\\int\\limits_{" + args[0] + "}^{" + args[1] + "}" + args[2] + "(t) dt"
+ return `\\int\\limits_{${args[0]}}^{${args[1]}}${args[2]}(t) dt`
case "sqrt":
- return "\\sqrt\\left(" + args.join(", ") + "\\right)"
+ return `\\sqrt\\left(${args.join(", ")}\\right)`
case "abs":
- return "\\left|" + args.join(", ") + "\\right|"
+ return `\\left|${args.join(", ")}\\right|`
case "floor":
- return "\\left\\lfloor" + args.join(", ") + "\\right\\rfloor"
+ return `\\left\\lfloor${args.join(", ")}\\right\\rfloor`
case "ceil":
- return "\\left\\lceil" + args.join(", ") + "\\right\\rceil"
+ return `\\left\\lceil${args.join(", ")}\\right\\rceil`
default:
- return "\\mathrm{" + f + "}\\left(" + args.join(", ") + "\\right)"
+ return `\\mathrm{${f}}\\left(${args.join(", ")}\\right)`
}
}
@@ -180,12 +185,12 @@ class LatexAPI extends Module {
if(wrapIn$)
for(let i = 0; i < unicodechars.length; i++) {
if(vari.includes(unicodechars[i]))
- vari = vari.replace(new RegExp(unicodechars[i], "g"), "$" + equivalchars[i] + "$")
+ vari = vari.replaceAll(unicodechars[i], "$" + equivalchars[i] + "$")
}
else
for(let i = 0; i < unicodechars.length; i++) {
if(vari.includes(unicodechars[i]))
- vari = vari.replace(new RegExp(unicodechars[i], "g"), equivalchars[i])
+ vari = vari.replaceAll(unicodechars[i], equivalchars[i])
}
return vari
}
@@ -325,5 +330,5 @@ class LatexAPI extends Module {
/** @type {LatexAPI} */
Modules.Latex = Modules.Latex || new LatexAPI()
-
+/** @type {LatexAPI} */
export default Modules.Latex
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs b/common/src/module/objects.mjs
similarity index 83%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs
rename to common/src/module/objects.mjs
index 5a63386..a95dc89 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/objects.mjs
+++ b/common/src/module/objects.mjs
@@ -1,28 +1,28 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-import { Module } from './common.mjs'
-import { textsub } from '../utils.mjs'
+import { Module } from "./common.mjs"
+import { textsub } from "../utils.mjs"
class ObjectsAPI extends Module {
constructor() {
- super('Objects')
+ super("Objects")
this.types = {}
/**
@@ -45,7 +45,7 @@ class ObjectsAPI extends Module {
* @param {string} prefix - Prefix to the name.
* @return {string} New unused name for a new object.
*/
- getNewName(allowedLetters, prefix='') {
+ getNewName(allowedLetters, prefix = "") {
// Allows to get a new name, based on the allowed letters,
// as well as adding a sub number when needs be.
let newid = 0
@@ -53,7 +53,7 @@ class ObjectsAPI extends Module {
do {
let letter = allowedLetters[newid % allowedLetters.length]
let num = Math.floor((newid - (newid % allowedLetters.length)) / allowedLetters.length)
- ret = prefix + letter + (num > 0 ? textsub(num-1) : '')
+ ret = prefix + letter + (num > 0 ? textsub(num - 1) : "")
newid += 1
} while(ret in this.currentObjectsByName)
return ret
@@ -78,7 +78,7 @@ class ObjectsAPI extends Module {
deleteObject(objName) {
let obj = this.currentObjectsByName[objName]
if(obj !== undefined) {
- this.currentObjects[obj.type].splice(this.currentObjects[obj.type].indexOf(obj),1)
+ this.currentObjects[obj.type].splice(this.currentObjects[obj.type].indexOf(obj), 1)
obj.delete()
delete this.currentObjectsByName[objName]
}
@@ -90,15 +90,10 @@ class ObjectsAPI extends Module {
* @returns {string[]} List of names of the objects.
*/
getObjectsName(objType) {
- if(objType === "ExecutableObject") {
- // NOTE: QMLJS does not support flatMap.
- // return getExecutableTypes().flatMap(elemType => currentObjects[elemType].map(obj => obj.name))
- let types = this.getExecutableTypes()
- let elementNames = ['']
- for(let elemType of types)
- elementNames = elementNames.concat(this.currentObjects[elemType].map(obj => obj.name))
- return elementNames
- }
+ if(objType === "ExecutableObject")
+ return this.getExecutableTypes().flatMap(
+ elemType => this.currentObjects[elemType].map(obj => obj.name)
+ )
if(this.currentObjects[objType] === undefined) return []
return this.currentObjects[objType].map(obj => obj.name)
}
@@ -117,9 +112,9 @@ class ObjectsAPI extends Module {
* @param {string[]} args - List of arguments for the objects (can be empty).
* @return {DrawableObject} Newly created object.
*/
- createNewRegisteredObject(objType, args= []) {
+ createNewRegisteredObject(objType, args = []) {
if(Object.keys(this.types).indexOf(objType) === -1) return null // Object type does not exist.
- let newobj = new this.types[objType](...args)
+ const newobj = new this.types[objType](...args)
if(Object.keys(this.currentObjects).indexOf(objType) === -1) {
this.currentObjects[objType] = []
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs b/common/src/module/preferences.mjs
similarity index 79%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs
rename to common/src/module/preferences.mjs
index 389a5ba..afb795e 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/module/preferences.mjs
+++ b/common/src/module/preferences.mjs
@@ -15,23 +15,23 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-import {Module} from "./common.mjs"
+import { Module } from "./common.mjs"
import General from "../preferences/general.mjs"
import Editor from "../preferences/expression.mjs"
import DefaultGraph from "../preferences/default.mjs"
class PreferencesAPI extends Module {
constructor() {
- super('Preferences')
+ super("Preferences")
this.categories = {
- [QT_TRANSLATE_NOOP('settingCategory', 'general')]: General,
- [QT_TRANSLATE_NOOP('settingCategory', 'editor')]: Editor,
- [QT_TRANSLATE_NOOP('settingCategory', 'default')]: DefaultGraph,
+ [QT_TRANSLATE_NOOP("settingCategory", "general")]: General,
+ [QT_TRANSLATE_NOOP("settingCategory", "editor")]: Editor,
+ [QT_TRANSLATE_NOOP("settingCategory", "default")]: DefaultGraph
}
}
}
/** @type {CanvasAPI} */
Modules.Preferences = Modules.Preferences || new PreferencesAPI()
-export const API = Modules.Preferences
+export default Modules.Preferences
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/common/src/objs/autoload.mjs
similarity index 78%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs
rename to common/src/objs/autoload.mjs
index a7351b5..26a6003 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs
+++ b/common/src/objs/autoload.mjs
@@ -1,33 +1,33 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import Objects from "../module/objects.mjs"
-import { DrawableObject } from "common.mjs"
-import Point from "point.mjs"
-import Text from "text.mjs"
-import Function from "function.mjs"
-import BodeMagnitude from "bodemagnitude.mjs"
-import BodePhase from "bodephase.mjs"
-import BodeMagnitudeSum from "bodemagnitudesum.mjs"
-import BodePhaseSum from "bodephasesum.mjs"
-import XCursor from "xcursor.mjs"
-import Sequence from "sequence.mjs"
-import DistributionFunction from "distribution.mjs"
+import { DrawableObject } from "./common.mjs"
+import Point from "./point.mjs"
+import Text from "./text.mjs"
+import Function from "./function.mjs"
+import BodeMagnitude from "./bodemagnitude.mjs"
+import BodePhase from "./bodephase.mjs"
+import BodeMagnitudeSum from "./bodemagnitudesum.mjs"
+import BodePhaseSum from "./bodephasesum.mjs"
+import XCursor from "./xcursor.mjs"
+import Sequence from "./sequence.mjs"
+import DistributionFunction from "./distribution.mjs"
/**
* Registers the object obj in the object list.
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs b/common/src/objs/bodemagnitude.mjs
similarity index 65%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs
rename to common/src/objs/bodemagnitude.mjs
index 7ca294d..82d9728 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitude.mjs
+++ b/common/src/objs/bodemagnitude.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -23,93 +23,104 @@ import Objects from "../module/objects.mjs"
import Latex from "../module/latex.mjs"
import History from "../module/history.mjs"
-import { ExecutableObject } from "common.mjs"
-import Function from "function.mjs"
+import { ExecutableObject } from "./common.mjs"
+import Function from "./function.mjs"
export default class BodeMagnitude extends ExecutableObject {
- static type(){return 'Gain Bode'}
- static displayType(){return qsTranslate("bodemagnitude", 'Bode Magnitude')}
- static displayTypeMultiple(){return qsTranslate("bodemagnitude", 'Bode Magnitudes')}
- static properties() {return {
- [QT_TRANSLATE_NOOP('prop','om_0')]: new P.ObjectType('Point'),
- [QT_TRANSLATE_NOOP('prop','pass')]: P.Enum.BodePass,
- [QT_TRANSLATE_NOOP('prop','gain')]: new P.Expression(),
- [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position,
- [QT_TRANSLATE_NOOP('prop','labelX')]: 'number',
- [QT_TRANSLATE_NOOP('prop','omGraduation')]: 'boolean'
- }}
+ static type() {
+ return "Gain Bode"
+ }
- constructor(name = null, visible = true, color = null, labelContent = 'name + value',
- om_0 = '', pass = 'high', gain = '20', labelPosition = 'above', labelX = 1, omGraduation = false) {
- if(name == null) name = Objects.getNewName('G')
- if(name === 'G') name = 'G₀' // G is reserved for sum of BODE magnitudes (Somme gains Bode).
+ static displayType() {
+ return qsTranslate("bodemagnitude", "Bode Magnitude")
+ }
+
+ static displayTypeMultiple() {
+ return qsTranslate("bodemagnitude", "Bode Magnitudes")
+ }
+
+ static properties() {
+ return {
+ [QT_TRANSLATE_NOOP("prop", "om_0")]: new P.ObjectType("Point"),
+ [QT_TRANSLATE_NOOP("prop", "pass")]: P.Enum.BodePass,
+ [QT_TRANSLATE_NOOP("prop", "gain")]: new P.Expression(),
+ [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position,
+ [QT_TRANSLATE_NOOP("prop", "labelX")]: "number",
+ [QT_TRANSLATE_NOOP("prop", "omGraduation")]: "boolean"
+ }
+ }
+
+ constructor(name = null, visible = true, color = null, labelContent = "name + value",
+ om_0 = "", pass = "high", gain = "20", labelPosition = "above", labelX = 1, omGraduation = false) {
+ if(name == null) name = Objects.getNewName("G")
+ if(name === "G") name = "G₀" // G is reserved for sum of BODE magnitudes (Somme gains Bode).
super(name, visible, color, labelContent)
if(typeof om_0 == "string") {
// Point name or create one
om_0 = Objects.currentObjectsByName[om_0]
if(om_0 == null) {
// Create new point
- om_0 = Objects.createNewRegisteredObject('Point', [Objects.getNewName('ω'), true, this.color, 'name'])
- History.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export()))
+ om_0 = Objects.createNewRegisteredObject("Point", [Objects.getNewName("ω"), true, this.color, "name"])
+ History.addToHistory(new CreateNewObject(om_0.name, "Point", om_0.export()))
om_0.update()
- labelPosition = 'below'
+ labelPosition = "below"
}
om_0.requiredBy.push(this)
}
/** @type {Point} */
this.om_0 = om_0
this.pass = pass
- if(typeof gain == 'number' || typeof gain == 'string') gain = new Expression(gain.toString())
+ if(typeof gain == "number" || typeof gain == "string") gain = new Expression(gain.toString())
this.gain = gain
this.labelPosition = labelPosition
this.labelX = labelX
this.omGraduation = omGraduation
}
-
+
getReadableString() {
- let pass = this.pass === "low" ? qsTranslate("bodemagnitude", "low-pass") : qsTranslate("bodemagnitude", "high-pass");
- return `${this.name}: ${pass}; ${this.om_0.name} = ${this.om_0.x}\n ${' '.repeat(this.name.length)}${this.gain.toString(true)} dB/dec`
+ let pass = this.pass === "low" ? qsTranslate("bodemagnitude", "low-pass") : qsTranslate("bodemagnitude", "high-pass")
+ return `${this.name}: ${pass}; ${this.om_0.name} = ${this.om_0.x}\n ${" ".repeat(this.name.length)}${this.gain.toString(true)} dB/dec`
}
-
+
getLatexString() {
- let pass = this.pass === "low" ? qsTranslate("bodemagnitude", "low-pass") : qsTranslate("bodemagnitude", "high-pass");
+ let pass = this.pass === "low" ? qsTranslate("bodemagnitude", "low-pass") : qsTranslate("bodemagnitude", "high-pass")
return `\\mathrm{${Latex.variable(this.name)}:}\\begin{array}{l}
\\textsf{${pass}};${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup} \\\\
${this.gain.latexMarkup}\\textsf{ dB/dec}
\\end{array}`
}
-
- execute(x=1) {
- if(typeof x == 'string') x = executeExpression(x)
- if((this.pass === 'high' && x < this.om_0.x) || (this.pass === 'low' && x > this.om_0.x)) {
+
+ execute(x = 1) {
+ if(typeof x == "string") x = executeExpression(x)
+ if((this.pass === "high" && x < this.om_0.x) || (this.pass === "low" && x > this.om_0.x)) {
let dbfn = new Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`)
return dbfn.execute(x)
} else {
return this.om_0.y.execute()
}
}
-
+
simplify(x = 1) {
let xval = x
- if(typeof x == 'string') xval = executeExpression(x)
- if((this.pass === 'high' && xval < this.om_0.x.execute()) || (this.pass === 'low' && xval > this.om_0.x.execute())) {
+ if(typeof x == "string") xval = executeExpression(x)
+ if((this.pass === "high" && xval < this.om_0.x.execute()) || (this.pass === "low" && xval > this.om_0.x.execute())) {
let dbfn = new Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`)
return dbfn.simplify(x)
} else {
return this.om_0.y.toString()
}
}
-
+
canExecute(x = 1) {
return true
}
-
+
draw(canvas) {
let base = [canvas.x2px(this.om_0.x.execute()), canvas.y2px(this.om_0.y.execute())]
let dbfn = new Expression(`${this.gain.execute()}*(log10(x)-log10(${this.om_0.x}))+${this.om_0.y}`)
- let inDrawDom = new EmptySet()
+ let inDrawDom
- if(this.pass === 'high') {
+ if(this.pass === "high") {
// High pass, linear line from beginning, then constant to the end.
canvas.drawLine(base[0], base[1], canvas.width, base[1])
inDrawDom = parseDomain(`]-inf;${this.om_0.x}[`)
@@ -122,26 +133,28 @@ export default class BodeMagnitude extends ExecutableObject {
// Dashed line representing break in function
let xpos = canvas.x2px(this.om_0.x.execute())
let dashPxSize = 10
- for(let i = 0; i < canvas.height && this.omGraduation; i += dashPxSize*2)
- canvas.drawLine(xpos, i, xpos, i+dashPxSize)
-
+ for(let i = 0; i < canvas.height && this.omGraduation; i += dashPxSize * 2)
+ canvas.drawLine(xpos, i, xpos, i + dashPxSize)
+
// Label
this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX)))
}
-
+
update() {
super.update()
- let sumObjs = Objects.currentObjects['Somme gains Bode']
+ /** @type {BodeMagnitudeSum[]} */
+ let sumObjs = Objects.currentObjects["Somme gains Bode"]
if(sumObjs !== undefined && sumObjs.length > 0) {
sumObjs[0].recalculateCache()
} else {
- Objects.createNewRegisteredObject('Somme gains Bode')
+ Objects.createNewRegisteredObject("Somme gains Bode")
}
}
-
+
delete() {
super.delete()
- let sumObjs = Objects.currentObjects['Somme gains Bode']
+ /** @type {BodeMagnitudeSum[]} */
+ let sumObjs = Objects.currentObjects["Somme gains Bode"]
if(sumObjs !== undefined && sumObjs.length > 0) {
sumObjs[0].recalculateCache()
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs b/common/src/objs/bodemagnitudesum.mjs
similarity index 80%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs
rename to common/src/objs/bodemagnitudesum.mjs
index 7d5c3e4..eb81663 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodemagnitudesum.mjs
+++ b/common/src/objs/bodemagnitudesum.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -21,37 +21,51 @@ import * as P from "../parameters.mjs"
import Objects from "../module/objects.mjs"
import Latex from "../module/latex.mjs"
-import { ExecutableObject } from "common.mjs"
-import Function from "function.mjs"
+import { ExecutableObject } from "./common.mjs"
+import Function from "./function.mjs"
export default class BodeMagnitudeSum extends ExecutableObject {
- static type(){return 'Somme gains Bode'}
- static displayType(){return qsTranslate("bodemagnitudesum", 'Bode Magnitudes Sum')}
- static displayTypeMultiple(){return qsTranslate("bodemagnitudesum", 'Bode Magnitudes Sum')}
- static createable() {return false}
- static properties() {return {
- [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position,
- [QT_TRANSLATE_NOOP('prop','labelX')]: 'number',
- }}
-
- constructor(name = null, visible = true, color = null, labelContent = 'name + value',
- labelPosition = 'above', labelX = 1) {
- if(name == null) name = 'G'
+ static type() {
+ return "Somme gains Bode"
+ }
+
+ static displayType() {
+ return qsTranslate("bodemagnitudesum", "Bode Magnitudes Sum")
+ }
+
+ static displayTypeMultiple() {
+ return qsTranslate("bodemagnitudesum", "Bode Magnitudes Sum")
+ }
+
+ static createable() {
+ return false
+ }
+
+ static properties() {
+ return {
+ [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position,
+ [QT_TRANSLATE_NOOP("prop", "labelX")]: "number"
+ }
+ }
+
+ constructor(name = null, visible = true, color = null, labelContent = "name + value",
+ labelPosition = "above", labelX = 1) {
+ if(name == null) name = "G"
super(name, visible, color, labelContent)
this.labelPosition = labelPosition
this.labelX = labelX
this.recalculateCache()
}
-
+
getReadableString() {
- return `${this.name} = ${Objects.getObjectsName('Gain Bode').join(' + ')}`
+ return `${this.name} = ${Objects.getObjectsName("Gain Bode").join(" + ")}`
}
-
+
getLatexString() {
- return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Gain Bode').map(name => Latex.variable(name)).join(' + ')}`
+ return `${Latex.variable(this.name)} = ${Objects.getObjectsName("Gain Bode").map(name => Latex.variable(name)).join(" + ")}`
}
-
+
execute(x = 0) {
for(let [limitedDrawFunction, inDrawDom] of this.cachedParts) {
if(inDrawDom.includes(x)) {
@@ -60,50 +74,50 @@ export default class BodeMagnitudeSum extends ExecutableObject {
}
return null
}
-
+
canExecute(x = 1) {
return true // Should always be true
}
-
+
simplify(x = 1) {
for(let [limitedDrawFunction, inDrawDom] of this.cachedParts) {
if(inDrawDom.includes(x)) {
return limitedDrawFunction.simplify(x)
}
}
- return ''
+ return ""
}
-
+
recalculateCache() {
this.cachedParts = []
// Calculating this is fairly resource expansive so it's cached.
- let magnitudeObjects = Objects.currentObjects['Gain Bode']
+ let magnitudeObjects = Objects.currentObjects["Gain Bode"]
if(magnitudeObjects === undefined || magnitudeObjects.length < 1) {
Objects.deleteObject(this.name)
} else {
- console.log('Recalculating cache gain')
+ console.log("Recalculating cache gain")
// Minimum to draw (can be expended if needed, just not infinite or it'll cause issues.
const MIN_DRAW = 1e-20
// Format: [[x value of where the filter transitions, magnitude, high-pass (bool)]]
- const magnitudes = []
+ const magnitudes = []
const XVALUE = 0
const MAGNITUDE = 1
const PASS = 2
magnitudes.push([Number.MAX_VALUE, 0, true]) // Draw the ending section
// Collect data from current magnitude (or gain in French) objects.
let baseY = 0
- for(/** @type {Bodemagnitude} */ let magnitudeObj of magnitudeObjects) { // Sorting by their om_0 position.
+ for(/** @type {BodeMagnitude} */ let magnitudeObj of magnitudeObjects) { // Sorting by their om_0 position.
const om0x = magnitudeObj.om_0.x.execute()
- magnitudes.push([om0x, magnitudeObj.gain.execute(), magnitudeObj.pass === 'high'])
+ magnitudes.push([om0x, magnitudeObj.gain.execute(), magnitudeObj.pass === "high"])
baseY += magnitudeObj.execute(MIN_DRAW)
}
// Sorting the data by their x transitions value
- magnitudes.sort((a,b) => a[XVALUE] - b[XVALUE])
+ magnitudes.sort((a, b) => a[XVALUE] - b[XVALUE])
// Adding the total gains.
let magnitudesBeforeTransition = []
let magnitudesAfterTransition = []
let totalMagnitudeAtStart = 0 // Magnitude at the lowest x value (sum of all high-pass magnitudes)
- for(let [om0x, magnitude, highpass] of magnitudes){
+ for(let [om0x, magnitude, highpass] of magnitudes) {
if(highpass) {
magnitudesBeforeTransition.push(magnitude)
magnitudesAfterTransition.push(0)
@@ -129,7 +143,7 @@ export default class BodeMagnitudeSum extends ExecutableObject {
}
}
}
-
+
draw(canvas) {
if(this.cachedParts.length > 0) {
for(let [limitedDrawFunction, drawDomain] of this.cachedParts) {
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs b/common/src/objs/bodephase.mjs
similarity index 67%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs
rename to common/src/objs/bodephase.mjs
index 3cafd52..9c93bba 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephase.mjs
+++ b/common/src/objs/bodephase.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -23,37 +23,48 @@ import Objects from "../module/objects.mjs"
import History from "../module/history.mjs"
import Latex from "../module/latex.mjs"
-import { ExecutableObject } from "common.mjs"
+import { ExecutableObject } from "./common.mjs"
export default class BodePhase extends ExecutableObject {
- static type(){return 'Phase Bode'}
- static displayType(){return qsTranslate("bodephase", 'Bode Phase')}
- static displayTypeMultiple(){return qsTranslate("bodephase", 'Bode Phases')}
- static properties() {return {
- [QT_TRANSLATE_NOOP('prop','om_0')]: new P.ObjectType('Point'),
- [QT_TRANSLATE_NOOP('prop','phase')]: new P.Expression(),
- [QT_TRANSLATE_NOOP('prop','unit')]: new P.Enum('°', 'deg', 'rad'),
- [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position,
- [QT_TRANSLATE_NOOP('prop','labelX')]: 'number'
- }}
-
- constructor(name = null, visible = true, color = null, labelContent = 'name + value',
- om_0 = '', phase = 90, unit = '°', labelPosition = 'above', labelX = 1) {
- if(name == null) name = Objects.getNewName('φ')
- if(name === 'φ') name = 'φ₀' // φ is reserved for sum of Bode phases.
+ static type() {
+ return "Phase Bode"
+ }
+
+ static displayType() {
+ return qsTranslate("bodephase", "Bode Phase")
+ }
+
+ static displayTypeMultiple() {
+ return qsTranslate("bodephase", "Bode Phases")
+ }
+
+ static properties() {
+ return {
+ [QT_TRANSLATE_NOOP("prop", "om_0")]: new P.ObjectType("Point"),
+ [QT_TRANSLATE_NOOP("prop", "phase")]: new P.Expression(),
+ [QT_TRANSLATE_NOOP("prop", "unit")]: new P.Enum("°", "deg", "rad"),
+ [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position,
+ [QT_TRANSLATE_NOOP("prop", "labelX")]: "number"
+ }
+ }
+
+ constructor(name = null, visible = true, color = null, labelContent = "name + value",
+ om_0 = "", phase = 90, unit = "°", labelPosition = "above", labelX = 1) {
+ if(name == null) name = Objects.getNewName("φ")
+ if(name === "φ") name = "φ₀" // φ is reserved for sum of Bode phases.
super(name, visible, color, labelContent)
- if(typeof phase == 'number' || typeof phase == 'string') phase = new Expression(phase.toString())
+ if(typeof phase == "number" || typeof phase == "string") phase = new Expression(phase.toString())
this.phase = phase
if(typeof om_0 == "string") {
// Point name or create one
om_0 = Objects.currentObjectsByName[om_0]
if(om_0 == null) {
// Create new point
- om_0 = Objects.createNewRegisteredObject('Point', [Objects.getNewName('ω'), this.color, 'name'])
- om_0.labelPosition = this.phase.execute() >= 0 ? 'above' : 'below'
- History.history.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export()))
- labelPosition = 'below'
+ om_0 = Objects.createNewRegisteredObject("Point", [Objects.getNewName("ω"), this.color, "name"])
+ om_0.labelPosition = this.phase.execute() >= 0 ? "above" : "below"
+ History.history.addToHistory(new CreateNewObject(om_0.name, "Point", om_0.export()))
+ labelPosition = "below"
}
om_0.requiredBy.push(this)
}
@@ -63,69 +74,71 @@ export default class BodePhase extends ExecutableObject {
this.labelPosition = labelPosition
this.labelX = labelX
}
-
+
getReadableString() {
return `${this.name}: ${this.phase.toString(true)}${this.unit} at ${this.om_0.name} = ${this.om_0.x}`
}
-
+
getLatexString() {
return `${Latex.variable(this.name)}: ${this.phase.latexMarkup}\\textsf{${this.unit} at }${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup}`
}
-
- execute(x=1) {
- if(typeof x == 'string') x = executeExpression(x)
+
+ execute(x = 1) {
+ if(typeof x == "string") x = executeExpression(x)
if(x < this.om_0.x) {
return this.om_0.y.execute()
} else {
return this.om_0.y.execute() + this.phase.execute()
}
}
-
+
simplify(x = 1) {
let xval = x
- if(typeof x == 'string') xval = executeExpression(x)
+ if(typeof x == "string") xval = executeExpression(x)
if(xval < this.om_0.x) {
return this.om_0.y.toString()
} else {
- let newExp = this.om_0.y.toEditableString() + ' + ' + this.phase.toEditableString()
+ let newExp = this.om_0.y.toEditableString() + " + " + this.phase.toEditableString()
return new Expression(newExp)
}
}
-
+
canExecute(x = 1) {
return true
}
-
+
draw(canvas) {
let baseX = canvas.x2px(this.om_0.x.execute())
let omy = this.om_0.y.execute()
let augmt = this.phase.execute()
let baseY = canvas.y2px(omy)
- let augmtY = canvas.y2px(omy+augmt)
+ let augmtY = canvas.y2px(omy + augmt)
// Before change line.
canvas.drawLine(0, baseY, Math.min(baseX, canvas.height), baseY)
// Transition line.
canvas.drawLine(baseX, baseY, baseX, augmtY)
// After change line
canvas.drawLine(Math.max(0, baseX), augmtY, canvas.width, augmtY)
-
+
// Label
this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX)))
}
-
+
update() {
super.update()
- let sumObjs = Objects.currentObjects['Somme phases Bode']
+ /** @type {BodePhaseSum[]} */
+ let sumObjs = Objects.currentObjects["Somme phases Bode"]
if(sumObjs !== undefined && sumObjs.length > 0) {
sumObjs[0].recalculateCache()
} else {
- Objects.createNewRegisteredObject('Somme phases Bode')
+ Objects.createNewRegisteredObject("Somme phases Bode")
}
}
-
+
delete() {
super.update()
- let sumObjs = Objects.currentObjects['Somme phases Bode']
+ /** @type {BodePhaseSum[]} */
+ let sumObjs = Objects.currentObjects["Somme phases Bode"]
if(sumObjs !== undefined && sumObjs.length > 0) {
sumObjs[0].recalculateCache()
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs b/common/src/objs/bodephasesum.mjs
similarity index 62%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs
rename to common/src/objs/bodephasesum.mjs
index cee3235..90864d7 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/bodephasesum.mjs
+++ b/common/src/objs/bodephasesum.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -21,104 +21,117 @@ import * as P from "../parameters.mjs"
import Objects from "../module/objects.mjs"
import Latex from "../module/latex.mjs"
-import { ExecutableObject } from "common.mjs"
+import { ExecutableObject } from "./common.mjs"
export default class BodePhaseSum extends ExecutableObject {
- static type(){return 'Somme phases Bode'}
- static displayType(){return qsTranslate("bodephasesum", 'Bode Phases Sum')}
- static displayTypeMultiple(){return qsTranslate("bodephasesum", 'Bode Phases Sum')}
- static createable() {return false}
- static properties() {return {
- [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position,
- [QT_TRANSLATE_NOOP('prop','labelX')]: 'number',
- }}
-
- constructor(name = null, visible = true, color = null, labelContent = 'name + value',
- labelPosition = 'above', labelX = 1) {
- if(name == null) name = 'φ'
+ static type() {
+ return "Somme phases Bode"
+ }
+
+ static displayType() {
+ return qsTranslate("bodephasesum", "Bode Phases Sum")
+ }
+
+ static displayTypeMultiple() {
+ return qsTranslate("bodephasesum", "Bode Phases Sum")
+ }
+
+ static createable() {
+ return false
+ }
+
+ static properties() {
+ return {
+ [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position,
+ [QT_TRANSLATE_NOOP("prop", "labelX")]: "number"
+ }
+ }
+
+ constructor(name = null, visible = true, color = null, labelContent = "name + value",
+ labelPosition = "above", labelX = 1) {
+ if(name == null) name = "φ"
super(name, visible, color, labelContent)
this.labelPosition = labelPosition
this.labelX = labelX
this.recalculateCache()
}
-
+
getReadableString() {
- return `${this.name} = ${Objects.getObjectsName('Phase Bode').join(' + ')}`
+ return `${this.name} = ${Objects.getObjectsName("Phase Bode").join(" + ")}`
}
-
+
getLatexString() {
- return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Phase Bode').map(name => Latex.variable(name)).join(' + ')}`
+ return `${Latex.variable(this.name)} = ${Objects.getObjectsName("Phase Bode").map(name => Latex.variable(name)).join(" + ")}`
}
-
- execute(x=1) {
- if(typeof x == 'string') x = executeExpression(x)
- for(let i = 0; i < this.om0xList.length-1; i++) {
- if(x >= this.om0xList[i] && x < this.om0xList[i+1]) return this.phasesList[i]
+
+ execute(x = 1) {
+ if(typeof x == "string") x = executeExpression(x)
+ for(let i = 0; i < this.om0xList.length - 1; i++) {
+ if(x >= this.om0xList[i] && x < this.om0xList[i + 1]) return this.phasesList[i]
}
}
-
+
simplify(x = 1) {
let xval = x
- if(typeof x == 'string') xval = executeExpression(x)
- for(let i = 0; i < this.om0xList.length-1; i++) {
- if(xval >= this.om0xList[i] && xval < this.om0xList[i+1]) {
+ if(typeof x == "string") xval = executeExpression(x)
+ for(let i = 0; i < this.om0xList.length - 1; i++) {
+ if(xval >= this.om0xList[i] && xval < this.om0xList[i + 1]) {
return (new Expression(this.phasesExprList[i])).simplify()
}
}
- return '0'
+ return "0"
}
-
+
canExecute(x = 1) {
return true
}
-
+
recalculateCache() {
// Minimum to draw (can be expended if needed, just not infinite or it'll cause issues.
let drawMin = 1e-20
let drawMax = 1e20
this.om0xList = [drawMin, drawMax]
this.phasesList = [0]
- this.phasesExprList = ['0']
+ this.phasesExprList = ["0"]
let phasesDict = new Map()
let phasesExprDict = new Map()
phasesDict.set(drawMax, 0)
-
- let phaseObjects = Objects.currentObjects['Phase Bode']
+
+ let phaseObjects = Objects.currentObjects["Phase Bode"]
if(phaseObjects === undefined || phaseObjects.length < 1) {
Objects.deleteObject(this.name)
} else {
- console.log('Recalculating cache phase')
- for(/** @type {Bodephase} */ let obj of phaseObjects) {
+ console.log("Recalculating cache phase")
+ for(/** @type {BodePhase} */ let obj of phaseObjects) {
this.om0xList.push(obj.om_0.x.execute())
if(!phasesDict.has(obj.om_0.x.execute())) {
phasesDict.set(obj.om_0.x.execute(), obj.phase.execute())
phasesExprDict.set(obj.om_0.x.execute(), obj.phase.toEditableString())
} else {
phasesDict.set(obj.om_0.x.execute(), obj.phase.execute() + phasesDict.get(obj.om_0.x.execute()))
- phasesExprDict.set(obj.om_0.x.execute(), obj.phase.toEditableString() + '+' + phasesExprDict.get(obj.om_0.x.execute()))
+ phasesExprDict.set(obj.om_0.x.execute(), obj.phase.toEditableString() + "+" + phasesExprDict.get(obj.om_0.x.execute()))
}
this.phasesList[0] += obj.om_0.y.execute()
- this.phasesExprList[0] += '+' + obj.om_0.y.toEditableString()
+ this.phasesExprList[0] += "+" + obj.om_0.y.toEditableString()
}
- this.om0xList.sort((a,b) => a - b)
- let totalAdded = this.phasesList[0]
+ this.om0xList.sort((a, b) => a - b)
for(let i = 1; i < this.om0xList.length; i++) {
- this.phasesList[i] = this.phasesList[i-1] + phasesDict.get(this.om0xList[i])
- this.phasesExprList[i] = this.phasesExprList[i-1] + '+' + phasesDict.get(this.om0xList[i])
+ this.phasesList[i] = this.phasesList[i - 1] + phasesDict.get(this.om0xList[i])
+ this.phasesExprList[i] = this.phasesExprList[i - 1] + "+" + phasesDict.get(this.om0xList[i])
}
}
}
-
+
draw(canvas) {
- for(let i = 0; i < this.om0xList.length-1; i++) {
+ for(let i = 0; i < this.om0xList.length - 1; i++) {
let om0xBegin = canvas.x2px(this.om0xList[i])
- let om0xEnd = canvas.x2px(this.om0xList[i+1])
+ let om0xEnd = canvas.x2px(this.om0xList[i + 1])
let baseY = canvas.y2px(this.phasesList[i])
- let nextY = canvas.y2px(this.phasesList[i+1])
+ let nextY = canvas.y2px(this.phasesList[i + 1])
canvas.drawLine(om0xBegin, baseY, om0xEnd, baseY)
canvas.drawLine(om0xEnd, baseY, om0xEnd, nextY)
}
-
+
// Label
this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX)))
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/common/src/objs/common.mjs
similarity index 74%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs
rename to common/src/objs/common.mjs
index 9b13fbd..891fdd5 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs
+++ b/common/src/objs/common.mjs
@@ -1,25 +1,25 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-import { getRandomColor, textsub } from "../utils.mjs"
+import { getRandomColor } from "../utils.mjs"
import Objects from "../module/objects.mjs"
import Latex from "../module/latex.mjs"
-import {ensureTypeSafety, serializesByPropertyType} from "../parameters.mjs"
+import { ensureTypeSafety, serializesByPropertyType } from "../parameters.mjs"
// This file contains the default data to be imported from all other objects
@@ -32,52 +32,64 @@ export class DrawableObject {
* Base name of the object. Needs to be constant over time.
* @return {string} Type of the object.
*/
- static type(){return 'Unknown'}
-
+ static type() {
+ return "Unknown"
+ }
+
/**
* Translated name of the object to be shown to the user.
* @return {string}
*/
- static displayType(){return 'Unknown'}
-
+ static displayType() {
+ return "Unknown"
+ }
+
/**
* Translated name of the object in plural form to be shown to the user.
* @return {string}
*/
- static displayTypeMultiple(){return 'Unknowns'}
-
+ static displayTypeMultiple() {
+ return "Unknowns"
+ }
+
/**
* True if this object can be created by the user, false if it can only
* be instantiated by other objects
* @return {boolean}
*/
- static createable() {return true}
-
+ static createable() {
+ return true
+ }
+
/**
* List of properties used in the Object Editor.
- *
+ *
* Properties are set with key as property name and
* value as it's type name (e.g 'numbers', 'string'...),
* an Enum for enumerations, an ObjectType for DrawableObjects
- * with a specific type, a List instance for lists, a
+ * with a specific type, a List instance for lists, a
* Dictionary instance for dictionaries, an Expression for expressions...
- *
+ *
* If the property is to be translated, the key should be passed
* through the QT_TRANSLATE_NOOP macro in that form:
* [QT_TRANSLATE_NOOP('prop','key')]
- * Enums that are translated should be indexed in parameters.mjs and
+ * Enums that are translated should be indexed in parameters.mjs and
* then be linked directly here.
- *
+ *
* @return {Object.}
*/
- static properties() {return {}}
-
+ static properties() {
+ return {}
+ }
+
/**
* True if this object can be executed, so that an y value might be computed
* for an x value. Only ExecutableObjects have that property set to true.
* @return {boolean}
*/
- static executable() {return false}
+ static executable() {
+ return false
+ }
/**
* Imports the object from its serialized form.
@@ -85,23 +97,23 @@ export class DrawableObject {
*/
static import(name, visible, color, labelContent, ...args) {
let importedArgs = [name.toString(), visible === true, color.toString(), labelContent]
- console.log('Importing', this.type(), name, args)
+ console.log("Importing", this.type(), name, args)
for(let [name, propType] of Object.entries(this.properties()))
- if(!name.startsWith('comment')) {
- importedArgs.push(ensureTypeSafety(propType, args[importedArgs.length-4]))
+ if(!name.startsWith("comment")) {
+ importedArgs.push(ensureTypeSafety(propType, args[importedArgs.length - 4]))
}
return new this(...importedArgs)
}
-
+
/**
* Base constructor for the object.
* @param {string} name - Name of the object
* @param {boolean} visible - true if the object is visible, false otherwise.
* @param {color|string} color - Color of the object (can be string or QColor)
- * @param {'null'|'name'|'name + value'} labelContent - One of 'null', 'name' or 'name + value' describing the content of the label.
+ * @param {"null"|"name"|"name + value"} labelContent - One of 'null', 'name' or 'name + value' describing the content of the label.
* @constructor
*/
- constructor(name, visible = true, color = null, labelContent = 'name + value') {
+ constructor(name, visible = true, color = null, labelContent = "name + value") {
if(color == null) color = getRandomColor()
this.type = this.constructor.type()
this.name = name
@@ -120,11 +132,11 @@ export class DrawableObject {
export() {
let exportList = [this.name, this.visible, this.color.toString(), this.labelContent]
for(let [name, propType] of Object.entries(this.constructor.properties()))
- if(!name.startsWith('comment'))
+ if(!name.startsWith("comment"))
exportList.push(serializesByPropertyType(propType, this[name]))
return exportList
}
-
+
/**
* String representing the object that will be displayed to the user.
* It allows for 2 lines and translated text, but it shouldn't be too long.
@@ -133,10 +145,10 @@ export class DrawableObject {
getReadableString() {
return `${this.name} = Unknown`
}
-
+
/**
* Latex markuped version of the readable string.
- * Every non latin character should be passed as latex symbols and formulas
+ * Every non latin character should be passed as latex symbols and formulas
* should be in latex form.
* See ../latex.mjs for helper methods.
* @return {string}
@@ -144,42 +156,42 @@ export class DrawableObject {
getLatexString() {
return this.getReadableString()
}
-
+
/**
* Readable string content of the label depending on the value of the latexContent.
* @return {string}
*/
getLabel() {
switch(this.labelContent) {
- case 'name':
+ case "name":
return this.name
- case 'name + value':
+ case "name + value":
return this.getReadableString()
- case 'null':
- return ''
-
+ case "null":
+ return ""
+
}
}
-
+
/**
* Latex markup string content of the label depending on the value of the latexContent.
- * Every non latin character should be passed as latex symbols and formulas
+ * Every non latin character should be passed as latex symbols and formulas
* should be in latex form.
* See ../latex.mjs for helper methods.
* @return {string}
*/
getLatexLabel() {
switch(this.labelContent) {
- case 'name':
+ case "name":
return Latex.variable(this.name)
- case 'name + value':
+ case "name + value":
return this.getLatexString()
- case 'null':
- return ''
-
+ case "null":
+ return ""
+
}
}
-
+
/**
* Returns the recursive list of objects this one depends on.
* @return {array}
@@ -190,7 +202,7 @@ export class DrawableObject {
dependencies = dependencies.concat(obj.getDependenciesList())
return dependencies
}
-
+
/**
* Callback method when one of the properties of the object is updated.
*/
@@ -203,8 +215,8 @@ export class DrawableObject {
let currentObjectsByName = Objects.currentObjectsByName
let properties = this.constructor.properties()
for(let property in properties)
- if(typeof properties[property] == 'object' && 'type' in properties[property])
- if(properties[property].type === 'Expression' && this[property] != null) {
+ if(typeof properties[property] == "object" && "type" in properties[property])
+ if(properties[property].type === "Expression" && this[property] != null) {
// Expressions with dependencies
for(let objName of this[property].requiredObjects()) {
if(objName in currentObjectsByName && !this.requires.includes(currentObjectsByName[objName])) {
@@ -215,8 +227,8 @@ export class DrawableObject {
if(this[property].cached && this[property].requiredObjects().length > 0)
// Recalculate
this[property].recache()
-
- } else if(properties[property].type === 'ObjectType' && this[property] != null) {
+
+ } else if(properties[property].type === "ObjectType" && this[property] != null) {
// Object dependency
this.requires.push(this[property])
this[property].requiredBy.push(this)
@@ -225,7 +237,7 @@ export class DrawableObject {
for(let req of this.requiredBy)
req.update()
}
-
+
/**
* Callback method when the object is about to get deleted.
*/
@@ -237,64 +249,65 @@ export class DrawableObject {
toRemoveFrom.requiredBy = toRemoveFrom.requiredBy.filter(o => o !== this)
}
}
-
+
/**
* Abstract method. Draw the object onto the canvas with the.
* @param {CanvasAPI} canvas
*/
- draw(canvas) {}
-
+ draw(canvas) {
+ }
+
/**
- * Applicates a drawFunction with two position arguments depending on
- * both the posX and posY of where the label should be displayed,
+ * Applicates a drawFunction with two position arguments depending on
+ * both the posX and posY of where the label should be displayed,
* and the labelPosition which declares the label should be displayed
* relatively to that position.
- *
+ *
* @param {string|Enum} labelPosition - Position of the label relative to the marked position
* @param {number} offset - Margin between the position and the object to be drawn
- * @param {Object.} size - Size of the label item, containing two properties, "width" and "height"
- * @param {number} posX - Component of the marked position on the x-axis
- * @param {number} posY - Component of the marked position on the y-axis
- * @param {function} drawFunction - Function with two arguments (x, y) that will be called to draw the label
+ * @param {{width: number, height: number}} size - Size of the label item, containing two properties, "width" and "height"
+ * @param {number} posX - Component of the marked position on the x-axis
+ * @param {number} posY - Component of the marked position on the y-axis
+ * @param {function} drawFunction - Function with two arguments (x, y) that will be called to draw the label
*/
drawPositionDivergence(labelPosition, offset, size, posX, posY, drawFunction) {
switch(labelPosition) {
- case 'center':
- drawFunction(posX-size.width/2, posY-size.height/2)
- break;
- case 'top':
- case 'above':
- drawFunction(posX-size.width/2, posY-size.height-offset)
- break;
- case 'bottom':
- case 'below':
- drawFunction(posX-size.width/2, posY+offset)
- break;
- case 'left':
- drawFunction(posX-size.width-offset, posY-size.height/2)
- break;
- case 'right':
- drawFunction(posX+offset, posY-size.height/2)
- break;
- case 'top-left':
- case 'above-left':
- drawFunction(posX-size.width, posY-size.height-offset)
- break;
- case 'top-right':
- case 'above-right':
- drawFunction(posX+offset, posY-size.height-offset)
- break;
- case 'bottom-left':
- case 'below-left':
- drawFunction(posX-size.width-offset, posY+offset)
- break;
- case 'bottom-right':
- case 'below-right':
- drawFunction(posX+offset, posY+offset)
- break;
+ case "center":
+ drawFunction(posX - size.width / 2, posY - size.height / 2)
+ break
+ case "top":
+ case "above":
+ drawFunction(posX - size.width / 2, posY - size.height - offset)
+ break
+ case "bottom":
+ case "below":
+ drawFunction(posX - size.width / 2, posY + offset)
+ break
+ case "left":
+ drawFunction(posX - size.width - offset, posY - size.height / 2)
+ break
+ case "right":
+ drawFunction(posX + offset, posY - size.height / 2)
+ break
+ case "top-left":
+ case "above-left":
+ drawFunction(posX - size.width, posY - size.height - offset)
+ break
+ case "top-right":
+ case "above-right":
+ drawFunction(posX + offset, posY - size.height - offset)
+ break
+ case "bottom-left":
+ case "below-left":
+ drawFunction(posX - size.width - offset, posY + offset)
+ break
+ case "bottom-right":
+ case "below-right":
+ drawFunction(posX + offset, posY + offset)
+ break
}
}
-
+
/**
* Automatically draw text (by default the label of the object on the canvas
* depending on user settings.
@@ -304,55 +317,54 @@ export class DrawableObject {
* depending on whether to use latex.
* Then, it's displayed using the drawFunctionLatex (x,y,imageData) and
* drawFunctionText (x,y,text) depending on whether to use latex.
- *
+ *
* @param {CanvasAPI} canvas
* @param {string|Enum} labelPosition - Position of the label relative to the marked position
- * @param {number} posX - Component of the marked position on the x-axis
- * @param {number} posY - Component of the marked position on the y-axis
+ * @param {number} posX - Component of the marked position on the x-axis
+ * @param {number} posY - Component of the marked position on the y-axis
* @param {boolean} forceText - Force the rendering of the label as text
* @param {function|null} getLatexFunction - Function (no argument) to get the latex markup to be displayed
* @param {function|null} getTextFunction - Function (no argument) to get the text to be displayed
* @param {function|null} drawFunctionLatex - Function (x,y,imageData) to display the latex image
* @param {function|null} drawFunctionText - Function (x,y,text,textSize) to display the text
*/
- drawLabel(canvas, labelPosition, posX, posY,forceText = false,
- getLatexFunction = null, getTextFunction = null, drawFunctionLatex = null, drawFunctionText = null) {
+ drawLabel(canvas, labelPosition, posX, posY, forceText = false,
+ getLatexFunction = null, getTextFunction = null, drawFunctionLatex = null, drawFunctionText = null) {
// Default functions
if(getLatexFunction == null)
getLatexFunction = this.getLatexLabel.bind(this)
if(getTextFunction == null)
getTextFunction = this.getLabel.bind(this)
if(drawFunctionLatex == null)
- drawFunctionLatex = (x,y,ltxImg) => canvas.drawVisibleImage(ltxImg.source, x, y, ltxImg.width, ltxImg.height)
+ drawFunctionLatex = (x, y, ltxImg) => canvas.drawVisibleImage(ltxImg.source, x, y, ltxImg.width, ltxImg.height)
if(drawFunctionText == null)
- drawFunctionText = (x,y,text,textSize) => canvas.drawVisibleText(text, x, y+textSize.height) // Positioned from left bottom
+ drawFunctionText = (x, y, text, textSize) => canvas.drawVisibleText(text, x, y + textSize.height) // Positioned from left bottom
// Drawing the label
- let offset
if(!forceText && Latex.enabled) {
// With latex
let drawLblCb = ((ltxImg) => {
- this.drawPositionDivergence(labelPosition, 8+canvas.linewidth/2, ltxImg, posX, posY, (x,y) => drawFunctionLatex(x,y,ltxImg))
- }).bind(this)
- let ltxLabel = getLatexFunction();
+ this.drawPositionDivergence(labelPosition, 8 + canvas.linewidth / 2, ltxImg, posX, posY, (x, y) => drawFunctionLatex(x, y, ltxImg))
+ })
+ let ltxLabel = getLatexFunction()
if(ltxLabel !== "")
- canvas.renderLatexImage(ltxLabel, this.color, drawLblCb.bind(this))
+ canvas.renderLatexImage(ltxLabel, this.color, drawLblCb)
} else {
// Without latex
let text = getTextFunction()
canvas.font = `${canvas.textsize}px sans-serif`
let textSize = canvas.measureText(text)
- this.drawPositionDivergence(labelPosition, 8+canvas.linewidth/2, textSize, posX, posY, (x,y) => drawFunctionText(x,y,text,textSize))
+ this.drawPositionDivergence(labelPosition, 8 + canvas.linewidth / 2, textSize, posX, posY, (x, y) => drawFunctionText(x, y, text, textSize))
}
}
-
+
toString() {
- return this.name;
+ return this.name
}
}
/**
- * Class to be extended for every object on which
+ * Class to be extended for every object on which
* an y for a x can be computed with the execute function.
* If a value cannot be found during execute, it will
* return null. However, theses same x values will
@@ -363,32 +375,42 @@ export class ExecutableObject extends DrawableObject {
* Returns the corresponding y value for an x value.
* If the object isn't defined on the given x, then
* this function will return null.
- *
+ *
* @param {number} x
* @returns {number|null}
*/
- execute(x = 1) {return 0}
+ execute(x = 1) {
+ return 0
+ }
+
/**
* Returns false if the object isn't defined on the given x, true otherwise.
- *
+ *
* @param {number} x
* @returns {boolean}
*/
- canExecute(x = 1) {return true}
+ canExecute(x = 1) {
+ return true
+ }
+
/**
* Returns the simplified expression string for a given x.
- *
+ *
* @param {number} x
* @returns {string|Expression}
*/
- simplify(x = 1) {return '0'}
-
+ simplify(x = 1) {
+ return "0"
+ }
+
/**
* True if this object can be executed, so that an y value might be computed
* for an x value. Only ExecutableObjects have that property set to true.
* @return {boolean}
*/
- static executable() {return true}
+ static executable() {
+ return true
+ }
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs b/common/src/objs/distribution.mjs
similarity index 53%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs
rename to common/src/objs/distribution.mjs
index 1ad9a7e..16aa4d4 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/distribution.mjs
+++ b/common/src/objs/distribution.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -20,22 +20,34 @@ import * as P from "../parameters.mjs"
import Objects from "../module/objects.mjs"
import Latex from "../module/latex.mjs"
-import { ExecutableObject } from "common.mjs"
+import { ExecutableObject } from "./common.mjs"
export default class DistributionFunction extends ExecutableObject {
- static type(){return 'Repartition'}
- static displayType(){return qsTranslate("distribution", 'Repartition')}
- static displayTypeMultiple(){return qsTranslate("distribution", 'Repartition functions')}
- static properties() {return {
- 'comment1': QT_TRANSLATE_NOOP(
- 'comment',
- 'Note: Specify the probability for each value.'
- ),
- [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'double', /^-?[\d.,]+$/, /^-?[\d.,]+$/, 'P({name_} = ', ') = '),
- [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position,
- [QT_TRANSLATE_NOOP('prop','labelX')]: 'number',
- }}
+ static type() {
+ return "Repartition"
+ }
+
+ static displayType() {
+ return qsTranslate("distribution", "Repartition")
+ }
+
+ static displayTypeMultiple() {
+ return qsTranslate("distribution", "Repartition functions")
+ }
+
+ static properties() {
+ return {
+ "comment1": QT_TRANSLATE_NOOP(
+ "comment",
+ "Note: Specify the probability for each value."
+ ),
+ [QT_TRANSLATE_NOOP("prop", "probabilities")]: new P.Dictionary("string", "double", /^-?[\d.,]+$/, /^-?[\d.,]+$/, "P({name_} = ", ") = "),
+ [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position,
+ [QT_TRANSLATE_NOOP("prop", "labelX")]: "number"
+ }
+ }
+
static import(name, visible, color, labelContent, ...args) {
console.log(args, args.length)
if(args.length === 5) {
@@ -45,99 +57,101 @@ export default class DistributionFunction extends ExecutableObject {
}
return super.import(name, visible, color, labelContent, ...args)
}
-
- constructor(name = null, visible = true, color = null, labelContent = 'name + value',
- probabilities = {'0': '0'}, labelPosition = 'above', labelX = 1) {
- if(name == null) name = Objects.getNewName('XYZUVW', "F_")
+
+ constructor(name = null, visible = true, color = null, labelContent = "name + value",
+ probabilities = { "0": "0" }, labelPosition = "above", labelX = 1) {
+ if(name == null) name = Objects.getNewName("XYZUVW", "F_")
super(name, visible, color, labelContent)
this.probabilities = probabilities
this.labelPosition = labelPosition
this.labelX = labelX
this.update()
}
-
+
getReadableString() {
- let keys = Object.keys(this.probabilities).sort((a,b) => a-b);
- let varname = this.name.substring(this.name.indexOf("_")+1)
+ let keys = Object.keys(this.probabilities).sort((a, b) => a - b)
+ let varname = this.name.substring(this.name.indexOf("_") + 1)
return `${this.name}(x) = P(${varname} ≤ x)\n` + keys.map(idx => `P(${varname}=${idx})=${this.probabilities[idx]}`).join("; ")
}
-
+
getLatexString() {
- let keys = Object.keys(this.probabilities).sort((a,b) => a-b);
+ let keys = Object.keys(this.probabilities).sort((a, b) => a - b)
let funcName = Latex.variable(this.name)
- let varName = Latex.variable(this.name.substring(this.name.indexOf("_")+1))
- return `\\begin{array}{l}{${funcName}}(x) = P(${varName} \\le x)\\\\` + keys.map(idx => `P(${varName}=${idx})=${this.probabilities[idx]}`).join("; ") + '\\end{array}'
+ let varName = Latex.variable(this.name.substring(this.name.indexOf("_") + 1))
+ return `\\begin{array}{l}{${funcName}}(x) = P(${varName} \\le x)\\\\` + keys.map(idx => `P(${varName}=${idx})=${this.probabilities[idx]}`).join("; ") + "\\end{array}"
}
-
+
execute(x = 1) {
- let ret = 0;
- Object.keys(this.probabilities).sort((a,b) => a-b).forEach(idx => {
- if(x >= idx) ret += parseFloat(this.probabilities[idx].replace(/,/g, '.'))
+ let ret = 0
+ Object.keys(this.probabilities).sort((a, b) => a - b).forEach(idx => {
+ if(x >= idx) ret += parseFloat(this.probabilities[idx].replace(/,/g, "."))
})
return ret
}
-
- canExecute(x = 1) {return true}
+
+ canExecute(x = 1) {
+ return true
+ }
// Simplify returns the simplified string of the expression.
simplify(x = 1) {
return this.execute(x).toString()
}
-
+
getLabel() {
switch(this.labelContent) {
- case 'name':
+ case "name":
return `${this.name}(x)`
- case 'name + value':
+ case "name + value":
return this.getReadableString()
- case 'null':
- return ''
+ case "null":
+ return ""
}
}
-
+
draw(canvas) {
- let currentY = 0;
- let keys = Object.keys(this.probabilities).map(idx => parseInt(idx)).sort((a,b) => a-b)
- if(canvas.isVisible(keys[0],this.probabilities[keys[0]].replace(/,/g, '.'))) {
+ let currentY = 0
+ let keys = Object.keys(this.probabilities).map(idx => parseInt(idx)).sort((a, b) => a - b)
+ if(canvas.isVisible(keys[0], this.probabilities[keys[0]].replace(/,/g, "."))) {
canvas.drawLine(0, canvas.y2px(0), canvas.x2px(keys[0]), canvas.y2px(0))
- if(canvas.isVisible(keys[0],0)) {
- canvas.arc(canvas.x2px(keys[0])+4,canvas.y2px(0), 4, Math.PI / 2, 3 * Math.PI / 2);
+ if(canvas.isVisible(keys[0], 0)) {
+ canvas.arc(canvas.x2px(keys[0]) + 4, canvas.y2px(0), 4, Math.PI / 2, 3 * Math.PI / 2)
}
}
- for(let i = 0; i < keys.length-1; i++) {
- let idx = keys[i];
- currentY += parseFloat(this.probabilities[idx].replace(/,/g, '.'));
- if(canvas.isVisible(idx,currentY) || canvas.isVisible(keys[i+1],currentY)) {
+ for(let i = 0; i < keys.length - 1; i++) {
+ let idx = keys[i]
+ currentY += parseFloat(this.probabilities[idx].replace(/,/g, "."))
+ if(canvas.isVisible(idx, currentY) || canvas.isVisible(keys[i + 1], currentY)) {
canvas.drawLine(
- Math.max(0,canvas.x2px(idx)),
+ Math.max(0, canvas.x2px(idx)),
canvas.y2px(currentY),
- Math.min(canvas.width,canvas.x2px(keys[i+1])),
+ Math.min(canvas.width, canvas.x2px(keys[i + 1])),
canvas.y2px(currentY)
)
- if(canvas.isVisible(idx,currentY)) {
+ if(canvas.isVisible(idx, currentY)) {
canvas.disc(canvas.x2px(idx), canvas.y2px(currentY), 4)
}
- if(canvas.isVisible(keys[i+1],currentY)) {
- canvas.arc(canvas.x2px(keys[i+1])+4,canvas.y2px(currentY), 4, Math.PI / 2, 3 * Math.PI / 2);
+ if(canvas.isVisible(keys[i + 1], currentY)) {
+ canvas.arc(canvas.x2px(keys[i + 1]) + 4, canvas.y2px(currentY), 4, Math.PI / 2, 3 * Math.PI / 2)
}
}
}
- if(canvas.isVisible(keys[keys.length-1],currentY+parseFloat(this.probabilities[keys[keys.length-1]]))) {
+ if(canvas.isVisible(keys[keys.length - 1], currentY + parseFloat(this.probabilities[keys[keys.length - 1]]))) {
canvas.drawLine(
- Math.max(0,canvas.x2px(keys[keys.length-1])),
- canvas.y2px(currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.'))),
+ Math.max(0, canvas.x2px(keys[keys.length - 1])),
+ canvas.y2px(currentY + parseFloat(this.probabilities[keys[keys.length - 1]].replace(/,/g, "."))),
canvas.width,
- canvas.y2px(currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.')))
+ canvas.y2px(currentY + parseFloat(this.probabilities[keys[keys.length - 1]].replace(/,/g, ".")))
)
canvas.disc(
- canvas.x2px(keys[keys.length-1]),
+ canvas.x2px(keys[keys.length - 1]),
canvas.y2px(
- currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.'))
+ currentY + parseFloat(this.probabilities[keys[keys.length - 1]].replace(/,/g, "."))
),
4
)
}
-
+
// Label
this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX)))
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/common/src/objs/function.mjs
similarity index 68%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs
rename to common/src/objs/function.mjs
index 752aa52..1e345cb 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs
+++ b/common/src/objs/function.mjs
@@ -1,63 +1,74 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import { textsub } from "../utils.mjs"
import Objects from "../module/objects.mjs"
-import { ExecutableObject } from "common.mjs"
+import { ExecutableObject } from "./common.mjs"
import { parseDomain, Expression, SpecialDomain } from "../math/index.mjs"
import * as P from "../parameters.mjs"
import Latex from "../module/latex.mjs"
export default class Function extends ExecutableObject {
- static type(){return 'Function'}
- static displayType(){return qsTranslate("function", 'Function')}
- static displayTypeMultiple(){return qsTranslate("function", 'Functions')}
- static properties() {return {
- [QT_TRANSLATE_NOOP('prop','expression')]: new P.Expression('x'),
- [QT_TRANSLATE_NOOP('prop','definitionDomain')]: 'Domain',
- [QT_TRANSLATE_NOOP('prop','destinationDomain')]: 'Domain',
- 'comment1': QT_TRANSLATE_NOOP(
- 'comment',
- 'Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5}'
- ),
- [QT_TRANSLATE_NOOP('prop','displayMode')]: P.Enum.FunctionDisplayType,
- [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position,
- [QT_TRANSLATE_NOOP('prop','labelX')]: 'number',
- 'comment2': QT_TRANSLATE_NOOP(
- 'comment',
- 'The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...)'
- ),
- [QT_TRANSLATE_NOOP('prop','drawPoints')]: 'boolean',
- [QT_TRANSLATE_NOOP('prop','drawDashedLines')]: 'boolean'
- }}
-
- constructor(name = null, visible = true, color = null, labelContent = 'name + value',
- expression = 'x', definitionDomain = 'RPE', destinationDomain = 'R',
- displayMode = 'application', labelPosition = 'above', labelX = 1,
- drawPoints = true, drawDashedLines = true) {
- if(name == null) name = Objects.getNewName('fghjqlmnopqrstuvwabcde')
+ static type() {
+ return "Function"
+ }
+
+ static displayType() {
+ return qsTranslate("function", "Function")
+ }
+
+ static displayTypeMultiple() {
+ return qsTranslate("function", "Functions")
+ }
+
+ static properties() {
+ return {
+ [QT_TRANSLATE_NOOP("prop", "expression")]: new P.Expression("x"),
+ [QT_TRANSLATE_NOOP("prop", "definitionDomain")]: "Domain",
+ [QT_TRANSLATE_NOOP("prop", "destinationDomain")]: "Domain",
+ "comment1": QT_TRANSLATE_NOOP(
+ "comment",
+ "Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5}"
+ ),
+ [QT_TRANSLATE_NOOP("prop", "displayMode")]: P.Enum.FunctionDisplayType,
+ [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position,
+ [QT_TRANSLATE_NOOP("prop", "labelX")]: "number",
+ "comment2": QT_TRANSLATE_NOOP(
+ "comment",
+ "The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...)"
+ ),
+ [QT_TRANSLATE_NOOP("prop", "drawPoints")]: "boolean",
+ [QT_TRANSLATE_NOOP("prop", "drawDashedLines")]: "boolean"
+ }
+ }
+
+ constructor(name = null, visible = true, color = null, labelContent = "name + value",
+ expression = "x", definitionDomain = "RPE", destinationDomain = "R",
+ displayMode = "application", labelPosition = "above", labelX = 1,
+ drawPoints = true, drawDashedLines = true) {
+ if(name == null) name = Objects.getNewName("fghjqlmnopqrstuvwabcde")
super(name, visible, color, labelContent)
- if(typeof expression == 'number' || typeof expression == 'string') expression = new Expression(expression.toString())
+ if(typeof expression == "number" || typeof expression == "string") expression = new Expression(expression.toString())
this.expression = expression
- if(typeof definitionDomain == 'string') definitionDomain = parseDomain(definitionDomain)
+ if(typeof definitionDomain == "string") definitionDomain = parseDomain(definitionDomain)
this.definitionDomain = definitionDomain
- if(typeof destinationDomain == 'string') destinationDomain = parseDomain(destinationDomain)
+ if(typeof destinationDomain == "string") destinationDomain = parseDomain(destinationDomain)
this.destinationDomain = destinationDomain
this.displayMode = displayMode
this.labelPosition = labelPosition
@@ -65,17 +76,17 @@ export default class Function extends ExecutableObject {
this.drawPoints = drawPoints
this.drawDashedLines = drawDashedLines
}
-
+
getReadableString() {
- if(this.displayMode === 'application') {
- return `${this.name}: ${this.definitionDomain} ⟶ ${this.destinationDomain}\n ${' '.repeat(this.name.length)}x ⟼ ${this.expression.toString()}`
+ if(this.displayMode === "application") {
+ return `${this.name}: ${this.definitionDomain} ⟶ ${this.destinationDomain}\n ${" ".repeat(this.name.length)}x ⟼ ${this.expression.toString()}`
} else {
return `${this.name}(x) = ${this.expression.toString()}\nD${textsub(this.name)} = ${this.definitionDomain}`
}
}
-
+
getLatexString() {
- if(this.displayMode === 'application') {
+ if(this.displayMode === "application") {
return `${Latex.variable(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup}\\textrm{ } & \\rightarrow & \\textrm{ }${this.destinationDomain.latexMarkup}\\\\
x\\textrm{ } & \\mapsto & \\textrm{ }${this.expression.latexMarkup}\\end{array}`
} else {
@@ -88,17 +99,17 @@ export default class Function extends ExecutableObject {
return this.expression.execute(x)
return null
}
-
+
canExecute(x = 1) {
return this.definitionDomain.includes(x)
}
-
+
simplify(x = 1) {
if(this.definitionDomain.includes(x))
return this.expression.simplify(x)
- return ''
+ return ""
}
-
+
draw(canvas) {
Function.drawFunction(canvas, this.expression, this.definitionDomain, this.destinationDomain, this.drawPoints, this.drawDashedLines)
// Label
@@ -112,7 +123,7 @@ export default class Function extends ExecutableObject {
static drawFunction(canvas, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) {
let pxprecision = 10
let previousX = canvas.px2x(0)
- let previousY = null;
+ let previousY = null
if(definitionDomain instanceof SpecialDomain && definitionDomain.moveSupported) {
// Point based functions.
previousX = definitionDomain.next(previousX)
@@ -121,16 +132,16 @@ export default class Function extends ExecutableObject {
if(!drawPoints && !drawDash) return
while(previousX !== null && canvas.x2px(previousX) < canvas.width) {
// Reconverted for canvas to fix for logarithmic scales.
- let currentX = definitionDomain.next(canvas.px2x(canvas.x2px(previousX)+pxprecision));
+ let currentX = definitionDomain.next(canvas.px2x(canvas.x2px(previousX) + pxprecision))
let currentY = expr.execute(currentX)
- if(currentX === null) break;
+ if(currentX === null) break
if((definitionDomain.includes(currentX) || definitionDomain.includes(previousX)) &&
(destinationDomain.includes(currentY) || destinationDomain.includes(previousY))) {
if(drawDash)
canvas.drawDashedLine(canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY))
if(drawPoints) {
- canvas.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2)
- canvas.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10)
+ canvas.fillRect(canvas.x2px(previousX) - 5, canvas.y2px(previousY) - 1, 10, 2)
+ canvas.fillRect(canvas.x2px(previousX) - 1, canvas.y2px(previousY) - 5, 2, 10)
}
}
previousX = currentX
@@ -138,8 +149,8 @@ export default class Function extends ExecutableObject {
}
if(drawPoints) {
// Drawing the last cross
- canvas.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2)
- canvas.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10)
+ canvas.fillRect(canvas.x2px(previousX) - 5, canvas.y2px(previousY) - 1, 10, 2)
+ canvas.fillRect(canvas.x2px(previousX) - 1, canvas.y2px(previousY) - 5, 2, 10)
}
} else {
// Use max precision if function is trigonometrical on log scale.
@@ -154,9 +165,9 @@ export default class Function extends ExecutableObject {
if(!definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) {
// Should draw up to currentX, but NOT at previousX.
// Need to find the starting point.
- let tmpPx = px-pxprecision
+ let tmpPx = px - pxprecision
do {
- tmpPx++;
+ tmpPx++
previousX = canvas.px2x(tmpPx)
} while(!definitionDomain.includes(previousX))
// Recaclulate previousY
@@ -166,16 +177,16 @@ export default class Function extends ExecutableObject {
// Augmenting the pixel precision until this condition is fulfilled.
let tmpPx = px
do {
- tmpPx--;
+ tmpPx--
currentX = canvas.px2x(tmpPx)
} while(!definitionDomain.includes(currentX) && currentX !== previousX)
}
// This max variation is needed for functions with asymptotical vertical lines (e.g. 1/x, tan x...)
- let maxvariation = (canvas.px2y(0)-canvas.px2y(canvas.height))
+ let maxvariation = (canvas.px2y(0) - canvas.px2y(canvas.height))
if(definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) {
let currentY = expr.execute(currentX)
if(destinationDomain.includes(currentY)) {
- if(previousY != null && destinationDomain.includes(previousY) && Math.abs(previousY-currentY) < maxvariation) {
+ if(previousY != null && destinationDomain.includes(previousY) && Math.abs(previousY - currentY) < maxvariation) {
canvas.drawLine(canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY))
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/common/src/objs/point.mjs
similarity index 50%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs
rename to common/src/objs/point.mjs
index 33d3858..d179481 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs
+++ b/common/src/objs/point.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -21,56 +21,66 @@ import * as P from "../parameters.mjs"
import Objects from "../module/objects.mjs"
import Latex from "../module/latex.mjs"
-import { DrawableObject } from "common.mjs"
+import { DrawableObject } from "./common.mjs"
-export default class Point extends DrawableObject {
- static type(){return 'Point'}
- static displayType(){return qsTranslate("point", 'Point')}
- static displayTypeMultiple(){return qsTranslate("point", 'Points')}
-
- static properties() {return {
- [QT_TRANSLATE_NOOP('prop','x')]: new P.Expression(),
- [QT_TRANSLATE_NOOP('prop','y')]: new P.Expression(),
- [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position,
- [QT_TRANSLATE_NOOP('prop','pointStyle')]: new P.Enum('●', '✕', '+')
- }}
-
- constructor(name = null, visible = true, color = null, labelContent = 'name + value',
- x = 1, y = 0, labelPosition = 'above', pointStyle = '●') {
- if(name == null) name = Objects.getNewName('ABCDEFJKLMNOPQRSTUVW')
+export default class Point extends DrawableObject {
+ static type() {
+ return "Point"
+ }
+
+ static displayType() {
+ return qsTranslate("point", "Point")
+ }
+
+ static displayTypeMultiple() {
+ return qsTranslate("point", "Points")
+ }
+
+ static properties() {
+ return {
+ [QT_TRANSLATE_NOOP("prop", "x")]: new P.Expression(),
+ [QT_TRANSLATE_NOOP("prop", "y")]: new P.Expression(),
+ [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position,
+ [QT_TRANSLATE_NOOP("prop", "pointStyle")]: new P.Enum("●", "✕", "+")
+ }
+ }
+
+ constructor(name = null, visible = true, color = null, labelContent = "name + value",
+ x = 1, y = 0, labelPosition = "above", pointStyle = "●") {
+ if(name == null) name = Objects.getNewName("ABCDEFJKLMNOPQRSTUVW")
super(name, visible, color, labelContent)
- if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString())
+ if(typeof x == "number" || typeof x == "string") x = new Expression(x.toString())
this.x = x
- if(typeof y == 'number' || typeof y == 'string') y = new Expression(y.toString())
+ if(typeof y == "number" || typeof y == "string") y = new Expression(y.toString())
this.y = y
this.labelPosition = labelPosition
this.pointStyle = pointStyle
}
-
+
getReadableString() {
return `${this.name} = (${this.x}, ${this.y})`
}
-
+
getLatexString() {
return `${Latex.variable(this.name)} = \\left(${this.x.latexMarkup}, ${this.y.latexMarkup}\\right)`
}
-
+
draw(canvas) {
let [canvasX, canvasY] = [canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())]
- let pointSize = 8+(canvas.linewidth*2)
+ let pointSize = 8 + (canvas.linewidth * 2)
switch(this.pointStyle) {
- case '●':
- canvas.disc(canvasX, canvasY, pointSize/2)
- break;
- case '✕':
- canvas.drawLine(canvasX-pointSize/2, canvasY-pointSize/2, canvasX+pointSize/2, canvasY+pointSize/2)
- canvas.drawLine(canvasX-pointSize/2, canvasY+pointSize/2, canvasX+pointSize/2, canvasY-pointSize/2)
- break;
- case '+':
- canvas.fillRect(canvasX-pointSize/2, canvasY-1, pointSize, 2)
- canvas.fillRect(canvasX-1, canvasY-pointSize/2, 2, pointSize)
- break;
+ case "●":
+ canvas.disc(canvasX, canvasY, pointSize / 2)
+ break
+ case "✕":
+ canvas.drawLine(canvasX - pointSize / 2, canvasY - pointSize / 2, canvasX + pointSize / 2, canvasY + pointSize / 2)
+ canvas.drawLine(canvasX - pointSize / 2, canvasY + pointSize / 2, canvasX + pointSize / 2, canvasY - pointSize / 2)
+ break
+ case "+":
+ canvas.fillRect(canvasX - pointSize / 2, canvasY - 1, pointSize, 2)
+ canvas.fillRect(canvasX - 1, canvasY - pointSize / 2, 2, pointSize)
+ break
}
this.drawLabel(canvas, this.labelPosition, canvasX, canvasY)
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/common/src/objs/sequence.mjs
similarity index 59%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs
rename to common/src/objs/sequence.mjs
index 0d2c488..0328041 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs
+++ b/common/src/objs/sequence.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -21,32 +21,42 @@ import * as P from "../parameters.mjs"
import Latex from "../module/latex.mjs"
import Objects from "../module/objects.mjs"
-import { ExecutableObject } from "common.mjs"
-import Function from "function.mjs"
+import { ExecutableObject } from "./common.mjs"
+import Function from "./function.mjs"
export default class Sequence extends ExecutableObject {
- static type(){return 'Sequence'}
- static displayType(){return qsTranslate("sequence", 'Sequence')}
- static displayTypeMultiple(){return qsTranslate("sequence", 'Sequences')}
-
- static properties() {return {
- [QT_TRANSLATE_NOOP('prop','drawPoints')]: 'boolean',
- [QT_TRANSLATE_NOOP('prop','drawDashedLines')]: 'boolean',
- [QT_TRANSLATE_NOOP('prop','defaultExpression')]: new P.Dictionary('string', 'int', /^.+$/, /^\d+$/, '{name}[n+', '] = ', true),
- 'comment1': QT_TRANSLATE_NOOP(
- 'comment',
- 'Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁...'
- ),
- [QT_TRANSLATE_NOOP('prop','baseValues')]: new P.Dictionary('string', 'int', /^.+$/, /^\d+$/, '{name}[', '] = '),
- [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position,
- [QT_TRANSLATE_NOOP('prop','labelX')]: 'number',
- }}
-
- constructor(name = null, visible = true, color = null, labelContent = 'name + value',
- drawPoints = true, drawDashedLines = true, defaultExp = {1: "n"},
- baseValues = {0: 0}, labelPosition = 'above', labelX = 1) {
- if(name == null) name = Objects.getNewName('uvwPSUVWabcde')
+ static type() {
+ return "Sequence"
+ }
+
+ static displayType() {
+ return qsTranslate("sequence", "Sequence")
+ }
+
+ static displayTypeMultiple() {
+ return qsTranslate("sequence", "Sequences")
+ }
+
+ static properties() {
+ return {
+ [QT_TRANSLATE_NOOP("prop", "drawPoints")]: "boolean",
+ [QT_TRANSLATE_NOOP("prop", "drawDashedLines")]: "boolean",
+ [QT_TRANSLATE_NOOP("prop", "defaultExpression")]: new P.Dictionary("string", "int", /^.+$/, /^\d+$/, "{name}[n+", "] = ", true),
+ "comment1": QT_TRANSLATE_NOOP(
+ "comment",
+ "Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁..."
+ ),
+ [QT_TRANSLATE_NOOP("prop", "baseValues")]: new P.Dictionary("string", "int", /^.+$/, /^\d+$/, "{name}[", "] = "),
+ [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Position,
+ [QT_TRANSLATE_NOOP("prop", "labelX")]: "number"
+ }
+ }
+
+ constructor(name = null, visible = true, color = null, labelContent = "name + value",
+ drawPoints = true, drawDashedLines = true, defaultExp = { 1: "n" },
+ baseValues = { 0: 0 }, labelPosition = "above", labelX = 1) {
+ if(name == null) name = Objects.getNewName("uvwPSUVWabcde")
super(name, visible, color, labelContent)
this.drawPoints = drawPoints
this.drawDashedLines = drawDashedLines
@@ -58,68 +68,71 @@ export default class Sequence extends ExecutableObject {
}
update() {
- console.log('Updating sequence', this.sequence)
+ console.log("Updating sequence", this.sequence)
super.update()
if(
this.sequence == null || this.baseValues !== this.sequence.baseValues ||
this.sequence.name !== this.name ||
this.sequence.expr !== Object.values(this.defaultExpression)[0] ||
- this.sequence.valuePlus !== Object.keys(this.defaultExpression)[0]
+ this.sequence.valuePlus.toString() !== Object.keys(this.defaultExpression)[0]
)
this.sequence = new MathSequence(
- this.name, this.baseValues,
- Object.keys(this.defaultExpression)[0],
+ this.name, this.baseValues,
+ parseFloat(Object.keys(this.defaultExpression)[0]),
Object.values(this.defaultExpression)[0]
)
}
-
+
getReadableString() {
return this.sequence.toString()
}
-
+
getLatexString() {
return this.sequence.toLatexString()
}
-
+
execute(x = 1) {
if(x % 1 === 0)
return this.sequence.execute(x)
return null
}
- canExecute(x = 1) {return x%1 === 0}
-
+
+ canExecute(x = 1) {
+ return x % 1 === 0
+ }
+
// Simplify returns the simplified string of the expression.
simplify(x = 1) {
if(x % 1 === 0)
return this.sequence.simplify(x)
return null
}
-
+
getLabel() {
switch(this.labelContent) {
- case 'name':
+ case "name":
return `(${this.name}ₙ)`
- case 'name + value':
+ case "name + value":
return this.getReadableString()
- case 'null':
- return ''
+ case "null":
+ return ""
}
}
-
+
getLatexLabel() {
switch(this.labelContent) {
- case 'name':
+ case "name":
return `(${Latex.variable(this.name)}_n)`
- case 'name + value':
+ case "name + value":
return this.getLatexString()
- case 'null':
- return ''
+ case "null":
+ return ""
}
}
-
+
draw(canvas) {
Function.drawFunction(canvas, this.sequence, canvas.logscalex ? Domain.NE : Domain.N, Domain.R, this.drawPoints, this.drawDashedLines)
-
+
// Label
this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX)))
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/common/src/objs/text.mjs
similarity index 53%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs
rename to common/src/objs/text.mjs
index bd30dfe..af79824 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs
+++ b/common/src/objs/text.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -21,75 +21,88 @@ import * as P from "../parameters.mjs"
import Objects from "../module/objects.mjs"
import Latex from "../module/latex.mjs"
-import { DrawableObject } from "common.mjs"
+import { DrawableObject } from "./common.mjs"
-export default class Text extends DrawableObject {
- static type(){return 'Text'}
- static displayType(){return qsTranslate("text", 'Text')}
- static displayTypeMultiple(){return qsTranslate("text", 'Texts')}
- static properties() {return {
- [QT_TRANSLATE_NOOP('prop','x')]: new P.Expression(),
- [QT_TRANSLATE_NOOP('prop','y')]: new P.Expression(),
- [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Positioning,
- [QT_TRANSLATE_NOOP('prop','text')]: 'string',
- 'comment1': QT_TRANSLATE_NOOP(
- 'comment',
- 'If you have latex enabled, you can use use latex markup in between $$ to create equations.'
- ),
- [QT_TRANSLATE_NOOP('prop','disableLatex')]: 'boolean'
- }}
-
- constructor(name = null, visible = true, color = null, labelContent = 'null',
- x = 1, y = 0, labelPosition = 'center', text = 'New text', disableLatex = false) {
- if(name == null) name = Objects.getNewName('t')
+export default class Text extends DrawableObject {
+ static type() {
+ return "Text"
+ }
+
+ static displayType() {
+ return qsTranslate("text", "Text")
+ }
+
+ static displayTypeMultiple() {
+ return qsTranslate("text", "Texts")
+ }
+
+ static properties() {
+ return {
+ [QT_TRANSLATE_NOOP("prop", "x")]: new P.Expression(),
+ [QT_TRANSLATE_NOOP("prop", "y")]: new P.Expression(),
+ [QT_TRANSLATE_NOOP("prop", "labelPosition")]: P.Enum.Positioning,
+ [QT_TRANSLATE_NOOP("prop", "text")]: "string",
+ "comment1": QT_TRANSLATE_NOOP(
+ "comment",
+ "If you have latex enabled, you can use use latex markup in between $$ to create equations."
+ ),
+ [QT_TRANSLATE_NOOP("prop", "disableLatex")]: "boolean"
+ }
+ }
+
+ constructor(name = null, visible = true, color = null, labelContent = "null",
+ x = 1, y = 0, labelPosition = "center", text = "New text", disableLatex = false) {
+ if(name == null) name = Objects.getNewName("t")
super(name, visible, color, labelContent)
- if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString())
+ if(typeof x == "number" || typeof x == "string") x = new Expression(x.toString())
this.x = x
- if(typeof y == 'number' || typeof y == 'string') y = new Expression(y.toString())
+ if(typeof y == "number" || typeof y == "string") y = new Expression(y.toString())
this.y = y
this.labelPosition = labelPosition
this.text = text
this.disableLatex = disableLatex
}
-
+
getReadableString() {
return `${this.name} = "${this.text}"`
}
-
+
latexMarkupText() {
// Check whether the text contains latex escaped elements.
let txt = []
- this.text.split('$$').forEach(function(t) { txt = txt.concat(Latex.variable(t, true).replace(/\$\$/g, '').split('$')) })
+ this.text.split("$$").forEach(function(t) {
+ txt = txt.concat(Latex.variable(t, true).replace(/\$\$/g, "").split("$"))
+ })
let newTxt = txt[0]
let i
// Split between normal text and latex escaped.
- for(i = 0; i < txt.length-1; i++)
+ for(i = 0; i < txt.length - 1; i++)
if(i & 0x01) // Every odd number
- newTxt += '\\textsf{'+Latex.variable(txt[i+1])
+ newTxt += "\\textsf{" + Latex.variable(txt[i + 1])
else
- newTxt += '}'+txt[i+1]
+ newTxt += "}" + txt[i + 1]
// Finished by a }
- if(i & 0x01)
+ if(i & 0x01)
newTxt += "{"
return newTxt
}
-
+
getLatexString() {
return `${Latex.variable(this.name)} = "\\textsf{${this.latexMarkupText()}}"`
}
-
+
getLabel() {
return this.text
}
-
+
getLatexLabel() {
return `\\textsf{${this.latexMarkupText()}}`
}
-
+
draw(canvas) {
- let yOffset = this.disableLatex ? canvas.textsize-4 : 0
- this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())+yOffset, this.disableLatex)
+ let yOffset = this.disableLatex ? canvas.textsize - 4 : 0
+ this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute()) + yOffset, this.disableLatex)
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/common/src/objs/xcursor.mjs
similarity index 90%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs
rename to common/src/objs/xcursor.mjs
index 20dc548..11f6a5a 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs
+++ b/common/src/objs/xcursor.mjs
@@ -21,7 +21,7 @@ import * as P from "../parameters.mjs"
import Latex from "../module/latex.mjs"
import Objects from "../module/objects.mjs"
-import { DrawableObject } from "common.mjs"
+import { DrawableObject } from "./common.mjs"
export default class XCursor extends DrawableObject {
@@ -72,30 +72,29 @@ export default class XCursor extends DrawableObject {
${this.getTargetValueLatexLabel()}
\\end{array}`
}
-
- getTargetValueLabel() {
- var t = this.targetElement
- var approx = ''
+
+ getApprox() {
+ let approx = ''
if(this.approximate) {
- approx = (t.execute(this.x.execute()))
+ approx = (this.targetElement.execute(this.x.execute()))
let intLength = Math.round(approx).toString().length
let rounding = Math.min(this.rounding, approx.toString().length - intLength - 1)
approx = approx.toPrecision(rounding + intLength)
}
+ return approx
+ }
+
+ getTargetValueLabel() {
+ const t = this.targetElement
+ const approx = this.getApprox()
return `${t.name}(${this.name}) = ${t.simplify(this.x.toEditableString())}` +
(this.approximate ? ' ≈ ' + approx : '')
}
getTargetValueLatexLabel() {
- let t = this.targetElement
- let approx = ''
- if(this.approximate) {
- approx = (t.execute(this.x.execute()))
- let intLength = Math.round(approx).toString().length
- let rounding = Math.min(this.rounding, approx.toString().length - intLength - 1)
- approx = approx.toPrecision(rounding + intLength)
- }
- let simpl = t.simplify(this.x.toEditableString())
+ const t = this.targetElement
+ const approx = this.getApprox()
+ const simpl = t.simplify(this.x.toEditableString())
return `${Latex.variable(t.name)}(${Latex.variable(this.name)}) = ${simpl.latexMarkup ? simpl.latexMarkup : Latex.variable(simpl)}` +
(this.approximate ? ' \\simeq ' + approx : '')
}
@@ -104,16 +103,13 @@ export default class XCursor extends DrawableObject {
switch(this.labelContent) {
case 'name':
return this.name
- break;
case 'name + value':
switch(this.targetValuePosition) {
case 'Next to target':
case 'Hidden':
return `${this.name} = ${this.x.toString()}`
- break;
case 'With label':
return this.getReadableString()
- break;
}
case 'null':
return ''
@@ -124,16 +120,13 @@ export default class XCursor extends DrawableObject {
switch(this.labelContent) {
case 'name':
return Latex.variable(this.name)
- break;
case 'name + value':
switch(this.targetValuePosition) {
case 'Next to target':
case 'Hidden':
return `${Latex.variable(this.name)} = ${this.x.latexMarkup}`
- break;
case 'With label':
return this.getLatexString()
- break;
}
case 'null':
return ''
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs b/common/src/parameters.mjs
similarity index 73%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs
rename to common/src/parameters.mjs
index b301997..1078518 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs
+++ b/common/src/parameters.mjs
@@ -15,15 +15,16 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-import {parseDomain, Expression as Expr, Domain} from "./math/index.mjs"
+import { parseDomain, Expression as Expr, Domain } from "./math/index.mjs"
import Objects from "./module/objects.mjs"
-const NONE = class Empty {}
+const NONE = class Empty {
+}
let stringValuesValidators = {
- 'int': [parseInt, (x) => !isNaN(x)],
- 'double': [parseFloat, (x) => !isNaN(x)],
- 'string': [(x) => x, () => true]
+ "int": [parseInt, (x) => !isNaN(x)],
+ "double": [parseFloat, (x) => !isNaN(x)],
+ "string": [(x) => x, () => true]
}
let stringValidatorTypes = Object.keys(stringValuesValidators)
@@ -52,17 +53,17 @@ class PropertyType {
export class Expression extends PropertyType {
constructor(...variables) {
super()
- this.type = 'Expression'
+ this.type = "Expression"
this.variables = variables
}
-
+
toString() {
- return this.variables.length === 0 ? 'Number' : `Expression(${this.variables.join(', ')})`
+ return this.variables.length === 0 ? "Number" : `Expression(${this.variables.join(", ")})`
}
parse(value) {
let result = NONE
- if(typeof value == 'string')
+ if(typeof value == "string")
try {
result = new Expr(value)
} catch(e) {
@@ -86,14 +87,14 @@ export class Expression extends PropertyType {
export class Enum extends PropertyType {
constructor(...values) {
super()
- this.type = 'Enum'
+ this.type = "Enum"
this.values = values
this.legacyValues = {}
- this.translatedValues = values.map(x => qsTranslate('parameters', x))
+ this.translatedValues = values.map(x => qsTranslate("parameters", x))
}
-
+
toString() {
- return `${this.type}(${this.values.join(', ')})`
+ return `${this.type}(${this.values.join(", ")})`
}
parse(value) {
@@ -111,28 +112,28 @@ export class Enum extends PropertyType {
else if(this.legacyValues[value])
return this.legacyValues[value]
else
- throw new TypeError(`Exportation error: ${value} not one of ${this.values.join(', ')}.`)
+ throw new TypeError(`Exportation error: ${value} not one of ${this.values.join(", ")}.`)
}
}
export class ObjectType extends PropertyType {
- constructor(objType, allowNull=false) {
+ constructor(objType, allowNull = false) {
super()
- this.type = 'ObjectType'
+ this.type = "ObjectType"
this.objType = objType
this.allowNull = allowNull
}
-
+
toString() {
return this.objType
}
parse(name) {
let result = NONE
- if(typeof name == 'string' && name in Objects.currentObjectsByName) {
+ if(typeof name == "string" && name in Objects.currentObjectsByName) {
let obj = Objects.currentObjectsByName[name]
- if (obj.type === this.objType || (this.objType === 'ExecutableObject' && obj.execute)) {
+ if(obj.type === this.objType || (this.objType === "ExecutableObject" && obj.execute)) {
result = obj
} else {
// Silently error and return null
@@ -147,7 +148,7 @@ export class ObjectType extends PropertyType {
export(value) {
if(value == null && this.allowNull)
return null
- else if(value.type === this.objType || (this.objType === 'ExecutableObject' && value.execute))
+ else if(value.type === this.objType || (this.objType === "ExecutableObject" && value.execute))
return value.name
else
throw new TypeError(`Exportation error: ${value} not a ${this.objType}.`)
@@ -156,28 +157,28 @@ export class ObjectType extends PropertyType {
export class List extends PropertyType {
- constructor(type, format = /^.+$/, label = '', forbidAdding = false) {
+ constructor(type, format = /^.+$/, label = "", forbidAdding = false) {
super()
// type can be string, int and double.
- this.type = 'List'
+ this.type = "List"
this.valueType = type
if(!stringValidatorTypes.includes(this.valueType))
- throw new TypeError(`${this.valueType} must be one of ${stringValidatorTypes.join(', ')}.`)
+ throw new TypeError(`${this.valueType} must be one of ${stringValidatorTypes.join(", ")}.`)
this.format = format
this.label = label
this.forbidAdding = forbidAdding
}
-
+
toString() {
return `${this.type}(${this.valueType}:${this.format})`
}
parse(value) {
let result = NONE
- if(typeof value == 'object' && value.__proto__ === Array) {
+ if(typeof value == "object" && value.__proto__ === Array) {
let valid = 0
for(let v of value) {
- if (this.format.test(v)) {
+ if(this.format.test(v)) {
v = stringValuesValidators[this.valueType][0](v)
if(stringValuesValidators[this.valueType][1](v))
valid++
@@ -190,7 +191,7 @@ export class List extends PropertyType {
}
export(value) {
- if(typeof value == 'object' && value.__proto__ === Array)
+ if(typeof value == "object" && value.__proto__ === Array)
return value
else
throw new TypeError(`Exportation error: ${value} not a list.`)
@@ -200,10 +201,10 @@ export class List extends PropertyType {
export class Dictionary extends PropertyType {
- constructor(type, keyType = 'string', format = /^.+$/, keyFormat = /^.+$/, preKeyLabel = '', postKeyLabel = ': ', forbidAdding = false) {
+ constructor(type, keyType = "string", format = /^.+$/, keyFormat = /^.+$/, preKeyLabel = "", postKeyLabel = ": ", forbidAdding = false) {
super()
// type & keyType can be string, int and double.
- this.type = 'Dict'
+ this.type = "Dict"
this.valueType = type
this.keyType = keyType
this.format = format
@@ -219,10 +220,10 @@ export class Dictionary extends PropertyType {
parse(value) {
let result = NONE
- if(typeof value == 'object' && value.__proto__ !== Array) {
+ if(typeof value == "object" && value.__proto__ !== Array) {
let dict = []
for(let [k, v] of Object.entries(value)) {
- if (this.format.test(v) && this.keyFormat.test(k)) {
+ if(this.format.test(v) && this.keyFormat.test(k)) {
k = stringValuesValidators[this.keyType][0](k)
v = stringValuesValidators[this.valueType][0](v)
if(stringValuesValidators[this.keyType][1](k))
@@ -237,7 +238,7 @@ export class Dictionary extends PropertyType {
}
export(value) {
- if(typeof value == 'object' && value.__proto__ !== Array)
+ if(typeof value == "object" && value.__proto__ !== Array)
return value
else
throw new TypeError(`Exportation error: ${value} not a dictionary.`)
@@ -247,51 +248,51 @@ export class Dictionary extends PropertyType {
// Common parameters for Enums
Enum.Position = new Enum(
- QT_TRANSLATE_NOOP('parameters', 'above'),
- QT_TRANSLATE_NOOP('parameters', 'below'),
- QT_TRANSLATE_NOOP('parameters', 'left'),
- QT_TRANSLATE_NOOP('parameters', 'right'),
- QT_TRANSLATE_NOOP('parameters', 'above-left'),
- QT_TRANSLATE_NOOP('parameters', 'above-right'),
- QT_TRANSLATE_NOOP('parameters', 'below-left'),
- QT_TRANSLATE_NOOP('parameters', 'below-right')
+ QT_TRANSLATE_NOOP("parameters", "above"),
+ QT_TRANSLATE_NOOP("parameters", "below"),
+ QT_TRANSLATE_NOOP("parameters", "left"),
+ QT_TRANSLATE_NOOP("parameters", "right"),
+ QT_TRANSLATE_NOOP("parameters", "above-left"),
+ QT_TRANSLATE_NOOP("parameters", "above-right"),
+ QT_TRANSLATE_NOOP("parameters", "below-left"),
+ QT_TRANSLATE_NOOP("parameters", "below-right")
)
Enum.Position.legacyValues = {
- 'top': 'above',
- 'bottom': 'below',
- 'top-left': 'above-left',
- 'top-right': 'above-right',
- 'bottom-left': 'below-left',
- 'bottom-right': 'below-right',
+ "top": "above",
+ "bottom": "below",
+ "top-left": "above-left",
+ "top-right": "above-right",
+ "bottom-left": "below-left",
+ "bottom-right": "below-right"
}
Enum.Positioning = new Enum(
- QT_TRANSLATE_NOOP('parameters', 'center'),
- QT_TRANSLATE_NOOP('parameters', 'top'),
- QT_TRANSLATE_NOOP('parameters', 'bottom'),
- QT_TRANSLATE_NOOP('parameters', 'left'),
- QT_TRANSLATE_NOOP('parameters', 'right'),
- QT_TRANSLATE_NOOP('parameters', 'top-left'),
- QT_TRANSLATE_NOOP('parameters', 'top-right'),
- QT_TRANSLATE_NOOP('parameters', 'bottom-left'),
- QT_TRANSLATE_NOOP('parameters', 'bottom-right')
+ QT_TRANSLATE_NOOP("parameters", "center"),
+ QT_TRANSLATE_NOOP("parameters", "top"),
+ QT_TRANSLATE_NOOP("parameters", "bottom"),
+ QT_TRANSLATE_NOOP("parameters", "left"),
+ QT_TRANSLATE_NOOP("parameters", "right"),
+ QT_TRANSLATE_NOOP("parameters", "top-left"),
+ QT_TRANSLATE_NOOP("parameters", "top-right"),
+ QT_TRANSLATE_NOOP("parameters", "bottom-left"),
+ QT_TRANSLATE_NOOP("parameters", "bottom-right")
)
Enum.FunctionDisplayType = new Enum(
- QT_TRANSLATE_NOOP('parameters', 'application'),
- QT_TRANSLATE_NOOP('parameters', 'function')
+ QT_TRANSLATE_NOOP("parameters", "application"),
+ QT_TRANSLATE_NOOP("parameters", "function")
)
Enum.BodePass = new Enum(
- QT_TRANSLATE_NOOP('parameters', 'high'),
- QT_TRANSLATE_NOOP('parameters', 'low')
+ QT_TRANSLATE_NOOP("parameters", "high"),
+ QT_TRANSLATE_NOOP("parameters", "low")
)
Enum.XCursorValuePosition = new Enum(
- QT_TRANSLATE_NOOP('parameters', 'Next to target'),
- QT_TRANSLATE_NOOP('parameters', 'With label'),
- QT_TRANSLATE_NOOP('parameters', 'Hidden')
+ QT_TRANSLATE_NOOP("parameters", "Next to target"),
+ QT_TRANSLATE_NOOP("parameters", "With label"),
+ QT_TRANSLATE_NOOP("parameters", "Hidden")
)
/**
@@ -303,23 +304,23 @@ Enum.XCursorValuePosition = new Enum(
export function ensureTypeSafety(propertyType, value) {
let result
let error = false
- if(typeof propertyType == 'string')
+ if(typeof propertyType == "string")
switch(propertyType) {
- case 'string':
+ case "string":
result = value
- error = typeof value !== 'string'
+ error = typeof value !== "string"
break
- case 'number':
+ case "number":
result = parseFloat(value)
error = isNaN(result)
break
- case 'boolean':
+ case "boolean":
result = value
error = value !== true && value !== false
break
- case 'Domain':
+ case "Domain":
try {
- error = typeof value !== 'string'
+ error = typeof value !== "string"
if(!error)
result = parseDomain(value)
} catch(e) {
@@ -353,18 +354,18 @@ export function ensureTypeSafety(propertyType, value) {
*/
export function serializesByPropertyType(propertyType, value) {
let result
- if(typeof propertyType == 'string')
+ if(typeof propertyType == "string")
switch(propertyType) {
- case 'string':
+ case "string":
result = value.toString()
break
- case 'number':
+ case "number":
result = parseFloat(value)
break
- case 'boolean':
+ case "boolean":
result = value === true
break
- case 'Domain':
+ case "Domain":
if(value instanceof Domain)
result = value.toString()
else
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md b/common/src/parsing/README.md
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md
rename to common/src/parsing/README.md
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs b/common/src/parsing/common.mjs
similarity index 80%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs
rename to common/src/parsing/common.mjs
index 3313a1b..72a9a4b 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs
+++ b/common/src/parsing/common.mjs
@@ -1,17 +1,17 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -19,30 +19,30 @@
export default class InputExpression {
constructor(expression) {
- this.position = 0;
- this.input = expression;
+ this.position = 0
+ this.input = expression
}
-
+
next() {
- return this.input[this.position++];
+ return this.input[this.position++]
}
-
+
peek() {
- return this.input[this.position];
+ return this.input[this.position]
}
-
+
skip(char) {
if(!this.atEnd() && this.peek() === char) {
- this.position++;
+ this.position++
} else {
- this.raise("Unexpected character " + this.peek() + ". Expected character " + char);
+ this.raise("Unexpected character " + this.peek() + ". Expected character " + char)
}
}
-
+
atEnd() {
- return this.position >= this.input.length;
+ return this.position >= this.input.length
}
-
+
raise(message) {
throw new SyntaxError(message + " at " + this.position + ".")
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs b/common/src/parsing/index.mjs
similarity index 93%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs
rename to common/src/parsing/index.mjs
index 71d34d1..6d0de80 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs
+++ b/common/src/parsing/index.mjs
@@ -16,9 +16,9 @@
* along with this program. If not, see .
*/
-import * as Reference from "reference.mjs"
+import * as Reference from "./reference.mjs"
import * as T from "./tokenizer.mjs"
-import InputExpression from "common.mjs"
+import InputExpression from "./common.mjs"
export const Input = InputExpression
export const TokenType = T.TokenType
diff --git a/common/src/parsing/reference.mjs b/common/src/parsing/reference.mjs
new file mode 100644
index 0000000..36d4c8c
--- /dev/null
+++ b/common/src/parsing/reference.mjs
@@ -0,0 +1,174 @@
+/**
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import * as Polyfill from "../lib/expr-eval/polyfill.mjs"
+
+export const CONSTANTS = {
+ "π": Math.PI,
+ "pi": Math.PI,
+ "inf": Infinity,
+ "infinity": Infinity,
+ "∞": Infinity,
+ "e": Math.E
+}
+export const CONSTANTS_LIST = Object.keys(CONSTANTS)
+
+export const FUNCTIONS = {
+ // The functions commented are the one either not implemented
+ // in the parser, or not to be used for autocompletion.
+ // Unary operators
+ //'+': Number,
+ //'-': (x) => -x,
+ //'!'
+ // Other operations
+ "length": (s) => Array.isArray(s) ? s.length : String(s).length,
+ // Boolean functions
+ "not": (x) => !x,
+ // Math functions
+ "abs": Math.abs,
+ "acos": Math.acos,
+ "acosh": Math.acosh,
+ "asin": Math.asin,
+ "asinh": Math.asinh,
+ "atan": Math.atan,
+ "atan2": Math.atan2,
+ "atanh": Math.atanh,
+ "cbrt": Math.cbrt,
+ "ceil": Math.ceil,
+ //'clz32': Math.clz32,
+ "cos": Math.cos,
+ "cosh": Math.cosh,
+ "exp": Math.exp,
+ "expm1": Math.expm1,
+ "floor": Math.floor,
+ //'fround': Math.fround,
+ "hypot": Math.hypot,
+ //'imul': Math.imul,
+ "lg": Math.log10,
+ "ln": Math.log,
+ "log": Math.log,
+ "log10": Math.log10,
+ "log1p": Math.log1p,
+ "log2": Math.log2,
+ "max": Math.max,
+ "min": Math.min,
+ "pow": Math.log2,
+ "random": Math.random,
+ "round": Math.round,
+ "sign": Math.sign,
+ "sin": Math.sin,
+ "sinh": Math.sinh,
+ "sqrt": Math.sqrt,
+ "tan": Math.tan,
+ "tanh": Math.tanh,
+ "trunc": Math.trunc,
+ // Functions in expr-eval, ported here.
+ "fac": Polyfill.factorial,
+ "gamma": Polyfill.gamma,
+ "Γ": Polyfill.gamma,
+ "roundTo": (x, exp) => Number(x).toFixed(exp),
+ // 'map': Polyfill.arrayMap,
+ // 'fold': Polyfill.arrayFold,
+ // 'filter': Polyfill.arrayFilter,
+ // 'indexOf': Polyfill.indexOf,
+ // 'join': Polyfill.arrayJoin,
+ // Integral & derivative (only here for autocomplete).
+ "integral": () => 0, // TODO: Implement
+ "derivative": () => 0
+}
+export const FUNCTIONS_LIST = Object.keys(FUNCTIONS)
+
+export class P {
+ // Parameter class.
+ constructor(type, name = "", optional = false, multipleAllowed = false) {
+ this.name = name
+ this.type = type
+ this.optional = optional
+ this.multipleAllowed = multipleAllowed
+ }
+
+ toString() {
+ let base_string = this.type
+ if(this.name !== "")
+ base_string = `${this.name}: ${base_string}`
+ if(this.multipleAllowed)
+ base_string += "..."
+ if(!this.optional)
+ base_string = `<${base_string}>`
+ else
+ base_string = `[${base_string}]`
+ return base_string
+ }
+}
+
+export let string = new P("string")
+export let bool = new P("bool")
+export let number = new P("number")
+export let array = new P("array")
+
+export const FUNCTIONS_USAGE = {
+ "length": [string],
+ "not": [bool],
+ // Math functions
+ "abs": [number],
+ "acos": [number],
+ "acosh": [number],
+ "asin": [number],
+ "asinh": [number],
+ "atan": [number],
+ "atan2": [number],
+ "atanh": [number],
+ "cbrt": [number],
+ "ceil": [number],
+ //'clz32': [number],
+ "cos": [number],
+ "cosh": [number],
+ "exp": [number],
+ "expm1": [number],
+ "floor": [number],
+ //'fround': [number],
+ "hypot": [number],
+ //'imul': [number],
+ "lg": [number],
+ "ln": [number],
+ "log": [number],
+ "log10": [number],
+ "log1p": [number],
+ "log2": [number],
+ "max": [number, number, new P("numbers", "", true, true)],
+ "min": [number, number, new P("numbers", "", true, true)],
+ "pow": [number, new P("number", "exp")],
+ "random": [number, number],
+ "round": [number],
+ "sign": [number],
+ "sin": [number],
+ "sinh": [number],
+ "sqrt": [number],
+ "tan": [number],
+ "tanh": [number],
+ "trunc": [number],
+ // Functions in expr-eval, ported here.
+ "fac": [number],
+ "gamma": [number],
+ "Γ": [number],
+ "roundTo": [number, new P("number")],
+ // Function manipulation
+ "derivative": [new P("f"), new P("string", "var", true), number],
+ "integral": [new P("from"), new P("to"), new P("f"), new P("string", "var", true)]
+}
+
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs b/common/src/parsing/tokenizer.mjs
similarity index 70%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs
rename to common/src/parsing/tokenizer.mjs
index bad6e7e..a8552fc 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs
+++ b/common/src/parsing/tokenizer.mjs
@@ -1,28 +1,28 @@
/**
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
* Copyright (C) 2021-2024 Ad5001
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-import * as Reference from "reference.mjs"
+import * as Reference from "./reference.mjs"
const WHITESPACES = " \t\n\r"
-const STRING_LIMITERS = '"\'`';
-const OPERATORS = "+-*/^%?:=!><";
-const PUNCTUATION = "()[]{},.";
+const STRING_LIMITERS = "\"'`"
+const OPERATORS = "+-*/^%?:=!><"
+const PUNCTUATION = "()[]{},."
const NUMBER_CHARS = "0123456789"
const IDENTIFIER_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789_₀₁₂₃₄₅₆₇₈₉αβγδεζηθκλμξρςστφχψωₐₑₒₓₔₕₖₗₘₙₚₛₜ"
@@ -41,8 +41,8 @@ export const TokenType = {
export class Token {
constructor(type, value, startPosition) {
- this.type = type;
- this.value = value;
+ this.type = type
+ this.value = value
this.startPosition = startPosition
}
}
@@ -55,120 +55,120 @@ export class ExpressionTokenizer {
* @param {boolean} errorOnUnknown
*/
constructor(input, tokenizeWhitespaces = false, errorOnUnknown = true) {
- this.input = input;
- this.currentToken = null;
+ this.input = input
+ this.currentToken = null
this.tokenizeWhitespaces = tokenizeWhitespaces
this.errorOnUnknown = errorOnUnknown
}
-
+
skipWhitespaces() {
while(!this.input.atEnd() && WHITESPACES.includes(this.input.peek()))
- this.input.next();
+ this.input.next()
}
-
+
readWhitespaces() {
- let included = "";
+ let included = ""
while(!this.input.atEnd() && WHITESPACES.includes(this.input.peek())) {
- included += this.input.next();
+ included += this.input.next()
}
- return new Token(TokenType.WHITESPACE, included, this.input.position-included.length)
+ return new Token(TokenType.WHITESPACE, included, this.input.position - included.length)
}
-
+
readString() {
- let delimitation = this.input.peek();
+ let delimitation = this.input.peek()
if(STRING_LIMITERS.includes(delimitation)) {
this.input.skip(delimitation)
- let included = "";
- let justEscaped = false;
+ let included = ""
+ let justEscaped = false
while(!this.input.atEnd() && (!STRING_LIMITERS.includes(this.input.peek()) || justEscaped)) {
justEscaped = this.input.peek() === "\\"
if(!justEscaped)
- included += this.input.next();
+ included += this.input.next()
}
this.input.skip(delimitation)
- let token = new Token(TokenType.STRING, included, this.input.position-included.length)
+ let token = new Token(TokenType.STRING, included, this.input.position - included.length)
token.limitator = delimitation
return token
} else {
this.input.raise("Unexpected " + delimitation + ". Expected string delimitator")
}
}
-
+
readNumber() {
- let included = "";
- let hasDot = false;
- while(!this.input.atEnd() && (NUMBER_CHARS.includes(this.input.peek()) || this.input.peek() === '.')) {
+ let included = ""
+ let hasDot = false
+ while(!this.input.atEnd() && (NUMBER_CHARS.includes(this.input.peek()) || this.input.peek() === ".")) {
if(this.input.peek() === ".") {
if(hasDot) this.input.raise("Unexpected '.'. Expected digit")
- hasDot = true;
+ hasDot = true
}
- included += this.input.next();
+ included += this.input.next()
}
- return new Token(TokenType.NUMBER, included, this.input.position-included.length)
+ return new Token(TokenType.NUMBER, included, this.input.position - included.length)
}
-
+
readOperator() {
- let included = "";
+ let included = ""
while(!this.input.atEnd() && OPERATORS.includes(this.input.peek())) {
- included += this.input.next();
+ included += this.input.next()
}
- return new Token(TokenType.OPERATOR, included, this.input.position-included.length)
+ return new Token(TokenType.OPERATOR, included, this.input.position - included.length)
}
-
+
readIdentifier() {
- let identifier = "";
+ let identifier = ""
while(!this.input.atEnd() && IDENTIFIER_CHARS.includes(this.input.peek().toLowerCase())) {
- identifier += this.input.next();
+ identifier += this.input.next()
}
if(Reference.CONSTANTS_LIST.includes(identifier.toLowerCase())) {
- return new Token(TokenType.CONSTANT, identifier.toLowerCase(), this.input.position-identifier.length)
+ return new Token(TokenType.CONSTANT, identifier.toLowerCase(), this.input.position - identifier.length)
} else if(Reference.FUNCTIONS_LIST.includes(identifier.toLowerCase())) {
- return new Token(TokenType.FUNCTION, identifier.toLowerCase(), this.input.position-identifier.length)
+ return new Token(TokenType.FUNCTION, identifier.toLowerCase(), this.input.position - identifier.length)
} else {
- return new Token(TokenType.VARIABLE, identifier, this.input.position-identifier.length)
+ return new Token(TokenType.VARIABLE, identifier, this.input.position - identifier.length)
}
}
-
+
readNextToken() {
if(!this.tokenizeWhitespaces)
this.skipWhitespaces()
- if(this.input.atEnd()) return null;
- let c = this.input.peek();
- if(this.tokenizeWhitespaces && WHITESPACES.includes(c)) return this.readWhitespaces();
- if(STRING_LIMITERS.includes(c)) return this.readString();
- if(NUMBER_CHARS.includes(c)) return this.readNumber();
- if(IDENTIFIER_CHARS.includes(c.toLowerCase())) return this.readIdentifier();
- if(OPERATORS.includes(c)) return this.readOperator();
- if(Reference.CONSTANTS_LIST.includes(c)) return new Token(TokenType.CONSTANT, this.input.next(), this.input.position-1);
- if(PUNCTUATION.includes(c)) return new Token(TokenType.PUNCT, this.input.next(), this.input.position-1);
+ if(this.input.atEnd()) return null
+ let c = this.input.peek()
+ if(this.tokenizeWhitespaces && WHITESPACES.includes(c)) return this.readWhitespaces()
+ if(STRING_LIMITERS.includes(c)) return this.readString()
+ if(NUMBER_CHARS.includes(c)) return this.readNumber()
+ if(IDENTIFIER_CHARS.includes(c.toLowerCase())) return this.readIdentifier()
+ if(OPERATORS.includes(c)) return this.readOperator()
+ if(Reference.CONSTANTS_LIST.includes(c)) return new Token(TokenType.CONSTANT, this.input.next(), this.input.position - 1)
+ if(PUNCTUATION.includes(c)) return new Token(TokenType.PUNCT, this.input.next(), this.input.position - 1)
if(this.errorOnUnknown)
this.input.raise("Unknown token character " + c)
else
- return new Token(TokenType.UNKNOWN, this.input.next(), this.input.position-1);
+ return new Token(TokenType.UNKNOWN, this.input.next(), this.input.position - 1)
}
peek() {
- if(this.currentToken == null) this.currentToken = this.readNextToken();
- return this.currentToken;
+ if(this.currentToken == null) this.currentToken = this.readNextToken()
+ return this.currentToken
}
next() {
- let tmp;
+ let tmp
if(this.currentToken == null)
- tmp = this.readNextToken();
+ tmp = this.readNextToken()
else
- tmp = this.currentToken;
- this.currentToken = null;
- return tmp;
+ tmp = this.currentToken
+ this.currentToken = null
+ return tmp
}
-
+
atEnd() {
- return this.peek() == null;
+ return this.peek() == null
}
-
+
skip(type) {
- let next = this.next();
+ let next = this.next()
if(next.type !== type)
- this.input.raise("Unexpected token " + next.type.toLowerCase() + ' "' + next.value + '". Expected ' + type.toLowerCase());
+ this.input.raise("Unexpected token " + next.type.toLowerCase() + " \"" + next.value + "\". Expected " + type.toLowerCase())
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs b/common/src/preferences/common.mjs
similarity index 86%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs
rename to common/src/preferences/common.mjs
index 1e708ca..e456dc2 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs
+++ b/common/src/preferences/common.mjs
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import {Expression} from "../math/index.mjs"
+import { Expression } from "../math/index.mjs"
class Setting {
constructor(type, name, nameInConfig, icon) {
@@ -49,7 +49,7 @@ class Setting {
export class BoolSetting extends Setting {
constructor(name, nameInConfig, icon) {
- super('bool', name, nameInConfig, icon)
+ super("bool", name, nameInConfig, icon)
}
value() {
@@ -63,9 +63,9 @@ export class BoolSetting extends Setting {
export class NumberSetting extends Setting {
constructor(name, nameInConfig, icon, min = -Infinity, max = +Infinity) {
- super('number', name, nameInConfig, icon)
- this.min = typeof min == 'number' ? () => min : min
- this.max = typeof max == 'number' ? () => max : max
+ super("number", name, nameInConfig, icon)
+ this.min = typeof min == "number" ? () => min : min
+ this.max = typeof max == "number" ? () => max : max
}
value() {
@@ -79,7 +79,7 @@ export class NumberSetting extends Setting {
export class EnumIntSetting extends Setting {
constructor(name, nameInConfig, icon, values = []) {
- super('enum', name, nameInConfig, icon)
+ super("enum", name, nameInConfig, icon)
this.values = values
}
@@ -94,7 +94,7 @@ export class EnumIntSetting extends Setting {
export class ExpressionSetting extends Setting {
constructor(name, nameInConfig, icon, variables = []) {
- super('expression', name, nameInConfig, icon)
+ super("expression", name, nameInConfig, icon)
this.variables = variables
}
@@ -112,17 +112,17 @@ export class ExpressionSetting extends Setting {
Helper.setSetting(this.nameInConfig, value)
else {
let undefinedVars = vars.filter(x => !this.variables.includes(x))
- let allowed = ''
+ let allowed = ""
if(this.variables.length > 0)
- allowed = `Allowed variables: ${this.variables.join(', ')}.`
- throw new TypeError(`Cannot use variable(s) ${undefinedVars.join(', or ')} to define ${this.displayName}. ${allowed}`)
+ allowed = `Allowed variables: ${this.variables.join(", ")}.`
+ throw new TypeError(`Cannot use variable(s) ${undefinedVars.join(", or ")} to define ${this.displayName}. ${allowed}`)
}
}
}
export class StringSetting extends Setting {
constructor(name, nameInConfig, icon, defaultValues = []) {
- super('string', name, nameInConfig, icon)
+ super("string", name, nameInConfig, icon)
this.defaultValues = defaultValues
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs b/common/src/preferences/default.mjs
similarity index 88%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs
rename to common/src/preferences/default.mjs
index 230c71a..0fa9531 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs
+++ b/common/src/preferences/default.mjs
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import {BoolSetting, ExpressionSetting, NumberSetting, StringSetting} from "common.mjs"
+import { BoolSetting, ExpressionSetting, NumberSetting, StringSetting } from "./common.mjs"
const XZOOM = new NumberSetting(
@@ -49,13 +49,13 @@ const YMAX = new NumberSetting(
const XAXISSTEP = new ExpressionSetting(
qsTranslate("Settings", "X Axis Step"),
"default_graph.xaxisstep",
- "xaxisstep",
+ "xaxisstep"
)
const YAXISSTEP = new ExpressionSetting(
qsTranslate("Settings", "Y Axis Step"),
"default_graph.yaxisstep",
- "yaxisstep",
+ "yaxisstep"
)
const LINE_WIDTH = new NumberSetting(
@@ -72,33 +72,33 @@ const TEXT_SIZE = new NumberSetting(
)
const X_LABEL = new StringSetting(
- qsTranslate("Settings", 'X Label'),
+ qsTranslate("Settings", "X Label"),
"default_graph.xlabel",
"xlabel",
["", "x", "ω (rad/s)"]
)
const Y_LABEL = new StringSetting(
- qsTranslate("Settings", 'Y Label'),
+ qsTranslate("Settings", "Y Label"),
"default_graph.ylabel",
"xlabel",
["", "y", "G (dB)", "φ (°)", "φ (deg)", "φ (rad)"]
)
const LOG_SCALE_X = new BoolSetting(
- qsTranslate("Settings", 'X Log scale'),
+ qsTranslate("Settings", "X Log scale"),
"default_graph.logscalex",
"logscalex"
)
const SHOW_X_GRAD = new BoolSetting(
- qsTranslate("Settings", 'Show X graduation'),
+ qsTranslate("Settings", "Show X graduation"),
"default_graph.showxgrad",
"showxgrad"
)
const SHOW_Y_GRAD = new BoolSetting(
- qsTranslate("Settings", 'Show Y graduation'),
+ qsTranslate("Settings", "Show Y graduation"),
"default_graph.showygrad",
"showygrad"
)
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs b/common/src/preferences/expression.mjs
similarity index 85%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs
rename to common/src/preferences/expression.mjs
index 4493c77..85e1fbe 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs
+++ b/common/src/preferences/expression.mjs
@@ -16,30 +16,30 @@
* along with this program. If not, see .
*/
-import {BoolSetting, EnumIntSetting} from "common.mjs"
+import { BoolSetting, EnumIntSetting } from "./common.mjs"
const AUTOCLOSE_FORMULA = new BoolSetting(
qsTranslate("expression", "Automatically close parenthesises and brackets"),
- 'expression_editor.autoclose',
- 'text'
+ "expression_editor.autoclose",
+ "text"
)
const ENABLE_SYNTAX_HIGHLIGHTING = new BoolSetting(
qsTranslate("expression", "Enable syntax highlighting"),
- 'expression_editor.colorize',
- 'appearance'
+ "expression_editor.colorize",
+ "appearance"
)
const ENABLE_AUTOCOMPLETE = new BoolSetting(
qsTranslate("expression", "Enable autocompletion"),
- 'autocompletion.enabled',
- 'label'
+ "autocompletion.enabled",
+ "label"
)
const PICK_COLOR_SCHEME = new EnumIntSetting(
qsTranslate("expression", "Color Scheme"),
- 'expression_editor.color_scheme',
- 'color',
+ "expression_editor.color_scheme",
+ "color",
["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"]
)
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs b/common/src/preferences/general.mjs
similarity index 87%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs
rename to common/src/preferences/general.mjs
index 2c5ef17..81c5e3d 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs
+++ b/common/src/preferences/general.mjs
@@ -16,25 +16,25 @@
* along with this program. If not, see .
*/
-import {BoolSetting} from "common.mjs"
+import { BoolSetting } from "./common.mjs"
import Canvas from "../module/canvas.mjs"
import LatexAPI from "../module/latex.mjs"
const CHECK_FOR_UPDATES = new BoolSetting(
qsTranslate("general", "Check for updates on startup"),
- 'check_for_updates',
- 'update'
+ "check_for_updates",
+ "update"
)
const RESET_REDO_STACK = new BoolSetting(
qsTranslate("general", "Reset redo stack automaticly"),
- 'reset_redo_stack',
- 'timeline'
+ "reset_redo_stack",
+ "timeline"
)
class EnableLatex extends BoolSetting {
constructor() {
- super(qsTranslate("general","Enable LaTeX rendering"), 'enable_latex', 'Expression')
+ super(qsTranslate("general", "Enable LaTeX rendering"), "enable_latex", "Expression")
}
set(value) {
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs b/common/src/utils.mjs
similarity index 96%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs
rename to common/src/utils.mjs
index 2e82be4..4f6b0c5 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs
+++ b/common/src/utils.mjs
@@ -16,6 +16,25 @@
* along with this program. If not, see .
*/
+// Add string methods
+/**
+ * Replaces latin characters with their uppercase versions.
+ * @return {string}
+ */
+String.prototype.toLatinUppercase = String.prototype.toLatinUppercase || function() {
+ return this.replace(/[a-z]/g, function(match) {
+ return match.toUpperCase()
+ })
+}
+
+/**
+ * Removes the 'enclosers' of a string (e.g. quotes, parentheses, brackets...)
+ * @return {string}
+ */
+String.prototype.removeEnclosure = function() {
+ return this.substring(1, this.length - 1)
+}
+
const powerpos = {
"-": "⁻",
"+": "⁺",
@@ -350,10 +369,6 @@ export function parseName(str, removeUnallowed = true) {
return str
}
-String.prototype.toLatinUppercase = function() {
- return this.replace(/[a-z]/g, function(match){return match.toUpperCase()})
-}
-
/**
* Transforms camel case strings to a space separated one.
*
diff --git a/common/test/hooks.mjs b/common/test/hooks.mjs
new file mode 100644
index 0000000..e48525e
--- /dev/null
+++ b/common/test/hooks.mjs
@@ -0,0 +1,30 @@
+/**
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+import * as fs from "./mock/fs.mjs";
+import Qt from "./mock/qt.mjs";
+import { MockHelper } from "./mock/helper.mjs";
+import { MockLatex } from "./mock/latex.mjs";
+import Modules from "../src/module/index.mjs";
+
+function setup() {
+ globalThis.Helper = new MockHelper()
+ globalThis.Latex = new MockLatex()
+ Modules.Latex.initialize({ latex: Latex, helper: Helper })
+}
+
+setup()
diff --git a/common/test/math/domain.mjs b/common/test/math/domain.mjs
new file mode 100644
index 0000000..c00384f
--- /dev/null
+++ b/common/test/math/domain.mjs
@@ -0,0 +1,64 @@
+/**
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import { describe, it } from "mocha"
+import { expect } from "chai"
+
+import { Domain, parseDomainSimple } from "../../src/math/domain.mjs"
+
+describe("math.domain", function() {
+ describe("#parseDomainSimple", function() {
+ it("returns predefined domains", function() {
+ const predefinedToCheck = [
+ // Real domains
+ { domain: Domain.R, shortcuts: ["R", "ℝ"] },
+ // Zero exclusive real domains
+ { domain: Domain.RE, shortcuts: ["RE", "R*", "ℝ*"] },
+ // Real positive domains
+ { domain: Domain.RP, shortcuts: ["RP", "R+", "ℝ⁺", "ℝ+"] },
+ // Zero-exclusive real positive domains
+ { domain: Domain.RPE, shortcuts: ["RPE", "REP", "R+*", "R*+", "ℝ*⁺", "ℝ⁺*", "ℝ*+", "ℝ+*"] },
+ // Real negative domain
+ { domain: Domain.RM, shortcuts: ["RM", "R-", "ℝ⁻", "ℝ-"] },
+ // Zero-exclusive real negative domains
+ { domain: Domain.RME, shortcuts: ["RME", "REM", "R-*", "R*-", "ℝ⁻*", "ℝ*⁻", "ℝ-*", "ℝ*-"] },
+ // Natural integers domain
+ { domain: Domain.N, shortcuts: ["ℕ", "N", "ZP", "Z+", "ℤ⁺", "ℤ+"] },
+ // Zero-exclusive natural integers domain
+ { domain: Domain.NE, shortcuts: ["NE", "NP", "N*", "N+", "ℕ*", "ℕ⁺", "ℕ+", "ZPE", "ZEP", "Z+*", "Z*+", "ℤ⁺*", "ℤ*⁺", "ℤ+*", "ℤ*+"] },
+ // Logarithmic natural domains
+ { domain: Domain.NLog, shortcuts: ["NLOG", "ℕˡᵒᵍ", "ℕLOG"] },
+ // All integers domains
+ { domain: Domain.Z, shortcuts: ["Z", "ℤ"] },
+ // Zero-exclusive all integers domain
+ { domain: Domain.ZE, shortcuts: ["ZE", "Z*", "ℤ*"] },
+ // Negative integers domain
+ { domain: Domain.ZM, shortcuts: ["ZM", "Z-", "ℤ⁻", "ℤ-"] },
+ // Zero-exclusive negative integers domain
+ { domain: Domain.ZME, shortcuts: ["ZME", "ZEM", "Z-*", "Z*-", "ℤ⁻*", "ℤ*⁻", "ℤ-*", "ℤ*-"] },
+ ]
+
+ // Real domains
+ for(const { domain, shortcuts } of predefinedToCheck)
+ for(const shortcut of shortcuts)
+ expect(parseDomainSimple(shortcut)).to.be.equal(domain)
+ })
+
+ it("")
+ })
+})
diff --git a/common/test/mock/fs.mjs b/common/test/mock/fs.mjs
new file mode 100644
index 0000000..bccb71f
--- /dev/null
+++ b/common/test/mock/fs.mjs
@@ -0,0 +1,44 @@
+/**
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import { readFileSync as readNode } from "node:fs"
+import { dirname } from 'node:path';
+import { fileURLToPath } from 'node:url';
+
+const __dirname = dirname(fileURLToPath(import.meta.url))
+
+export const HOME = "/home/user"
+export const TMP = "/tmp"
+
+
+const filesystem = {
+ [`${HOME}/test1.lpf`]: readNode(__dirname + "/../../../ci/test1.lpf")
+}
+
+
+export function existsSync(file) {
+ return filesystem[file] !== undefined
+}
+
+export function writeFileSync(file, data, encoding) {
+ filesystem[file] = Buffer.from(data, encoding)
+}
+
+export function readFileSync(file, encoding) {
+ return filesystem[file].toString(encoding)
+}
\ No newline at end of file
diff --git a/common/test/mock/helper.mjs b/common/test/mock/helper.mjs
new file mode 100644
index 0000000..9f74b64
--- /dev/null
+++ b/common/test/mock/helper.mjs
@@ -0,0 +1,158 @@
+/**
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import { readFileSync, writeFileSync, existsSync } from "./fs.mjs"
+
+const DEFAULT_SETTINGS = {
+ "check_for_updates": true,
+ "reset_redo_stack": true,
+ "last_install_greet": "0",
+ "enable_latex": false,
+ "expression_editor": {
+ "autoclose": true,
+ "colorize": true,
+ "color_scheme": 0
+ },
+ "autocompletion": {
+ "enabled": true
+ },
+ "default_graph": {
+ "xzoom": 100,
+ "yzoom": 10,
+ "xmin": 5 / 10,
+ "ymax": 25,
+ "xaxisstep": "4",
+ "yaxisstep": "4",
+ "xlabel": "",
+ "ylabel": "",
+ "linewidth": 1,
+ "textsize": 18,
+ "logscalex": true,
+ "showxgrad": true,
+ "showygrad": true
+ }
+}
+
+export class MockHelper {
+ constructor() {
+ this.__settings = { ...DEFAULT_SETTINGS }
+ }
+
+ __getSetting(settingName) {
+ const namespace = settingName.split(".")
+ let data = this.__settings
+ for(const name of namespace)
+ if(data.hasOwnProperty(name))
+ data = data[name]
+ else
+ throw new Error(`Setting ${namespace} does not exist.`)
+ return data
+ }
+
+ __setSetting(settingName, value) {
+ const namespace = settingName.split(".")
+ const finalName = namespace.pop()
+ let data = this.__settings
+ for(const name of namespace)
+ if(data.hasOwnProperty(name))
+ data = data[name]
+ else
+ throw new Error(`Setting ${namespace} does not exist.`)
+ data[finalName] = value
+ }
+
+ /**
+ * Gets a setting from the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin")
+ * @returns {boolean} Value of the setting
+ */
+ getSettingBool(settingName) {
+ return this.__getSetting(settingName) === true
+ }
+
+ /**
+ * Gets a setting from the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin")
+ * @returns {number} Value of the setting
+ */
+ getSettingInt(settingName) {
+ return +(this.__getSetting(settingName))
+ }
+
+ /**
+ * Gets a setting from the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to get (e.g. "default_graph.xmin")
+ * @returns {string} Value of the setting
+ */
+ getSetting(settingName) {
+ return this.__getSetting(settingName).toString()
+ }
+
+ /**
+ * Sets a setting in the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin")
+ * @param {boolean} value
+ */
+ setSettingBool(settingName, value) {
+ return this.__setSetting(settingName, value === true)
+ }
+
+ /**
+ * Sets a setting in the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin")
+ * @param {number} value
+ */
+ setSettingInt(settingName, value) {
+ return this.__setSetting(settingName, +(value))
+ }
+
+ /**
+ * Sets a setting in the config
+ * @param {string} settingName - Setting (and its dot-separated namespace) to set (e.g. "default_graph.xmin")
+ * @param {string} value
+ */
+ setSetting(settingName, value) {
+ return this.__setSetting(settingName, value.toString())
+ }
+
+ /**
+ * Sends data to be written
+ * @param {string} file
+ * @param {string} dataToWrite - just JSON encoded, requires the "LPFv1" mime to be added before writing
+ */
+ write(file, dataToWrite) {
+ writeFileSync(file, "LPFv1" + dataToWrite)
+ }
+
+ /**
+ * Requests data to be read from a file
+ * @param {string} file
+ * @returns {string} the loaded data - just JSON encoded, requires the "LPFv1" mime to be stripped
+ */
+ load(file) {
+ if(existsSync(file)) {
+ const data = readFileSync(file, "utf8")
+ if(data.startsWith("LPFv1"))
+ return data.substring(5)
+ else
+ throw new Error(`Invalid LogarithmPlotter file.`)
+ } else
+ throw new Error(`File not found.`)
+ }
+
+}
\ No newline at end of file
diff --git a/common/test/mock/latex.mjs b/common/test/mock/latex.mjs
new file mode 100644
index 0000000..ab56999
--- /dev/null
+++ b/common/test/mock/latex.mjs
@@ -0,0 +1,90 @@
+/**
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import { TMP, existsSync, writeFileSync } from "./fs.mjs"
+
+const PIXEL = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVR4AWNgAAAAAgABc3UBGAAAAABJRU5ErkJggg=="
+
+export class MockLatex {
+ constructor() {
+ }
+
+ /**
+ * Creates a simple string hash.
+ * @param {string} string
+ * @return {number}
+ * @private
+ */
+ __hash(string) {
+ let hash = 0
+ let i, chr
+ if(string.length === 0) return hash
+ for(i = 0; i < string.length; i++) {
+ chr = string.charCodeAt(i)
+ hash = ((hash << 5) - hash) + chr
+ hash |= 0 // Convert to 32bit integer
+ }
+ return hash
+ }
+
+ /**
+ *
+ * @param {string} markup
+ * @param {number} fontSize
+ * @param {string} color
+ * @return {string}
+ * @private
+ */
+ __getFileName(markup, fontSize, color) {
+ const name = this.__hash(`${markup}_${fontSize}_${color}`)
+ return `${TMP}/${name}.png`
+ }
+
+ /**
+ * @param {string} markup - LaTeX markup to render
+ * @param {number} fontSize - Font size (in pt) to render
+ * @param {string} color - Color of the text to render
+ * @returns {string} - Comma separated data of the image (source, width, height)
+ */
+ render(markup, fontSize, color) {
+ const file = this.__getFileName(markup, fontSize, color)
+ writeFileSync(file, PIXEL, "base64")
+ return `${file},1,1`
+ }
+
+ /**
+ * @param {string} markup - LaTeX markup to render
+ * @param {number} fontSize - Font size (in pt) to render
+ * @param {string} color - Color of the text to render
+ * @returns {string} - Comma separated data of the image (source, width, height)
+ */
+ findPrerendered(markup, fontSize, color) {
+ const file = this.__getFileName(markup, fontSize, color)
+ if(existsSync(file))
+ return `${file},1,1`
+ return ""
+ }
+
+ /**
+ * Checks if the Latex installation is valid
+ * @returns {boolean}
+ */
+ checkLatexInstallation() {
+ return true // We're not *actually* doing any latex.
+ }
+}
\ No newline at end of file
diff --git a/common/test/mock/qt.mjs b/common/test/mock/qt.mjs
new file mode 100644
index 0000000..50ec349
--- /dev/null
+++ b/common/test/mock/qt.mjs
@@ -0,0 +1,60 @@
+/**
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+// Mock qt methods.
+
+/**
+ * Polyfill for Qt.rect.
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ * @returns {{x, width, y, height}}
+ */
+function rect(x, y, width, height) {
+ return { x, y, width, height }
+}
+
+/**
+ * Mock for QT_TRANSLATE_NOOP and qsTranslate
+ * @param {string} category
+ * @param {string} string
+ * @return {string}
+ */
+function QT_TRANSLATE_NOOP(category, string) {
+ return string
+}
+
+function setup() {
+ globalThis.Qt = {
+ rect
+ }
+
+ globalThis.QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP
+ globalThis.qsTranslate = QT_TRANSLATE_NOOP
+
+ String.prototype.arg = function() { return this; } // No need to reimplement it for now.
+}
+
+setup()
+
+export default {
+ rect,
+ QT_TRANSLATE_NOOP,
+ qtTranslate: QT_TRANSLATE_NOOP,
+}
\ No newline at end of file
diff --git a/linux/application-x-logarithm-plot.svg b/linux/application-x-logarithm-plot.svg
deleted file mode 100644
index 580277f..0000000
--- a/linux/application-x-logarithm-plot.svg
+++ /dev/null
@@ -1,177 +0,0 @@
-
-
diff --git a/linux/debian/depends b/linux/debian/depends
deleted file mode 100644
index c17dcdd..0000000
--- a/linux/debian/depends
+++ /dev/null
@@ -1 +0,0 @@
-python3, python3-pip, python3-pyside6-essentials (>= 6.7), python3-pyside6-addons (>= 6.7), texlive-latex-base, dvipng
diff --git a/run.py b/run.py
index 1481dba..783e23b 100644
--- a/run.py
+++ b/run.py
@@ -15,21 +15,24 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
"""
-def update_translations():
+from os import system, getcwd, path
+from sys import path as sys_path, argv
+
+def build():
"""
Updates all binary translations
"""
- from os import system, getcwd, chdir, path
- pwd = getcwd()
- chdir(path.join("LogarithmPlotter", "i18n"))
- system("./release.sh")
- chdir(pwd)
+ system("./scripts/build.sh")
def run():
- update_translations()
from LogarithmPlotter import logarithmplotter
logarithmplotter.run()
if __name__ == "__main__":
+ if '--test-build' not in argv:
+ build()
+ logplotter_path = path.realpath(path.join(getcwd(), "build", "runtime-pyside6"))
+ print(f"Appending {logplotter_path} to path...")
+ sys_path.append(logplotter_path)
run()
diff --git a/LogarithmPlotter/__init__.py b/runtime-pyside6/LogarithmPlotter/__init__.py
similarity index 100%
rename from LogarithmPlotter/__init__.py
rename to runtime-pyside6/LogarithmPlotter/__init__.py
diff --git a/LogarithmPlotter/logarithmplotter.py b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py
similarity index 98%
rename from LogarithmPlotter/logarithmplotter.py
rename to runtime-pyside6/LogarithmPlotter/logarithmplotter.py
index bc4d895..3264097 100644
--- a/LogarithmPlotter/logarithmplotter.py
+++ b/runtime-pyside6/LogarithmPlotter/logarithmplotter.py
@@ -43,7 +43,7 @@ if path.realpath(path.join(getcwd(), "..")) not in sys_path:
sys_path.append(path.realpath(path.join(getcwd(), "..")))
from LogarithmPlotter import __VERSION__
-from LogarithmPlotter.util import config, native
+from LogarithmPlotter.util import config, native, debug
from LogarithmPlotter.util.update import check_for_updates
from LogarithmPlotter.util.helper import Helper
from LogarithmPlotter.util.latex import Latex
@@ -130,7 +130,7 @@ def create_engine(helper: Helper, latex: Latex, dep_time: float) -> tuple[QQmlAp
global tmpfile
engine = QQmlApplicationEngine()
js_globals = PyJSValue(engine.globalObject())
- js_globals.Modules = engine.newObject()
+ js_globals.globalThis = engine.globalObject()
js_globals.Helper = engine.newQObject(helper)
js_globals.Latex = engine.newQObject(latex)
engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv)
@@ -155,6 +155,7 @@ def run():
register_icon_directories()
app = create_qapp()
translator = install_translation(app)
+ debug.setup()
# Installing macOS file handler.
macos_file_open_handler = None
diff --git a/runtime-pyside6/LogarithmPlotter/logarithmplotter.svg b/runtime-pyside6/LogarithmPlotter/logarithmplotter.svg
new file mode 100644
index 0000000..77a2817
--- /dev/null
+++ b/runtime-pyside6/LogarithmPlotter/logarithmplotter.svg
@@ -0,0 +1,64 @@
+
+
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml
similarity index 97%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml
index d0c2621..f26fd5b 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml
@@ -20,7 +20,7 @@ import QtQuick
import Qt.labs.platform as Native
//import QtQuick.Controls 2.15
import eu.ad5001.MixedMenu 1.1
-import "js/history/index.mjs" as HistoryLib
+import "js/index.mjs" as JS
/*!
@@ -119,7 +119,7 @@ MenuBar {
icon.color: sysPalette.buttonText
onTriggered: {
var newObj = Modules.Objects.createNewRegisteredObject(modelData)
- history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export()))
+ history.addToHistory(new JS.HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export()))
objectLists.update()
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml
similarity index 96%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml
index 85abbc7..47db5f3 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml
@@ -19,7 +19,7 @@
import QtQuick
import QtQml
import QtQuick.Window
-import "../js/history/index.mjs" as HistoryLib
+import "../js/index.mjs" as JS
/*!
\qmltype History
@@ -97,9 +97,9 @@ Item {
function unserialize(undoSt, redoSt) {
clear();
for(let i = 0; i < undoSt.length; i++)
- undoStack.push(new HistoryLib.Actions[undoSt[i][0]](...undoSt[i][1]))
+ undoStack.push(new JS.HistoryLib.Actions[undoSt[i][0]](...undoSt[i][1]))
for(let i = 0; i < redoSt.length; i++)
- redoStack.push(new HistoryLib.Actions[redoSt[i][0]](...redoSt[i][1]))
+ redoStack.push(new JS.HistoryLib.Actions[redoSt[i][0]](...redoSt[i][1]))
undoCount = undoSt.length;
redoCount = redoSt.length;
objectLists.update()
@@ -110,7 +110,7 @@ Item {
Adds an instance of HistoryLib.Action to history.
*/
function addToHistory(action) {
- if(action instanceof HistoryLib.Action) {
+ if(action instanceof JS.HistoryLib.Action) {
console.log("Added new entry to history: " + action.getReadableString())
undoStack.push(action)
undoCount++;
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml
similarity index 99%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml
index 3fa37f8..926b42a 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml
@@ -19,7 +19,6 @@
import QtQuick.Controls
import QtQuick
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
-import "../js/utils.mjs" as Utils
/*!
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml
similarity index 99%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml
index 41d0015..f1e20a0 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml
@@ -19,7 +19,6 @@
import QtQuick.Controls
import QtQuick
import Qt5Compat.GraphicalEffects
-import "../js/utils.mjs" as Utils
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/qmldir
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml
similarity index 98%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml
index e54781f..38d05be 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml
@@ -18,8 +18,6 @@
import QtQuick
import Qt.labs.platform as Native
-import "js/utils.mjs" as Utils
-import "js/math/index.mjs" as MathLib
/*!
\qmltype LogGraphCanvas
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml
similarity index 97%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml
index 1a44958..8545153 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml
@@ -23,7 +23,7 @@ import QtQuick.Layouts 1.12
import QtQuick
// Auto loading all modules.
-import "js/autoload.mjs" as ModulesAutoload
+import "js/index.mjs" as JS
import eu.ad5001.LogarithmPlotter.History 1.0
import eu.ad5001.LogarithmPlotter.ObjectLists 1.0
@@ -259,4 +259,10 @@ ApplicationWindow {
function showUpdateMenu() {
appMenu.addMenu(updateMenu)
}
+
+ // Initializing modules
+ Component.onCompleted: {
+ Modules.IO.initialize({ root, settings, alert })
+ Modules.Latex.initialize({ latex: Latex, helper: Helper })
+ }
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml
similarity index 92%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml
index 361dcbf..57ea4ae 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml
@@ -20,9 +20,7 @@ import QtQuick
import QtQuick.Controls
import Qt.labs.platform as Native
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
-import "../../js/history/index.mjs" as HistoryLib
-import "../../js/utils.mjs" as Utils
-import "../../js/math/index.mjs" as MathLib
+import "../../js/index.mjs" as JS
/*!
\qmltype CustomPropertyList
@@ -77,12 +75,12 @@ Repeater {
height: 30
label: propertyLabel
icon: `settings/custom/${propertyIcon}.svg`
- defValue: Utils.simplifyExpression(obj[propertyName].toEditableString())
+ defValue: JS.Utils.simplifyExpression(obj[propertyName].toEditableString())
self: obj.name
variables: propertyType.variables
onChanged: function(newExpr) {
if(obj[propertyName].toString() != newExpr.toString()) {
- history.addToHistory(new HistoryLib.EditedProperty(
+ history.addToHistory(new JS.HistoryLib.EditedProperty(
obj.name, objType, propertyName,
obj[propertyName], newExpr
))
@@ -117,7 +115,7 @@ Repeater {
onChanged: function(newValue) {
try {
var newValueParsed = {
- "Domain": () => MathLib.parseDomain(newValue),
+ "Domain": () => JS.MathLib.parseDomain(newValue),
"string": () => newValue,
"number": () => newValue,
"int": () => newValue
@@ -125,7 +123,7 @@ Repeater {
// Ensuring old and new values are different to prevent useless adding to history.
if(obj[propertyName] != newValueParsed) {
- history.addToHistory(new HistoryLib.EditedProperty(
+ history.addToHistory(new JS.HistoryLib.EditedProperty(
obj.name, objType, propertyName,
obj[propertyName], newValueParsed
))
@@ -170,7 +168,7 @@ Repeater {
return obj[propertyName]
}
onClicked: {
- history.addToHistory(new HistoryLib.EditedProperty(
+ history.addToHistory(new JS.HistoryLib.EditedProperty(
obj.name, objType, propertyName,
obj[propertyName], this.checked
))
@@ -211,7 +209,7 @@ Repeater {
if(selectedObj == null) {
// Creating new object.
selectedObj = Modules.Objects.createNewRegisteredObject(propertyType.objType)
- history.addToHistory(new HistoryLib.CreateNewObject(selectedObj.name, propertyType.objType, selectedObj.export()))
+ history.addToHistory(new JS.HistoryLib.CreateNewObject(selectedObj.name, propertyType.objType, selectedObj.export()))
baseModel = Modules.Objects.getObjectsName(propertyType.objType).concat(
isRealObject ? [qsTr("+ Create new %1").arg(Modules.Objects.types[propertyType.objType].displayType())] :
[])
@@ -221,14 +219,14 @@ Repeater {
//Modules.Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name)
}
obj.requiredBy = obj.requiredBy.filter((obj) => obj.name != obj.name)
- history.addToHistory(new HistoryLib.EditedProperty(
+ history.addToHistory(new JS.HistoryLib.EditedProperty(
obj.name, objType, propertyName,
obj[propertyName], selectedObj
))
obj[propertyName] = selectedObj
} else if(baseModel[newIndex] != obj[propertyName]) {
// Ensuring new property is different to not add useless history entries.
- history.addToHistory(new HistoryLib.EditedProperty(
+ history.addToHistory(new JS.HistoryLib.EditedProperty(
obj.name, objType, propertyName,
obj[propertyName], baseModel[newIndex]
))
@@ -258,11 +256,10 @@ Repeater {
onChanged: {
var exported = exportModel()
- history.addToHistory(new HistoryLib.EditedProperty(
+ history.addToHistory(new JS.HistoryLib.EditedProperty(
obj.name, objType, propertyName,
obj[propertyName], exported
))
- //Modules.Objects.currentObjects[objType][objIndex][propertyName] = exported
obj[propertyName] = exported
root.changed()
}
@@ -284,7 +281,7 @@ Repeater {
property string propertyName: modelData[0]
property var propertyType: modelData[1]
property string propertyLabel: qsTranslate('prop',propertyName)
- property string propertyIcon: Utils.camelCase2readable(propertyName)
+ property string propertyIcon: JS.Utils.camelCase2readable(propertyName)
sourceComponent: {
if(propertyName.startsWith('comment'))
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml
similarity index 95%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml
index 7a357b3..e2b149b 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml
@@ -22,9 +22,7 @@ import QtQuick.Dialogs as D
import Qt.labs.platform as Native
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup
-import "../../js/history/index.mjs" as HistoryLib
-import "../../js/utils.mjs" as Utils
-import "../../js/math/index.mjs" as MathLib
+import "../../js/index.mjs" as JS
/*!
\qmltype Dialog
@@ -109,12 +107,12 @@ Popup.BaseDialog {
width: dlgProperties.width
value: objEditor.obj.name
onChanged: function(newValue) {
- let newName = Utils.parseName(newValue)
+ let newName = JS.Utils.parseName(newValue)
if(newName != '' && objEditor.obj.name != newName) {
if(newName in Modules.Objects.currentObjectsByName) {
invalidNameDialog.showDialog(newName)
} else {
- history.addToHistory(new HistoryLib.NameChanged(
+ history.addToHistory(new JS.HistoryLib.NameChanged(
objEditor.obj.name, objEditor.objType, newName
))
Modules.Objects.renameObject(obj.name, newName)
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml
similarity index 96%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml
index 3d0a56a..7aa9574 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml
@@ -18,8 +18,8 @@
import QtQuick
import QtQuick.Controls
-import "../js/history/index.mjs" as HistoryLib
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
+import "../js/index.mjs" as JS
/*!
@@ -104,7 +104,7 @@ Column {
onClicked: {
let newObj = Modules.Objects.createNewRegisteredObject(modelData)
- history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export()))
+ history.addToHistory(new JS.HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export()))
objectLists.update()
let hasXProp = newObj.constructor.properties().hasOwnProperty('x')
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml
similarity index 97%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml
index a1b9d82..5018e5e 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml
@@ -21,7 +21,7 @@ import QtQuick.Dialogs
import QtQuick.Controls
import QtQuick.Window
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
-import "../js/history/index.mjs" as HistoryLib
+import "../js/index.mjs" as JS
/*!
@@ -72,7 +72,7 @@ Item {
anchors.left: parent.left
anchors.leftMargin: 5
onClicked: {
- history.addToHistory(new HistoryLib.EditedVisibility(
+ history.addToHistory(new JS.HistoryLib.EditedVisibility(
obj.name, obj.type, this.checked
))
obj.visible = this.checked
@@ -212,7 +212,7 @@ Item {
selectedColor: obj.color
title: qsTr("Pick new color for %1 %2").arg(obj.constructor.displayType()).arg(obj.name)
onAccepted: {
- history.addToHistory(new HistoryLib.ColorChanged(
+ history.addToHistory(new JS.HistoryLib.ColorChanged(
obj.name, obj.type, obj.color, selectedColor.toString()
))
obj.color = selectedColor.toString()
@@ -231,7 +231,7 @@ Item {
// Object still exists
// Temporary fix for objects require not being propertly updated.
object.requiredBy = []
- history.addToHistory(new HistoryLib.DeleteObject(
+ history.addToHistory(new JS.HistoryLib.DeleteObject(
object.name, object.type, object.export()
))
Modules.Objects.deleteObject(object.name)
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml
similarity index 97%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml
index cecdf13..2fb45d4 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml
@@ -19,8 +19,7 @@
import QtQuick
import QtQuick.Controls
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
-import "js/math/index.mjs" as MathLib
-import "js/history/index.mjs" as HistoryLib
+import "js/index.mjs" as JS
/*!
\qmltype PickLocationOverlay
@@ -116,7 +115,7 @@ Item {
let obj = Modules.Objects.currentObjectsByName[objName]
// Set values
if(parent.userPickX && parent.userPickY) {
- history.addToHistory(new HistoryLib.EditedPosition(
+ history.addToHistory(new JS.HistoryLib.EditedPosition(
objName, objType, obj[propertyX], newValueX, obj[propertyY], newValueY
))
obj[propertyX] = newValueX
@@ -125,7 +124,7 @@ Item {
objectLists.update()
pickerRoot.picked(obj)
} else if(parent.userPickX) {
- history.addToHistory(new HistoryLib.EditedProperty(
+ history.addToHistory(new JS.HistoryLib.EditedProperty(
objName, objType, propertyX, obj[propertyX], newValueX
))
obj[propertyX] = newValueX
@@ -133,7 +132,7 @@ Item {
objectLists.update()
pickerRoot.picked(obj)
} else if(parent.userPickY) {
- history.addToHistory(new HistoryLib.EditedProperty(
+ history.addToHistory(new JS.HistoryLib.EditedProperty(
objName, objType, propertyY, obj[propertyY], newValueY
))
obj[propertyY] = newValueY
@@ -327,6 +326,6 @@ Item {
if(Modules.Objects.types[objType].properties()[propertyName] == 'number')
return parseFloat(value)
else
- return new MathLib.Expression(value)
+ return new JS.MathLib.Expression(value)
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml
similarity index 97%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml
index 44b1c8f..a76410f 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml
@@ -20,8 +20,7 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
-import "../js/preferences/common.mjs" as S
-import "../js/utils.mjs" as Utils
+import "../js/index.mjs" as JS
/*!
\qmltype Preferences
@@ -77,7 +76,7 @@ Popup {
currentIndex: find(setting.value())
model: setting.defaultValues
onAccepted: function() {
- editText = Utils.parseName(editText, false)
+ editText = JS.Utils.parseName(editText, false)
if(find(editText) === -1) model.append(editText)
setting.set(editText)
}
@@ -116,7 +115,7 @@ Popup {
height: 30
label: setting.name
icon: `settings/${setting.icon}.svg`
- defValue: Utils.simplifyExpression(setting.value())
+ defValue: JS.Utils.simplifyExpression(setting.value())
variables: setting.variables
allowGraphObjects: false
property string propertyName: setting.name
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml
similarity index 93%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml
index 6a17423..afa3e09 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml
@@ -20,9 +20,7 @@ import QtQuick.Controls
import QtQuick
import Qt.labs.platform as Native
import eu.ad5001.LogarithmPlotter.Popup 1.0 as P
-import "../js/math/index.mjs" as MathLib
-import "../js/utils.mjs" as Utils
-import "../js/parsing/parsing.mjs" as Parsing
+import "../js/index.mjs" as JS
/*!
@@ -319,9 +317,9 @@ Item {
width: parent.width
readonly property var identifierTokenTypes: [
- Parsing.TokenType.VARIABLE,
- Parsing.TokenType.FUNCTION,
- Parsing.TokenType.CONSTANT
+ JS.Parsing.TokenType.VARIABLE,
+ JS.Parsing.TokenType.FUNCTION,
+ JS.Parsing.TokenType.CONSTANT
]
property var currentToken: generateTokenInformation(getTokenAt(editor.tokens, editor.cursorPosition))
property var previousToken: generateTokenInformation(getPreviousToken(currentToken.token))
@@ -346,7 +344,7 @@ Item {
'value': exists ? token.value : null,
'type': exists ? token.type : null,
'startPosition': exists ? token.startPosition : 0,
- 'dot': exists ? (token.type == Parsing.TokenType.PUNCT && token.value == ".") : false,
+ 'dot': exists ? (token.type == JS.Parsing.TokenType.PUNCT && token.value == ".") : false,
'identifier': exists ? identifierTokenTypes.includes(token.type) : false
}
}
@@ -385,7 +383,7 @@ Item {
*/
function getPreviousToken(token) {
let newToken = getTokenAt(editor.tokens, token.startPosition)
- if(newToken != null && newToken.type == Parsing.TokenType.WHITESPACE)
+ if(newToken != null && newToken.type == JS.Parsing.TokenType.WHITESPACE)
return getPreviousToken(newToken)
return newToken
}
@@ -444,9 +442,9 @@ Item {
visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot
itemStartIndex: variablesList.itemStartIndex + variablesList.model.length
itemSelected: parent.itemSelected
- categoryItems: Parsing.CONSTANTS_LIST
+ categoryItems: JS.Parsing.CONSTANTS_LIST
autocompleteGenerator: (item) => {return {
- 'text': item, 'annotation': Parsing.CONSTANTS[item],
+ 'text': item, 'annotation': JS.Parsing.CONSTANTS[item],
'autocomplete': item + " ", 'cursorFinalOffset': 0
}}
baseText: parent.visible ? parent.currentToken.value : ""
@@ -459,9 +457,9 @@ Item {
visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot
itemStartIndex: constantsList.itemStartIndex + constantsList.model.length
itemSelected: parent.itemSelected
- categoryItems: Parsing.FUNCTIONS_LIST
+ categoryItems: JS.Parsing.FUNCTIONS_LIST
autocompleteGenerator: (item) => {return {
- 'text': item, 'annotation': Parsing.FUNCTIONS_USAGE[item].join(', '),
+ 'text': item, 'annotation': JS.Parsing.FUNCTIONS_USAGE[item].join(', '),
'autocomplete': item+'()', 'cursorFinalOffset': -1
}}
baseText: parent.visible ? parent.currentToken.value : ""
@@ -538,9 +536,9 @@ Item {
function parse(newExpression) {
let expr = null
try {
- expr = new MathLib.Expression(value.toString())
+ expr = new JS.MathLib.Expression(value.toString())
// Check if the expression is valid, throws error otherwise.
- if(!expr.allRequirementsFullfilled()) {
+ if(!expr.allRequirementsFulfilled()) {
let undefVars = expr.undefinedVariables()
if(undefVars.length > 1)
throw new Error(qsTranslate('error', 'No object found with names %1.').arg(undefVars.join(', ')))
@@ -572,7 +570,7 @@ Item {
Generates a list of tokens from the given.
*/
function tokens(text) {
- let tokenizer = new Parsing.Tokenizer(new Parsing.Input(text), true, false)
+ let tokenizer = new JS.Parsing.Tokenizer(new JS.Parsing.Input(text), true, false)
let tokenList = []
let token
while((token = tokenizer.next()) != null)
@@ -605,28 +603,28 @@ Item {
let scheme = colorSchemes[Helper.getSettingInt("expression_editor.color_scheme")]
for(let token of tokenList) {
switch(token.type) {
- case Parsing.TokenType.VARIABLE:
+ case JS.Parsing.TokenType.VARIABLE:
parsedText += `${token.value}`
break;
- case Parsing.TokenType.CONSTANT:
+ case JS.Parsing.TokenType.CONSTANT:
parsedText += `${token.value}`
break;
- case Parsing.TokenType.FUNCTION:
- parsedText += `${Utils.escapeHTML(token.value)}`
+ case JS.Parsing.TokenType.FUNCTION:
+ parsedText += `${JS.Utils.escapeHTML(token.value)}`
break;
- case Parsing.TokenType.OPERATOR:
- parsedText += `${Utils.escapeHTML(token.value)}`
+ case JS.Parsing.TokenType.OPERATOR:
+ parsedText += `${JS.Utils.escapeHTML(token.value)}`
break;
- case Parsing.TokenType.NUMBER:
- parsedText += `${Utils.escapeHTML(token.value)}`
+ case JS.Parsing.TokenType.NUMBER:
+ parsedText += `${JS.Utils.escapeHTML(token.value)}`
break;
- case Parsing.TokenType.STRING:
- parsedText += `${token.limitator}${Utils.escapeHTML(token.value)}${token.limitator}`
+ case JS.Parsing.TokenType.STRING:
+ parsedText += `${token.limitator}${JS.Utils.escapeHTML(token.value)}${token.limitator}`
break;
- case Parsing.TokenType.WHITESPACE:
- case Parsing.TokenType.PUNCT:
+ case JS.Parsing.TokenType.WHITESPACE:
+ case JS.Parsing.TokenType.PUNCT:
default:
- parsedText += Utils.escapeHTML(token.value).replace(/ /g, ' ')
+ parsedText += JS.Utils.escapeHTML(token.value).replace(/ /g, ' ')
break;
}
}
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml
similarity index 98%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml
index 3c6e994..534556f 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml
@@ -20,7 +20,7 @@ import QtQuick
import QtQuick.Controls
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup
-import "js/utils.mjs" as Utils
+import "js/index.mjs" as JS
/*!
\qmltype Settings
@@ -127,10 +127,6 @@ ScrollView {
*/
property string saveFilename: ""
- Component.onCompleted: {
- Modules.IO.initialize({ root, settings, alert })
- }
-
Column {
spacing: 10
width: parent.width
@@ -330,7 +326,7 @@ ScrollView {
currentIndex: find(settings.xlabel)
editable: true
onAccepted: function(){
- editText = Utils.parseName(editText, false)
+ editText = JS.Utils.parseName(editText, false)
if (find(editText) === -1) model.append({text: editText})
settings.xlabel = editText
settings.changed()
@@ -359,7 +355,7 @@ ScrollView {
currentIndex: find(settings.ylabel)
editable: true
onAccepted: function(){
- editText = Utils.parseName(editText, false)
+ editText = JS.Utils.parseName(editText, false)
if (find(editText) === -1) model.append({text: editText, yaxisstep: root.yaxisstep})
settings.ylabel = editText
settings.changed()
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml
similarity index 98%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml
index b06fbcf..e8514d4 100644
--- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml
+++ b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml
@@ -19,8 +19,6 @@
import QtQuick
import QtQuick.Controls
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
-import "js/math/index.mjs" as MathLib
-import "js/history/index.mjs" as HistoryLib
/*!
\qmltype ViewPositionChangeOverlay
diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/qmldir
diff --git a/LogarithmPlotter/qml/eu/ad5001/MixedMenu b/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/MixedMenu
similarity index 100%
rename from LogarithmPlotter/qml/eu/ad5001/MixedMenu
rename to runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/MixedMenu
diff --git a/LogarithmPlotter/util/__init__.py b/runtime-pyside6/LogarithmPlotter/util/__init__.py
similarity index 100%
rename from LogarithmPlotter/util/__init__.py
rename to runtime-pyside6/LogarithmPlotter/util/__init__.py
diff --git a/LogarithmPlotter/util/config.py b/runtime-pyside6/LogarithmPlotter/util/config.py
similarity index 93%
rename from LogarithmPlotter/util/config.py
rename to runtime-pyside6/LogarithmPlotter/util/config.py
index d295caa..a5ee23c 100644
--- a/LogarithmPlotter/util/config.py
+++ b/runtime-pyside6/LogarithmPlotter/util/config.py
@@ -120,11 +120,9 @@ def setSetting(namespace, data):
"""
names = namespace.split(".")
setting = current_config
- for name in names:
- if name != names[-1]:
- if name in setting:
- setting = setting[name]
- else:
- raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}")
+ for name in names[:-1]:
+ if name in setting:
+ setting = setting[name]
else:
- setting[name] = data
+ raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}")
+ setting[names[-1]] = data
diff --git a/runtime-pyside6/LogarithmPlotter/util/debug.py b/runtime-pyside6/LogarithmPlotter/util/debug.py
new file mode 100644
index 0000000..8b57687
--- /dev/null
+++ b/runtime-pyside6/LogarithmPlotter/util/debug.py
@@ -0,0 +1,102 @@
+"""
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+"""
+
+from PySide6.QtCore import QtMsgType, qInstallMessageHandler, QMessageLogContext
+from math import ceil, log10
+from os import path
+
+CURRENT_PATH = path.dirname(path.realpath(__file__))
+SOURCEMAP_PATH = path.realpath(f"{CURRENT_PATH}/../qml/eu/ad5001/LogarithmPlotter/js/index.mjs.map")
+SOURCEMAP_INDEX = None
+
+
+class LOG_COLORS:
+ GRAY = "\033[90m"
+ BLUE = "\033[94m"
+ ORANGE = "\033[38;5;166m"
+ RED = "\033[38;5;204m"
+ INVERT = "\033[7m"
+ RESET_INVERT = "\033[27m"
+ RESET = "\033[0m"
+
+
+MODES = {
+ QtMsgType.QtInfoMsg: ['info', LOG_COLORS.BLUE],
+ QtMsgType.QtWarningMsg: ['warning', LOG_COLORS.ORANGE],
+ QtMsgType.QtCriticalMsg: ['critical', LOG_COLORS.RED],
+ QtMsgType.QtFatalMsg: ['critical', LOG_COLORS.RED]
+}
+
+DEFAULT_MODE = ['debug', LOG_COLORS.GRAY]
+
+
+def map_javascript_source(source_file: str, line: str) -> tuple[str, str]:
+ """
+ Maps a line from the compiled javascript to its source.
+ """
+ try:
+ if SOURCEMAP_INDEX is not None:
+ token = SOURCEMAP_INDEX.lookup(line, 20)
+ source_file = token.src.split("../")[-1]
+ line = token.src_line
+ except IndexError:
+ pass # Unable to find source, leave as is.
+ return source_file, line
+
+
+def create_log_terminal_message(mode: QtMsgType, context: QMessageLogContext, message: str):
+ """
+ Parses a qt log message and returns it.
+ """
+ mode = MODES[mode] if mode in MODES else DEFAULT_MODE
+ line = context.line
+ source_file = context.file
+ # Remove source and line from message
+ if source_file is not None:
+ if message.startswith(source_file):
+ message = message[len(source_file) + 1:]
+ source_file = "LogarithmPlotter/qml/" + source_file.split("/qml/")[-1] # We're only interested in that part.
+ if line is not None and message.startswith(str(line)):
+ line_length = ceil(log10((line + 1) if line > 0 else 1))
+ message = message[line_length + 2:]
+ # Check MJS
+ if line is not None and source_file is not None and source_file.endswith("index.mjs"):
+ source_file, line = map_javascript_source(source_file, line)
+ prefix = f"{LOG_COLORS.INVERT}{mode[1]}[{mode[0].upper()}]{LOG_COLORS.RESET_INVERT}"
+ message = message + LOG_COLORS.RESET
+ context = f"{context.function} at {source_file}:{line}"
+ return f"{prefix} {message} ({context})"
+
+
+def log_qt_debug(mode: QtMsgType, context: QMessageLogContext, message: str):
+ """
+ Parses and renders qt log messages.
+ """
+ print(create_log_terminal_message(mode, context, message))
+
+
+def setup():
+ global SOURCEMAP_INDEX
+ try:
+ with open(SOURCEMAP_PATH, "r") as f:
+ from sourcemap import loads
+ SOURCEMAP_INDEX = loads(f.read())
+ except Exception as e:
+ log_qt_debug(QtMsgType.QtWarningMsg, QMessageLogContext(),
+ f"Could not setup JavaScript source mapper in logs: {repr(e)}")
+ qInstallMessageHandler(log_qt_debug)
diff --git a/LogarithmPlotter/util/helper.py b/runtime-pyside6/LogarithmPlotter/util/helper.py
similarity index 100%
rename from LogarithmPlotter/util/helper.py
rename to runtime-pyside6/LogarithmPlotter/util/helper.py
diff --git a/LogarithmPlotter/util/js.py b/runtime-pyside6/LogarithmPlotter/util/js.py
similarity index 100%
rename from LogarithmPlotter/util/js.py
rename to runtime-pyside6/LogarithmPlotter/util/js.py
diff --git a/LogarithmPlotter/util/latex.py b/runtime-pyside6/LogarithmPlotter/util/latex.py
similarity index 100%
rename from LogarithmPlotter/util/latex.py
rename to runtime-pyside6/LogarithmPlotter/util/latex.py
diff --git a/LogarithmPlotter/util/native.py b/runtime-pyside6/LogarithmPlotter/util/native.py
similarity index 100%
rename from LogarithmPlotter/util/native.py
rename to runtime-pyside6/LogarithmPlotter/util/native.py
diff --git a/LogarithmPlotter/util/update.py b/runtime-pyside6/LogarithmPlotter/util/update.py
similarity index 99%
rename from LogarithmPlotter/util/update.py
rename to runtime-pyside6/LogarithmPlotter/util/update.py
index 32017d5..1d2ecec 100644
--- a/LogarithmPlotter/util/update.py
+++ b/runtime-pyside6/LogarithmPlotter/util/update.py
@@ -78,7 +78,6 @@ def check_for_updates(current_version, window):
return
def cb(show_alert, msg_text, update_available):
- pass
if show_alert:
window.showAlert(msg_text)
if update_available:
diff --git a/MANIFEST.in b/runtime-pyside6/MANIFEST.in
similarity index 100%
rename from MANIFEST.in
rename to runtime-pyside6/MANIFEST.in
diff --git a/poetry.lock b/runtime-pyside6/poetry.lock
similarity index 91%
rename from poetry.lock
rename to runtime-pyside6/poetry.lock
index 0c25a10..a4727e1 100644
--- a/poetry.lock
+++ b/runtime-pyside6/poetry.lock
@@ -261,36 +261,36 @@ setuptools = ">=42.0.0"
[[package]]
name = "pyside6-addons"
-version = "6.7.2"
+version = "6.7.3"
description = "Python bindings for the Qt cross-platform application and UI framework (Addons)"
optional = false
python-versions = "<3.13,>=3.9"
files = [
- {file = "PySide6_Addons-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:90b995efce61058d995c603ea480a9a3054fe8206739dcbc273fc3b53d40650f"},
- {file = "PySide6_Addons-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:94b9bf6a2a4a7ac671e1776633e50d51326c86f4184f1c6e556f4dd5498fd52a"},
- {file = "PySide6_Addons-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:22979b1aa09d9cf1d7a86c8a9aa0cb4791d6bd1cc94f96c5b6780c5ef8a9e34e"},
- {file = "PySide6_Addons-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:ebf549eb25998665d8e4ec24014fbbd37bebc5ecdcb050b34db1e1c03e1bf81d"},
+ {file = "PySide6_Addons-6.7.3-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:3174cb3a373c09c98740b452e8e8f4945d64cfa18ed8d43964111d570f0dc647"},
+ {file = "PySide6_Addons-6.7.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:bde1eb03dbffd089b50cd445847aaecaf4056cea84c49ea592d00f84f247251e"},
+ {file = "PySide6_Addons-6.7.3-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:5a9e0df31345fe6caea677d916ea48b53ba86f95cc6499c57f89e392447ad6db"},
+ {file = "PySide6_Addons-6.7.3-cp39-abi3-win_amd64.whl", hash = "sha256:d8a19c2b2446407724c81c33ebf3217eaabd092f0f72da8130c17079e04a7813"},
]
[package.dependencies]
-PySide6-Essentials = "6.7.2"
-shiboken6 = "6.7.2"
+PySide6-Essentials = "6.7.3"
+shiboken6 = "6.7.3"
[[package]]
name = "pyside6-essentials"
-version = "6.7.2"
+version = "6.7.3"
description = "Python bindings for the Qt cross-platform application and UI framework (Essentials)"
optional = false
python-versions = "<3.13,>=3.9"
files = [
- {file = "PySide6_Essentials-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:4d13666e796ec140ecfb432c4f3d7baef6dfafc11929985a83b22c0025532fb7"},
- {file = "PySide6_Essentials-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a1a4c09f1e916b9cfe53151fe4a503a6acb1f6621ba28204d1bfe636f80d6780"},
- {file = "PySide6_Essentials-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:9135513e1c4c6e2fbb1e4f9afcb3d42e54708b0d9ed870cb3213ea4874cafa1e"},
- {file = "PySide6_Essentials-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:0111d5fa8cf826de3ca9d82fed54726cce116d57f454f88a6467578652032d69"},
+ {file = "PySide6_Essentials-6.7.3-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:f9e08a4e9e7dc7b5ab72fde20abce8c97df7af1b802d9743f098f577dfe1f649"},
+ {file = "PySide6_Essentials-6.7.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cda6fd26aead48f32e57f044d18aa75dc39265b49d7957f515ce7ac3989e7029"},
+ {file = "PySide6_Essentials-6.7.3-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:acdde06b74f26e7d26b4ae1461081b32a6cb17fcaa2a580050b5e0f0f12236c9"},
+ {file = "PySide6_Essentials-6.7.3-cp39-abi3-win_amd64.whl", hash = "sha256:f0950fcdcbcd4f2443336dc6a5fe692172adc225f876839583503ded0ab2f2a7"},
]
[package.dependencies]
-shiboken6 = "6.7.2"
+shiboken6 = "6.7.3"
[[package]]
name = "pytest"
@@ -384,15 +384,26 @@ type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11
[[package]]
name = "shiboken6"
-version = "6.7.2"
+version = "6.7.3"
description = "Python/C++ bindings helper module"
optional = false
python-versions = "<3.13,>=3.9"
files = [
- {file = "shiboken6-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:50c33ac6317b673a1eb97a9abaafccb162c4ba0c9ca658a8e449c49a8aadc379"},
- {file = "shiboken6-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:70e80737b27cd5d83504b373013b55e70462bd4a27217d919ff9a83958731990"},
- {file = "shiboken6-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:98bedf9a15f1d8ba1af3e4d1e7527f7946ce36da541e08074fd9dc9ab5ff1adf"},
- {file = "shiboken6-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:9024e6afb2af1568ebfc8a5d07e4ff6c8829f40923eeb28901f535463e2b6b65"},
+ {file = "shiboken6-6.7.3-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:285fe3cf79be3135fe1ad1e2b9ff6db3a48698887425af6aa6ed7a05a9abc3d6"},
+ {file = "shiboken6-6.7.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f0852e5781de78be5b13c140ec4c7fb9734e2aaf2986eb2d6a224363e03efccc"},
+ {file = "shiboken6-6.7.3-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:f0dd635178e64a45be2f84c9f33dd79ac30328da87f834f21a0baf69ae210e6e"},
+ {file = "shiboken6-6.7.3-cp39-abi3-win_amd64.whl", hash = "sha256:5f29325dfa86fde0274240f1f38e421303749d3174ce3ada178715b5f4719db9"},
+]
+
+[[package]]
+name = "sourcemap"
+version = "0.2.1"
+description = "Parse JavaScript source maps."
+optional = false
+python-versions = "*"
+files = [
+ {file = "sourcemap-0.2.1-py2.py3-none-any.whl", hash = "sha256:c448a8c48f9482e522e4582106b0c641a83b5dbc7f13927b178848e3ea20967b"},
+ {file = "sourcemap-0.2.1.tar.gz", hash = "sha256:be00a90185e7a16b87bbe62a68ffd5e38bc438ef4700806d9b90e44d8027787c"},
]
[[package]]
@@ -438,4 +449,4 @@ type = ["pytest-mypy"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.9,<3.13"
-content-hash = "3db79d8b611fd2e37486fbd8e10c6d454b293cc7156d83b05c1a8459cb9b33e6"
+content-hash = "5636605737f21954e102a0110972e6bd3df07f2d5929f41fe541c7347c3ecf08"
diff --git a/pyproject.toml b/runtime-pyside6/pyproject.toml
similarity index 76%
rename from pyproject.toml
rename to runtime-pyside6/pyproject.toml
index f705e04..5293365 100644
--- a/pyproject.toml
+++ b/runtime-pyside6/pyproject.toml
@@ -9,14 +9,19 @@ package-mode = false
[tool.poetry.dependencies]
python = ">=3.9,<3.13"
-PySide6-Essentials = "^6.7.2"
-pyside6-addons = "^6.7.2"
+PySide6-Essentials = "^6.7"
+PySide6-Addons = "^6.7"
[tool.poetry.group.packaging.dependencies]
pyinstaller = "^6.10.0"
stdeb = "^0.10.0"
+setuptools = "^75.1.0"
[tool.poetry.group.test.dependencies]
pytest = "^8.3.3"
pytest-cov = "^5.0.0"
pytest-qt = "^4.4.0"
+
+[tool.poetry.group.dev.dependencies]
+sourcemap = "^0.2.1"
+
diff --git a/setup.py b/runtime-pyside6/setup.py
similarity index 66%
rename from setup.py
rename to runtime-pyside6/setup.py
index 4a4d2ea..08769a6 100644
--- a/setup.py
+++ b/runtime-pyside6/setup.py
@@ -96,30 +96,30 @@ def package_data():
data_files = []
if sys.platform == 'linux':
- data_files.append(('share/applications/', ['linux/logarithmplotter.desktop']))
- data_files.append(('share/mime/packages/', ['linux/x-logarithm-plot.xml']))
- data_files.append(('share/icons/hicolor/scalable/mimetypes/', ['linux/application-x-logarithm-plot.svg']))
- data_files.append(('share/icons/hicolor/scalable/apps/', ['LogarithmPlotter/logarithmplotter.svg']))
- data_files.append((os.environ["PREFIX"] + '/applications/', ['linux/logarithmplotter.desktop']))
- data_files.append((os.environ["PREFIX"] + '/mime/packages/', ['linux/x-logarithm-plot.xml']))
- data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/', ['linux/application-x-logarithm-plot.svg']))
- data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', ['LogarithmPlotter/logarithmplotter.svg']))
- if len(sys.argv) > 1:
- if sys.argv[1] == "install":
- os.makedirs(os.environ["PREFIX"] + '/applications/', exist_ok=True)
- os.makedirs(os.environ["PREFIX"] + '/mime/packages/', exist_ok=True)
- os.makedirs(os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/', exist_ok=True)
- os.makedirs(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', exist_ok=True)
- os.makedirs(os.environ["PREFIX"] + '/metainfo/', exist_ok=True)
- copyfile(current_dir + '/linux/x-logarithm-plot.xml', os.environ["PREFIX"] + '/mime/packages/x-logarithm-plot.xml')
- copyfile(current_dir + '/linux/application-x-logarithm-plot.svg',
- os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg')
- copyfile(current_dir + '/LogarithmPlotter/logarithmplotter.svg', os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/LogarithmPlotter/logarithmplotter.svg')
- elif sys.argv[1] == "uninstall":
- os.remove(os.environ["PREFIX"] + '/applications/logarithmplotter.desktop')
- os.remove(os.environ["PREFIX"] + '/mime/packages/x-logarithm-plot.xml')
- os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg')
- os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/LogarithmPlotter/logarithmplotter.svg')
+ data_files.append(('share/applications/', ['assets/native/linux/logarithmplotter.desktop']))
+ data_files.append(('share/mime/packages/', ['assets/native/linux/x-logarithm-plot.xml']))
+ data_files.append(('share/icons/hicolor/scalable/mimetypes/', ['assets/native/linux/application-x-logarithm-plot.svg']))
+ data_files.append(('share/icons/hicolor/scalable/apps/', ['assets/logarithmplotter.svg']))
+ # data_files.append((os.environ["PREFIX"] + '/applications/', ['linux/logarithmplotter.desktop']))
+ # data_files.append((os.environ["PREFIX"] + '/mime/packages/', ['linux/x-logarithm-plot.xml']))
+ # data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/', ['linux/application-x-logarithm-plot.svg']))
+ # data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', ['logplotter.svg']))
+ # if len(sys.argv) > 1:
+ # if sys.argv[1] == "install":
+ # os.makedirs(os.environ["PREFIX"] + '/applications/', exist_ok=True)
+ # os.makedirs(os.environ["PREFIX"] + '/mime/packages/', exist_ok=True)
+ # os.makedirs(os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/', exist_ok=True)
+ # os.makedirs(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', exist_ok=True)
+ # os.makedirs(os.environ["PREFIX"] + '/metainfo/', exist_ok=True)
+ # copyfile(current_dir + '/linux/x-logarithm-plot.xml', os.environ["PREFIX"] + '/mime/packages/x-logarithm-plot.xml')
+ # copyfile(current_dir + '/linux/application-x-logarithm-plot.svg',
+ # os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg')
+ # copyfile(current_dir + '/logplotter.svg', os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg')
+ # elif sys.argv[1] == "uninstall":
+ # os.remove(os.environ["PREFIX"] + '/applications/logarithmplotter.desktop')
+ # os.remove(os.environ["PREFIX"] + '/mime/packages/x-logarithm-plot.xml')
+ # os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg')
+ # os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg')
setuptools.setup(
install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide6-Essentials", "PySide6-Addons"]),
diff --git a/tests/python/globals.py b/runtime-pyside6/tests/globals.py
similarity index 100%
rename from tests/python/globals.py
rename to runtime-pyside6/tests/globals.py
diff --git a/tests/python/test_config.py b/runtime-pyside6/tests/test_config.py
similarity index 100%
rename from tests/python/test_config.py
rename to runtime-pyside6/tests/test_config.py
diff --git a/runtime-pyside6/tests/test_debug.py b/runtime-pyside6/tests/test_debug.py
new file mode 100644
index 0000000..4799024
--- /dev/null
+++ b/runtime-pyside6/tests/test_debug.py
@@ -0,0 +1,68 @@
+"""
+ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+ * Copyright (C) 2021-2024 Ad5001
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+"""
+
+import pytest
+
+from os.path import exists
+from PySide6.QtCore import QtMsgType, QMessageLogContext
+
+from LogarithmPlotter.util import debug
+
+
+def test_setup():
+ sourcemap_installed = False
+ try:
+ import sourcemap
+ sourcemap_installed = True
+ except:
+ pass
+ if sourcemap_installed:
+ file = debug.SOURCEMAP_PATH
+ debug.SOURCEMAP_PATH = None
+ debug.setup() # Nothing could be setup.
+ debug.SOURCEMAP_PATH = file
+ debug.setup()
+ assert (sourcemap_installed and exists(debug.SOURCEMAP_PATH)) == (debug.SOURCEMAP_INDEX is not None)
+
+
+def test_map_source():
+ sourcemap_available = debug.SOURCEMAP_INDEX is not None
+ if sourcemap_available:
+ assert debug.map_javascript_source("js/index.mjs", 22) != ("js/module/index.mjs", 22)
+ assert debug.map_javascript_source("js/index.mjs", 100000) == ("js/index.mjs", 100000) # Too long, not found
+ debug.SOURCEMAP_INDEX = None
+ assert debug.map_javascript_source("js/index.mjs", 21) == ("js/index.mjs", 21)
+
+
+def test_log_terminal_message():
+ msg1 = debug.create_log_terminal_message(
+ QtMsgType.QtWarningMsg, QMessageLogContext(),
+ "a long and random message"
+ )
+ assert "[WARNING]" in msg1
+ assert "a long and random message" in msg1
+ msg2 = debug.create_log_terminal_message(
+ QtMsgType.QtCriticalMsg,
+ QMessageLogContext("LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Index.qml", 15, "anotherFunctionName",
+ "aCategoryDifferent"),
+ "LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Index.qml:15: a potentially potential error message"
+ )
+ assert "[CRITICAL]" in msg2
+ assert "Index.qml" in msg2
+ assert "a potentially potential error message" in msg2
+ assert "anotherFunctionName" in msg2
diff --git a/tests/python/test_helper.py b/runtime-pyside6/tests/test_helper.py
similarity index 100%
rename from tests/python/test_helper.py
rename to runtime-pyside6/tests/test_helper.py
diff --git a/tests/python/test_latex.py b/runtime-pyside6/tests/test_latex.py
similarity index 100%
rename from tests/python/test_latex.py
rename to runtime-pyside6/tests/test_latex.py
diff --git a/tests/python/test_main.py b/runtime-pyside6/tests/test_main.py
similarity index 100%
rename from tests/python/test_main.py
rename to runtime-pyside6/tests/test_main.py
diff --git a/tests/python/test_native.py b/runtime-pyside6/tests/test_native.py
similarity index 100%
rename from tests/python/test_native.py
rename to runtime-pyside6/tests/test_native.py
diff --git a/tests/python/test_pyjs.py b/runtime-pyside6/tests/test_pyjs.py
similarity index 100%
rename from tests/python/test_pyjs.py
rename to runtime-pyside6/tests/test_pyjs.py
diff --git a/tests/python/test_update.py b/runtime-pyside6/tests/test_update.py
similarity index 100%
rename from tests/python/test_update.py
rename to runtime-pyside6/tests/test_update.py
diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh
index a8f0783..2ccd626 100755
--- a/scripts/build-macosx.sh
+++ b/scripts/build-macosx.sh
@@ -1,20 +1,34 @@
#!/usr/bin/env bash
DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-cd "$DIR/.."
+cd "$DIR/.." || exit 1
+rebuild=true
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --no-rebuild)
+ rebuild=false
+ ;;
+ *)
+ box "Error: Invalid argument."
+ exit 1
+ esac
+ shift
+done
+
+if [ "$rebuild" == "true" ]; then
+ rm -rf build
+ bash scripts/build.sh
+fi
+
+cd build/runtime-pyside6 || exit 1
-rm $(find . -name "*.qmlc")
rm $(find . -name "*.pyc")
-# Building translations
-cd "LogarithmPlotter/i18n/"
-bash release.sh
-cd ../../
-
pyinstaller --add-data "LogarithmPlotter/qml:qml" \
--add-data "LogarithmPlotter/i18n:i18n" \
--add-data "LICENSE.md:." \
- --add-data "mac/logarithmplotterfile.icns:." \
+ --add-data "../assets/native/mac/logarithmplotterfile.icns:." \
--add-data "README.md:." \
--exclude-module "FixTk" \
--exclude-module "tcl" \
@@ -24,21 +38,19 @@ pyinstaller --add-data "LogarithmPlotter/qml:qml" \
--exclude-module "Tkinter" \
--noconsole \
--noconfirm \
- --icon=mac/logarithmplotter.icns \
+ --icon=../../assets/native/mac/logarithmplotter.icns \
--osx-bundle-identifier eu.ad5001.LogarithmPlotter \
-n LogarithmPlotter \
LogarithmPlotter/logarithmplotter.py
-cp mac/Info.plist dist/LogarithmPlotter.app/Contents/Info.plist
+cp ../../assets/native/mac/Info.plist dist/LogarithmPlotter.app/Contents/Info.plist
# Remove QtWebEngine, 3D and all other unused libs libs
rm -rf dist/LogarithmPlotter.app/Contents/MacOS/{QtWeb*,*3D*,QtRemote*,QtPdf,QtCharts,QtLocation,QtTest,QtMultimedia,QtSpatialAudio,QtDataVisualization,QtQuickParticles,QtChartsQml,QtScxml,QtDataVisualizationQml,QtTest,QtPositioningQuick,QtQuickTest,QtSql,QtSensorsQuick}
-rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/{QtNetwork.abi3.so}
+rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/QtNetwork.abi3.so
# Removing QtQuick3D
-rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtQuick3D
-rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/Qt3D
-rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtWebEngine
+rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/{QtQuick3D,Qt3D,QtWebEngine}
# Remove the QtQuick styles that are unused
rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtQuick/Controls/{Imagine,Material,iOS,Universal,designer}
diff --git a/scripts/build-windows.bat b/scripts/build-windows.bat
deleted file mode 100644
index ef92aee..0000000
--- a/scripts/build-windows.bat
+++ /dev/null
@@ -1,17 +0,0 @@
-rem Make sure pyinstaller is installed
-python -m pip install -U pyinstaller
-
-rem Building translations
-cd "LogarithmPlotter\i18n"
-cmd release.sh
-cd ..\..
-
-pyinstaller --add-data "logplotter.svg;." --add-data "LogarithmPlotter/qml;qml" --add-data "LogarithmPlotter/i18n;i18n" --noconsole LogarithmPlotter/logarithmplotter.py --icon=win/logarithmplotter.ico -n logarithmplotter
-
-rem Remove QtWebEngine
-del dist\logarithmplotter\PySide6\Qt6WebEngineCore.dll
-rem Remove the QtQuick styles that are unused
-rmdir dist\logarithmplotter\PySide6\qml\QtQuick\Controls\Imagine /s /q
-rmdir dist\logarithmplotter\PySide6\qml\QtQuick\Controls\Material /s /q
-rmdir dist\logarithmplotter\PySide6\qml\QtQuick\Controls\designer /s /q
-rem Remove unused translations
diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh
index 95a5995..fa78bb1 100644
--- a/scripts/build-wine.sh
+++ b/scripts/build-wine.sh
@@ -1,22 +1,35 @@
#!/bin/bash
-cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.."
+cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit
-rm -rf dist
+rebuild=true
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --no-rebuild)
+ rebuild=false
+ ;;
+ *)
+ box "Error: Invalid argument."
+ exit 1
+ esac
+ shift
+done
+
+if [ "$rebuild" == "true" ]; then
+ rm -rf build
+ bash scripts/build.sh
+fi
+
+cd build/runtime-pyside6 || exit 1
-rm $(find . -name "*.qmlc")
rm -rf $(find . -name "*.pyc")
-# Building translations
-cd "LogarithmPlotter/i18n/"
-bash release.sh
-cd ../../
-
wine pyinstaller --add-data "LogarithmPlotter/logarithmplotter.svg;." \
--add-data "LogarithmPlotter/qml;qml" \
--add-data "LogarithmPlotter/i18n;i18n" \
--noconsole \
LogarithmPlotter/logarithmplotter.py \
- --icon=win/logarithmplotter.ico \
+ --icon=../../assets/native/win/logarithmplotter.ico \
-n logarithmplotter
# Copy Qt6ShaderTools, a required library for for Qt5Compat
diff --git a/scripts/build.sh b/scripts/build.sh
new file mode 100755
index 0000000..be25274
--- /dev/null
+++ b/scripts/build.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+#
+# LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
+# Copyright (C) 2021-2024 Ad5001
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+# This script builds a dist version of LogarithmPlotter
+
+DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+cd "$DIR/.." || exit 1
+
+box() {
+ len=${#1}
+ echo "┌─$(printf '─%.0s' $(seq 1 "$len"))─┐"
+ echo "│ $1 │"
+ echo "└─$(printf '─%.0s' $(seq 1 "$len"))─┘"
+}
+
+rm -rf build
+mkdir -p build/runtime-pyside6
+
+# Copy python
+box "Copying pyside6 python runtime..."
+cp -r runtime-pyside6/{setup.py,LogarithmPlotter} build/runtime-pyside6
+
+box "Building ecmascript modules..."
+mkdir -p build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js
+cd common && (npm run build || exit) && cd ..
+
+box "Building translations..."
+cd assets/i18n/ && (bash release.sh || exit) && cd ../../
+mkdir -p build/runtime-pyside6/LogarithmPlotter/i18n && cp assets/i18n/*.qm build/runtime-pyside6/LogarithmPlotter/i18n/
+
+box "Building icons..."
+cp -r assets/icons build/runtime-pyside6/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/
+cp assets/logarithmplotter.svg build/runtime-pyside6/LogarithmPlotter/
diff --git a/scripts/package-deb.sh b/scripts/package-deb.sh
new file mode 100755
index 0000000..8ed03ee
--- /dev/null
+++ b/scripts/package-deb.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit 1
+
+rebuild=true
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --no-rebuild)
+ rebuild=false
+ ;;
+ *)
+ box "Error: Invalid argument."
+ exit 1
+ esac
+ shift
+done
+
+if [ "$rebuild" == "true" ]; then
+ rm -rf build
+ bash scripts/build.sh
+fi
+
+cd build/runtime-pyside6 || exit 1
+
+mkdir assets
+cp -r ../../assets/{native,*.svg} assets/
+cp ../../README.md .
+
+python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \
+ --package logarithmplotter --copyright-file assets/native/linux/debian/copyright \
+ --suite noble --depends3 "$(cat assets/native/linux/debian/depends)" --section science \
+ bdist_deb
diff --git a/scripts/package-linux.sh b/scripts/package-linux.sh
deleted file mode 100755
index ca2bcf7..0000000
--- a/scripts/package-linux.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/bash
-cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.."
-
-# Building translations
-cd "LogarithmPlotter/i18n/"
-bash release.sh
-cd ../../
-
-# Deb
-sudo python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \
- --package logarithmplotter --copyright-file linux/debian/copyright --suite noble --depends3 "$(cat linux/debian/depends)" --section science \
- bdist_deb
-
-# Flatpak building
-FLATPAK_BUILDER=$(which flatpak-builder)
-if [ -z $FLATPAK_BUILDER ]; then
- echo "flatpak-builder not installed. Will not proceed to build flatpak."
-else
- cd linux
- git clone https://github.com/Ad5001/eu.ad5001.LogarithmPlotter
- cd eu.ad5001.LogarithmPlotter
- flatpak-builder AppDir eu.ad5001.LogarithmPlotter.json --user --force-clean --install
- cd ../../
-fi
-
-# Snapcraft building
-SNAPCRAFT=$(which snapcraft)
-if [ -z $SNAPCRAFT ]; then
- echo "snapcraft not installed. Will not proceed to build snap"
-else
- snapcraft
-fi
diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh
index 745f05b..c050a32 100644
--- a/scripts/package-macosx.sh
+++ b/scripts/package-macosx.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.."
+cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/../build/runtime-pyside6/dist" || exit 1
VERSION=0.6.0
title="LogarithmPlotter v${VERSION} Setup"
@@ -8,18 +8,17 @@ applicationName=LogarithmPlotter
backgroundPictureName=logarithmplotter-installer-background.png
source=Installer
-cd dist
rm -rf Installer
mkdir -p Installer
mkdir -p Installer/.background
-cp ../mac/install-bg.png "./Installer/.background/${backgroundPictureName}"
+cp ../../../assets/native/mac/install-bg.png "./Installer/.background/${backgroundPictureName}"
cp -r LogarithmPlotter.app Installer/LogarithmPlotter.app
-cp ../LICENSE.md Installer/LICENSE.md
-cp ../README.md Installer/README.md
+cp ../../../LICENSE.md Installer/LICENSE.md
+cp ../../../README.md Installer/README.md
# Calculating folder size
duoutput=$(du -h Installer | tail -n1)
-size=$(expr ${duoutput%M*} + 2) # +2 for allowing small space to edit.
+size=$(( ${duoutput%M*} + 2)) # +2 for allowing small space to edit.
echo "Creating DMG file with size ${size}M."
# Adapted from https://stackoverflow.com/a/1513578
@@ -27,7 +26,7 @@ hdiutil create -srcfolder "${source}" -volname "${title}" -fs HFS+ \
-fsargs "-c c=64,a=16,e=16" -format UDRW -size ${size}M pack.temp.dmg
device=$(hdiutil attach -readwrite -noverify -noautoopen "pack.temp.dmg" | \
- egrep '^/dev/' | sed 1q | awk '{print $1}')
+ grep -E '^/dev/' | sed 1q | awk '{print $1}')
sleep 3
@@ -54,10 +53,10 @@ echo '
end tell
end tell
' | osascript
-chmod -Rf go-w /Volumes/"${title}"
+chmod -Rf go-w "/Volumes/${title}"
sync
sync
-hdiutil detach ${device}
+hdiutil detach "${device}"
hdiutil convert "pack.temp.dmg" -format UDZO -imagekey zlib-level=9 -o "${finalDMGName}"
rm -f pack.temp.dmg
rm -rf Installer
diff --git a/scripts/package-windows.bat b/scripts/package-windows.bat
deleted file mode 100644
index 777f2f9..0000000
--- a/scripts/package-windows.bat
+++ /dev/null
@@ -1,7 +0,0 @@
-XCOPY win\*.* dist\logarithmplotter /C /S /D /Y /I
-XCOPY README.md dist\logarithmplotter /C /D /Y
-XCOPY LICENSE.md dist\logarithmplotter /C /D /Y
-rem Creating installer
-cd dist\logarithmplotter
-"C:\Program Files (x86)\NSIS\makensis" installer.nsi
-cd ..\..
diff --git a/scripts/package-wine.sh b/scripts/package-wine.sh
index 98209e0..89295e7 100644
--- a/scripts/package-wine.sh
+++ b/scripts/package-wine.sh
@@ -1,8 +1,8 @@
#!/bin/bash
-cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.."
+cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit 1
# Moving files
-cp win/* README.md LICENSE.md dist/logarithmplotter/
+cp assets/native/win/* README.md LICENSE.md build/runtime-pyside6/dist/logarithmplotter/
# Creating installer
-cd dist/logarithmplotter/
+cd build/runtime-pyside6/dist/logarithmplotter/ || exit 1
makensis installer.nsi
diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh
index 52d4413..1410244 100644
--- a/scripts/run-tests.sh
+++ b/scripts/run-tests.sh
@@ -1,7 +1,35 @@
#!/bin/bash
-cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.."
+cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." || exit 1
+
+rebuild=true
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --no-rebuild)
+ rebuild=false
+ ;;
+ *)
+ box "Error: Invalid argument."
+ exit 1
+ esac
+ shift
+done
+
+if [ "$rebuild" == "true" ]; then
+ rm -rf build
+ bash scripts/build.sh
+fi
+
+
# Run python tests
+cp -r runtime-pyside6/tests build/runtime-pyside6
+cp -r ci CHANGELOG.md build/runtime-pyside6
+cd build/runtime-pyside6 || exit 1
PYTHONPATH="$PYTHONPATH:." pytest --cov=LogarithmPlotter --cov-report term-missing .
+cd ../../
+# Run js tests
+cd common || exit 1
+npm test
diff --git a/scripts/sign-deb.sh b/scripts/sign-deb.sh
index 6939243..f8e0a9a 100755
--- a/scripts/sign-deb.sh
+++ b/scripts/sign-deb.sh
@@ -1,11 +1,10 @@
#!/bin/bash
# This script is used to sign the LogarithmPlotter deb directly from it's DSC file.
# Adapted from https://github.com/astraw/stdeb/issues/181
+cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/../build/runtime-pyside6/deb_dist" || exit 1
PPA_ARCHIVE="ppa:ad5001/logarithmplotter"
-cd ../deb_dist
-
# create a temporary folder
mkdir tmp -p
cd tmp
diff --git a/snapcraft.yaml b/snapcraft.yaml
index e8c8628..12b41d2 100644
--- a/snapcraft.yaml
+++ b/snapcraft.yaml
@@ -5,7 +5,7 @@ summary: Create and edit Bode plots
confinement: strict
base: core22
grade: stable
-icon: LogarithmPlotter/logarithmplotter.svg
+icon: assets/logarithmplotter.svg
adopt-info: linuxfiles
license: GPL-3.0+
@@ -57,21 +57,26 @@ parts:
# - fcitx-frontend-gtk3
# - libgtk2.0-0
launchers:
- source: linux/snapcraft/launcher/
+ source: assets/native/linux/snapcraft/launcher/
plugin: dump
organize:
'*': bin/
linuxfiles:
- source: linux/
+ source: assets/native/linux/
plugin: dump
parse-info: [eu.ad5001.LogarithmPlotter.metainfo.xml]
organize:
logarithmplotter.desktop: usr/share/applications/logarithmplotter.desktop
x-logarithm-plot.xml: usr/share/mime/packages/x-logarithm-plot.xml
application-x-logarithm-plot.svg: usr/share/mime/packages/application-x-logarithm-plot.svg
+ filetypeicon:
+ source: assets/
+ plugin: dump
+ organize:
+ logplotterfile.svg: usr/share/mime/packages/application-x-logarithm-plot.svg
logarithmplotter:
plugin: python
- source: .
+ source: build
stage-packages:
- breeze-icon-theme
# Latex dependencies
@@ -145,7 +150,7 @@ parts:
source: .
plugin: dump
organize:
- CHANGELOG.md: lib/python3.8/site-packages/LogarithmPlotter/util/
+ CHANGELOG.md: lib/python3.12/site-packages/LogarithmPlotter/util/
apps:
logarithmplotter: