Started segmenting formula wizard, Prepared for PHP minifaction

Update .gitignore, .htaccess, and 38 more files...
This commit is contained in:
2023-08-13 18:28:05 +02:00
parent 2dd262fe2c
commit fc37c5926f
40 changed files with 174911 additions and 30 deletions

3
.gitignore vendored
View File

@@ -20,6 +20,9 @@ resources/NibblePoker/js/*.min.js
*.exe
*.url
# Compiled Stuff
*.min.php
# Others
*.pdn
*.min.json

View File

@@ -27,6 +27,9 @@ AddType text/javascript .mjs
Options -Indexes +FollowSymlinks -ExecCGI
ServerSignature Off
# Helping out with minified pages and/or pre-rendered ones first if available
DirectoryIndex index.min.html index.min.php index.html index.php
# Custom error pages.
ErrorDocument 403 /error.php
ErrorDocument 404 /error.php
@@ -43,7 +46,7 @@ ErrorDocument 404 /error.php
# Static files: 1 Week
Header set Cache-Control "max-age=604800, public, must-revalidate"
</FilesMatch>
##<FilesMatch "\.(?i:css|js)$">
##<FilesMatch "\.(?i:css|js|mjs)$">
## # Semi-static files: 1 Day
## Header set Cache-Control "max-age=86400, public, must-revalidate"
##</FilesMatch>
@@ -56,7 +59,7 @@ ErrorDocument 404 /error.php
<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$
mod_gzip_item_include file \.(html?|txt|css|js|mjs|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +1,27 @@
@echo off
:: Going into the script's directory
cd /D "%~dp0"
:compile-lang
:lang
echo.
echo Handling the languages
echo ----------------------
:lang-compile
echo Compiling lang files...
python commons/strings/compile.py
:compile-sass
:lang-end
:sass
echo.
echo Handling the SASS files
echo -----------------------
:sass-compile
echo Compiling SASS files...
pushd %CD%
cd %~dp0\resources\NibblePoker\scss\
@@ -14,6 +29,86 @@ call "%~dp0node_modules\.bin\sass" nibblepoker.scss:../css/nibblepoker.css -q
call "%~dp0node_modules\.bin\sass" nibblepoker.scss:../css/nibblepoker.min.css -q --style compressed
popd
:sass-end
:libs
echo.
echo Handling the external libraries
echo -------------------------------
:libs-decimaljs-minify
echo Minifying Decimal.JS
pushd %CD%
cd %~dp0\resources\DecimalJs\10.4.3\
echo ^> resources\DecimalJs\10.4.3\decimal.mjs
call "%~dp0node_modules\.bin\terser" decimal.mjs -c -m --toplevel -o decimal.min.mjs
cd %~dp0\resources\DecimalJsLight\2.5.1\
echo ^> resources\DecimalJsLight\2.5.1\decimal.mjs
call "%~dp0node_modules\.bin\terser" decimal.mjs -c -m --toplevel -o decimal.min.mjs
popd
:libs-end
:: THE FW min files don't poitn to the proper JS file !!!!
:formula-wizard
echo.
echo Handling the 'Formula Wizard'
echo -----------------------------
:formula-wizard-compile
echo Compiling TypeScript...
pushd %CD%
cd %~dp0\tools\items\formula-wizard\src\
call "%~dp0node_modules\.bin\tsc"
popd
:formula-wizard-fix-imports
echo Fixing imports...
pushd %CD%
cd %~dp0\tools\items\formula-wizard\src\
call node "%~dp0fix-import-path.js" "formulas.js;lang.js;main.js;units.js;ui_catalog.js;mvc_context.js;sets.js" "decimal" "decimal.min.mjs"
call node "%~dp0fix-import-path.js" "formulas.js;lang.js;main.js;units.js;ui_catalog.js;mvc_context.js;sets.js" "lang" "lang.js"
call node "%~dp0fix-import-path.js" "formulas.js;lang.js;main.js;units.js;ui_catalog.js;mvc_context.js;sets.js" "formulas" "formulas.js"
call node "%~dp0fix-import-path.js" "formulas.js;lang.js;main.js;units.js;ui_catalog.js;mvc_context.js;sets.js" "units" "units.js"
call node "%~dp0fix-import-path.js" "formulas.js;lang.js;main.js;units.js;ui_catalog.js;mvc_context.js;sets.js" "ui_catalog" "ui_catalog.js"
call node "%~dp0fix-import-path.js" "formulas.js;lang.js;main.js;units.js;ui_catalog.js;mvc_context.js;sets.js" "mvc_context" "mvc_context.js"
call node "%~dp0fix-import-path.js" "formulas.js;lang.js;main.js;units.js;ui_catalog.js;mvc_context.js;sets.js" "sets" "sets.js"
popd
:formula-wizard-bundle
echo Making the bundle...
pushd %CD%
cd %~dp0\tools\items\formula-wizard\src\
call "%~dp0node_modules\.bin\rollup" main.js --format cjs --sourcemap --file formula-wizard.js
popd
:formula-wizard-minify
echo Minifying the files...
pushd %CD%
cd %~dp0\tools\items\formula-wizard\src\
call "%~dp0node_modules\.bin\terser" main.js -c -m --toplevel -o main.min.js
call "%~dp0node_modules\.bin\terser" lang.js -c -m --toplevel -o lang.min.js
call "%~dp0node_modules\.bin\terser" formulas.js -c -m --toplevel -o formulas.min.js
call "%~dp0node_modules\.bin\terser" units.js -c -m --toplevel -o units.min.js
call "%~dp0node_modules\.bin\terser" formula-wizard.js -c -m --toplevel -o formula-wizard.min.js
:: We also minify the .php file to help with some weird spacing issues that cannot be fixed with CSS.
:: This issue is usually handled by the reverse-proxy or a middleware, but since I need to export a SPA, I can't rely
:: on it
cd ..
call "%~dp0node_modules\.bin\html-minifier-terser" --conservative-collapse --collapse-inline-tag-whitespace --collapse-whitespace --remove-comments --decode-entities -o page.min.php page.php
popd
:formula-wizard-end
goto end
:compile-typescript
echo Compiling TypeScript for ".js" files...
call .\node_modules\.bin\tsc
@@ -26,6 +121,8 @@ node .\fix-import-path.js "tools/items/formula-wizard/code.js" "decimal" "decima
echo Minifying JS manually...
pushd %CD%
:: rollup, maybe
cd %~dp0\resources\DecimalJs\10.4.3\
echo ^> resources\DecimalJs\10.4.3\decimal.mjs
call "%~dp0node_modules\.bin\terser" decimal.mjs -c -m --toplevel -o decimal.min.mjs
@@ -46,3 +143,5 @@ echo ^> tools\items\b64-tools\code.js
call "%~dp0node_modules\.bin\terser" code.js -c --module --ecma 2017 --mangle -o code.min.js
popd
:end

View File

@@ -13,7 +13,7 @@ const inputFile = process.argv[2];
const inputImportName = process.argv[3];
const inputReplacement = process.argv[4];
let filesToProcess = [inputFile];
let filesToProcess = inputFile.split(";");
// Fixing the files

View File

@@ -1 +1 @@
const fs=require("fs"),path=require("path"),inputFile=(5!==process.argv.length&&(console.error("!> Invalid syntax !"),console.error("Use: node fix-import-path.js <input_file> <import_name> <replacement_file>"),process.exit(1)),process.argv[2]),inputImportName=process.argv[3],inputReplacement=process.argv[4];let filesToProcess=[inputFile];for(const a of filesToProcess){console.log("> Replacing '"+inputImportName+"' with '"+inputReplacement+"' in '"+a+"' ...");const b=fs.readFileSync(a).toString().split("\n"),c=(null==b&&(console.error("!> Failed to read lines !"),process.exit(2)),[]);for(let e of b)e.startsWith("import")&&e.includes("from")&&((e=e.split(/['"]+/))[e.length-2]=e[e.length-2].replace(inputImportName,inputReplacement),e=e.join('"')),c.push(e);try{fs.unlinkSync(a),fs.writeFileSync(a,c.join("\n"),"utf8")}catch(e){console.error(e)}}
const fs=require("fs"),path=require("path"),inputFile=(5!==process.argv.length&&(console.error("!> Invalid syntax !"),console.error("Use: node fix-import-path.js <input_file> <import_name> <replacement_file>"),process.exit(1)),process.argv[2]),inputImportName=process.argv[3],inputReplacement=process.argv[4];let filesToProcess=inputFile.split(";");for(const a of filesToProcess){console.log("> Replacing '"+inputImportName+"' with '"+inputReplacement+"' in '"+a+"' ...");const b=fs.readFileSync(a).toString().split("\n"),c=(null==b&&(console.error("!> Failed to read lines !"),process.exit(2)),[]);for(let e of b)e.startsWith("import")&&e.includes("from")&&((e=e.split(/['"]+/))[e.length-2]=e[e.length-2].replace(inputImportName,inputReplacement),e=e.join('"')),c.push(e);try{fs.unlinkSync(a),fs.writeFileSync(a,c.join("\n"),"utf8")}catch(e){console.error(e)}}

View File

@@ -1,9 +1,10 @@
{
"devDependencies": {
"minify": "^10.2.0",
"rollup": "^3.26.2",
"rollup": "^3.27.2",
"sass": "^1.63.6",
"terser": "^5.19.0",
"typescript": "^5.1.6"
"typescript": "^5.1.6",
"html-minifier-terser": "^7.2.0"
}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -23,7 +23,7 @@
"en": "TODO: Description",
"fr": "TODO: Description"
},
"_image": "",
"image": "/resources/NibblePoker/images/content/formula-wizard/v1.png",
"tags": ["converter"],
"priority": 200
},

View File

@@ -1,9 +1,9 @@
{
"dom": "formula-wizard/page.php",
"dom": "formula-wizard/page.min.php",
"lang": "formula-wizard/lang.json",
"code": [],
"module": [
"formula-wizard/code.min.js"
"formula-wizard/src/main.js"
],
"styles": [
"formula-wizard/styles.css"

View File

@@ -833,6 +833,9 @@ eContextAddButton.onclick = function () {
function getRee() {
}
class NumberProlapsingMachine {
static createNewFromUi(formulaVariant) {
return null;
}
}
if (new URLSearchParams(window.location.search).has("debug")) {
console.debug("Preparing debugging tools...");

View File

@@ -1285,7 +1285,15 @@ function getRee() {
// -----------------------------------------------------------------------------------------------------------------
class NumberProlapsingMachine {
// uiContextComponents: ContextComponentUiElement[]
// uiWorkbenchFormulas: WorkbenchFormulaUiElement[]
public static createNewFromUi(formulaVariant: FormulaVariant): NumberProlapsingMachine {
return null!;
}
}
// -----------

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,150 @@
import { localize } from "./lang.js";
import { scaleFactors, units, scaleToBase, scaleFromBase } from "./units.js";
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];
}
}
export 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);
}
}
export 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);
}
}
export 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")),
};
let areFormulasInitialized = false;
export function initFormulas() {
if (!areFormulasInitialized) {
console.debug("Initializing formulas...");
Object.keys(formulas).forEach(formulaKey => {
formulas[formulaKey].variants.forEach(formulaVariant => {
formulaVariant.parentFormula = formulas[formulaKey];
});
});
areFormulasInitialized = true;
}
}
//# sourceMappingURL=formulas.js.map

View File

@@ -0,0 +1 @@
import{localize as t}from"./lang.js";import{scaleFactors as e,units as a,scaleToBase as l,scaleFromBase as u}from"./units.js";class r{constructor(t){this.contextValueIndex=t}getContextValue(e){if(e.length<=this.contextValueIndex)throw alert(t("error.formulaContext.tooSmall")),new Error(t("error.formulaContext.tooSmall"));return e[this.contextValueIndex]}}export class FormulaValue{constructor(t,e){this.unit=t,this.scaleFactor=e,this.parentFormula=null,this.valueSource=null}getFormulaValue(e){if(null===this.parentFormula)throw alert(t("error.formulaValue.noParent")),new Error(t("error.formulaValue.noParent"));if(null===this.valueSource)throw alert(t("error.formulaValue.noSource")),new Error(t("error.formulaValue.noSource"));return this.valueSource instanceof r?this.valueSource.getContextValue(e):u(l(this.valueSource.getVariantValue(this.parentFormula,e),this.valueSource.getOutputValueDefinition().scaleFactor),this.scaleFactor)}}export class Formula{constructor(e,a,l,u,r){this.values=e,this.variants=a,this.formulaKey=l,this.name=t("formula."+l+".name"),this.description=t("formula."+l+".desc"),this.categories=u,this.wikiLink=r,this.values.forEach((t=>{t.parentFormula=this}))}getClone(){const t=[];return this.values.forEach((e=>{t.push(new FormulaValue(e.unit,e.scaleFactor))})),new Formula(t,this.variants,this.formulaKey,this.categories,this.wikiLink)}}export const formulas={OHM_LAW:new Formula([new FormulaValue(a.OHM,e.SI_BASE),new FormulaValue(a.AMPERE,e.SI_BASE),new FormulaValue(a.VOLT,e.SI_BASE)],[new class{constructor(){this.description="V=I*R",this.getVariantValue=(t,e)=>t.values[0].getFormulaValue(e).times(t.values[1].getFormulaValue(e)),this.getInputValuesDefinition=()=>[this.parentFormula.values[0],this.parentFormula.values[1]],this.getOutputValueDefinition=()=>this.parentFormula.values[2],this.getMathMl=t=>"<math><mi>"+t.values[2].unit.symbol+"</mi><mo>=</mo><mi>"+t.values[0].unit.symbol+"</mi><mo>*</mo><mi>"+t.values[1].unit.symbol+"</mi></math>",this.parentFormula=null}},new class{constructor(){this.description="I=V/R",this.getVariantValue=(t,e)=>t.values[2].getFormulaValue(e).dividedBy(t.values[0].getFormulaValue(e)),this.getInputValuesDefinition=()=>[this.parentFormula.values[0],this.parentFormula.values[2]],this.getOutputValueDefinition=()=>this.parentFormula.values[1],this.getMathMl=t=>"<math><mi>"+t.values[1].unit.symbol+"</mi><mo>=</mo><mfrac><mi>"+t.values[2].unit.symbol+"</mi><mi>"+t.values[0].unit.symbol+"</mi></mfrac></math>",this.parentFormula=null}},new class{constructor(){this.description="R=V/I",this.getVariantValue=(t,e)=>t.values[2].getFormulaValue(e).dividedBy(t.values[1].getFormulaValue(e)),this.getInputValuesDefinition=()=>[this.parentFormula.values[2],this.parentFormula.values[1]],this.getOutputValueDefinition=()=>this.parentFormula.values[0],this.getMathMl=t=>"<math><mi>"+t.values[0].unit.symbol+"</mi><mo>=</mo><mfrac><mi>"+t.values[2].unit.symbol+"</mi><mi>"+t.values[1].unit.symbol+"</mi></mfrac></math>",this.parentFormula=null}}],"ohm_law",["electricity"],new URL("https://wikipedia.org/wiki/Ohm's_law"))};let i=!1;export function initFormulas(){i||(console.debug("Initializing formulas..."),Object.keys(formulas).forEach((t=>{formulas[t].variants.forEach((e=>{e.parentFormula=formulas[t]}))})),i=!0)}

View File

@@ -0,0 +1,248 @@
// ==- Basic Info -================================
// Name: Formula Wizard - Formulas
// File: tools/items/formula-wizard/src/formulas.ts
// Version: N/A
// Author: Herwin Bozet
//
// ==- Requirements -==============================
// DecimalJS: https://github.com/MikeMcl/decimal.js/ (MIT)
//
// ==- Links & License -===========================
// License: Unlicense
// GitHub: https://github.com/aziascreations/Web-NibblePoker
// -----------------
// Units > Imports
// -----------------
import {Decimal} from '../../../../resources/DecimalJs/10.4.3/decimal';
import {localize} from "./lang";
import {Unit, UnitScale, UnitScaleFactor, scaleFactors, units, scaleToBase, scaleFromBase} from "./units";
// ----------------
// ???
// ----------------
type FormulaContext = Decimal[];
class FormulaContextHandler {
contextValueIndex: number;
constructor(contextValueIndex: number) {
this.contextValueIndex = contextValueIndex
}
getContextValue(context: FormulaContext): Decimal {
if(context.length <= this.contextValueIndex) {
alert(localize("error.formulaContext.tooSmall"));
throw new Error(localize("error.formulaContext.tooSmall"));
}
return context[this.contextValueIndex];
}
}
export class FormulaValue {
unit: Unit;
scaleFactor: UnitScaleFactor;
// Set when preparing the final formula chain
parentFormula: Formula | null;
valueSource: FormulaVariant | FormulaContextHandler | null; // TODO: Add context fetcher
constructor(unit: Unit, scaleFactor: UnitScaleFactor) {
this.unit = unit;
this.scaleFactor = scaleFactor;
this.parentFormula = null;
this.valueSource = null;
}
getFormulaValue(context: FormulaContext): Decimal {
// Should be set when preparing the formula chain for calculations
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);
}
// We can safely assume that "this.valueSource" is an instance of "FormulaVariant".
return scaleFromBase(
scaleToBase(
this.valueSource.getVariantValue(this.parentFormula, context),
this.valueSource.getOutputValueDefinition().scaleFactor
),
this.scaleFactor
);
}
}
export class Formula {
values: FormulaValue[];
variants: FormulaVariant[];
name: string;
description: string;
formulaKey: string
categories: string[];
wikiLink: URL;
constructor(values: FormulaValue[], variants: FormulaVariant[], formulaKey: string, categories: string[],
wikiLink: URL) {
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;
// Adding references to "Formula" in each "FormulaValue"
this.values.forEach(value => {
value.parentFormula = this;
})
}
getClone(): Formula {
// Making a semi-deep clone of the "Formula" itself and its "FormulaValues".
// We can keep the "FormulaVariant" identical since they only contain static code.
// We couldn't use "structuredClone" since the "Unit" class were getting cloned and couldn't be.
const clonedFormulaValues: FormulaValue[] = [];
this.values.forEach(originalValue => {
clonedFormulaValues.push(
new FormulaValue(
originalValue.unit,
originalValue.scaleFactor,
)
);
});
return new Formula(
clonedFormulaValues,
this.variants,
this.formulaKey,
this.categories,
this.wikiLink,
);
}
}
export interface FormulaVariant {
// TODO: Use HTML5 math formula tags
//id: string
description: string
getVariantValue: (formula: Formula, context: FormulaContext) => Decimal;
getInputValuesDefinition: () => FormulaValue[];
getOutputValueDefinition: () => FormulaValue;
getMathMl: (formula: Formula) => string;
parentFormula: Formula; // Set to null when instantiating, set to proper parent right after.
}
export const formulas: { [key: string]: Formula } = {
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 implements FormulaVariant {
description = "V=I*R";
getVariantValue = (formula: Formula, context: FormulaContext): Decimal => {
// V = I * R <=> [2] = [0] * [1]
return formula.values[0].getFormulaValue(context).times(formula.values[1].getFormulaValue(context));
};
getInputValuesDefinition = (): FormulaValue[] => {
return [this.parentFormula.values[0], this.parentFormula.values[1]];
};
getOutputValueDefinition = (): FormulaValue => {
return this.parentFormula.values[2];
};
getMathMl = (formula: Formula): string => {
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>";
}
parentFormula = (null! as Formula);
},
new class implements FormulaVariant {
description = "I=V/R";
getVariantValue = (formula: Formula, context: FormulaContext): Decimal => {
// I = V / R <=> [1] = [2] / [0]
return formula.values[2].getFormulaValue(context).dividedBy(formula.values[0].getFormulaValue(context));
};
getInputValuesDefinition = (): FormulaValue[] => {
return [this.parentFormula.values[0], this.parentFormula.values[2]];
};
getOutputValueDefinition = (): FormulaValue => {
return this.parentFormula.values[1];
};
getMathMl = (formula: Formula): string => {
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>";
};
parentFormula = (null! as Formula);
},
new class implements FormulaVariant {
description = "R=V/I";
getVariantValue = (formula: Formula, context: FormulaContext): Decimal => {
// R = V / I <=> [0] = [2] / [1]
return formula.values[2].getFormulaValue(context).dividedBy(formula.values[1].getFormulaValue(context));
};
getInputValuesDefinition = (): FormulaValue[] => {
return [this.parentFormula.values[2], this.parentFormula.values[1]];
};
getOutputValueDefinition = (): FormulaValue => {
return this.parentFormula.values[0];
};
getMathMl = (formula: Formula): string => {
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>";
};
parentFormula = (null! as Formula);
},
],
"ohm_law",
["electricity"],
new URL("https://wikipedia.org/wiki/Ohm's_law")
),
}
// ---------------------------
// ??? > On-Import Handler
// ---------------------------
let areFormulasInitialized = false;
export function initFormulas() {
if (!areFormulasInitialized) {
console.debug("Initializing formulas...");
// Fixing the `parentFormula` property in every formula variant.
Object.keys(formulas).forEach(formulaKey => {
formulas[formulaKey].variants.forEach(formulaVariant => {
formulaVariant.parentFormula = formulas[formulaKey];
});
});
areFormulasInitialized = true;
}
}

View File

@@ -0,0 +1,57 @@
export 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",
}
};
export 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);
}
//# sourceMappingURL=lang.js.map

View File

@@ -0,0 +1 @@
export const langKey=document.documentElement.lang.match("(en|fr)")?document.documentElement.lang:"en";const e={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"}};export function localize(t){let a=langKey in e?e[langKey]:e.en;return t in a?a[t]:t in e.en?e.en[t]:t}

View File

@@ -0,0 +1,75 @@
// TODO: Move into a common lib with parameter support !
export 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": "???",
// "error.ui.context.component.missingElement"
// "error.ui.context.component.cannotGetElement"
},
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",
}
}
/**
* Localizes a given `stringKey` into it's associated localized string.
* @param stringKey - ???.
*/
export 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
);
}

