Added basic Formula Wizard, Added script to compile SASS and TS, many other random changes.
Update .gitignore, .htaccess, and 68 more files...
This commit is contained in:
25
tools/items/b64-tools.json
Normal file
25
tools/items/b64-tools.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"dom": "b64-tools/page.php",
|
||||
"lang": "b64-tools/lang.json",
|
||||
"code": [],
|
||||
"module": [
|
||||
"b64-tools/code.min.js"
|
||||
],
|
||||
"styles": [],
|
||||
"icon": "fad fa-magic",
|
||||
"title": "tool.b64-tools.title",
|
||||
"opengraph": {
|
||||
"title": {
|
||||
"en": "Base64 Tools",
|
||||
"fr": "Outils pour Base64"
|
||||
},
|
||||
"description": {
|
||||
"en": "TODO: Description",
|
||||
"fr": "TODO: Description"
|
||||
},
|
||||
"type": "website",
|
||||
"url": "https://nibblepoker.lu/tools/b64-tools",
|
||||
"image": "/resources/NibblePoker/images/placeholder.png",
|
||||
"image_type": "image/png"
|
||||
}
|
||||
}
|
112
tools/items/b64-tools/code.js
Normal file
112
tools/items/b64-tools/code.js
Normal file
@@ -0,0 +1,112 @@
|
||||
"use strict";
|
||||
const langKey = document.documentElement.lang.match("(en|fr)") ? document.documentElement.lang : "en";
|
||||
const langData = {
|
||||
en: {
|
||||
"alert.textarea.missing.text": "The 'TextArea' element for text is missing !",
|
||||
"alert.textarea.missing.b64": "The 'TextArea' element for base64 is missing !",
|
||||
"alert.textarea.mismatch.text": "The 'TextArea' element for text isn't declared as a 'TextArea'!",
|
||||
"alert.textarea.mismatch.b64": "The 'TextArea' element for base64 isn't declared as a 'TextArea'!",
|
||||
"alert.other.missing": "An element is missing from the page !",
|
||||
"alert.other.mismatch": "An element is no declared with the proper element type !",
|
||||
},
|
||||
fr: {
|
||||
"alert.textarea.missing.text": "L'élément 'TextArea' pour le texte est introuvable !",
|
||||
"alert.textarea.missing.b64": "L'élément 'TextArea' pour les données base64 est introuvable !",
|
||||
"alert.textarea.mismatch.text": "L'élément 'TextArea' pour le texte n'est pas un 'TextArea'!",
|
||||
"alert.textarea.mismatch.b64": "L'élément 'TextArea' pour les données base64 n'est pas un 'TextArea'!",
|
||||
"alert.other.missing": "Un élément de la page est introuvable !",
|
||||
"alert.other.mismatch": "Un élément de la page n'est pas bien déclaré !",
|
||||
}
|
||||
};
|
||||
function localize(stringKey) {
|
||||
let _langData = langKey in langData ? langData[langKey] : langData.en;
|
||||
return stringKey in _langData ? _langData[stringKey] : (stringKey in langData["en"] ? langData["en"][stringKey] : stringKey);
|
||||
}
|
||||
const idPrefix = "tool-b64-tools-";
|
||||
const eTextTextarea = document.getElementById(idPrefix + "ta-text");
|
||||
const eBase64Textarea = document.getElementById(idPrefix + "ta-b64");
|
||||
const eClearAllButton = document.getElementById(idPrefix + "btn-clear-all");
|
||||
const eClearTextButton = document.getElementById(idPrefix + "btn-clear-text");
|
||||
const eClearBase64Button = document.getElementById(idPrefix + "btn-clear-b64");
|
||||
const eConvertTextButton = document.getElementById(idPrefix + "btn-convert-text");
|
||||
const eConvertBase64Button = document.getElementById(idPrefix + "btn-convert-b64");
|
||||
const eSelectEncoding = document.getElementById(idPrefix + "encoding");
|
||||
const eCheckboxPadding = document.getElementById(idPrefix + "checkbox-padding");
|
||||
if (eTextTextarea == null) {
|
||||
alert(localize("alert.textarea.missing.text"));
|
||||
throw new Error(localize("alert.textarea.missing.text"));
|
||||
}
|
||||
if (eBase64Textarea == null) {
|
||||
alert(localize("alert.textarea.missing.b64"));
|
||||
throw new Error(localize("alert.textarea.missing.b64"));
|
||||
}
|
||||
if (eClearAllButton == null || eClearTextButton == null || eClearBase64Button == null || eConvertTextButton == null ||
|
||||
eConvertBase64Button == null || eCheckboxPadding == null || eSelectEncoding == null) {
|
||||
alert(localize("alert.other.missing"));
|
||||
throw new Error(localize("alert.other.missing"));
|
||||
}
|
||||
var TextEncoding;
|
||||
(function (TextEncoding) {
|
||||
TextEncoding[TextEncoding["UTF8"] = 0] = "UTF8";
|
||||
TextEncoding[TextEncoding["ASCII"] = 1] = "ASCII";
|
||||
TextEncoding[TextEncoding["UNICODE"] = 2] = "UNICODE";
|
||||
})(TextEncoding || (TextEncoding = {}));
|
||||
if (!(eTextTextarea instanceof HTMLTextAreaElement)) {
|
||||
alert(localize("alert.textarea.mismatch.text"));
|
||||
throw new Error(localize("alert.textarea.mismatch.text"));
|
||||
}
|
||||
if (!(eBase64Textarea instanceof HTMLTextAreaElement)) {
|
||||
alert(localize("alert.textarea.mismatch.b64"));
|
||||
throw new Error(localize("alert.textarea.mismatch.b64"));
|
||||
}
|
||||
if (!(eCheckboxPadding instanceof HTMLInputElement)) {
|
||||
alert(localize("alert.other.mismatch"));
|
||||
throw new Error(localize("alert.other.mismatch"));
|
||||
}
|
||||
if (!(eSelectEncoding instanceof HTMLSelectElement)) {
|
||||
alert(localize("alert.other.mismatch"));
|
||||
throw new Error(localize("alert.other.mismatch"));
|
||||
}
|
||||
function shouldAddPadding() {
|
||||
return eCheckboxPadding.checked;
|
||||
}
|
||||
function getTextEncoding() {
|
||||
switch (eSelectEncoding.value) {
|
||||
case "utf8":
|
||||
return TextEncoding.UTF8;
|
||||
case "unicode":
|
||||
return TextEncoding.UNICODE;
|
||||
case "ascii":
|
||||
return TextEncoding.ASCII;
|
||||
default:
|
||||
return TextEncoding.UTF8;
|
||||
}
|
||||
}
|
||||
function getText() {
|
||||
switch (getTextEncoding()) {
|
||||
case TextEncoding.UTF8:
|
||||
break;
|
||||
case TextEncoding.UNICODE:
|
||||
return new TextEncoder().encode(eTextTextarea.value);
|
||||
case TextEncoding.ASCII:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
eClearAllButton.addEventListener('click', function handleClick() {
|
||||
eTextTextarea.value = "";
|
||||
eBase64Textarea.value = "";
|
||||
});
|
||||
eClearTextButton.addEventListener('click', function handleClick() {
|
||||
eTextTextarea.value = "";
|
||||
});
|
||||
eClearBase64Button.addEventListener('click', function handleClick() {
|
||||
eBase64Textarea.value = "";
|
||||
});
|
||||
eConvertTextButton.addEventListener('click', function handleClick() {
|
||||
eBase64Textarea.value = "";
|
||||
});
|
||||
eConvertBase64Button.addEventListener('click', function handleClick() {
|
||||
eTextTextarea.value = "";
|
||||
});
|
||||
//# sourceMappingURL=code.js.map
|
137
tools/items/b64-tools/code.ts
Normal file
137
tools/items/b64-tools/code.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
const langKey= document.documentElement.lang.match("(en|fr)") ? document.documentElement.lang : "en";
|
||||
const langData = {
|
||||
en: {
|
||||
"alert.textarea.missing.text": "The 'TextArea' element for text is missing !",
|
||||
"alert.textarea.missing.b64": "The 'TextArea' element for base64 is missing !",
|
||||
"alert.textarea.mismatch.text": "The 'TextArea' element for text isn't declared as a 'TextArea'!",
|
||||
"alert.textarea.mismatch.b64": "The 'TextArea' element for base64 isn't declared as a 'TextArea'!",
|
||||
"alert.other.missing": "An element is missing from the page !",
|
||||
"alert.other.mismatch": "An element is no declared with the proper element type !",
|
||||
},
|
||||
fr: {
|
||||
"alert.textarea.missing.text": "L'élément 'TextArea' pour le texte est introuvable !",
|
||||
"alert.textarea.missing.b64": "L'élément 'TextArea' pour les données base64 est introuvable !",
|
||||
"alert.textarea.mismatch.text": "L'élément 'TextArea' pour le texte n'est pas un 'TextArea'!",
|
||||
"alert.textarea.mismatch.b64": "L'élément 'TextArea' pour les données base64 n'est pas un 'TextArea'!",
|
||||
"alert.other.missing": "Un élément de la page est introuvable !",
|
||||
"alert.other.mismatch": "Un élément de la page n'est pas bien déclaré !",
|
||||
}
|
||||
}
|
||||
|
||||
function localize(stringKey: string): string {
|
||||
// @ts-ignore -> Implicit any on "langData[langKey]"
|
||||
let _langData = langKey in langData ? langData[langKey] : langData.en;
|
||||
return stringKey in _langData ? _langData[stringKey] : (
|
||||
// @ts-ignore -> Implicit any on " langData["en"][stringKey]"
|
||||
stringKey in langData["en"] ? langData["en"][stringKey] : stringKey
|
||||
);
|
||||
}
|
||||
|
||||
const idPrefix : string = "tool-b64-tools-"
|
||||
|
||||
const eTextTextarea : HTMLElement | null = document.getElementById(idPrefix + "ta-text");
|
||||
const eBase64Textarea : HTMLElement | null = document.getElementById(idPrefix + "ta-b64");
|
||||
|
||||
const eClearAllButton : HTMLElement | null = document.getElementById(idPrefix + "btn-clear-all");
|
||||
const eClearTextButton : HTMLElement | null = document.getElementById(idPrefix + "btn-clear-text");
|
||||
const eClearBase64Button : HTMLElement | null = document.getElementById(idPrefix + "btn-clear-b64");
|
||||
|
||||
const eConvertTextButton : HTMLElement | null = document.getElementById(idPrefix + "btn-convert-text");
|
||||
const eConvertBase64Button : HTMLElement | null = document.getElementById(idPrefix + "btn-convert-b64");
|
||||
|
||||
const eSelectEncoding : HTMLElement | null = document.getElementById(idPrefix + "encoding");
|
||||
const eCheckboxPadding : HTMLElement | null = document.getElementById(idPrefix + "checkbox-padding");
|
||||
|
||||
// Checking if the elements exist
|
||||
if(eTextTextarea == null) {
|
||||
alert(localize("alert.textarea.missing.text"));
|
||||
throw new Error(localize("alert.textarea.missing.text"));
|
||||
}
|
||||
|
||||
if(eBase64Textarea == null) {
|
||||
alert(localize("alert.textarea.missing.b64"));
|
||||
throw new Error(localize("alert.textarea.missing.b64"));
|
||||
}
|
||||
|
||||
if(eClearAllButton == null || eClearTextButton == null || eClearBase64Button == null || eConvertTextButton == null ||
|
||||
eConvertBase64Button == null || eCheckboxPadding == null || eSelectEncoding == null) {
|
||||
alert(localize("alert.other.missing"));
|
||||
throw new Error(localize("alert.other.missing"));
|
||||
}
|
||||
|
||||
// Other stuff
|
||||
enum TextEncoding {
|
||||
UTF8,
|
||||
ASCII,
|
||||
UNICODE,
|
||||
}
|
||||
|
||||
// Checking their type
|
||||
if(!(eTextTextarea instanceof HTMLTextAreaElement)) {
|
||||
alert(localize("alert.textarea.mismatch.text"));
|
||||
throw new Error(localize("alert.textarea.mismatch.text"));
|
||||
}
|
||||
|
||||
if(!(eBase64Textarea instanceof HTMLTextAreaElement)) {
|
||||
alert(localize("alert.textarea.mismatch.b64"));
|
||||
throw new Error(localize("alert.textarea.mismatch.b64"));
|
||||
}
|
||||
|
||||
if(!(eCheckboxPadding instanceof HTMLInputElement)) {
|
||||
alert(localize("alert.other.mismatch"));
|
||||
throw new Error(localize("alert.other.mismatch"));
|
||||
}
|
||||
|
||||
if(!(eSelectEncoding instanceof HTMLSelectElement)) {
|
||||
alert(localize("alert.other.mismatch"));
|
||||
throw new Error(localize("alert.other.mismatch"));
|
||||
}
|
||||
|
||||
// Generic functions
|
||||
function shouldAddPadding(): boolean {
|
||||
return (eCheckboxPadding as HTMLInputElement).checked;
|
||||
}
|
||||
|
||||
function getTextEncoding(): TextEncoding {
|
||||
switch((eSelectEncoding as HTMLSelectElement).value) {
|
||||
case "utf8":
|
||||
return TextEncoding.UTF8;
|
||||
case "unicode":
|
||||
return TextEncoding.UNICODE;
|
||||
case "ascii":
|
||||
return TextEncoding.ASCII;
|
||||
default:
|
||||
return TextEncoding.UTF8;
|
||||
}
|
||||
}
|
||||
|
||||
function getText(): Uint8Array | null {
|
||||
switch(getTextEncoding()) {
|
||||
case TextEncoding.UTF8:
|
||||
break;
|
||||
case TextEncoding.UNICODE:
|
||||
return new TextEncoder().encode((eTextTextarea as HTMLTextAreaElement).value);
|
||||
case TextEncoding.ASCII:
|
||||
break; //return new Buffer(string, "ascii");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Setting up button actions
|
||||
eClearAllButton.addEventListener('click', function handleClick() {
|
||||
eTextTextarea.value = "";
|
||||
eBase64Textarea.value = "";
|
||||
});
|
||||
eClearTextButton.addEventListener('click', function handleClick() {
|
||||
eTextTextarea.value = "";
|
||||
});
|
||||
eClearBase64Button.addEventListener('click', function handleClick() {
|
||||
eBase64Textarea.value = "";
|
||||
});
|
||||
|
||||
eConvertTextButton.addEventListener('click', function handleClick() {
|
||||
eBase64Textarea.value = "";
|
||||
});
|
||||
eConvertBase64Button.addEventListener('click', function handleClick() {
|
||||
eTextTextarea.value = "";
|
||||
});
|
26
tools/items/b64-tools/lang.json
Normal file
26
tools/items/b64-tools/lang.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"en": {
|
||||
"tool.b64-tools.title": "Base64 Tools",
|
||||
"tool.b64-tools.text": "Text",
|
||||
"tool.b64-tools.base64": "Base64",
|
||||
"tool.b64-tools.actions": "Other actions",
|
||||
"tool.b64-tools.actions.clear.all": "Clear All",
|
||||
"tool.b64-tools.actions.clear.text": "Clear",
|
||||
"tool.b64-tools.actions.clear.base64": "Clear",
|
||||
"tool.b64-tools.actions.convert.text": "Convert to Base64",
|
||||
"tool.b64-tools.actions.convert.b64": "Convert to text",
|
||||
"tool.b64-tools.options": "Options"
|
||||
},
|
||||
"fr": {
|
||||
"tool.b64-tools.title": "Outils pour Base64",
|
||||
"tool.b64-tools.text": "Texte",
|
||||
"tool.b64-tools.base64": "Base64",
|
||||
"tool.b64-tools.actions": "Autres actions",
|
||||
"tool.b64-tools.actions.clear.all": "Nettoyer Tout",
|
||||
"tool.b64-tools.actions.clear.text": "Nettoyer",
|
||||
"tool.b64-tools.actions.clear.base64": "Nettoyer",
|
||||
"tool.b64-tools.actions.convert.text": "Convertir en Base64",
|
||||
"tool.b64-tools.actions.convert.b64": "Convertir en texte",
|
||||
"tool.b64-tools.options": "Options"
|
||||
}
|
||||
}
|
68
tools/items/b64-tools/page.php
Normal file
68
tools/items/b64-tools/page.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
echo(getMainHeader(localize("tool.b64-tools.text"), null, null, null,
|
||||
true, "bkgd-math", 3, false, false, true));
|
||||
?>
|
||||
<div class="p-xs pb-0">
|
||||
<label for="tool-b64-tools-ta-text"></label>
|
||||
<textarea id="tool-b64-tools-ta-text" class="my-xs w-full no-resize border r-s" name="" rows="10"></textarea>
|
||||
|
||||
<?php
|
||||
echo('<button id="tool-b64-tools-btn-convert-text" class="p-mxs r-s border b-light primary">');
|
||||
echo('<span class="text-monospace"><i class="fad fa-file-search"></i> ');
|
||||
echo(localize("tool.b64-tools.actions.convert.text"));
|
||||
echo('</span></button>');
|
||||
|
||||
echo('<button id="tool-b64-tools-btn-clear-text" class="p-mxs r-s border b-light primary">');
|
||||
echo('<span class="text-monospace"><i class="fad fa-file-search"></i> ');
|
||||
echo(localize("tool.b64-tools.actions.clear.text"));
|
||||
echo('</span></button>');
|
||||
|
||||
echo('<div class="f-right">');
|
||||
echo('<label for="tool-b64-tools-encoding" class="mr-xs">Encoding:</label>');
|
||||
echo('<select id="tool-b64-tools-encoding">');
|
||||
echo('<option value="utf8">UTF-8</option>');
|
||||
echo('<option value="unicode">Unicode</option>');
|
||||
echo('<option value="ascii">ASCII</option>');
|
||||
echo('</select>');
|
||||
echo('</div>');
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
echo(getMainHeader(localize("tool.b64-tools.base64"), null, null, null,
|
||||
true, "bkgd-math", 3, false, false, true));
|
||||
?>
|
||||
<div class="p-xs pb-0">
|
||||
<label for="tool-b64-tools-ta-b64"></label>
|
||||
<textarea id="tool-b64-tools-ta-b64" class="my-xs w-full no-resize border r-s" name="" rows="10"></textarea>
|
||||
<?php
|
||||
echo('<button id="tool-b64-tools-btn-convert-b64" class="p-mxs r-s border b-light primary">');
|
||||
echo('<span class="text-monospace"><i class="fad fa-file-search"></i> ');
|
||||
echo(localize("tool.b64-tools.actions.convert.b64"));
|
||||
echo('</span></button>');
|
||||
|
||||
echo('<button id="tool-b64-tools-btn-clear-b64" class="p-mxs r-s border b-light primary">');
|
||||
echo('<span class="text-monospace"><i class="fad fa-file-search"></i> ');
|
||||
echo(localize("tool.b64-tools.actions.clear.base64"));
|
||||
echo('</span></button>');
|
||||
|
||||
echo('<div class="f-right">');
|
||||
echo('<input class="border r-s my-0" type="checkbox" id="tool-b64-tools-checkbox-padding" name="vehicle1" value="Bike">');
|
||||
echo('<label for="tool-b64-tools-checkbox-padding"> Add padding</label>');
|
||||
echo('</div>');
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
echo(getMainHeader(localize("tool.b64-tools.actions"), null, null, null,
|
||||
true, "bkgd-math", 3, false, false, true));
|
||||
|
||||
echo('<div class="px-xs pt-s">');
|
||||
|
||||
echo('<button id="tool-b64-tools-btn-clear-all" class="p-mxs r-s border b-light primary">');
|
||||
echo('<span class="text-monospace"><i class="fad fa-file-search"></i> ');
|
||||
echo(localize("tool.b64-tools.actions.clear.all"));
|
||||
echo('</span></button>');
|
||||
|
||||
echo('</div>');
|
||||
?>
|
27
tools/items/formula-wizard.json
Normal file
27
tools/items/formula-wizard.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"dom": "formula-wizard/page.php",
|
||||
"lang": "formula-wizard/lang.json",
|
||||
"code": [],
|
||||
"module": [
|
||||
"formula-wizard/code.min.js"
|
||||
],
|
||||
"styles": [
|
||||
"formula-wizard/styles.css"
|
||||
],
|
||||
"icon": "fad fa-magic",
|
||||
"title": "tool.formula-wizard.title",
|
||||
"opengraph": {
|
||||
"title": {
|
||||
"en": "Formula Wizard",
|
||||
"fr": "Ensorceleur de formules"
|
||||
},
|
||||
"description": {
|
||||
"en": "TODO: Description",
|
||||
"fr": "TODO: Description"
|
||||
},
|
||||
"type": "website",
|
||||
"url": "https://nibblepoker.lu/tools/formula-wizard",
|
||||
"image": "/resources/NibblePoker/images/placeholder.png",
|
||||
"image_type": "image/png"
|
||||
}
|
||||
}
|
804
tools/items/formula-wizard/code.js
Normal file
804
tools/items/formula-wizard/code.js
Normal file
@@ -0,0 +1,804 @@
|
||||
import { Decimal } from "../../../resources/DecimalJs/10.4.3/decimal.min.mjs";
|
||||
const version = [0, 0, 1];
|
||||
console.log("Initializing 'Formula Wizard v" + version.join(".") + "'...");
|
||||
const startTime = new Date().getMilliseconds();
|
||||
Decimal.set({ precision: 25, rounding: 8 });
|
||||
console.debug("Preparing langs...");
|
||||
const langKey = document.documentElement.lang.match("(en|fr)") ? document.documentElement.lang : "en";
|
||||
const langData = {
|
||||
en: {
|
||||
"unit.any.name": "Not Important",
|
||||
"unit.watt.name": "Watt",
|
||||
"unit.ampere.name": "Ampere",
|
||||
"unit.ohm.name": "Ohm",
|
||||
"unit.ohm.desc": "Electrical Resistance",
|
||||
"unit.volt.name": "Volt",
|
||||
"unit.farad.name": "Farad",
|
||||
"error.formulaValue.noParent": "Attempting to get a formula's value whose parent formula isn't set !",
|
||||
"error.formulaValue.noSource": "Attempting to get a formula's value whose value source is null !",
|
||||
"error.formulaContext.tooSmall": "The current calculation context is too small !",
|
||||
"ui.formulaCount": "formulas",
|
||||
"formula.ohm_law.name": "Ohm's Law",
|
||||
"dataset.resistor-e3.name": "E3 IEC Resistors",
|
||||
"dataset.resistor-e3.desc": "???",
|
||||
"dataset.resistor-e6.name": "E6 IEC Resistors",
|
||||
"dataset.resistor-e6.desc": "???",
|
||||
"dataset.resistor-e12.name": "E12 IEC Resistors",
|
||||
"dataset.resistor-e12.desc": "???",
|
||||
"dataset.resistor-e24.name": "E24 IEC Resistors",
|
||||
"dataset.resistor-e24.desc": "???",
|
||||
"dataset.resistor-e48.name": "E48 IEC Resistors",
|
||||
"dataset.resistor-e48.desc": "???",
|
||||
"dataset.capacitor-iec.name": "IEC E24 Capacitors",
|
||||
"dataset.capacitor-iec.desc": "???",
|
||||
"context.type.disabled.name": "Disabled",
|
||||
"context.type.constant.name": "Constant",
|
||||
"context.type.continuous.name": "Continuous",
|
||||
"context.type.valueRange.name": "Value Range",
|
||||
"context.type.dataSetRange.name": "Set-based Range",
|
||||
"context.type.disabled.desc": "???",
|
||||
"context.type.constant.desc": "???",
|
||||
"context.type.continuous.desc": "???",
|
||||
"context.type.valueRange.desc": "???",
|
||||
"context.type.dataSetRange.desc": "???",
|
||||
},
|
||||
fr: {
|
||||
"unit.ampere.name": "Ampère",
|
||||
"unit.ohm.desc": "Résistance électrique",
|
||||
"_error.formulaValue.noParent": "",
|
||||
"_error.formulaValue.noSource": "",
|
||||
"ui.formulaCount": "formules",
|
||||
"formula.ohm_law.name": "Loi d'Ohm",
|
||||
"context.type.disabled.name": "Désactivé",
|
||||
"context.type.constant.name": "Constante",
|
||||
"context.type.continuous.name": "Continue",
|
||||
"context.type.valueRange.name": "Valeurs distinctes",
|
||||
"context.type.dataSetRange.name": "Set de valeurs",
|
||||
}
|
||||
};
|
||||
function localize(stringKey) {
|
||||
let _langData = langKey in langData ? langData[langKey] : langData.en;
|
||||
return stringKey in _langData ? _langData[stringKey] : (stringKey in langData["en"] ? langData["en"][stringKey] : stringKey);
|
||||
}
|
||||
console.debug("Preparing scales...");
|
||||
const scales = {
|
||||
SI: new class {
|
||||
constructor() {
|
||||
this.formatName = (unit) => {
|
||||
return unit.symbol;
|
||||
};
|
||||
this.formatSymbol = (unit) => {
|
||||
return unit.symbol;
|
||||
};
|
||||
this.scaleFactors = [];
|
||||
}
|
||||
},
|
||||
IMPERIAL_DISTANCE: new class {
|
||||
constructor() {
|
||||
this.formatName = (unit) => {
|
||||
return unit.symbol;
|
||||
};
|
||||
this.formatSymbol = (unit) => {
|
||||
return unit.symbol;
|
||||
};
|
||||
this.scaleFactors = [];
|
||||
}
|
||||
},
|
||||
IMPERIAL_WEIGHT: new class {
|
||||
constructor() {
|
||||
this.formatName = (unit) => {
|
||||
return unit.symbol;
|
||||
};
|
||||
this.formatSymbol = (unit) => {
|
||||
return unit.symbol;
|
||||
};
|
||||
this.scaleFactors = [];
|
||||
}
|
||||
},
|
||||
TIME_SECONDS: new class {
|
||||
constructor() {
|
||||
this.formatName = (unit) => {
|
||||
return unit.symbol;
|
||||
};
|
||||
this.formatSymbol = (unit) => {
|
||||
return unit.symbol;
|
||||
};
|
||||
this.scaleFactors = [];
|
||||
}
|
||||
},
|
||||
NONE: new class {
|
||||
constructor() {
|
||||
this.formatName = (unit) => {
|
||||
return unit.name;
|
||||
};
|
||||
this.formatSymbol = (unit) => {
|
||||
return unit.symbol;
|
||||
};
|
||||
this.scaleFactors = [];
|
||||
}
|
||||
},
|
||||
};
|
||||
const scaleFactors = {
|
||||
SI_GIGA: new class {
|
||||
constructor() {
|
||||
this.scale = scales.SI;
|
||||
this.multiplier = new Decimal('1e9');
|
||||
this.prefix = "giga";
|
||||
this.suffix = "";
|
||||
this.symbol = "G";
|
||||
}
|
||||
},
|
||||
SI_MEGA: new class {
|
||||
constructor() {
|
||||
this.scale = scales.SI;
|
||||
this.multiplier = new Decimal('1e6');
|
||||
this.prefix = "mega";
|
||||
this.suffix = "";
|
||||
this.symbol = "M";
|
||||
}
|
||||
},
|
||||
SI_KILO: new class {
|
||||
constructor() {
|
||||
this.scale = scales.SI;
|
||||
this.multiplier = new Decimal('1e3');
|
||||
this.prefix = "kilo";
|
||||
this.suffix = "";
|
||||
this.symbol = "k";
|
||||
}
|
||||
},
|
||||
SI_BASE: new class {
|
||||
constructor() {
|
||||
this.scale = scales.SI;
|
||||
this.multiplier = new Decimal('1');
|
||||
this.prefix = "";
|
||||
this.suffix = "";
|
||||
this.symbol = "";
|
||||
}
|
||||
},
|
||||
SI_CENTI: new class {
|
||||
constructor() {
|
||||
this.scale = scales.SI;
|
||||
this.multiplier = new Decimal('1e-2');
|
||||
this.prefix = "centi";
|
||||
this.suffix = "";
|
||||
this.symbol = "c";
|
||||
}
|
||||
},
|
||||
SI_MILLI: new class {
|
||||
constructor() {
|
||||
this.scale = scales.SI;
|
||||
this.multiplier = new Decimal('1e-3');
|
||||
this.prefix = "milli";
|
||||
this.suffix = "";
|
||||
this.symbol = "m";
|
||||
}
|
||||
},
|
||||
TIME_MILLI: new class {
|
||||
constructor() {
|
||||
this.scale = scales.TIME_SECONDS;
|
||||
this.multiplier = new Decimal('1e-3');
|
||||
this.prefix = "milli";
|
||||
this.suffix = "";
|
||||
this.symbol = "m";
|
||||
}
|
||||
},
|
||||
TIME_BASE: new class {
|
||||
constructor() {
|
||||
this.scale = scales.TIME_SECONDS;
|
||||
this.multiplier = new Decimal('1');
|
||||
this.prefix = "";
|
||||
this.suffix = "";
|
||||
this.symbol = "";
|
||||
}
|
||||
},
|
||||
TIME_MINUTE: new class {
|
||||
constructor() {
|
||||
this.scale = scales.TIME_SECONDS;
|
||||
this.multiplier = new Decimal('60');
|
||||
this.prefix = "";
|
||||
this.suffix = "";
|
||||
this.symbol = "";
|
||||
}
|
||||
},
|
||||
TIME_HOUR: new class {
|
||||
constructor() {
|
||||
this.scale = scales.TIME_SECONDS;
|
||||
this.multiplier = new Decimal('3600');
|
||||
this.prefix = "";
|
||||
this.suffix = "";
|
||||
this.symbol = "";
|
||||
}
|
||||
},
|
||||
TIME_DAY: new class {
|
||||
constructor() {
|
||||
this.scale = scales.TIME_SECONDS;
|
||||
this.multiplier = new Decimal('86400');
|
||||
this.prefix = "";
|
||||
this.suffix = "";
|
||||
this.symbol = "";
|
||||
}
|
||||
},
|
||||
};
|
||||
Object.keys(scaleFactors).forEach(scaleFactorKey => {
|
||||
const scaleFactor = scaleFactors[scaleFactorKey];
|
||||
scaleFactor.scale.scaleFactors.push(scaleFactor);
|
||||
});
|
||||
function scaleToBase(value, scaleFactor) {
|
||||
return value.times(scaleFactor.multiplier);
|
||||
}
|
||||
function scaleFromBase(value, scaleFactor) {
|
||||
return value.dividedBy(scaleFactor.multiplier);
|
||||
}
|
||||
console.debug("Preparing units...");
|
||||
class Unit {
|
||||
constructor(unitKey, symbol, scale) {
|
||||
this.name = localize("unit." + unitKey + ".name");
|
||||
this.symbol = symbol;
|
||||
this.scale = scale;
|
||||
this.description = localize("unit." + unitKey + ".desc");
|
||||
}
|
||||
}
|
||||
const units = {
|
||||
ANY: new Unit("any", "", scales.NONE),
|
||||
WATT: new Unit("watt", "W", scales.SI),
|
||||
VOLT: new Unit("volt", "V", scales.SI),
|
||||
AMPERE: new Unit("ampere", "A", scales.SI),
|
||||
OHM: new Unit("ohm", "Ω", scales.SI),
|
||||
FARAD: new Unit("farad", "F", scales.SI),
|
||||
METER: new Unit("meter", "m", scales.SI),
|
||||
INCH: new Unit("inch", "in", scales.IMPERIAL_DISTANCE),
|
||||
POUND: new Unit("pound", "p", scales.IMPERIAL_WEIGHT),
|
||||
};
|
||||
console.debug("Preparing formulas...");
|
||||
class FormulaContextHandler {
|
||||
constructor(contextValueIndex) {
|
||||
this.contextValueIndex = contextValueIndex;
|
||||
}
|
||||
getContextValue(context) {
|
||||
if (context.length <= this.contextValueIndex) {
|
||||
alert(localize("error.formulaContext.tooSmall"));
|
||||
throw new Error(localize("error.formulaContext.tooSmall"));
|
||||
}
|
||||
return context[this.contextValueIndex];
|
||||
}
|
||||
}
|
||||
class FormulaValue {
|
||||
constructor(unit, scaleFactor) {
|
||||
this.unit = unit;
|
||||
this.scaleFactor = scaleFactor;
|
||||
this.parentFormula = null;
|
||||
this.valueSource = null;
|
||||
}
|
||||
getFormulaValue(context) {
|
||||
if (this.parentFormula === null) {
|
||||
alert(localize("error.formulaValue.noParent"));
|
||||
throw new Error(localize("error.formulaValue.noParent"));
|
||||
}
|
||||
if (this.valueSource === null) {
|
||||
alert(localize("error.formulaValue.noSource"));
|
||||
throw new Error(localize("error.formulaValue.noSource"));
|
||||
}
|
||||
if (this.valueSource instanceof FormulaContextHandler) {
|
||||
return this.valueSource.getContextValue(context);
|
||||
}
|
||||
return scaleFromBase(scaleToBase(this.valueSource.getVariantValue(this.parentFormula, context), this.valueSource.getOutputValueDefinition().scaleFactor), this.scaleFactor);
|
||||
}
|
||||
}
|
||||
class Formula {
|
||||
constructor(values, variants, formulaKey, categories, wikiLink) {
|
||||
this.values = values;
|
||||
this.variants = variants;
|
||||
this.formulaKey = formulaKey;
|
||||
this.name = localize("formula." + formulaKey + ".name");
|
||||
this.description = localize("formula." + formulaKey + ".desc");
|
||||
this.categories = categories;
|
||||
this.wikiLink = wikiLink;
|
||||
this.values.forEach(value => {
|
||||
value.parentFormula = this;
|
||||
});
|
||||
}
|
||||
getClone() {
|
||||
const clonedFormulaValues = [];
|
||||
this.values.forEach(originalValue => {
|
||||
clonedFormulaValues.push(new FormulaValue(originalValue.unit, originalValue.scaleFactor));
|
||||
});
|
||||
return new Formula(clonedFormulaValues, this.variants, this.formulaKey, this.categories, this.wikiLink);
|
||||
}
|
||||
}
|
||||
const formulas = {
|
||||
OHM_LAW: new Formula([
|
||||
new FormulaValue(units.OHM, scaleFactors.SI_BASE),
|
||||
new FormulaValue(units.AMPERE, scaleFactors.SI_BASE),
|
||||
new FormulaValue(units.VOLT, scaleFactors.SI_BASE),
|
||||
], [
|
||||
new class {
|
||||
constructor() {
|
||||
this.description = "V=I*R";
|
||||
this.getVariantValue = (formula, context) => {
|
||||
return formula.values[0].getFormulaValue(context).times(formula.values[1].getFormulaValue(context));
|
||||
};
|
||||
this.getInputValuesDefinition = () => {
|
||||
return [this.parentFormula.values[0], this.parentFormula.values[1]];
|
||||
};
|
||||
this.getOutputValueDefinition = () => {
|
||||
return this.parentFormula.values[2];
|
||||
};
|
||||
this.getMathMl = (formula) => {
|
||||
return "<math><mi>" +
|
||||
formula.values[2].unit.symbol +
|
||||
"</mi><mo>=</mo><mi>" +
|
||||
formula.values[0].unit.symbol +
|
||||
"</mi><mo>*</mo><mi>" +
|
||||
formula.values[1].unit.symbol +
|
||||
"</mi></math>";
|
||||
};
|
||||
this.parentFormula = null;
|
||||
}
|
||||
},
|
||||
new class {
|
||||
constructor() {
|
||||
this.description = "I=V/R";
|
||||
this.getVariantValue = (formula, context) => {
|
||||
return formula.values[2].getFormulaValue(context).dividedBy(formula.values[0].getFormulaValue(context));
|
||||
};
|
||||
this.getInputValuesDefinition = () => {
|
||||
return [this.parentFormula.values[0], this.parentFormula.values[2]];
|
||||
};
|
||||
this.getOutputValueDefinition = () => {
|
||||
return this.parentFormula.values[1];
|
||||
};
|
||||
this.getMathMl = (formula) => {
|
||||
return "<math><mi>" +
|
||||
formula.values[1].unit.symbol +
|
||||
"</mi><mo>=</mo><mfrac><mi>" +
|
||||
formula.values[2].unit.symbol +
|
||||
"</mi><mi>" +
|
||||
formula.values[0].unit.symbol +
|
||||
"</mi></mfrac></math>";
|
||||
};
|
||||
this.parentFormula = null;
|
||||
}
|
||||
},
|
||||
new class {
|
||||
constructor() {
|
||||
this.description = "R=V/I";
|
||||
this.getVariantValue = (formula, context) => {
|
||||
return formula.values[2].getFormulaValue(context).dividedBy(formula.values[1].getFormulaValue(context));
|
||||
};
|
||||
this.getInputValuesDefinition = () => {
|
||||
return [this.parentFormula.values[2], this.parentFormula.values[1]];
|
||||
};
|
||||
this.getOutputValueDefinition = () => {
|
||||
return this.parentFormula.values[0];
|
||||
};
|
||||
this.getMathMl = (formula) => {
|
||||
return "<math><mi>" +
|
||||
formula.values[0].unit.symbol +
|
||||
"</mi><mo>=</mo><mfrac><mi>" +
|
||||
formula.values[2].unit.symbol +
|
||||
"</mi><mi>" +
|
||||
formula.values[1].unit.symbol +
|
||||
"</mi></mfrac></math>";
|
||||
};
|
||||
this.parentFormula = null;
|
||||
}
|
||||
},
|
||||
], "ohm_law", ["electricity"], new URL("https://wikipedia.org/wiki/Ohm's_law")),
|
||||
};
|
||||
Object.keys(formulas).forEach(formulaKey => {
|
||||
formulas[formulaKey].variants.forEach(formulaVariant => {
|
||||
formulaVariant.parentFormula = formulas[formulaKey];
|
||||
});
|
||||
});
|
||||
class ContextType {
|
||||
constructor(name, description) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
const contextTypes = {
|
||||
DISABLED: new ContextType(localize("context.type.disabled.name"), localize("context.type.disabled.desc")),
|
||||
CONSTANT: new ContextType(localize("context.type.constant.name"), localize("context.type.constant.desc")),
|
||||
CONTINUOUS: new ContextType(localize("context.type.continuous.name"), localize("context.type.continuous.desc")),
|
||||
VALUE_RANGE: new ContextType(localize("context.type.valueRange.name"), localize("context.type.valueRange.desc")),
|
||||
DATASET_RANG: new ContextType(localize("context.type.dataSetRange.name"), localize("context.type.dataSetRange.desc")),
|
||||
};
|
||||
console.debug("Preparing sets...");
|
||||
class DataSet {
|
||||
constructor(name, description, values, unit, scaleFactor) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.values = values;
|
||||
this.unit = unit;
|
||||
this.scaleFactor = scaleFactor;
|
||||
if (unit.scale != scaleFactor.scale) {
|
||||
alert("");
|
||||
throw Error("");
|
||||
}
|
||||
}
|
||||
getDataSet() {
|
||||
return this.values;
|
||||
}
|
||||
}
|
||||
const e3Range = [1, 2.2, 4.7];
|
||||
const e6Range = [1, 1.5, 2.2, 3.3, 4.7, 6.8];
|
||||
const e12Range = [1, 1.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2];
|
||||
const e24Range = [
|
||||
1, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2, 2.2, 2.4, 2.7, 3, 3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1
|
||||
];
|
||||
const e48Range = [
|
||||
1, 1.05, 1.1, 1.15, 1.21, 1.27, 1.33, 1.4, 1.47, 1.54, 1.62, 1.69, 1.78, 1.87, 1.96, 2.05, 2.15, 2.26, 2.37, 2.49,
|
||||
2.61, 2.74, 2.87, 3.01, 3.16, 3.32, 3.48, 3.65, 3.83, 4.02, 4.22, 4.42, 4.64, 4.87, 5.11, 5.36, 5.62, 5.9, 6.19,
|
||||
6.49, 6.81, 7.15, 7.5, 7.87, 8.25, 8.66, 9.09, 9.53
|
||||
];
|
||||
const resistorsScales = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000];
|
||||
const capacitorScales = [10e-12, 10e-11, 10e-10, 10e-9, 10e-8, 10e-7, 10e-6, 10e-5, 10e-4, 10e-3, 10e-2];
|
||||
const sets = {
|
||||
RESISTOR_E3: new DataSet(localize("dataset.resistor-e3.name"), localize("dataset.resistor-e3.desc"), resistorsScales.flatMap((e3Scale) => e3Range.map((e3Multiplier) => new Decimal(e3Scale).times(e3Multiplier))), units.OHM, scaleFactors.SI_BASE),
|
||||
RESISTOR_E6: new DataSet(localize("dataset.resistor-e6.name"), localize("dataset.resistor-e6.desc"), resistorsScales.flatMap((e6Scale) => e6Range.map((e6Multiplier) => new Decimal(e6Scale).times(e6Multiplier))), units.OHM, scaleFactors.SI_BASE),
|
||||
RESISTOR_E12: new DataSet(localize("dataset.resistor-e12.name"), localize("dataset.resistor-e12.desc"), resistorsScales.flatMap((e12Scale) => e12Range.map((e12Multiplier) => new Decimal(e12Scale).times(e12Multiplier))), units.OHM, scaleFactors.SI_BASE),
|
||||
RESISTOR_E24: new DataSet(localize("dataset.resistor-e24.name"), localize("dataset.resistor-e24.desc"), resistorsScales.flatMap((e24Scale) => e24Range.map((e24Multiplier) => new Decimal(e24Scale).times(e24Multiplier))), units.OHM, scaleFactors.SI_BASE),
|
||||
RESISTOR_E48: new DataSet(localize("dataset.resistor-e48.name"), localize("dataset.resistor-e48.desc"), resistorsScales.flatMap((e48Scale) => e48Range.map((e48Multiplier) => new Decimal(e48Scale).times(e48Multiplier))), units.OHM, scaleFactors.SI_BASE),
|
||||
CAPACITOR_IEC: new DataSet(localize("dataset.capacitor-iec.name"), localize("dataset.capacitor-iec.desc"), capacitorScales.flatMap((cScale) => e24Range.map((eMultiplier) => new Decimal(cScale).times(eMultiplier))), units.FARAD, scaleFactors.SI_BASE),
|
||||
};
|
||||
console.debug("Preparing UI...");
|
||||
const idWorkbenchFormulaPrefix = "fw-workbench-formula-";
|
||||
const idWorkbenchFormulaSpawnPoint = idWorkbenchFormulaPrefix + "spawn";
|
||||
const idTemplateFormula = "template-workbench-formula";
|
||||
const idFormulaName = idWorkbenchFormulaPrefix + "name";
|
||||
const idFormulaInputs = idWorkbenchFormulaPrefix + "inputs";
|
||||
const idFormulaOutputs = idWorkbenchFormulaPrefix + "outputs";
|
||||
const classTemplateFormulaValue = "formula-value-input-form";
|
||||
const idTemplateFormulaValue = idTemplateFormula + "-value";
|
||||
const idFormulaValuePrefix = idWorkbenchFormulaPrefix + "value-";
|
||||
const idFormulaValueId = idFormulaValuePrefix + "id";
|
||||
const idFormulaValueName = idFormulaValuePrefix + "name";
|
||||
const idFormulaValueLink = idFormulaValuePrefix + "link";
|
||||
const idFormulaValueTestValue = idFormulaValuePrefix + "test-value";
|
||||
const idFormulaValueTestScale = idFormulaValuePrefix + "test-scale";
|
||||
const idFormulaValueTestValueSet = idFormulaValuePrefix + "test-value-set";
|
||||
let eTemplateWorkbenchFormula = document.getElementById(idTemplateFormula);
|
||||
let eTemplateWorkbenchFormulaValue = document.getElementById(idTemplateFormulaValue);
|
||||
if (eTemplateWorkbenchFormula === null || eTemplateWorkbenchFormulaValue === null) {
|
||||
alert("error.ui.workbench.noTemplate");
|
||||
throw Error("error.ui.workbench.noTemplate");
|
||||
}
|
||||
eTemplateWorkbenchFormula = eTemplateWorkbenchFormula.cloneNode(true).content;
|
||||
eTemplateWorkbenchFormulaValue = eTemplateWorkbenchFormulaValue.cloneNode(true).content;
|
||||
const eWorkbenchFormulaSpawnPoint = document.querySelector(`a#${idWorkbenchFormulaSpawnPoint}`);
|
||||
if (eWorkbenchFormulaSpawnPoint === null) {
|
||||
alert("error.ui.workbench.noAnchor");
|
||||
throw Error("error.ui.workbench.noAnchor");
|
||||
}
|
||||
let uiWorkbenchFormulas = [];
|
||||
var WorkbenchFormulaValueTypes;
|
||||
(function (WorkbenchFormulaValueTypes) {
|
||||
WorkbenchFormulaValueTypes[WorkbenchFormulaValueTypes["INPUT"] = 0] = "INPUT";
|
||||
WorkbenchFormulaValueTypes[WorkbenchFormulaValueTypes["OUTPUT"] = 1] = "OUTPUT";
|
||||
})(WorkbenchFormulaValueTypes || (WorkbenchFormulaValueTypes = {}));
|
||||
class WorkbenchFormulaValueUiElement {
|
||||
constructor(rootElement, formulaValue, parentFormulaElement, valueType) {
|
||||
this.rootElement = rootElement;
|
||||
this.idSuffix = Date.now().toString() + Math.floor(Math.random() * 9999);
|
||||
this.valueType = valueType;
|
||||
this.formulaValue = formulaValue;
|
||||
this.parentFormulaElement = parentFormulaElement;
|
||||
this.eFormulaValueId = rootElement.querySelector(`input#${idFormulaValueId}`);
|
||||
this.eFormulaValueName = rootElement.querySelector(`p#${idFormulaValueName}`);
|
||||
this.eFormulaValueLink = rootElement.querySelector(`select#${idFormulaValueLink}`);
|
||||
this.eFormulaValueTestValue = rootElement.querySelector(`input#${idFormulaValueTestValue}`);
|
||||
this.eFormulaValueTestScale = rootElement.querySelector(`select#${idFormulaValueTestScale}`);
|
||||
this.eFormulaValueTestValueSet = rootElement.querySelector(`select#${idFormulaValueTestValueSet}`);
|
||||
if ([this.eFormulaValueId, this.eFormulaValueName, this.eFormulaValueLink, this.eFormulaValueTestValue,
|
||||
this.eFormulaValueTestScale, this.eFormulaValueTestValueSet].some((item) => item === null)) {
|
||||
alert("error.ui.formula.value.missingElement");
|
||||
throw Error("error.ui.formula.value.missingElement");
|
||||
}
|
||||
this.rootElement.querySelectorAll(`input, select, p, div`).forEach(eFormInput => {
|
||||
if (eFormInput.hasAttribute("id")) {
|
||||
eFormInput.setAttribute("id", eFormInput.getAttribute("id") + this.idSuffix);
|
||||
}
|
||||
});
|
||||
this.rootElement.querySelectorAll(`label`).forEach(eFormLabel => {
|
||||
if (eFormLabel.hasAttribute("for")) {
|
||||
eFormLabel.setAttribute("for", eFormLabel.getAttribute("for") + this.idSuffix);
|
||||
}
|
||||
});
|
||||
this.eFormulaValueName.innerText = `${this.formulaValue.unit.name} (${this.formulaValue.unit.symbol})`;
|
||||
this.toggleField(this.eFormulaValueTestValueSet, true);
|
||||
if (this.valueType === WorkbenchFormulaValueTypes.INPUT) {
|
||||
this.setupInput();
|
||||
}
|
||||
else {
|
||||
this.setupOutput();
|
||||
}
|
||||
}
|
||||
toggleTestMode(hidden) {
|
||||
this.eFormulaValueTestScale.parentNode.parentNode.hidden = hidden;
|
||||
this.eFormulaValueTestScale.parentNode.parentNode.hidden = hidden;
|
||||
}
|
||||
toggleField(eFormField, hidden) {
|
||||
eFormField.parentNode.parentNode.hidden = hidden;
|
||||
}
|
||||
setupInput() {
|
||||
console.log("Setting up as input...");
|
||||
this.toggleField(this.eFormulaValueId, true);
|
||||
}
|
||||
setupOutput() {
|
||||
console.log("Setting up as output...");
|
||||
this.toggleField(this.eFormulaValueLink, true);
|
||||
}
|
||||
static getNew(formulaValue, parentFormulaElement, valueType) {
|
||||
const eNewWorkbenchFormulaValue = eTemplateWorkbenchFormulaValue.cloneNode(true).firstElementChild;
|
||||
if (eNewWorkbenchFormulaValue === null) {
|
||||
alert("error.ui.workbench.formula.value.cannotGetElement");
|
||||
throw Error("error.ui.workbench.formula.value.cannotGetElement");
|
||||
}
|
||||
return new WorkbenchFormulaValueUiElement(eNewWorkbenchFormulaValue, formulaValue, parentFormulaElement, valueType);
|
||||
}
|
||||
}
|
||||
class WorkbenchFormulaUiElement {
|
||||
constructor(rootElement, formulaVariant) {
|
||||
this.rootElement = rootElement;
|
||||
this.idSuffix = Date.now().toString();
|
||||
this.formulaVariant = formulaVariant;
|
||||
this.eFormulaName = rootElement.querySelector(`p#${idFormulaName}`);
|
||||
this.eFormulaInputs = rootElement.querySelector(`div#${idFormulaInputs}`);
|
||||
this.eFormulaOutputs = rootElement.querySelector(`div#${idFormulaOutputs}`);
|
||||
if ([this.eFormulaName, this.eFormulaInputs, this.eFormulaOutputs].some((item) => item === null)) {
|
||||
alert("error.ui.formula.missingElement");
|
||||
throw Error("error.ui.formula.missingElement");
|
||||
}
|
||||
this.eFormulaName.innerText = this.formulaVariant.parentFormula.name;
|
||||
this.inputValueElements = [];
|
||||
this.formulaVariant.getInputValuesDefinition().forEach(variantValue => {
|
||||
const newInputValueElement = WorkbenchFormulaValueUiElement.getNew(variantValue, this, WorkbenchFormulaValueTypes.INPUT);
|
||||
this.inputValueElements.push(newInputValueElement);
|
||||
this.eFormulaInputs.appendChild(newInputValueElement.rootElement);
|
||||
});
|
||||
this.outputValueElements = [];
|
||||
[this.formulaVariant.getOutputValueDefinition()].forEach(variantValue => {
|
||||
const newOutputValueElement = WorkbenchFormulaValueUiElement.getNew(variantValue, this, WorkbenchFormulaValueTypes.OUTPUT);
|
||||
this.outputValueElements.push(newOutputValueElement);
|
||||
this.eFormulaOutputs.appendChild(newOutputValueElement.rootElement);
|
||||
});
|
||||
}
|
||||
toggleTestMode(hidden) {
|
||||
}
|
||||
static createNew(formulaVariant) {
|
||||
const eNewWorkbenchFormula = eTemplateWorkbenchFormula.cloneNode(true).firstElementChild;
|
||||
if (eNewWorkbenchFormula === null) {
|
||||
alert("error.ui.workbench.formula.cannotGetElement");
|
||||
throw Error("error.ui.workbench.formula.cannotGetElement");
|
||||
}
|
||||
const newWorkbenchUiElement = new WorkbenchFormulaUiElement(eNewWorkbenchFormula, formulaVariant);
|
||||
uiWorkbenchFormulas.push(newWorkbenchUiElement);
|
||||
eWorkbenchFormulaSpawnPoint.parentNode.insertBefore(newWorkbenchUiElement.rootElement, eWorkbenchFormulaSpawnPoint);
|
||||
return newWorkbenchUiElement;
|
||||
}
|
||||
}
|
||||
const idCatalogPrefix = "fw-catalog-";
|
||||
const idCatalogCategoryPrefix = idCatalogPrefix + "category-";
|
||||
const idCatalogCategoryCount = idCatalogPrefix + "formula-count";
|
||||
const eCategoryContainers = {};
|
||||
document.querySelectorAll('[id]').forEach((element) => {
|
||||
if (element.id.startsWith(idCatalogCategoryPrefix)) {
|
||||
eCategoryContainers[element.id.replace(idCatalogCategoryPrefix, "")] = element;
|
||||
}
|
||||
});
|
||||
const eFormulaCount = document.getElementById(idCatalogCategoryCount);
|
||||
if (eFormulaCount !== null) {
|
||||
eFormulaCount.innerText = Object.keys(formulas).length.toString();
|
||||
}
|
||||
let eTemplateFormula = document.getElementById("template-formula-available");
|
||||
let eTemplateFormulaVariant = document.getElementById("template-formula-available-variant");
|
||||
if (eTemplateFormula === null || eTemplateFormulaVariant === null) {
|
||||
alert("error.ui.catalog.noTemplate");
|
||||
throw Error("error.ui.catalog.noTemplate");
|
||||
}
|
||||
Object.keys(formulas).forEach(formulaKey => {
|
||||
const hasValidCategory = formulas[formulaKey].categories.every(function (categoryId) {
|
||||
return Object.keys(eCategoryContainers).indexOf(categoryId) !== -1;
|
||||
});
|
||||
if (hasValidCategory) {
|
||||
let eNewFormula = eTemplateFormula.content.cloneNode(true);
|
||||
let eNewFormulaTitle = eNewFormula.querySelector("p");
|
||||
if (eNewFormulaTitle !== null) {
|
||||
eNewFormulaTitle.innerText = formulas[formulaKey].name;
|
||||
}
|
||||
let eNewFormulaVariants = eNewFormula.querySelector("div.fw-variants");
|
||||
if (eNewFormulaVariants === null) {
|
||||
alert("");
|
||||
throw Error("");
|
||||
}
|
||||
eNewFormulaVariants.innerHTML = "";
|
||||
formulas[formulaKey].variants.forEach(variant => {
|
||||
let eNewFormulaVariant = eTemplateFormulaVariant.content.cloneNode(true);
|
||||
let eNewFormulaVariantButton = eNewFormulaVariant.querySelector("button");
|
||||
if (eNewFormulaVariantButton === null) {
|
||||
alert("");
|
||||
throw Error("");
|
||||
}
|
||||
eNewFormulaVariantButton.innerHTML = variant.getMathMl(formulas[formulaKey]);
|
||||
eNewFormulaVariantButton.title = variant.description;
|
||||
eNewFormulaVariantButton.onclick = function () {
|
||||
WorkbenchFormulaUiElement.createNew(variant);
|
||||
};
|
||||
eNewFormulaVariants.appendChild(eNewFormulaVariant);
|
||||
});
|
||||
formulas[formulaKey].categories.forEach(categoryKey => {
|
||||
if (Object.keys(eCategoryContainers).includes(categoryKey)) {
|
||||
eCategoryContainers[categoryKey].appendChild(eNewFormula);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
const idContextComponentPrefix = "fw-context-component-";
|
||||
const idContextComponentId = idContextComponentPrefix + "id";
|
||||
const idContextComponentDelete = idContextComponentPrefix + "delete";
|
||||
const idContextComponentTypes = idContextComponentPrefix + "type";
|
||||
const idContextComponentManualValue = idContextComponentPrefix + "manual-value";
|
||||
const idContextComponentManualValues = idContextComponentManualValue + "s";
|
||||
const idContextComponentRangeFrom = idContextComponentPrefix + "range-from";
|
||||
const idContextComponentRangeTo = idContextComponentPrefix + "range-to";
|
||||
const idContextComponentRangeStep = idContextComponentPrefix + "range-step";
|
||||
const idContextComponentSets = idContextComponentPrefix + "set";
|
||||
const idContextComponentUnit = idContextComponentPrefix + "unit";
|
||||
const idContextComponentScale = idContextComponentPrefix + "scale";
|
||||
let uiContextComponents = [];
|
||||
let eTemplateContextComponent = document.getElementById("template-context-component");
|
||||
if (eTemplateContextComponent === null) {
|
||||
alert("error.ui.context.noTemplate");
|
||||
throw Error("error.ui.context.noTemplate");
|
||||
}
|
||||
eTemplateContextComponent = eTemplateContextComponent.cloneNode(true).content;
|
||||
const eContextTypes = eTemplateContextComponent.getElementById(idContextComponentTypes);
|
||||
const eContextSets = eTemplateContextComponent.getElementById(idContextComponentSets);
|
||||
const eContextUnits = eTemplateContextComponent.getElementById(idContextComponentUnit);
|
||||
const eContextScales = eTemplateContextComponent.getElementById(idContextComponentScale);
|
||||
if ([eContextTypes, eContextSets, eContextUnits, eContextScales].some((item) => item === null)) {
|
||||
alert("error.ui.context.noSets");
|
||||
throw Error("error.ui.context.noSets");
|
||||
}
|
||||
Object.keys(contextTypes).forEach(value => {
|
||||
const eNewContextTypesOption = document.createElement("option");
|
||||
eNewContextTypesOption.setAttribute("value", value);
|
||||
eNewContextTypesOption.innerText = contextTypes[value].name;
|
||||
eContextTypes.appendChild(eNewContextTypesOption);
|
||||
});
|
||||
Object.keys(sets).forEach(value => {
|
||||
const eNewContextSetsOption = document.createElement("option");
|
||||
eNewContextSetsOption.setAttribute("value", value);
|
||||
eNewContextSetsOption.innerText = sets[value].name;
|
||||
eContextSets.appendChild(eNewContextSetsOption);
|
||||
});
|
||||
Object.keys(units).forEach(unitKey => {
|
||||
const eNewContextUnitsOption = document.createElement("option");
|
||||
eNewContextUnitsOption.setAttribute("value", unitKey);
|
||||
eNewContextUnitsOption.innerText = units[unitKey].name;
|
||||
eContextUnits.appendChild(eNewContextUnitsOption);
|
||||
});
|
||||
Object.keys(scaleFactors).forEach(scaleKey => {
|
||||
const eNewContextScalesOption = document.createElement("option");
|
||||
eNewContextScalesOption.setAttribute("value", scaleKey);
|
||||
eNewContextScalesOption.innerText = scaleFactors[scaleKey].prefix;
|
||||
eContextScales.appendChild(eNewContextScalesOption);
|
||||
});
|
||||
let eContextStatusMessage = document.getElementById("fw-text-context-middle");
|
||||
if (eContextStatusMessage === null) {
|
||||
alert("error.ui.context.noStatus");
|
||||
throw Error("error.ui.context.noStatus");
|
||||
}
|
||||
let eContextAddButton = document.getElementById("fw-button-add-context");
|
||||
let eContextDebugButton = document.getElementById("fw-button-debug-context");
|
||||
if (eContextAddButton === null || eContextDebugButton === null) {
|
||||
alert("error.ui.context.missingButton");
|
||||
throw Error("error.ui.context.missingButton");
|
||||
}
|
||||
class ContextComponentUiElement {
|
||||
constructor(rootElement) {
|
||||
this.rootElement = rootElement;
|
||||
this.idSuffix = Date.now().toString();
|
||||
this.eIdLabel = rootElement.querySelector(`label[for="${idContextComponentId}"]`);
|
||||
this.eIdInput = rootElement.querySelector(`input#${idContextComponentId}`);
|
||||
this.eDeleteButton = rootElement.querySelector(`button#${idContextComponentDelete}`);
|
||||
this.eTypeLabel = rootElement.querySelector(`label[for="${idContextComponentTypes}"]`);
|
||||
this.eTypeSelect = rootElement.querySelector(`select#${idContextComponentTypes}`);
|
||||
this.eManualValueLabel = rootElement.querySelector(`label[for="${idContextComponentManualValue}"]`);
|
||||
this.eManualValueInput = rootElement.querySelector(`input#${idContextComponentManualValue}`);
|
||||
this.eManualValuesLabel = rootElement.querySelector(`label[for="${idContextComponentManualValues}"]`);
|
||||
this.eManualValuesInput = rootElement.querySelector(`input#${idContextComponentManualValues}`);
|
||||
this.eRangeFromLabel = rootElement.querySelector(`label[for="${idContextComponentRangeFrom}"]`);
|
||||
this.eRangeFromInput = rootElement.querySelector(`input#${idContextComponentRangeFrom}`);
|
||||
this.eRangeToLabel = rootElement.querySelector(`label[for="${idContextComponentRangeTo}"]`);
|
||||
this.eRangeToInput = rootElement.querySelector(`input#${idContextComponentRangeTo}`);
|
||||
this.eRangeStepLabel = rootElement.querySelector(`label[for="${idContextComponentRangeStep}"]`);
|
||||
this.eRangeStepInput = rootElement.querySelector(`input#${idContextComponentRangeStep}`);
|
||||
this.eDataSetLabel = rootElement.querySelector(`label[for="${idContextComponentSets}"]`);
|
||||
this.eDataSetSelect = rootElement.querySelector(`select#${idContextComponentSets}`);
|
||||
this.eUnitLabel = rootElement.querySelector(`label[for="${idContextComponentUnit}"]`);
|
||||
this.eUnitSelect = rootElement.querySelector(`select#${idContextComponentUnit}`);
|
||||
this.eScaleLabel = rootElement.querySelector(`label[for="${idContextComponentScale}"]`);
|
||||
this.eScaleSelect = rootElement.querySelector(`select#${idContextComponentScale}`);
|
||||
this.allElements = [
|
||||
this.eIdLabel, this.eIdInput, this.eDeleteButton, this.eTypeLabel, this.eTypeSelect,
|
||||
this.eManualValuesLabel, this.eManualValuesInput, this.eRangeFromLabel, this.eRangeFromInput,
|
||||
this.eRangeToLabel, this.eRangeToInput, this.eRangeStepLabel, this.eRangeStepInput, this.eDataSetLabel,
|
||||
this.eDataSetSelect, this.eUnitLabel, this.eUnitSelect, this.eScaleLabel, this.eScaleSelect,
|
||||
this.eManualValueLabel, this.eManualValueInput
|
||||
];
|
||||
if (this.allElements.some((item) => item === null)) {
|
||||
alert("error.ui.context.component.missingElement");
|
||||
throw Error("error.ui.context.component.missingElement");
|
||||
}
|
||||
rootElement.querySelectorAll(`input, select`).forEach(eFormInput => {
|
||||
if (eFormInput.hasAttribute("id")) {
|
||||
eFormInput.setAttribute("id", eFormInput.getAttribute("id") + this.idSuffix);
|
||||
}
|
||||
});
|
||||
rootElement.querySelectorAll(`label`).forEach(eFormLabel => {
|
||||
if (eFormLabel.hasAttribute("for")) {
|
||||
eFormLabel.setAttribute("for", eFormLabel.getAttribute("for") + this.idSuffix);
|
||||
}
|
||||
});
|
||||
this.eDeleteButton.removeAttribute('id');
|
||||
this.eIdInput.value = this.idSuffix;
|
||||
this.eTypeSelect.onchange = this.onTypeChange.bind(this);
|
||||
this.eDeleteButton.onclick = this.onDeleteClick.bind(this);
|
||||
this.onTypeChange(null);
|
||||
}
|
||||
onTypeChange(event) {
|
||||
this.allElements.forEach(eFormElement => {
|
||||
this.toggleField(eFormElement, true);
|
||||
});
|
||||
this.toggleField(this.eIdLabel, false);
|
||||
this.toggleField(this.eTypeLabel, false);
|
||||
if (this.getContextType() !== contextTypes.DISABLED) {
|
||||
this.toggleField(this.eUnitLabel, false);
|
||||
this.toggleField(this.eScaleLabel, false);
|
||||
}
|
||||
switch (this.getContextType()) {
|
||||
case contextTypes.CONSTANT:
|
||||
this.toggleField(this.eManualValueInput, false);
|
||||
break;
|
||||
case contextTypes.CONTINUOUS:
|
||||
this.toggleField(this.eRangeFromLabel, false);
|
||||
this.toggleField(this.eRangeToLabel, false);
|
||||
this.toggleField(this.eRangeStepLabel, false);
|
||||
break;
|
||||
case contextTypes.VALUE_RANGE:
|
||||
this.toggleField(this.eManualValuesInput, false);
|
||||
break;
|
||||
case contextTypes.DATASET_RANG:
|
||||
this.toggleField(this.eDataSetLabel, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
onDeleteClick(event) {
|
||||
this.rootElement.remove();
|
||||
uiContextComponents = uiContextComponents.filter(item => item !== this);
|
||||
if (uiContextComponents.length < 1) {
|
||||
eContextStatusMessage.hidden = false;
|
||||
}
|
||||
}
|
||||
toggleField(eFormField, hidden) {
|
||||
eFormField.parentNode.parentNode.hidden = hidden;
|
||||
}
|
||||
getContextType() {
|
||||
return contextTypes[this.eTypeSelect.value];
|
||||
}
|
||||
}
|
||||
eContextAddButton.onclick = function () {
|
||||
const eNewContextComponent = eTemplateContextComponent.cloneNode(true).firstElementChild;
|
||||
if (eNewContextComponent === null) {
|
||||
alert("error.ui.context.component.cannotGetElement");
|
||||
throw Error("error.ui.context.component.cannotGetElement");
|
||||
}
|
||||
const newContextComponent = new ContextComponentUiElement(eNewContextComponent);
|
||||
uiContextComponents.push(newContextComponent);
|
||||
eContextStatusMessage.parentNode.insertBefore(newContextComponent.rootElement, eContextStatusMessage);
|
||||
eContextStatusMessage.hidden = true;
|
||||
};
|
||||
const endTime = new Date().getMilliseconds();
|
||||
console.log("Done, took " + (endTime - startTime) + "ms !");
|
||||
//# sourceMappingURL=code.js.map
|
1268
tools/items/formula-wizard/code.ts
Normal file
1268
tools/items/formula-wizard/code.ts
Normal file
File diff suppressed because it is too large
Load Diff
0
tools/items/formula-wizard/lang-en.ts
Normal file
0
tools/items/formula-wizard/lang-en.ts
Normal file
51
tools/items/formula-wizard/lang.json
Normal file
51
tools/items/formula-wizard/lang.json
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"en": {
|
||||
"tool.formula-wizard.title": "Formula Wizard - (W.I.P)",
|
||||
"tool.formula-wizard.output.graph": "Output Graph",
|
||||
"tool.formula-wizard.workbench": "Formula Workbench",
|
||||
"tool.formula-wizard.workbench.context": "Context",
|
||||
"tool.formula-wizard.workbench.context.components": "Components:",
|
||||
"tool.formula-wizard.workbench.context.placeholder": "No components present in the context.<br>Use the button below to add one :)",
|
||||
"tool.formula-wizard.workbench.placeholder": "???",
|
||||
|
||||
"tool.formula-wizard.workbench.formula.inputs": "Input(s):",
|
||||
"tool.formula-wizard.workbench.formula.outputs": "Output(s):",
|
||||
"tool.formula-wizard.workbench.formula.value.expand": "Enable live experiment mode",
|
||||
|
||||
"tool.formula-wizard.categories": "Available Formulas",
|
||||
"tool.formula-wizard.categories.electricity": "Electricity",
|
||||
"tool.formula-wizard.categories.convert": "Converters",
|
||||
"tool.formula-wizard.categories.physics": "Physics",
|
||||
"tool.formula-wizard.categories.chemistry": "Chemistry",
|
||||
"tool.formula-wizard.categories.radioactivity": "Radioactivity",
|
||||
|
||||
"tool.formula-wizard.button.context.add": "Add a context element.",
|
||||
"tool.formula-wizard.button.context.debug": "Show debugging print-out of current context.",
|
||||
|
||||
"tool.formula-wizard.source": "Downloads & Source Code"
|
||||
},
|
||||
"fr": {
|
||||
"tool.formula-wizard.title": "Ensorceleur de formules - (W.I.P)",
|
||||
"tool.formula-wizard.output.graph": "Graphes des résultats",
|
||||
"tool.formula-wizard.workbench": "Atelier de formule",
|
||||
"tool.formula-wizard.workbench.context": "Contexte",
|
||||
"tool.formula-wizard.workbench.context.components": "Composantes:",
|
||||
"tool.formula-wizard.workbench.context.placeholder": "Aucune composante n'est présente dans le contexte.<br>Utilisez les bouttons ci-dessous pour en ajouter :)",
|
||||
"tool.formula-wizard.workbench.placeholder": "???",
|
||||
|
||||
"tool.formula-wizard.workbench.formula.inputs": "Entrée(s):",
|
||||
"tool.formula-wizard.workbench.formula.outputs": "Sortie(s):",
|
||||
|
||||
"tool.formula-wizard.categories": "Formules disponible",
|
||||
"tool.formula-wizard.categories.electricity": "Électricité",
|
||||
"tool.formula-wizard.categories.convert": "Convertisseurs",
|
||||
"tool.formula-wizard.categories.physics": "Physique",
|
||||
"tool.formula-wizard.categories.chemistry": "Chimie",
|
||||
"tool.formula-wizard.categories.radioactivity": "Radioactivité",
|
||||
|
||||
"tool.formula-wizard.button.context.add": "Ajouter un élement au contexte.",
|
||||
"tool.formula-wizard.button.context.debug": "Afficher un récapitulatif de débogage pour le contexte actuel.",
|
||||
|
||||
"tool.formula-wizard.source": "Télechargements & code source"
|
||||
}
|
||||
}
|
432
tools/items/formula-wizard/page.php
Normal file
432
tools/items/formula-wizard/page.php
Normal file
@@ -0,0 +1,432 @@
|
||||
<?php
|
||||
echo(getMainHeader(localize("tool.formula-wizard.introduction.title"), null, null, null,
|
||||
true, "bkgd-math", 3, false, false, true));
|
||||
?>
|
||||
<div class="m-s mt-xs">
|
||||
<p>Welcome to the <i>Formula Wizard</i> !</p>
|
||||
<p class="mt-xs">This tool was made ???.</p>
|
||||
<p class="mt-xs">
|
||||
If any formula you need is missing, you can email me at
|
||||
<a href="mailto:herwin.bozet@gmail.com.com?subject=Formula%20Wizard%20Request">herwin.bozet@gmail.com</a>
|
||||
and I'll look into it.</p>
|
||||
<p>I'll look into it ASAP and should take less than a couple of days.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<?php
|
||||
echo(getMainHeader(localize("tool.formula-wizard.output.graph"), null, null, null,
|
||||
true, "bkgd-math", 3, false, false, true));
|
||||
?>
|
||||
<div class="m-s mt-xs">
|
||||
<p>TODO</p>
|
||||
</div>
|
||||
|
||||
|
||||
<?php
|
||||
echo(getMainHeader(localize("tool.formula-wizard.workbench"), null, null, null,
|
||||
true, "bkgd-math", 3, false, false, true));
|
||||
?>
|
||||
|
||||
<template id="template-context-component">
|
||||
<div class="my-xs ml-xs context-component-form">
|
||||
<table class="border stylish table-v-center">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-id" class="mx-xs t-center">Id:</label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="fw-context-component-id" type="text" class="p-mxs w-full">
|
||||
</td>
|
||||
<td>
|
||||
<button id="fw-context-component-delete" class="error p-mxs px-xs"
|
||||
title="<?php echo(localize("tool.formula-wizard.button.context.add")); ?>">
|
||||
<i class="fad fa-trash-alt"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-type" class="mx-xs t-center">Type:</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<select id="fw-context-component-type" class="w-full p-mxs">
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-manual-value" class="mx-xs t-center">Value:</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<input id="fw-context-component-manual-value" type="number" class="p-mxs w-full">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-manual-values" class="mx-xs t-center">Values:</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<input id="fw-context-component-manual-values" type="text" class="p-mxs w-full">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-range-from" class="mx-xs t-center">From:</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<input id="fw-context-component-range-from" type="number" class="p-mxs w-full">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-range-to" class="mx-xs t-center">To:</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<input id="fw-context-component-range-to" type="number" class="p-mxs w-full">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-range-step" class="mx-xs t-center">Step:</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<input id="fw-context-component-range-step" type="number" class="p-mxs w-full">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-set" class="mx-xs t-center">Set:</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<select id="fw-context-component-set" class="w-full p-mxs">
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-unit" class="mx-xs t-center">Unit:</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<select id="fw-context-component-unit" class="w-full p-mxs">
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-scale" class="mx-xs t-center">Scale:</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<select id="fw-context-component-scale" class="w-full p-mxs">
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="template-workbench-formula-value">
|
||||
<div class="my-xs ml-xs formula-value-input-form">
|
||||
<table class="border stylish table-v-center">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<p id="fw-workbench-formula-value-name" class="p-xxs t-center t-w-500">${value.name}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-workbench-formula-value-id" class="mx-xs t-center">Id:</label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="fw-workbench-formula-value-id" type="text" class="p-mxs w-full">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-workbench-formula-value-link" class="mx-xs t-center">Link:</label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="fw-workbench-formula-value-link" class="p-mxs w-full">
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-workbench-formula-value-test-value" class="mx-xs t-center">Value:</label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="fw-workbench-formula-value-test-value" type="number" class="p-mxs w-full">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-workbench-formula-value-test-value-set" class="mx-xs t-center">Scale:</label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="fw-workbench-formula-value-test-value-set" class="p-mxs w-full">
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-workbench-formula-value-test-scale" class="mx-xs t-center">Scale:</label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="fw-workbench-formula-value-test-scale" class="p-mxs w-full">
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<template id="template-workbench-formula">
|
||||
<div class="border border-t-0 border-l-0 border-r-0">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="border border-t-0 border-l-0 border-b-0 p-xs mobile-hide">
|
||||
<p class="t-size-14"><i class="fad fa-grip-vertical"></i></p>
|
||||
</td>
|
||||
<td class="w-full">
|
||||
<p id="fw-workbench-formula-name" class="p-xxs t-w-600 t-center border border-t-0 border-l-0 border-r-0">${formula.name}</p>
|
||||
<div class="fw-formula-io">
|
||||
<div id="fw-workbench-formula-inputs" class="p-xxs">
|
||||
<p class="t-w-500 t-italic">
|
||||
<?php echo(localize("tool.formula-wizard.workbench.formula.inputs")); ?>
|
||||
</p>
|
||||
</div>
|
||||
<div id="fw-workbench-formula-outputs" class="p-xxs border border-l-0 border-r-0">
|
||||
<p class="t-w-500 t-italic">
|
||||
<?php echo(localize("tool.formula-wizard.workbench.formula.outputs")); ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<div class="m-s mt-xs">
|
||||
<div class=" border r-s bkgd-grid w-full">
|
||||
<div class="border border-t-0 border-l-0 border-r-0">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="border border-t-0 border-l-0 border-b-0 p-xs mobile-hide">
|
||||
<p class="t-size-14"><i class="fad fa-grip-vertical"></i></p>
|
||||
</td>
|
||||
<td class="w-full">
|
||||
<p class="p-xxs t-w-600 t-center border border-t-0 border-l-0 border-r-0 fw-workbench-name">
|
||||
<?php echo(localize("tool.formula-wizard.workbench.context")); ?>
|
||||
</p>
|
||||
<div class="fw-formula-io">
|
||||
<div class="fw-formula-components p-xxs">
|
||||
<p class="t-w-500 t-italic">
|
||||
<?php echo(localize("tool.formula-wizard.workbench.context.components")); ?>
|
||||
</p>
|
||||
|
||||
<!-- The graph's axis will point to these - Not the other way around -->
|
||||
|
||||
<p id="fw-text-context-middle" class="my-xs ml-xs">
|
||||
<?php echo(localize("tool.formula-wizard.workbench.context.placeholder")); ?>
|
||||
</p>
|
||||
|
||||
<div class="my-xs ml-xs">
|
||||
<button id="fw-button-add-context" class="success p-mxs px-xs border r-s"
|
||||
title="<?php echo(localize("tool.formula-wizard.button.context.add")); ?>">
|
||||
<i class="fad fa-plus"></i>
|
||||
</button>
|
||||
<button id="fw-button-debug-context" class="warning p-mxs px-xs border r-s"
|
||||
title="<?php echo(localize("tool.formula-wizard.button.context.debug")); ?>">
|
||||
<i class="fad fa-bug"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="border border-t-0 border-l-0 border-r-0">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="border border-t-0 border-l-0 border-b-0 p-xs mobile-hide">
|
||||
<p class="t-size-14"><i class="fad fa-grip-vertical"></i></p>
|
||||
</td>
|
||||
<td class="w-full">
|
||||
<p class="p-xxs t-w-600 t-center border border-t-0 border-l-0 border-r-0 fw-workbench-name">${formula.name}</p>
|
||||
<div class="fw-formula-io">
|
||||
<div class="fw-formula-inputs p-xxs">
|
||||
<p class="t-w-500 t-italic">
|
||||
<?php echo(localize("tool.formula-wizard.workbench.formula.inputs")); ?>
|
||||
</p>
|
||||
<div class="border r-s d-inline-block bkgd-surround my-xs ml-xs">
|
||||
<label for="test-123" class="mx-xs t-center">Ohms (Ω)</label>
|
||||
<input id="test-123" type="text" class="p-mxs rr-s border border-t-0 border-b-0 border-r-0">
|
||||
</div>
|
||||
|
||||
<div class="my-xs ml-xs formula-value-input-form">
|
||||
<table class="border stylish table-v-center">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<p class="p-xxs t-center t-w-500">Current (A)</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="test-123" class="mx-xs t-center">Link:</label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="fw-context-component-unit" class="p-mxs w-full">
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<!--<tr>
|
||||
<td colspan="2" class="p-xxs bkgd-blank">
|
||||
</td>
|
||||
</tr>-->
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-unit" class="mx-xs t-center">Value:</label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="fw-context-component-unit" type="number" class="p-mxs w-full">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="fw-context-component-scale" class="mx-xs t-center">Scale:</label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="fw-context-component-scale" class="p-mxs w-full">
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<button id="fw-context-component-delete" class="primary p-mxs px-xs border r-s"
|
||||
title="<?php echo(localize("tool.formula-wizard.workbench.formula.value.expand")); ?>">
|
||||
<i class="fad fa-vial"></i>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="fw-formula-outputs p-xxs border border-l-0 border-r-0">
|
||||
<p class="t-w-500 t-italic">
|
||||
<?php echo(localize("tool.formula-wizard.workbench.formula.outputs")); ?>
|
||||
</p>
|
||||
|
||||
<div class="border r-s d-inline-block bkgd-surround my-xs ml-xs">
|
||||
<label for="test-123" class="mx-xs t-center">Volts (V)</label>
|
||||
<input id="test-123" type="text" class="p-mxs rr-s border border-t-0 border-b-0 border-r-0" disabled>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="border r-s d-inline-block bkgd-surround my-xs ml-xs">
|
||||
<label for="test-123" class="mx-xs t-center">Watts (W)</label>
|
||||
<input id="test-123" type="text" class="p-mxs rr-s border border-t-0 border-b-0 border-r-0">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<a id="fw-workbench-formula-spawn"></a>
|
||||
|
||||
|
||||
<div class="border border-t-0 border-l-0 border-r-0">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="border border-t-0 border-l-0 border-b-0 p-xs mobile-hide">
|
||||
<p class="t-size-14"><i class="fad fa-grip-vertical"></i></p>
|
||||
</td>
|
||||
<td class="w-full">
|
||||
<p class="p-xxs t-w-600 t-center border border-t-0 border-l-0 border-r-0 fw-workbench-name">${formula.graph}</p>
|
||||
<div class="fw-formula-io">
|
||||
<div class="w-formula-graphing p-xxs">
|
||||
<p class="t-w-500 t-italic">Inputs:</p>
|
||||
|
||||
<div class="border r-s d-inline-block bkgd-surround my-xs ml-xs">
|
||||
<label for="test-123" class="mx-xs t-center">Style</label>
|
||||
<input id="test-123" type="text" class="p-mxs rr-s border border-t-0 border-b-0 border-r-0">
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="border r-s d-inline-block bkgd-surround my-xs ml-xs">
|
||||
<label for="test-123" class="mx-xs t-center">X/Y/Z-Axis (From context or calculated)</label>
|
||||
<input id="test-123" type="text" class="p-mxs rr-s border border-t-0 border-b-0 border-r-0">
|
||||
</div>
|
||||
|
||||
<!-- ON/OFF -> Add extra ranges as sliders, or refuse to proceed -->
|
||||
|
||||
<!-- Highlights, limits, extra styles, ... -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="p-xxs">
|
||||
<p class="t-center t-muted t-size-8">Selected formulas will appear here, all seems good.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
echo(getMainHeader(localize("tool.formula-wizard.categories"), null, "<span id='fw-catalog-formula-count'></span>", null,
|
||||
true, "bkgd-math", 3, false, false, true));
|
||||
?>
|
||||
|
||||
<!-- Template used for every formula -->
|
||||
<template id="template-formula-available">
|
||||
<div class="border border-b-0 border-l-0 border-r-0 p-xxs px-s">
|
||||
<p class="t-w-500 t-italic t-underline">${formula.name}</p>
|
||||
<div class="fw-variants">
|
||||
${formula.variants}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Template used for every formula variant -->
|
||||
<template id="template-formula-available-variant">
|
||||
<button class="t-size-15 primary p-xxs border r-m">
|
||||
${formula.variant.mathml}
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<div class="m-s mt-xs">
|
||||
<details class="border rt-s bkgd-grid" id="fw-catalog-category-electricity" open>
|
||||
<summary class="t-w-600 p-xs"><i class="fad fa-bolt mr-xs"></i><?php echo(localize("tool.formula-wizard.categories.electricity")); ?></summary>
|
||||
</details>
|
||||
<details class="border border-t-0 bkgd-grid p-xs" id="fw-catalog-category-converter">
|
||||
<summary class="t-w-600"><i class="fad fa-sync-alt mr-xs"></i><?php echo(localize("tool.formula-wizard.categories.convert")); ?></summary>
|
||||
</details>
|
||||
<details class="border border-t-0 bkgd-grid p-xs" id="fw-catalog-category-physics">
|
||||
<summary class="t-w-600"><i class="fad fa-apple-alt mr-xs"></i></i><?php echo(localize("tool.formula-wizard.categories.physics")); ?></summary>
|
||||
</details>
|
||||
<details class="border border-t-0 bkgd-grid p-xs" id="fw-catalog-category-chemistry">
|
||||
<summary class="t-w-600"><i class="fad fa-flask mr-xs"></i><?php echo(localize("tool.formula-wizard.categories.chemistry")); ?></summary>
|
||||
</details>
|
||||
<details class="border border-t-0 bkgd-grid p-xs" id="fw-catalog-category-radioactivity">
|
||||
<summary class="t-w-600"><i class="fad fa-radiation mr-xs"></i><?php echo(localize("tool.formula-wizard.categories.radioactivity")); ?></summary>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
echo(getMainHeader(localize("tool.formula-wizard.source"), null, null, null,
|
||||
true, "bkgd-math", 3, false, false, true));
|
||||
?>
|
||||
|
||||
<div id="formula-wizard.test"></div>
|
21
tools/items/formula-wizard/styles.css
Normal file
21
tools/items/formula-wizard/styles.css
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
/* https://cssflex-generator.netlify.app/ */
|
||||
|
||||
.fw-variants {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.fw-variants div, .fw-variants button {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.fw-workbench-name {
|
||||
border-bottom: 1px solid;
|
||||
}
|
18
tools/items/formula-wizard/super-minifier.json
Normal file
18
tools/items/formula-wizard/super-minifier.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"files": [
|
||||
"code.min.js"
|
||||
],
|
||||
"properties": [
|
||||
"WATT",
|
||||
"VOLT",
|
||||
"AMPERE",
|
||||
"OHM",
|
||||
"METER",
|
||||
"INCH",
|
||||
"POUND",
|
||||
"symbol",
|
||||
"symbol",
|
||||
"symbol",
|
||||
"symbol"
|
||||
]
|
||||
}
|
@@ -4,6 +4,22 @@
|
||||
"code": [
|
||||
"svg-to-png/code.min.js"
|
||||
],
|
||||
"styles": [],
|
||||
"module": [],
|
||||
"icon": "fad fa-exchange-alt",
|
||||
"title": "tool.svg-to-png.title"
|
||||
"title": "tool.svg-to-png.title",
|
||||
"opengraph": {
|
||||
"title": {
|
||||
"en": "SVG to PNG Converter",
|
||||
"fr": "Convertisseur SVG vers PNG"
|
||||
},
|
||||
"description": {
|
||||
"en": "TODO: Description",
|
||||
"fr": "TODO: Description"
|
||||
},
|
||||
"type": "website",
|
||||
"url": "https://nibblepoker.lu/tools/svg-to-png",
|
||||
"image": "/resources/NibblePoker/images/placeholder.png",
|
||||
"image_type": "image/png"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user