View File

@@ -0,0 +1,25 @@
/*!
* Formula Wizard v0.0.2
* [Short desc here]
* https://github.com/aziascreations/Web-NibblePoker
* Copyright (c) 2023 Herwin Bozet <herwin.bozet@gmail.com>
* Unlicense Licence
*/
const version = [0, 0, 2];
console.log("Initializing 'Formula Wizard v" + version.join(".") + "'...");
const startTime = new Date().getMilliseconds();
import { Decimal } from "../../../../resources/DecimalJs/10.4.3/decimal.min.mjs";
import { localize } from "./lang.js";
import { units, initUnits } from "./units.js";
import { formulas, initFormulas } from "./formulas.js";
import { initCatalog } from "./ui_catalog.js";
import { setupWorkbenchContext } from "./mvc_context.js";
Decimal.set({ precision: 25, rounding: 8 });
initUnits();
initFormulas();
initCatalog();
setupWorkbenchContext();
console.log(localize("joe.mama"));
console.log(units);
console.log(formulas);
//# sourceMappingURL=main.js.map

View File

@@ -0,0 +1,8 @@
/*!
* Formula Wizard v0.0.2
* [Short desc here]
* https://github.com/aziascreations/Web-NibblePoker
* Copyright (c) 2023 Herwin Bozet <herwin.bozet@gmail.com>
* Unlicense Licence
*/
console.log("Initializing 'Formula Wizard v"+[0,0,2].join(".")+"'...");(new Date).getMilliseconds();import{Decimal as o}from"../../../../resources/DecimalJs/10.4.3/decimal.min.mjs";import{localize as i}from"./lang.js";import{units as m,initUnits as r}from"./units.js";import{formulas as s,initFormulas as l}from"./formulas.js";import{initCatalog as e}from"./ui_catalog.js";import{setupWorkbenchContext as n}from"./mvc_context.js";o.set({precision:25,rounding:8}),r(),l(),e(),n(),console.log(i("joe.mama")),console.log(m),console.log(s);

View File

@@ -0,0 +1,35 @@
/*!
* Formula Wizard v0.0.2
* [Short desc here]
* https://github.com/aziascreations/Web-NibblePoker
* Copyright (c) 2023 Herwin Bozet <herwin.bozet@gmail.com>
* Unlicense Licence
*/
// Preparing some things before the import statements.
const version = [0, 0, 2];
console.log("Initializing 'Formula Wizard v" + version.join(".") + "'...");
const startTime = new Date().getMilliseconds();
// Importing stuff
import {Decimal} from '../../../../resources/DecimalJs/10.4.3/decimal';
import {localize} from "./lang";
import {units, initUnits} from "./units";
import {formulas, initFormulas} from "./formulas";
import {initCatalog} from "./ui_catalog";
import {setupWorkbenchContext} from "./mvc_context"
// Configuring the Decimal.JS library to use its maximum potential precision.
Decimal.set({ precision: 25, rounding: 8 });
// Setting up non-primary things
initUnits();
initFormulas();
initCatalog();
setupWorkbenchContext();
// Tests
console.log(localize("joe.mama"));
console.log(units);
console.log(formulas);

View File

@@ -0,0 +1,124 @@
/*!
* Formula Wizard v0.0.2
* [Short desc here]
* https://github.com/aziascreations/Web-NibblePoker
* Copyright (c) 2023 Herwin Bozet <herwin.bozet@gmail.com>
* Unlicense Licence
*/
import { localize } from "./lang.js";
import { units, scaleFactors } from "./units.js";
import { sets } from "./sets.js";
class ContextType {
constructor(name, description) {
this.name = name;
this.description = description;
}
}
export 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")),
};
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";
class WorkbenchContextComponentData {
}
class WorkbenchContextComponentInterface {
}
export class WorkbenchContextComponent {
constructor(uiElement, data) {
this.uiElement = uiElement;
this.data = data;
}
static createNew(eRootElement) {
return null;
}
toJson() {
return JSON.stringify(this.data);
}
fromJson() {
return false;
}
}
export let workbenchContextComponents = [];
let eTemplateContextComponent = null;
let eContextStatusMessage = null;
let eContextAddButton = null;
let isWorkbenchContextSetup = false;
export function setupWorkbenchContext() {
if (!isWorkbenchContextSetup) {
console.debug("Preparing UI for workbench context components...");
eTemplateContextComponent = document.getElementById("template-context-component");
if (eTemplateContextComponent === null) {
alert(localize("error.ui.context.noTemplate"));
throw Error(localize("error.ui.context.noTemplate"));
}
eTemplateContextComponent = eTemplateContextComponent.cloneNode(true).content;
document.getElementById("template-context-component").remove();
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(localize("error.ui.context.noSets"));
throw Error(localize("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);
});
eContextStatusMessage = document.getElementById("fw-text-context-middle");
if (eContextStatusMessage === null) {
alert(localize("error.ui.context.noStatus"));
throw Error(localize("error.ui.context.noStatus"));
}
eContextAddButton = document.querySelector("button#fw-button-add-context");
if (eContextAddButton === null) {
alert(localize("error.ui.context.missingButton"));
throw Error(localize("error.ui.context.missingButton"));
}
eContextAddButton.onclick = function () {
const eNewContextComponent = eTemplateContextComponent.cloneNode(true).firstElementChild;
if (eNewContextComponent === null) {
alert(localize("error.ui.context.component.cannotGetElement"));
throw Error(localize("error.ui.context.component.cannotGetElement"));
}
const newContextComponent = WorkbenchContextComponent.createNew(eNewContextComponent);
workbenchContextComponents.push(newContextComponent);
};
isWorkbenchContextSetup = true;
}
}
//# sourceMappingURL=mvc_context.js.map

View File

@@ -0,0 +1,187 @@
/*!
* Formula Wizard v0.0.2
* [Short desc here]
* https://github.com/aziascreations/Web-NibblePoker
* Copyright (c) 2023 Herwin Bozet <herwin.bozet@gmail.com>
* Unlicense Licence
*/
import {localize} from "./lang";
import {units, scaleFactors} from "./units";
import {sets} from "./sets";
// ----------------
// ???
// ----------------
class ContextType {
name: string;
description: string;
constructor(name: string, description: string) {
this.name = name;
this.description = description;
}
}
export const contextTypes: { [key: string]: ContextType } = {
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")),
}
// ----------------
// ???
// ----------------
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";
class WorkbenchContextComponentData {
//id: string;
}
class WorkbenchContextComponentInterface {
}
export class WorkbenchContextComponent {
uiElement: WorkbenchContextComponentInterface;
data: WorkbenchContextComponentData;
constructor(uiElement: WorkbenchContextComponentInterface, data: WorkbenchContextComponentData) {
this.uiElement = uiElement;
this.data = data;
}
public static createNew(eRootElement: HTMLElement): WorkbenchContextComponent {
// formulaVariant: FormulaVariant
return null!;
}
toJson(): string {
return JSON.stringify(this.data);
}
fromJson(): boolean {
return false;
}
}
// ----------------
// ???
// ----------------
export let workbenchContextComponents: WorkbenchContextComponent[] = [];
//
let eTemplateContextComponent: HTMLElement | DocumentFragment | null = null;
let eContextStatusMessage = null;
// Preparing the context components buttons.
// Those are simply used to add and debug context components.
let eContextAddButton: HTMLButtonElement | null = null;
let isWorkbenchContextSetup = false;
export function setupWorkbenchContext() {
if (!isWorkbenchContextSetup) {
console.debug("Preparing UI for workbench context components...");
eTemplateContextComponent = document.getElementById("template-context-component");
if(eTemplateContextComponent === null) {
alert(localize("error.ui.context.noTemplate"));
throw Error(localize("error.ui.context.noTemplate"));
}
// Cloning and deleting from DOM.
eTemplateContextComponent = (eTemplateContextComponent.cloneNode(true) as HTMLTemplateElement).content;
document.getElementById("template-context-component")!.remove();
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(localize("error.ui.context.noSets"));
throw Error(localize("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);
});
eContextStatusMessage = document.getElementById("fw-text-context-middle");
if(eContextStatusMessage === null) {
alert(localize("error.ui.context.noStatus"));
throw Error(localize("error.ui.context.noStatus"));
}
eContextAddButton = document.querySelector("button#fw-button-add-context");
if(eContextAddButton === null) {
alert(localize("error.ui.context.missingButton"));
throw Error(localize("error.ui.context.missingButton"));
}
eContextAddButton.onclick = function() {
// We only get the fragment via the template, we have to use this monstrosity to get a proper element out of it.
const eNewContextComponent=
(eTemplateContextComponent!.cloneNode(true) as DocumentFragment).firstElementChild as HTMLElement;
if(eNewContextComponent === null) {
alert(localize("error.ui.context.component.cannotGetElement"));
throw Error(localize("error.ui.context.component.cannotGetElement"));
}
const newContextComponent = WorkbenchContextComponent.createNew(
eNewContextComponent
);
workbenchContextComponents.push(newContextComponent);
//eContextStatusMessage!.parentNode!.insertBefore(newContextComponent.uiElement, eContextStatusMessage);
//eContextStatusMessage!.hidden = true;
////eContextStatusMessage!.parentNode!.insertBefore(newContextComponent.rootElement, eContextStatusMessage);
////eContextStatusMessage!.hidden = true;
}
isWorkbenchContextSetup = true;
}
}

View File

@@ -0,0 +1,18 @@
/*!
* Formula Wizard - v0.0.2
* [Short desc here]
* https://github.com/aziascreations/Web-NibblePoker
* Copyright (c) 2023 Herwin Bozet <herwin.bozet@gmail.com>
* Unlicense Licence
*/
// -----------------------------------------------------------------------------------------------------------------
// The "Nobody could give me a synonym for a math nerd/number cruncher to serve as a pun" mechanism.
// -----------------------------------------------------------------------------------------------------------------
// You can all go eat a bag of dicks with your
// "muh, I cAn'T GiVE yoU AnYtHinG That remOtEly rEsEmBlEs a PejOraTiVE Term, eveN In A friEndLY/jOkey cONteXT".
// I'll just call it the "NumberProlapsingMachine" then...
// Fuck you all and your tumblr-esque PC brain-rot.
// -----------------------------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,41 @@
import { Decimal } from "../../../../resources/DecimalJs/10.4.3/decimal.min.mjs";
import { localize } from "./lang.js";
import { units, scaleFactors } from "./units.js";
export 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];
export 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),
};
//# sourceMappingURL=sets.js.map

View File

@@ -0,0 +1,138 @@
/*
* Formula Wizard v0.0.2
* [Short desc here]
* https://github.com/aziascreations/Web-NibblePoker
* Copyright (c) 2023 Herwin Bozet <herwin.bozet@gmail.com>
* Unlicense Licence
*/
import {Decimal} from '../../../../resources/DecimalJs/10.4.3/decimal';
import {localize} from "./lang";
import {Unit, UnitScaleFactor, units, scaleFactors} from "./units";
// -----------
// Data Sets
// -----------
export class DataSet {
name: string;
description: string;
protected values: Decimal[];
unit: Unit;
scaleFactor: UnitScaleFactor;
constructor(name: string, description: string, values: Decimal[], unit: Unit, scaleFactor: UnitScaleFactor) {
this.name = name;
this.description = description;
this.values = values;
this.unit = unit;
this.scaleFactor = scaleFactor;
if(unit.scale != scaleFactor.scale) {
alert("");
throw Error("");
}
}
getDataSet(): Decimal[] {
return this.values;
}
}
// This "technically" worked, but the values we """slightly""" off...
/*class ResistorIecDataSet extends DataSet {
private stepCount: number;
constructor(name: string, description: string, stepCount: number) {
super(name, description, [], units.OHM, scaleFactors.SI_BASE);
this.stepCount = stepCount;
// Calculating the values according to "IEC 60063:1963".
// See: https://eepower.com/resistor-guide/resistor-standards-and-codes/resistor-values/
for(let iLogMult = -1; iLogMult < 2; iLogMult++) {
for(let iStep = 1; iStep < this.stepCount; iStep++) {
this.values.push(
(new Decimal(10).pow(iLogMult)).pow(new Decimal(iStep).dividedBy(stepCount))
)
}
}
}
}*/
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
];
//https://electronicsplanet.ch/en/resistor/e192-series.php
//TODO: E96, E192
// https://electronicsplanet.ch/en/resistor/e12-series.php
const resistorsScales = [1, 10, 100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000];
// https://www.rfcafe.com/references/electrical/capacitor-values.htm
const capacitorScales = [10e-12, 10e-11, 10e-10, 10e-9, 10e-8, 10e-7, 10e-6, 10e-5, 10e-4, 10e-3, 10e-2];
export const sets: { [key: string]: DataSet } = {
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,
),
};

View File

@@ -0,0 +1,115 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2019", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "ES6", /* Specify what module code is generated. */
"rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
"sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
//"outFile": "./formula-wizard.js", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
"removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
"noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
"alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"files": [
"./main.ts",
],
"exclude": [
"../../../../resources/DecimalJs/10.4.3"
]
}

View File

@@ -0,0 +1,69 @@
/*!
* Formula Wizard v0.0.2
* [Short desc here]
* https://github.com/aziascreations/Web-NibblePoker
* Copyright (c) 2023 Herwin Bozet <herwin.bozet@gmail.com>
* Unlicense Licence
*/
import { formulas } from "./formulas.js";
const idCatalogPrefix = "fw-catalog-";
const idCatalogCategoryPrefix = idCatalogPrefix + "category-";
const idCatalogCategoryCount = idCatalogPrefix + "formula-count";
export const eCategoryContainers = {};
let IsCatalogInitialized = false;
export function initCatalog() {
if (!IsCatalogInitialized) {
console.debug("Populating formula catalog...");
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;
eNewFormulaVariants.appendChild(eNewFormulaVariant);
});
formulas[formulaKey].categories.forEach(categoryKey => {
if (Object.keys(eCategoryContainers).includes(categoryKey)) {
eCategoryContainers[categoryKey].appendChild(eNewFormula);
}
});
}
});
IsCatalogInitialized = true;
}
}
//# sourceMappingURL=ui_catalog.js.map

View File

@@ -0,0 +1,99 @@
/*!
* Formula Wizard v0.0.2
* [Short desc here]
* https://github.com/aziascreations/Web-NibblePoker
* Copyright (c) 2023 Herwin Bozet <herwin.bozet@gmail.com>
* Unlicense Licence
*/
import {formulas} from "./formulas";
const idCatalogPrefix = "fw-catalog-";
const idCatalogCategoryPrefix = idCatalogPrefix + "category-"
const idCatalogCategoryCount = idCatalogPrefix + "formula-count"
// We grab all the categories and put them in a map.
// The key is their ID without the prefix. (Result: electricity, chemistry, ...)
export const eCategoryContainers: { [key: string]: HTMLElement } = {};
let IsCatalogInitialized = false;
export function initCatalog() {
if (!IsCatalogInitialized) {
console.debug("Populating formula catalog...");
document.querySelectorAll('[id]').forEach((element ) => {
if(element.id.startsWith(idCatalogCategoryPrefix)) {
eCategoryContainers[element.id.replace(idCatalogCategoryPrefix, "")] = element as HTMLElement;
}
});
// Showing the formula count.
const eFormulaCount = document.getElementById(idCatalogCategoryCount);
if(eFormulaCount !== null) {
//eFormulaCount.innerText = Object.keys(formulas).length + " "+ localize("ui.formulaCount");
eFormulaCount.innerText = Object.keys(formulas).length.toString();
}
// Grabbing the templates for formulas and their variants
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");
}
// Adding the formulas and their variants to the page
Object.keys(formulas).forEach(formulaKey => {
const hasValidCategory: boolean = formulas[formulaKey].categories.every(function(categoryId) {
return Object.keys(eCategoryContainers).indexOf(categoryId) !== -1;
});
if(hasValidCategory) {
// Preparing the common element for the formula
let eNewFormula = (eTemplateFormula as HTMLTemplateElement).content.cloneNode(true) as HTMLElement;
let eNewFormulaTitle = eNewFormula.querySelector("p");
if(eNewFormulaTitle !== null) {
//eNewFormulaTitle.innerText = localize(formulas[formulaKey].name);
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 as HTMLTemplateElement).content.cloneNode(true) as HTMLElement;
let eNewFormulaVariantButton = eNewFormulaVariant.querySelector("button");
if(eNewFormulaVariantButton === null) {
alert("");
throw Error("");
}
eNewFormulaVariantButton.innerHTML = variant.getMathMl(formulas[formulaKey]);
eNewFormulaVariantButton.title = variant.description;
// FIXME: Add this back !
//eNewFormulaVariantButton.onclick = function() {
// WorkbenchFormulaUiElement.createNew(variant);
//};
// @ts-ignore - "eNewFormulaVariants" cannot be null here !
eNewFormulaVariants.appendChild(eNewFormulaVariant);
});
// Adding it to any relevant category.
formulas[formulaKey].categories.forEach(categoryKey => {
if(Object.keys(eCategoryContainers).includes(categoryKey)) {
// @ts-ignore - "eCategoryContainers[categoryKey]" cannot be null !
eCategoryContainers[categoryKey].appendChild(eNewFormula);
}
});
}
});
IsCatalogInitialized = true;
}
}

View File

@@ -0,0 +1,17 @@
// Prefixes
// Separated into their own section to minimize further
// ???
class WorkbenchContextComponentUi {
}
class WorkbenchFormulaUi {
}

View File

@@ -0,0 +1,197 @@
import { Decimal } from "../../../../resources/DecimalJs/10.4.3/decimal.min.mjs";
import { localize } from "./lang.js";
export class Unit {
constructor(unitKey, symbol, scale) {
this.name = localize("unit." + unitKey + ".name");
this.symbol = symbol;
this.scale = scale;
this.description = localize("unit." + unitKey + ".desc");
}
}
export 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 = [];
}
},
};
export 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 = "";
}
},
};
export 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),
};
export function scaleToBase(value, scaleFactor) {
return value.times(scaleFactor.multiplier);
}
export function scaleFromBase(value, scaleFactor) {
return value.dividedBy(scaleFactor.multiplier);
}
let areUnitsInitialized = false;
export function initUnits() {
if (!areUnitsInitialized) {
console.debug("Initializing scales & units...");
Object.keys(scaleFactors).forEach(scaleFactorKey => {
const scaleFactor = scaleFactors[scaleFactorKey];
scaleFactor.scale.scaleFactors.push(scaleFactor);
});
areUnitsInitialized = true;
}
}
//# sourceMappingURL=units.js.map

View File

@@ -0,0 +1 @@
import{Decimal as s}from"../../../../resources/DecimalJs/10.4.3/decimal.min.mjs";import{localize as t}from"./lang.js";export class Unit{constructor(s,i,e){this.name=t("unit."+s+".name"),this.symbol=i,this.scale=e,this.description=t("unit."+s+".desc")}}export const scales={SI:new class{constructor(){this.formatName=s=>s.symbol,this.formatSymbol=s=>s.symbol,this.scaleFactors=[]}},IMPERIAL_DISTANCE:new class{constructor(){this.formatName=s=>s.symbol,this.formatSymbol=s=>s.symbol,this.scaleFactors=[]}},IMPERIAL_WEIGHT:new class{constructor(){this.formatName=s=>s.symbol,this.formatSymbol=s=>s.symbol,this.scaleFactors=[]}},TIME_SECONDS:new class{constructor(){this.formatName=s=>s.symbol,this.formatSymbol=s=>s.symbol,this.scaleFactors=[]}},NONE:new class{constructor(){this.formatName=s=>s.name,this.formatSymbol=s=>s.symbol,this.scaleFactors=[]}}};export const scaleFactors={SI_GIGA:new class{constructor(){this.scale=scales.SI,this.multiplier=new s("1e9"),this.prefix="giga",this.suffix="",this.symbol="G"}},SI_MEGA:new class{constructor(){this.scale=scales.SI,this.multiplier=new s("1e6"),this.prefix="mega",this.suffix="",this.symbol="M"}},SI_KILO:new class{constructor(){this.scale=scales.SI,this.multiplier=new s("1e3"),this.prefix="kilo",this.suffix="",this.symbol="k"}},SI_BASE:new class{constructor(){this.scale=scales.SI,this.multiplier=new s("1"),this.prefix="",this.suffix="",this.symbol=""}},SI_CENTI:new class{constructor(){this.scale=scales.SI,this.multiplier=new s("1e-2"),this.prefix="centi",this.suffix="",this.symbol="c"}},SI_MILLI:new class{constructor(){this.scale=scales.SI,this.multiplier=new s("1e-3"),this.prefix="milli",this.suffix="",this.symbol="m"}},TIME_MILLI:new class{constructor(){this.scale=scales.TIME_SECONDS,this.multiplier=new s("1e-3"),this.prefix="milli",this.suffix="",this.symbol="m"}},TIME_BASE:new class{constructor(){this.scale=scales.TIME_SECONDS,this.multiplier=new s("1"),this.prefix="",this.suffix="",this.symbol=""}},TIME_MINUTE:new class{constructor(){this.scale=scales.TIME_SECONDS,this.multiplier=new s("60"),this.prefix="",this.suffix="",this.symbol=""}},TIME_HOUR:new class{constructor(){this.scale=scales.TIME_SECONDS,this.multiplier=new s("3600"),this.prefix="",this.suffix="",this.symbol=""}},TIME_DAY:new class{constructor(){this.scale=scales.TIME_SECONDS,this.multiplier=new s("86400"),this.prefix="",this.suffix="",this.symbol=""}}};export 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)};export function scaleToBase(s,t){return s.times(t.multiplier)}export function scaleFromBase(s,t){return s.dividedBy(t.multiplier)}let i=!1;export function initUnits(){i||(console.debug("Initializing scales & units..."),Object.keys(scaleFactors).forEach((s=>{const t=scaleFactors[s];t.scale.scaleFactors.push(t)})),i=!0)}

View File

@@ -0,0 +1,238 @@
// ==- Basic Info -================================
// Name: Formula Wizard - Units
// File: tools/items/formula-wizard/src/units.ts
// Version: N/A
// Author: Herwin Bozet
//
// ==- Requirements -==============================
// DecimalJS: https://github.com/MikeMcl/decimal.js/ (MIT)
//
// ==- Links & License -===========================
// License: Unlicense
// GitHub: https://github.com/aziascreations/Web-NibblePoker
// -----------------
// Units > Imports
// -----------------
import {Decimal} from '../../../../resources/DecimalJs/10.4.3/decimal';
import {localize} from "./lang";
// -----------------------------------------------
// Units > Type Definition, Classes & Interfaces
// -----------------------------------------------
export interface UnitScale {
formatName: (unit: Unit) => string;
formatSymbol: (unit: Unit) => string;
scaleFactors: UnitScaleFactor[];
}
export interface UnitScaleFactor {
scale: UnitScale
prefix: string;
suffix: string;
symbol: string;
/** Multiplier to go from scaled to base value */
// Not the most intuitive IMO, but it is similar to the standard power notation for SI.
multiplier: Decimal;
}
export class Unit {
name: string;
symbol: string;
description: string;
scale: UnitScale;
constructor(unitKey: string, symbol: string, scale: UnitScale) {
this.name = localize("unit." + unitKey + ".name");
this.symbol = symbol;
this.scale = scale;
this.description = localize("unit." + unitKey + ".desc");
}
}
// ---------------------
// Units > Collections
// ---------------------
export const scales= {
SI: new class implements UnitScale {
formatName = (unit: Unit): string => {
return unit.symbol
};
formatSymbol = (unit: Unit): string => {
return unit.symbol
};
scaleFactors = [];
},
IMPERIAL_DISTANCE: new class implements UnitScale {
formatName = (unit: Unit): string => {
return unit.symbol
};
formatSymbol = (unit: Unit): string => {
return unit.symbol
};
scaleFactors = [];
},
IMPERIAL_WEIGHT: new class implements UnitScale {
formatName = (unit: Unit): string => {
return unit.symbol
};
formatSymbol = (unit: Unit): string => {
return unit.symbol
};
scaleFactors = [];
},
TIME_SECONDS: new class implements UnitScale {
formatName = (unit: Unit): string => {
return unit.symbol
};
formatSymbol = (unit: Unit): string => {
return unit.symbol
};
scaleFactors = [];
},
NONE: new class implements UnitScale {
formatName = (unit: Unit): string => {
return unit.name
};
formatSymbol = (unit: Unit): string => {
return unit.symbol
};
scaleFactors = [];
},
};
export const scaleFactors: { [key: string]: UnitScaleFactor } = {
SI_GIGA: new class implements UnitScaleFactor {
scale = scales.SI;
multiplier = new Decimal('1e9');
prefix = "giga";
suffix = "";
symbol = "G";
},
SI_MEGA: new class implements UnitScaleFactor {
scale = scales.SI;
multiplier = new Decimal('1e6');
prefix = "mega";
suffix = "";
symbol = "M";
},
SI_KILO: new class implements UnitScaleFactor {
scale = scales.SI;
multiplier = new Decimal('1e3');
prefix = "kilo";
suffix = "";
symbol = "k";
},
SI_BASE: new class implements UnitScaleFactor {
scale = scales.SI;
multiplier = new Decimal('1');
prefix = "";
suffix = "";
symbol = "";
},
SI_CENTI: new class implements UnitScaleFactor {
scale = scales.SI;
multiplier = new Decimal('1e-2');
prefix = "centi";
suffix = "";
symbol = "c";
},
SI_MILLI: new class implements UnitScaleFactor {
scale = scales.SI;
multiplier = new Decimal('1e-3');
prefix = "milli";
suffix = "";
symbol = "m";
},
TIME_MILLI: new class implements UnitScaleFactor {
scale = scales.TIME_SECONDS;
multiplier = new Decimal('1e-3');
prefix = "milli";
suffix = "";
symbol = "m";
},
TIME_BASE: new class implements UnitScaleFactor {
scale = scales.TIME_SECONDS;
multiplier = new Decimal('1');
prefix = "";
suffix = "";
symbol = "";
},
TIME_MINUTE: new class implements UnitScaleFactor {
scale = scales.TIME_SECONDS;
multiplier = new Decimal('60');
prefix = "";
suffix = "";
symbol = "";
},
TIME_HOUR: new class implements UnitScaleFactor {
scale = scales.TIME_SECONDS;
multiplier = new Decimal('3600');
prefix = "";
suffix = "";
symbol = "";
},
TIME_DAY: new class implements UnitScaleFactor {
scale = scales.TIME_SECONDS;
multiplier = new Decimal('86400');
prefix = "";
suffix = "";
symbol = "";
},
};
export const units: { [key: string]: Unit } = {
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),
};
// -----------------
// Units > Helpers
// -----------------
export function scaleToBase(value: Decimal, scaleFactor: UnitScaleFactor): Decimal {
return value.times(scaleFactor.multiplier);
}
export function scaleFromBase(value: Decimal, scaleFactor: UnitScaleFactor): Decimal {
return value.dividedBy(scaleFactor.multiplier);
}
// ---------------------------
// Units > On-Import Handler
// ---------------------------
let areUnitsInitialized = false;
export function initUnits() {
if (!areUnitsInitialized) {
console.debug("Initializing scales & units...");
// Adding the `UnitScaleFactor` in their respective `UnitScale`.
Object.keys(scaleFactors).forEach(scaleFactorKey => {
// @ts-ignore - Ignoring BS implicit any.
const scaleFactor: UnitScaleFactor = scaleFactors[scaleFactorKey];
scaleFactor.scale.scaleFactors.push(scaleFactor);
});
areUnitsInitialized = true;
}
}

View File

@@ -0,0 +1,16 @@
/*class WorkbenchValueProvider {
}
class WorkbenchValueConsumer {
}*/
class WorkbenchFormula {
id: string;
}

View File

@@ -1,18 +0,0 @@
{
"files": [
"code.min.js"
],
"properties": [
"WATT",
"VOLT",
"AMPERE",
"OHM",
"METER",
"INCH",
"POUND",
"symbol",
"symbol",
"symbol",
"symbol"
]
}

View File

@@ -0,0 +1 @@
0.0.1