@cortex-js/compute-engine 0.55.5 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compile.esm.js +912 -770
- package/dist/compile.min.esm.js +300 -523
- package/dist/compile.min.umd.cjs +301 -524
- package/dist/compile.umd.cjs +912 -770
- package/dist/compute-engine.esm.js +1517 -902
- package/dist/compute-engine.min.esm.js +300 -522
- package/dist/compute-engine.min.umd.cjs +300 -522
- package/dist/compute-engine.umd.cjs +1517 -902
- package/dist/core.esm.js +1516 -901
- package/dist/core.min.esm.js +299 -521
- package/dist/core.min.umd.cjs +299 -521
- package/dist/core.umd.cjs +1516 -901
- package/dist/interval.esm.js +268 -63
- package/dist/interval.min.esm.js +7 -7
- package/dist/interval.min.umd.cjs +7 -7
- package/dist/interval.umd.cjs +268 -63
- package/dist/latex-syntax.esm.js +371 -77
- package/dist/latex-syntax.min.esm.js +7 -6
- package/dist/latex-syntax.min.umd.cjs +7 -6
- package/dist/latex-syntax.umd.cjs +371 -77
- package/dist/math-json.esm.js +2 -2
- package/dist/math-json.min.esm.js +2 -2
- package/dist/math-json.min.umd.cjs +2 -2
- package/dist/math-json.umd.cjs +2 -2
- package/dist/numerics.esm.js +4 -2
- package/dist/numerics.min.esm.js +3 -3
- package/dist/numerics.min.umd.cjs +3 -3
- package/dist/numerics.umd.cjs +4 -2
- package/dist/types/big-decimal/big-decimal.d.ts +1 -1
- package/dist/types/big-decimal/index.d.ts +1 -1
- package/dist/types/big-decimal/transcendentals.d.ts +1 -1
- package/dist/types/big-decimal/utils.d.ts +1 -1
- package/dist/types/common/ansi-codes.d.ts +1 -1
- package/dist/types/common/configuration-change.d.ts +1 -1
- package/dist/types/common/fuzzy-string-match.d.ts +1 -1
- package/dist/types/common/grapheme-splitter.d.ts +1 -1
- package/dist/types/common/interruptible.d.ts +1 -1
- package/dist/types/common/one-of.d.ts +1 -1
- package/dist/types/common/signals.d.ts +1 -1
- package/dist/types/common/type/ast-nodes.d.ts +1 -1
- package/dist/types/common/type/boxed-type.d.ts +1 -1
- package/dist/types/common/type/lexer.d.ts +1 -1
- package/dist/types/common/type/parse.d.ts +1 -1
- package/dist/types/common/type/parser.d.ts +1 -1
- package/dist/types/common/type/primitive.d.ts +1 -1
- package/dist/types/common/type/reduce.d.ts +1 -1
- package/dist/types/common/type/serialize.d.ts +1 -1
- package/dist/types/common/type/subtype.d.ts +1 -1
- package/dist/types/common/type/type-builder.d.ts +1 -1
- package/dist/types/common/type/types.d.ts +2 -2
- package/dist/types/common/type/utils.d.ts +1 -1
- package/dist/types/common/utils.d.ts +1 -1
- package/dist/types/compile.d.ts +1 -1
- package/dist/types/compute-engine/assume.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/apply.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-operator-definition.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/cache.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/constants.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expand.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/factor.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/hold.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/inequality-bounds.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/init-lazy-refs.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/invisible-operator.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/match.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/negate.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/numerics.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/pattern-utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/polynomial-degree.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/predicates.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/rules.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/sgn.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/solve-linear-system.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/solve.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/stochastic-equal.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/type-guards.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
- package/dist/types/compute-engine/collection-utils.d.ts +1 -1
- package/dist/types/compute-engine/compilation/base-compiler.d.ts +1 -1
- package/dist/types/compute-engine/compilation/compile-expression.d.ts +2 -3
- package/dist/types/compute-engine/compilation/constant-folding.d.ts +1 -1
- package/dist/types/compute-engine/compilation/glsl-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/gpu-target.d.ts +15 -58
- package/dist/types/compute-engine/compilation/interval-javascript-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/javascript-target.d.ts +25 -3
- package/dist/types/compute-engine/compilation/python-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/types.d.ts +1 -67
- package/dist/types/compute-engine/compilation/wgsl-target.d.ts +1 -1
- package/dist/types/compute-engine/cost-function.d.ts +1 -1
- package/dist/types/compute-engine/engine-assumptions.d.ts +1 -1
- package/dist/types/compute-engine/engine-cache.d.ts +1 -1
- package/dist/types/compute-engine/engine-common-symbols.d.ts +1 -1
- package/dist/types/compute-engine/engine-compilation-targets.d.ts +1 -1
- package/dist/types/compute-engine/engine-configuration-lifecycle.d.ts +1 -1
- package/dist/types/compute-engine/engine-declarations.d.ts +1 -1
- package/dist/types/compute-engine/engine-expression-entrypoints.d.ts +1 -1
- package/dist/types/compute-engine/engine-extension-contracts.d.ts +1 -1
- package/dist/types/compute-engine/engine-library-bootstrap.d.ts +1 -1
- package/dist/types/compute-engine/engine-numeric-configuration.d.ts +1 -1
- package/dist/types/compute-engine/engine-runtime-state.d.ts +1 -1
- package/dist/types/compute-engine/engine-scope.d.ts +1 -1
- package/dist/types/compute-engine/engine-sequences.d.ts +1 -1
- package/dist/types/compute-engine/engine-simplification-rules.d.ts +1 -1
- package/dist/types/compute-engine/engine-startup-coordinator.d.ts +1 -1
- package/dist/types/compute-engine/engine-type-resolver.d.ts +1 -1
- package/dist/types/compute-engine/engine-validation-entrypoints.d.ts +1 -1
- package/dist/types/compute-engine/free-functions.d.ts +1 -1
- package/dist/types/compute-engine/function-utils.d.ts +1 -1
- package/dist/types/compute-engine/global-types.d.ts +1 -1
- package/dist/types/compute-engine/index.d.ts +23 -3
- package/dist/types/compute-engine/interval/arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/interval/comparison.d.ts +1 -1
- package/dist/types/compute-engine/interval/elementary.d.ts +1 -1
- package/dist/types/compute-engine/interval/index.d.ts +1 -1
- package/dist/types/compute-engine/interval/trigonometric.d.ts +1 -1
- package/dist/types/compute-engine/interval/types.d.ts +1 -1
- package/dist/types/compute-engine/interval/util.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/default-dictionary.d.ts +4 -3
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-colors.d.ts +10 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-units.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/indexed-types.d.ts +9 -1
- package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse-number.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serialize-dms.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer.d.ts +4 -2
- package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/types.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/utils.d.ts +1 -1
- package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/library/calculus.d.ts +1 -1
- package/dist/types/compute-engine/library/collections.d.ts +1 -1
- package/dist/types/compute-engine/library/colors.d.ts +1 -1
- package/dist/types/compute-engine/library/combinatorics.d.ts +1 -1
- package/dist/types/compute-engine/library/complex.d.ts +1 -1
- package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
- package/dist/types/compute-engine/library/core.d.ts +1 -1
- package/dist/types/compute-engine/library/fractals.d.ts +1 -1
- package/dist/types/compute-engine/library/library.d.ts +1 -1
- package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/library/logic-analysis.d.ts +1 -1
- package/dist/types/compute-engine/library/logic.d.ts +1 -1
- package/dist/types/compute-engine/library/number-theory.d.ts +1 -1
- package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
- package/dist/types/compute-engine/library/quantity-arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
- package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
- package/dist/types/compute-engine/library/sets.d.ts +1 -1
- package/dist/types/compute-engine/library/statistics.d.ts +1 -1
- package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/library/type-handlers.d.ts +1 -1
- package/dist/types/compute-engine/library/unit-data.d.ts +1 -1
- package/dist/types/compute-engine/library/units.d.ts +1 -1
- package/dist/types/compute-engine/library/utils.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/types.d.ts +1 -1
- package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
- package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
- package/dist/types/compute-engine/numerics/linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
- package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
- package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
- package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
- package/dist/types/compute-engine/numerics/special-functions.d.ts +1 -1
- package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
- package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
- package/dist/types/compute-engine/numerics/types.d.ts +1 -1
- package/dist/types/compute-engine/numerics/unit-data.d.ts +1 -1
- package/dist/types/compute-engine/oeis.d.ts +1 -1
- package/dist/types/compute-engine/sequence.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/antiderivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-cost.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-transforms.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/logic-utils.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-abs.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-divide.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-factorial.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-hyperbolic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-infinity.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-log.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-logic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-power.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-product.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-trig.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensor-fields.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensors.d.ts +1 -1
- package/dist/types/compute-engine/types-definitions.d.ts +1 -1
- package/dist/types/compute-engine/types-engine.d.ts +6 -2
- package/dist/types/compute-engine/types-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-expression.d.ts +1 -1
- package/dist/types/compute-engine/types-kernel-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-kernel-serialization.d.ts +1 -1
- package/dist/types/compute-engine/types-serialization.d.ts +1 -1
- package/dist/types/compute-engine/types.d.ts +1 -1
- package/dist/types/compute-engine.d.ts +2 -3
- package/dist/types/core.d.ts +1 -1
- package/dist/types/interval.d.ts +1 -1
- package/dist/types/latex-syntax.d.ts +2 -2
- package/dist/types/math-json/symbols.d.ts +1 -1
- package/dist/types/math-json/types.d.ts +1 -1
- package/dist/types/math-json/utils.d.ts +1 -1
- package/dist/types/math-json.d.ts +2 -2
- package/dist/types/numerics.d.ts +1 -1
- package/package.json +2 -2
- package/dist/types/compute-engine/compilation/fractal-orbit.d.ts +0 -19
package/dist/core.umd.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** ComputeEngineCore 0.
|
|
1
|
+
/** ComputeEngineCore 0.56.0 */
|
|
2
2
|
(function(global,factory){typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'],factory):(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ComputeEngineCore = {}));})(this, (function (exports) { 'use strict';
|
|
3
3
|
var ComputeEngineCore = (() => {
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -2287,6 +2287,7 @@ var ComputeEngineCore = (() => {
|
|
|
2287
2287
|
];
|
|
2288
2288
|
var VALUE_TYPES = [
|
|
2289
2289
|
"value",
|
|
2290
|
+
"color",
|
|
2290
2291
|
...COLLECTION_TYPES,
|
|
2291
2292
|
...SCALAR_TYPES
|
|
2292
2293
|
];
|
|
@@ -3986,6 +3987,7 @@ var ComputeEngineCore = (() => {
|
|
|
3986
3987
|
symbol: [],
|
|
3987
3988
|
boolean: [],
|
|
3988
3989
|
string: [],
|
|
3990
|
+
color: [],
|
|
3989
3991
|
expression: EXPRESSION_TYPES
|
|
3990
3992
|
};
|
|
3991
3993
|
function isPrimitiveSubtype(lhs, rhs) {
|
|
@@ -7869,9 +7871,10 @@ var ComputeEngineCore = (() => {
|
|
|
7869
7871
|
if (!materialized.isLazyCollection) return materialized.latex;
|
|
7870
7872
|
}
|
|
7871
7873
|
const syntax = this.engine._requireLatexSyntax();
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
);
|
|
7874
|
+
const json = this.toMathJson({ prettify: true, fractionalDigits: "auto" });
|
|
7875
|
+
const latexOpts = this.engine.latexOptions;
|
|
7876
|
+
if (Object.keys(latexOpts).length === 0) return syntax.serialize(json);
|
|
7877
|
+
return syntax.serialize(json, { ...latexOpts });
|
|
7875
7878
|
}
|
|
7876
7879
|
/**
|
|
7877
7880
|
* Return a LaTeX representation of this expression with custom
|
|
@@ -7895,9 +7898,13 @@ var ComputeEngineCore = (() => {
|
|
|
7895
7898
|
fractionalDigits: "auto"
|
|
7896
7899
|
});
|
|
7897
7900
|
const syntax = this.engine._requireLatexSyntax();
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
+
const latexOpts = this.engine.latexOptions;
|
|
7902
|
+
const haveEngineOpts = Object.keys(latexOpts).length > 0;
|
|
7903
|
+
const haveCallOpts = options && Object.keys(options).length > 0;
|
|
7904
|
+
if (!haveEngineOpts && !haveCallOpts) return syntax.serialize(json);
|
|
7905
|
+
if (!haveEngineOpts) return syntax.serialize(json, options);
|
|
7906
|
+
if (!haveCallOpts) return syntax.serialize(json, { ...latexOpts });
|
|
7907
|
+
return syntax.serialize(json, { ...latexOpts, ...options });
|
|
7901
7908
|
}
|
|
7902
7909
|
/** Called by `JSON.stringify()` when serializing to json.
|
|
7903
7910
|
*
|
|
@@ -7941,11 +7948,13 @@ var ComputeEngineCore = (() => {
|
|
|
7941
7948
|
"number",
|
|
7942
7949
|
"dictionary"
|
|
7943
7950
|
];
|
|
7944
|
-
}
|
|
7945
|
-
if (Array.isArray(options.shorthands))
|
|
7951
|
+
} else if (Array.isArray(options.shorthands)) {
|
|
7946
7952
|
defaultOptions.shorthands = options.shorthands;
|
|
7953
|
+
}
|
|
7947
7954
|
if (typeof options.metadata === "string" && options.metadata === "all" || options.metadata?.includes("all")) {
|
|
7948
7955
|
defaultOptions.metadata = ["latex", "wikidata"];
|
|
7956
|
+
} else if (Array.isArray(options.metadata)) {
|
|
7957
|
+
defaultOptions.metadata = options.metadata;
|
|
7949
7958
|
}
|
|
7950
7959
|
if (options.fractionalDigits === "auto")
|
|
7951
7960
|
defaultOptions.fractionalDigits = -this.engine.precision;
|
|
@@ -11084,10 +11093,6 @@ var ComputeEngineCore = (() => {
|
|
|
11084
11093
|
// Lagrange notation
|
|
11085
11094
|
{
|
|
11086
11095
|
name: "Derivative",
|
|
11087
|
-
// @todo: Leibniz notation: {% latex " \\frac{d^n}{dx^n} f(x)" %}
|
|
11088
|
-
// @todo: Euler modified notation: This notation is used by Mathematica. The Euler notation uses `D` instead of
|
|
11089
|
-
// `\partial`: `\partial_{x} f`, `\partial_{x,y} f`
|
|
11090
|
-
// Newton notation (\dot{v}, \ddot{v}) is implemented below
|
|
11091
11096
|
serialize: (serializer, expr2) => {
|
|
11092
11097
|
const degree = machineValue(operand(expr2, 2)) ?? 1;
|
|
11093
11098
|
const base = serializer.serialize(operand(expr2, 1));
|
|
@@ -12125,14 +12130,18 @@ var ComputeEngineCore = (() => {
|
|
|
12125
12130
|
return ["Complement", lhs];
|
|
12126
12131
|
}
|
|
12127
12132
|
// precedence: 240,
|
|
12128
|
-
// @todo: serialize for the multiple argument case
|
|
12129
12133
|
},
|
|
12130
12134
|
{
|
|
12131
12135
|
name: "Complement",
|
|
12132
12136
|
latexTrigger: ["^", "<{>", "\\complement", "<}>"],
|
|
12133
|
-
kind: "postfix"
|
|
12137
|
+
kind: "postfix",
|
|
12134
12138
|
// precedence: 240,
|
|
12135
|
-
|
|
12139
|
+
serialize: (serializer, expr2) => {
|
|
12140
|
+
return joinLatex([
|
|
12141
|
+
serializer.serialize(operand(expr2, 1)),
|
|
12142
|
+
"^\\complement"
|
|
12143
|
+
]);
|
|
12144
|
+
}
|
|
12136
12145
|
},
|
|
12137
12146
|
{
|
|
12138
12147
|
name: "Intersection",
|
|
@@ -12219,7 +12228,6 @@ var ComputeEngineCore = (() => {
|
|
|
12219
12228
|
// commands like \rbrack a, b \rbrack which are unambiguous.
|
|
12220
12229
|
{
|
|
12221
12230
|
name: "Multiple",
|
|
12222
|
-
// @todo: parse
|
|
12223
12231
|
serialize: serializeSet
|
|
12224
12232
|
},
|
|
12225
12233
|
{
|
|
@@ -12228,14 +12236,28 @@ var ComputeEngineCore = (() => {
|
|
|
12228
12236
|
kind: "infix",
|
|
12229
12237
|
precedence: 350
|
|
12230
12238
|
},
|
|
12239
|
+
// \mid as a separator/operator (used in set-builder notation: {x \mid x > 0})
|
|
12240
|
+
// Low precedence so it binds loosely — everything on each side is parsed first
|
|
12241
|
+
{
|
|
12242
|
+
name: "Divides",
|
|
12243
|
+
latexTrigger: ["\\mid"],
|
|
12244
|
+
kind: "infix",
|
|
12245
|
+
precedence: 160
|
|
12246
|
+
},
|
|
12231
12247
|
{
|
|
12232
12248
|
name: "Set",
|
|
12233
12249
|
kind: "matchfix",
|
|
12234
12250
|
openTrigger: "{",
|
|
12235
12251
|
closeTrigger: "}",
|
|
12236
|
-
// @todo: the set syntax can also include conditions...
|
|
12237
12252
|
parse: (_parser, body) => {
|
|
12238
12253
|
if (isEmptySequence(body)) return "EmptySet";
|
|
12254
|
+
const h = operator(body);
|
|
12255
|
+
if (h === "Divides" || h === "Colon") {
|
|
12256
|
+
const expr2 = operand(body, 1);
|
|
12257
|
+
const condition = operand(body, 2);
|
|
12258
|
+
if (expr2 !== null && condition !== null)
|
|
12259
|
+
return ["Set", expr2, ["Condition", condition]];
|
|
12260
|
+
}
|
|
12239
12261
|
if (operator(body) == "Delimiter" && stringValue(operand(body, 2)) === ",") {
|
|
12240
12262
|
body = operand(body, 1);
|
|
12241
12263
|
}
|
|
@@ -12243,6 +12265,17 @@ var ComputeEngineCore = (() => {
|
|
|
12243
12265
|
return ["Set", ...operands(body)];
|
|
12244
12266
|
},
|
|
12245
12267
|
serialize: (serializer, expr2) => {
|
|
12268
|
+
if (nops(expr2) === 2 && operator(operand(expr2, 2)) === "Condition") {
|
|
12269
|
+
const condition = operand(expr2, 2);
|
|
12270
|
+
return joinLatex([
|
|
12271
|
+
"\\lbrace",
|
|
12272
|
+
serializer.serialize(operand(expr2, 1)),
|
|
12273
|
+
"\\mid",
|
|
12274
|
+
// Serialize the inner expression of the Condition wrapper
|
|
12275
|
+
serializer.serialize(operand(condition, 1)),
|
|
12276
|
+
"\\rbrace"
|
|
12277
|
+
]);
|
|
12278
|
+
}
|
|
12246
12279
|
return joinLatex([
|
|
12247
12280
|
"\\lbrace",
|
|
12248
12281
|
operands(expr2).map((x) => serializer.serialize(x)).join(", "),
|
|
@@ -12409,23 +12442,6 @@ var ComputeEngineCore = (() => {
|
|
|
12409
12442
|
if (expr2 === null) return "";
|
|
12410
12443
|
const h = operator(expr2);
|
|
12411
12444
|
if (!h) return "";
|
|
12412
|
-
if (h === "Set") {
|
|
12413
|
-
if (nops(expr2) === 0) return "\\emptyset";
|
|
12414
|
-
if (nops(expr2) === 2 && operator(operand(expr2, 2)) === "Condition") {
|
|
12415
|
-
return joinLatex([
|
|
12416
|
-
"\\left\\lbrace",
|
|
12417
|
-
serializer.serialize(operand(expr2, 1)),
|
|
12418
|
-
"\\middle\\mid",
|
|
12419
|
-
serializer.serialize(operand(expr2, 2)),
|
|
12420
|
-
"\\right\\rbrace"
|
|
12421
|
-
]);
|
|
12422
|
-
}
|
|
12423
|
-
return joinLatex([
|
|
12424
|
-
"\\left\\lbrace",
|
|
12425
|
-
...operands(expr2).map((x) => serializer.serialize(x) + " ,"),
|
|
12426
|
-
"\\right\\rbrace"
|
|
12427
|
-
]);
|
|
12428
|
-
}
|
|
12429
12445
|
if (h === "Multiple") {
|
|
12430
12446
|
}
|
|
12431
12447
|
if (h === "Range") {
|
|
@@ -13573,11 +13589,13 @@ var ComputeEngineCore = (() => {
|
|
|
13573
13589
|
if (!parser.match("_")) return null;
|
|
13574
13590
|
const base = parser.parseGroup();
|
|
13575
13591
|
if (operator(base) !== "To") return null;
|
|
13576
|
-
const expr2 = parser.
|
|
13592
|
+
const expr2 = parser.parseExpression({
|
|
13593
|
+
minPrec: MULTIPLICATION_PRECEDENCE
|
|
13594
|
+
});
|
|
13577
13595
|
if (!expr2) return null;
|
|
13578
13596
|
return [
|
|
13579
13597
|
"Limit",
|
|
13580
|
-
["Function", expr2
|
|
13598
|
+
["Function", expr2, operand(base, 1)],
|
|
13581
13599
|
operand(base, 2)
|
|
13582
13600
|
];
|
|
13583
13601
|
},
|
|
@@ -13658,6 +13676,8 @@ var ComputeEngineCore = (() => {
|
|
|
13658
13676
|
precedence: DIVISION_PRECEDENCE,
|
|
13659
13677
|
parse: "Mod"
|
|
13660
13678
|
},
|
|
13679
|
+
// Function-style alias: `\operatorname{mod}(a, b)`
|
|
13680
|
+
{ latexTrigger: "\\operatorname{mod}", parse: "Mod" },
|
|
13661
13681
|
{
|
|
13662
13682
|
latexTrigger: "\\pmod",
|
|
13663
13683
|
kind: "prefix",
|
|
@@ -13898,6 +13918,13 @@ var ComputeEngineCore = (() => {
|
|
|
13898
13918
|
const rhs = serializer.wrap(operand(expr2, 2), ADDITION_PRECEDENCE + 3);
|
|
13899
13919
|
return joinLatex([lhs, "-", rhs]);
|
|
13900
13920
|
}
|
|
13921
|
+
},
|
|
13922
|
+
// Euclidean distance between two points (tuples of numbers).
|
|
13923
|
+
{
|
|
13924
|
+
name: "Distance",
|
|
13925
|
+
latexTrigger: ["\\operatorname{distance}"],
|
|
13926
|
+
kind: "function",
|
|
13927
|
+
serialize: (serializer, expr2) => "\\operatorname{distance}" + serializer.wrapArguments(expr2)
|
|
13901
13928
|
}
|
|
13902
13929
|
];
|
|
13903
13930
|
function getIndexAssignment(expr2, upper) {
|
|
@@ -15322,7 +15349,9 @@ var ComputeEngineCore = (() => {
|
|
|
15322
15349
|
if (!expr2 || !symbol(expr2)) return null;
|
|
15323
15350
|
return ["Mean", expr2];
|
|
15324
15351
|
}
|
|
15325
|
-
}
|
|
15352
|
+
},
|
|
15353
|
+
// Function-style alias: `\operatorname{var}(...)`
|
|
15354
|
+
{ latexTrigger: "\\operatorname{var}", parse: "Variance" }
|
|
15326
15355
|
];
|
|
15327
15356
|
|
|
15328
15357
|
// src/compute-engine/numerics/unit-data.ts
|
|
@@ -15874,12 +15903,52 @@ var ComputeEngineCore = (() => {
|
|
|
15874
15903
|
];
|
|
15875
15904
|
|
|
15876
15905
|
// src/compute-engine/latex-syntax/dictionary/definitions-other.ts
|
|
15906
|
+
var TEX_UNITS = [
|
|
15907
|
+
"pt",
|
|
15908
|
+
"em",
|
|
15909
|
+
"mu",
|
|
15910
|
+
"ex",
|
|
15911
|
+
"mm",
|
|
15912
|
+
"cm",
|
|
15913
|
+
"in",
|
|
15914
|
+
"bp",
|
|
15915
|
+
"sp",
|
|
15916
|
+
"dd",
|
|
15917
|
+
"cc",
|
|
15918
|
+
"pc",
|
|
15919
|
+
"nc",
|
|
15920
|
+
"nd"
|
|
15921
|
+
];
|
|
15922
|
+
function skipTexDimension(parser) {
|
|
15923
|
+
parser.skipSpace();
|
|
15924
|
+
if (parser.peek === "-" || parser.peek === "+") parser.nextToken();
|
|
15925
|
+
while (/^[\d.]$/.test(parser.peek)) parser.nextToken();
|
|
15926
|
+
for (const unit of TEX_UNITS) {
|
|
15927
|
+
if (parser.matchAll([...unit])) return;
|
|
15928
|
+
}
|
|
15929
|
+
}
|
|
15877
15930
|
function parseSingleArg(cmd) {
|
|
15878
15931
|
return (parser) => {
|
|
15879
15932
|
const arg = parser.parseGroup();
|
|
15880
15933
|
return arg === null ? [cmd] : [cmd, arg];
|
|
15881
15934
|
};
|
|
15882
15935
|
}
|
|
15936
|
+
function parseMathStyleSwitch(mathStyle) {
|
|
15937
|
+
return (parser) => {
|
|
15938
|
+
const body = parser.parseExpression();
|
|
15939
|
+
if (body !== null && !isEmptySequence(body))
|
|
15940
|
+
return ["Annotated", body, { dict: { mathStyle } }];
|
|
15941
|
+
return "Nothing";
|
|
15942
|
+
};
|
|
15943
|
+
}
|
|
15944
|
+
function parseSizeSwitch(size) {
|
|
15945
|
+
return (parser) => {
|
|
15946
|
+
const body = parser.parseExpression();
|
|
15947
|
+
if (body !== null && !isEmptySequence(body))
|
|
15948
|
+
return ["Annotated", body, { dict: { size } }];
|
|
15949
|
+
return "Nothing";
|
|
15950
|
+
};
|
|
15951
|
+
}
|
|
15883
15952
|
var DEFINITIONS_OTHERS = [
|
|
15884
15953
|
{
|
|
15885
15954
|
name: "Overscript",
|
|
@@ -16119,80 +16188,71 @@ var ComputeEngineCore = (() => {
|
|
|
16119
16188
|
},
|
|
16120
16189
|
{
|
|
16121
16190
|
latexTrigger: ["\\displaystyle"],
|
|
16122
|
-
parse: (
|
|
16123
|
-
// @todo: parse as ['Annotated'...]
|
|
16191
|
+
parse: parseMathStyleSwitch("normal")
|
|
16124
16192
|
},
|
|
16125
16193
|
{
|
|
16126
16194
|
latexTrigger: ["\\textstyle"],
|
|
16127
|
-
parse: (
|
|
16128
|
-
// @todo: parse as ['Annotated'...]
|
|
16195
|
+
parse: parseMathStyleSwitch("compact")
|
|
16129
16196
|
},
|
|
16130
16197
|
{
|
|
16131
16198
|
latexTrigger: ["\\scriptstyle"],
|
|
16132
|
-
parse: (
|
|
16133
|
-
// @todo: parse as ['Annotated'...]
|
|
16199
|
+
parse: parseMathStyleSwitch("script")
|
|
16134
16200
|
},
|
|
16135
16201
|
{
|
|
16136
16202
|
latexTrigger: ["\\scriptscriptstyle"],
|
|
16137
|
-
parse: (
|
|
16138
|
-
// @todo: parse as ['Annotated'...]
|
|
16203
|
+
parse: parseMathStyleSwitch("scriptscript")
|
|
16139
16204
|
},
|
|
16140
16205
|
{
|
|
16141
16206
|
latexTrigger: ["\\color"],
|
|
16142
16207
|
parse: (parser) => {
|
|
16143
|
-
parser.
|
|
16208
|
+
const color = parser.parseStringGroup();
|
|
16209
|
+
if (color !== null) {
|
|
16210
|
+
const body = parser.parseExpression();
|
|
16211
|
+
if (body !== null && !isEmptySequence(body))
|
|
16212
|
+
return ["Annotated", body, { dict: { color } }];
|
|
16213
|
+
}
|
|
16144
16214
|
return "Nothing";
|
|
16145
16215
|
}
|
|
16146
16216
|
},
|
|
16147
16217
|
{
|
|
16148
16218
|
latexTrigger: ["\\tiny"],
|
|
16149
|
-
parse: ()
|
|
16150
|
-
// @todo: parse as ['Annotated'...]
|
|
16219
|
+
parse: parseSizeSwitch(1)
|
|
16151
16220
|
},
|
|
16152
16221
|
{
|
|
16153
16222
|
latexTrigger: ["\\scriptsize"],
|
|
16154
|
-
parse: ()
|
|
16155
|
-
// @todo: parse as ['Annotated'...]
|
|
16223
|
+
parse: parseSizeSwitch(2)
|
|
16156
16224
|
},
|
|
16157
16225
|
{
|
|
16158
16226
|
latexTrigger: ["\\footnotesize"],
|
|
16159
|
-
parse: ()
|
|
16160
|
-
// @todo: parse as ['Annotated'...]
|
|
16227
|
+
parse: parseSizeSwitch(3)
|
|
16161
16228
|
},
|
|
16162
16229
|
{
|
|
16163
16230
|
latexTrigger: ["\\small"],
|
|
16164
|
-
parse: ()
|
|
16165
|
-
// @todo: parse as ['Annotated'...]
|
|
16231
|
+
parse: parseSizeSwitch(4)
|
|
16166
16232
|
},
|
|
16167
16233
|
{
|
|
16168
16234
|
latexTrigger: ["\\normalsize"],
|
|
16169
|
-
parse: ()
|
|
16170
|
-
// @todo: parse as ['Annotated'...]
|
|
16235
|
+
parse: parseSizeSwitch(5)
|
|
16171
16236
|
},
|
|
16172
16237
|
{
|
|
16173
16238
|
latexTrigger: ["\\large"],
|
|
16174
|
-
parse: ()
|
|
16175
|
-
// @todo: parse as ['Annotated'...]
|
|
16239
|
+
parse: parseSizeSwitch(6)
|
|
16176
16240
|
},
|
|
16177
16241
|
{
|
|
16178
16242
|
latexTrigger: ["\\Large"],
|
|
16179
|
-
parse: ()
|
|
16180
|
-
// @todo: parse as ['Annotated'...]
|
|
16243
|
+
parse: parseSizeSwitch(7)
|
|
16181
16244
|
},
|
|
16182
16245
|
{
|
|
16183
16246
|
latexTrigger: ["\\LARGE"],
|
|
16184
|
-
parse: ()
|
|
16185
|
-
// @todo: parse as ['Annotated'...]
|
|
16247
|
+
parse: parseSizeSwitch(8)
|
|
16186
16248
|
},
|
|
16187
16249
|
{
|
|
16188
16250
|
latexTrigger: ["\\huge"],
|
|
16189
|
-
parse: ()
|
|
16190
|
-
// @todo: parse as ['Annotated'...]
|
|
16251
|
+
parse: parseSizeSwitch(9)
|
|
16191
16252
|
},
|
|
16192
16253
|
{
|
|
16193
16254
|
latexTrigger: ["\\Huge"],
|
|
16194
|
-
parse: ()
|
|
16195
|
-
// @todo: parse as ['Annotated'...]
|
|
16255
|
+
parse: parseSizeSwitch(10)
|
|
16196
16256
|
},
|
|
16197
16257
|
{
|
|
16198
16258
|
name: "Annotated",
|
|
@@ -16204,6 +16264,10 @@ var ComputeEngineCore = (() => {
|
|
|
16204
16264
|
result = joinLatex(["{\\displaystyle", result, "}"]);
|
|
16205
16265
|
else if (dict.dict.mathStyle === "compact")
|
|
16206
16266
|
result = joinLatex(["{\\textstyle", result, "}"]);
|
|
16267
|
+
else if (dict.dict.mathStyle === "script")
|
|
16268
|
+
result = joinLatex(["{\\scriptstyle", result, "}"]);
|
|
16269
|
+
else if (dict.dict.mathStyle === "scriptscript")
|
|
16270
|
+
result = joinLatex(["{\\scriptscriptstyle", result, "}"]);
|
|
16207
16271
|
const v = dict.dict.size;
|
|
16208
16272
|
if (v !== null && v >= 1 && v <= 10) {
|
|
16209
16273
|
result = joinLatex([
|
|
@@ -16291,6 +16355,28 @@ var ComputeEngineCore = (() => {
|
|
|
16291
16355
|
latexTrigger: ["\\enspace"],
|
|
16292
16356
|
parse: () => ["HorizontalSpacing", 9]
|
|
16293
16357
|
},
|
|
16358
|
+
{
|
|
16359
|
+
latexTrigger: ["\\hspace"],
|
|
16360
|
+
parse: (parser) => {
|
|
16361
|
+
if (parser.peek === "*") parser.nextToken();
|
|
16362
|
+
parser.parseStringGroup();
|
|
16363
|
+
return ["HorizontalSpacing", 0];
|
|
16364
|
+
}
|
|
16365
|
+
},
|
|
16366
|
+
{
|
|
16367
|
+
latexTrigger: ["\\hskip"],
|
|
16368
|
+
parse: (parser) => {
|
|
16369
|
+
skipTexDimension(parser);
|
|
16370
|
+
return ["HorizontalSpacing", 0];
|
|
16371
|
+
}
|
|
16372
|
+
},
|
|
16373
|
+
{
|
|
16374
|
+
latexTrigger: ["\\kern"],
|
|
16375
|
+
parse: (parser) => {
|
|
16376
|
+
skipTexDimension(parser);
|
|
16377
|
+
return ["HorizontalSpacing", 0];
|
|
16378
|
+
}
|
|
16379
|
+
},
|
|
16294
16380
|
{
|
|
16295
16381
|
latexTrigger: ["\\phantom"],
|
|
16296
16382
|
parse: (parser) => {
|
|
@@ -16341,7 +16427,17 @@ var ComputeEngineCore = (() => {
|
|
|
16341
16427
|
// `["HorizontalSpacing", expr, 'op'|'bin'|rel]` -> indicate a spacing around and expression, i.e. `\mathbin{x}`, etc...
|
|
16342
16428
|
serialize: (serializer, expr2) => {
|
|
16343
16429
|
if (operand(expr2, 2) !== null) {
|
|
16344
|
-
|
|
16430
|
+
const cls = stringValue(operand(expr2, 2));
|
|
16431
|
+
const inner = serializer.serialize(operand(expr2, 1));
|
|
16432
|
+
if (cls === "bin") return `\\mathbin{${inner}}`;
|
|
16433
|
+
if (cls === "op") return `\\mathop{${inner}}`;
|
|
16434
|
+
if (cls === "rel") return `\\mathrel{${inner}}`;
|
|
16435
|
+
if (cls === "ord") return `\\mathord{${inner}}`;
|
|
16436
|
+
if (cls === "open") return `\\mathopen{${inner}}`;
|
|
16437
|
+
if (cls === "close") return `\\mathclose{${inner}}`;
|
|
16438
|
+
if (cls === "punct") return `\\mathpunct{${inner}}`;
|
|
16439
|
+
if (cls === "inner") return `\\mathinner{${inner}}`;
|
|
16440
|
+
return inner;
|
|
16345
16441
|
}
|
|
16346
16442
|
const v = machineValue(operand(expr2, 1));
|
|
16347
16443
|
if (v === null) return "";
|
|
@@ -16356,7 +16452,7 @@ var ComputeEngineCore = (() => {
|
|
|
16356
16452
|
36: "\\qquad"
|
|
16357
16453
|
}[v] ?? "";
|
|
16358
16454
|
}
|
|
16359
|
-
}
|
|
16455
|
+
},
|
|
16360
16456
|
// if (
|
|
16361
16457
|
// [
|
|
16362
16458
|
// '\\!',
|
|
@@ -16380,6 +16476,121 @@ var ComputeEngineCore = (() => {
|
|
|
16380
16476
|
// name: '',
|
|
16381
16477
|
// trigger: '\\check',
|
|
16382
16478
|
// },
|
|
16479
|
+
// ---------------------------------------------------------------------------
|
|
16480
|
+
// Function-style aliases for collection / random operators that some
|
|
16481
|
+
// notations write in lowercase (e.g. `\operatorname{shuffle}(L)`).
|
|
16482
|
+
// The capitalized library entries already exist; these are pure parse
|
|
16483
|
+
// aliases so the lowercase names don't land in `unsupported-operator`.
|
|
16484
|
+
// ---------------------------------------------------------------------------
|
|
16485
|
+
{ latexTrigger: "\\operatorname{random}", parse: "Random" },
|
|
16486
|
+
{ latexTrigger: "\\operatorname{shuffle}", parse: "Shuffle" },
|
|
16487
|
+
{ latexTrigger: "\\operatorname{repeat}", parse: "Repeat" },
|
|
16488
|
+
{ latexTrigger: "\\operatorname{join}", parse: "Join" },
|
|
16489
|
+
// ---------------------------------------------------------------------------
|
|
16490
|
+
// Geometric primitive heads. Registered as known typed heads so consumers
|
|
16491
|
+
// can branch on the operator name; CE itself doesn't render them. The
|
|
16492
|
+
// library entries (with no evaluator) live in `library/core.ts`.
|
|
16493
|
+
// ---------------------------------------------------------------------------
|
|
16494
|
+
{
|
|
16495
|
+
name: "Triangle",
|
|
16496
|
+
latexTrigger: ["\\operatorname{triangle}"],
|
|
16497
|
+
kind: "function",
|
|
16498
|
+
serialize: (serializer, expr2) => "\\operatorname{triangle}" + serializer.wrapArguments(expr2)
|
|
16499
|
+
},
|
|
16500
|
+
// Desmos's geometric `vector(p1, p2)` — a directed segment between two
|
|
16501
|
+
// points. Routed to a dedicated head (not the existing column-vector
|
|
16502
|
+
// `Vector`, which has a narrower `(number+) -> vector` signature).
|
|
16503
|
+
{
|
|
16504
|
+
name: "GeometricVector",
|
|
16505
|
+
latexTrigger: ["\\operatorname{vector}"],
|
|
16506
|
+
kind: "function",
|
|
16507
|
+
serialize: (serializer, expr2) => "\\operatorname{vector}" + serializer.wrapArguments(expr2)
|
|
16508
|
+
},
|
|
16509
|
+
{
|
|
16510
|
+
name: "Sphere",
|
|
16511
|
+
latexTrigger: ["\\operatorname{sphere}"],
|
|
16512
|
+
kind: "function",
|
|
16513
|
+
serialize: (serializer, expr2) => "\\operatorname{sphere}" + serializer.wrapArguments(expr2)
|
|
16514
|
+
},
|
|
16515
|
+
{
|
|
16516
|
+
name: "Segment",
|
|
16517
|
+
latexTrigger: ["\\operatorname{segment}"],
|
|
16518
|
+
kind: "function",
|
|
16519
|
+
serialize: (serializer, expr2) => "\\operatorname{segment}" + serializer.wrapArguments(expr2)
|
|
16520
|
+
}
|
|
16521
|
+
];
|
|
16522
|
+
|
|
16523
|
+
// src/compute-engine/latex-syntax/dictionary/definitions-colors.ts
|
|
16524
|
+
var DEFINITIONS_COLORS = [
|
|
16525
|
+
// Color constructors (one per colorspace, preserves space on evaluation)
|
|
16526
|
+
{
|
|
16527
|
+
name: "Rgb",
|
|
16528
|
+
latexTrigger: ["\\operatorname{rgb}"],
|
|
16529
|
+
kind: "function",
|
|
16530
|
+
serialize: (serializer, expr2) => "\\operatorname{rgb}" + serializer.wrapArguments(expr2)
|
|
16531
|
+
},
|
|
16532
|
+
{
|
|
16533
|
+
name: "Hsv",
|
|
16534
|
+
latexTrigger: ["\\operatorname{hsv}"],
|
|
16535
|
+
kind: "function",
|
|
16536
|
+
serialize: (serializer, expr2) => "\\operatorname{hsv}" + serializer.wrapArguments(expr2)
|
|
16537
|
+
},
|
|
16538
|
+
{
|
|
16539
|
+
name: "Hsl",
|
|
16540
|
+
latexTrigger: ["\\operatorname{hsl}"],
|
|
16541
|
+
kind: "function",
|
|
16542
|
+
serialize: (serializer, expr2) => "\\operatorname{hsl}" + serializer.wrapArguments(expr2)
|
|
16543
|
+
},
|
|
16544
|
+
{
|
|
16545
|
+
name: "Oklab",
|
|
16546
|
+
latexTrigger: ["\\operatorname{oklab}"],
|
|
16547
|
+
kind: "function",
|
|
16548
|
+
serialize: (serializer, expr2) => "\\operatorname{oklab}" + serializer.wrapArguments(expr2)
|
|
16549
|
+
},
|
|
16550
|
+
{
|
|
16551
|
+
name: "Oklch",
|
|
16552
|
+
latexTrigger: ["\\operatorname{oklch}"],
|
|
16553
|
+
kind: "function",
|
|
16554
|
+
serialize: (serializer, expr2) => "\\operatorname{oklch}" + serializer.wrapArguments(expr2)
|
|
16555
|
+
},
|
|
16556
|
+
// Conversion functions (color → color in the named space)
|
|
16557
|
+
{
|
|
16558
|
+
name: "AsRgb",
|
|
16559
|
+
latexTrigger: ["\\operatorname{asRgb}"],
|
|
16560
|
+
kind: "function",
|
|
16561
|
+
serialize: (serializer, expr2) => "\\operatorname{asRgb}" + serializer.wrapArguments(expr2)
|
|
16562
|
+
},
|
|
16563
|
+
{
|
|
16564
|
+
name: "AsHsv",
|
|
16565
|
+
latexTrigger: ["\\operatorname{asHsv}"],
|
|
16566
|
+
kind: "function",
|
|
16567
|
+
serialize: (serializer, expr2) => "\\operatorname{asHsv}" + serializer.wrapArguments(expr2)
|
|
16568
|
+
},
|
|
16569
|
+
{
|
|
16570
|
+
name: "AsHsl",
|
|
16571
|
+
latexTrigger: ["\\operatorname{asHsl}"],
|
|
16572
|
+
kind: "function",
|
|
16573
|
+
serialize: (serializer, expr2) => "\\operatorname{asHsl}" + serializer.wrapArguments(expr2)
|
|
16574
|
+
},
|
|
16575
|
+
{
|
|
16576
|
+
name: "AsOklab",
|
|
16577
|
+
latexTrigger: ["\\operatorname{asOklab}"],
|
|
16578
|
+
kind: "function",
|
|
16579
|
+
serialize: (serializer, expr2) => "\\operatorname{asOklab}" + serializer.wrapArguments(expr2)
|
|
16580
|
+
},
|
|
16581
|
+
{
|
|
16582
|
+
name: "AsOklch",
|
|
16583
|
+
latexTrigger: ["\\operatorname{asOklch}"],
|
|
16584
|
+
kind: "function",
|
|
16585
|
+
serialize: (serializer, expr2) => "\\operatorname{asOklch}" + serializer.wrapArguments(expr2)
|
|
16586
|
+
},
|
|
16587
|
+
// Perceptual difference (returns a scalar in [0, ~1])
|
|
16588
|
+
{
|
|
16589
|
+
name: "ColorDelta",
|
|
16590
|
+
latexTrigger: ["\\operatorname{colorDelta}"],
|
|
16591
|
+
kind: "function",
|
|
16592
|
+
serialize: (serializer, expr2) => "\\operatorname{colorDelta}" + serializer.wrapArguments(expr2)
|
|
16593
|
+
}
|
|
16383
16594
|
];
|
|
16384
16595
|
|
|
16385
16596
|
// src/compute-engine/latex-syntax/dictionary/default-dictionary.ts
|
|
@@ -16410,7 +16621,8 @@ var ComputeEngineCore = (() => {
|
|
|
16410
16621
|
...DEFINITIONS_STATISTICS,
|
|
16411
16622
|
...DEFINITIONS_UNITS,
|
|
16412
16623
|
...DEFINITIONS_OTHERS,
|
|
16413
|
-
...DEFINITIONS_PHYSICS
|
|
16624
|
+
...DEFINITIONS_PHYSICS,
|
|
16625
|
+
...DEFINITIONS_COLORS
|
|
16414
16626
|
];
|
|
16415
16627
|
|
|
16416
16628
|
// src/math-json/symbols.ts
|
|
@@ -16575,6 +16787,17 @@ var ComputeEngineCore = (() => {
|
|
|
16575
16787
|
} else if (Array.isArray(openTrigger) && openTrigger.length > 0) {
|
|
16576
16788
|
openTokens.push(openTrigger[0]);
|
|
16577
16789
|
}
|
|
16790
|
+
const closeTrigger = indexedEntry.closeTrigger;
|
|
16791
|
+
const closeTokens = /* @__PURE__ */ new Set();
|
|
16792
|
+
if (typeof closeTrigger === "string") {
|
|
16793
|
+
const variants = DELIMITER_SHORTHAND[closeTrigger];
|
|
16794
|
+
if (variants) for (const v of variants) closeTokens.add(v);
|
|
16795
|
+
else closeTokens.add(closeTrigger);
|
|
16796
|
+
if (closeTrigger === "||") closeTokens.add("|");
|
|
16797
|
+
} else if (Array.isArray(closeTrigger) && closeTrigger.length > 0) {
|
|
16798
|
+
closeTokens.add(closeTrigger[0]);
|
|
16799
|
+
}
|
|
16800
|
+
indexedEntry.closeTokens = closeTokens;
|
|
16578
16801
|
for (const token of openTokens) {
|
|
16579
16802
|
const existing = result.matchfixByOpen.get(token);
|
|
16580
16803
|
if (existing) {
|
|
@@ -16732,25 +16955,43 @@ var ComputeEngineCore = (() => {
|
|
|
16732
16955
|
result.arguments = entry.arguments;
|
|
16733
16956
|
return result;
|
|
16734
16957
|
}
|
|
16958
|
+
function serializeTabularBody(serializer, body) {
|
|
16959
|
+
if (!body) return "";
|
|
16960
|
+
if (operator(body) !== "List") return serializer.serialize(body);
|
|
16961
|
+
const rows = operands(body);
|
|
16962
|
+
if (rows.length === 0) return "";
|
|
16963
|
+
if (!rows.every((row) => operator(row) === "List"))
|
|
16964
|
+
return serializer.serialize(body);
|
|
16965
|
+
return rows.map(
|
|
16966
|
+
(row) => operands(row).map((cell) => serializer.serialize(cell)).join(" & ")
|
|
16967
|
+
).join(" \\\\\n");
|
|
16968
|
+
}
|
|
16735
16969
|
function makeSerializeHandler(entry, latexTrigger, idTrigger) {
|
|
16736
16970
|
if (typeof entry.serialize === "function") return entry.serialize;
|
|
16737
16971
|
const kind = entry["kind"] ?? "expression";
|
|
16738
16972
|
if (kind === "environment") {
|
|
16739
16973
|
const envName = entry["symbolTrigger"] ?? entry.name ?? "unknown";
|
|
16740
|
-
return (serializer, expr2) =>
|
|
16741
|
-
|
|
16742
|
-
|
|
16743
|
-
|
|
16744
|
-
|
|
16974
|
+
return (serializer, expr2) => {
|
|
16975
|
+
const body = operand(expr2, 1);
|
|
16976
|
+
return joinLatex([
|
|
16977
|
+
`\\begin{${envName}}`,
|
|
16978
|
+
serializeTabularBody(serializer, body),
|
|
16979
|
+
`\\end{${envName}}`
|
|
16980
|
+
]);
|
|
16981
|
+
};
|
|
16745
16982
|
}
|
|
16746
16983
|
if (isMatchfixEntry(entry)) {
|
|
16747
16984
|
const openDelim = typeof entry.openTrigger === "string" ? DEFAULT_DELIMITER[entry.openTrigger] : tokensToString(entry.openTrigger);
|
|
16748
16985
|
const closeDelim = typeof entry.closeTrigger === "string" ? DEFAULT_DELIMITER[entry.closeTrigger] : tokensToString(entry.closeTrigger);
|
|
16749
|
-
return (serializer, expr2) =>
|
|
16750
|
-
|
|
16751
|
-
serializer.serialize(operand(expr2, 1))
|
|
16752
|
-
|
|
16753
|
-
|
|
16986
|
+
return (serializer, expr2) => {
|
|
16987
|
+
const style = serializer.groupStyle(expr2, serializer.level + 1);
|
|
16988
|
+
const inner = serializer.serialize(operand(expr2, 1));
|
|
16989
|
+
if (style === "scaled")
|
|
16990
|
+
return joinLatex([`\\left${openDelim}`, inner, `\\right${closeDelim}`]);
|
|
16991
|
+
if (style === "big")
|
|
16992
|
+
return joinLatex([`\\Bigl${openDelim}`, inner, `\\Bigr${closeDelim}`]);
|
|
16993
|
+
return joinLatex([openDelim, inner, closeDelim]);
|
|
16994
|
+
};
|
|
16754
16995
|
}
|
|
16755
16996
|
let latex = entry.serialize;
|
|
16756
16997
|
if (latex === void 0 && latexTrigger) latex = tokensToString(latexTrigger);
|
|
@@ -17635,6 +17876,16 @@ var ComputeEngineCore = (() => {
|
|
|
17635
17876
|
}
|
|
17636
17877
|
|
|
17637
17878
|
// src/compute-engine/latex-syntax/parse.ts
|
|
17879
|
+
var _symbolToUnicode = null;
|
|
17880
|
+
function getSymbolToUnicode() {
|
|
17881
|
+
if (!_symbolToUnicode) {
|
|
17882
|
+
_symbolToUnicode = /* @__PURE__ */ new Map();
|
|
17883
|
+
for (const [, latex, codepoint] of SYMBOLS2) {
|
|
17884
|
+
_symbolToUnicode.set(latex, String.fromCodePoint(codepoint));
|
|
17885
|
+
}
|
|
17886
|
+
}
|
|
17887
|
+
return _symbolToUnicode;
|
|
17888
|
+
}
|
|
17638
17889
|
var DELIMITER_SHORTHAND2 = {
|
|
17639
17890
|
"(": ["\\lparen", "("],
|
|
17640
17891
|
")": ["\\rparen", ")"],
|
|
@@ -18082,6 +18333,35 @@ var ComputeEngineCore = (() => {
|
|
|
18082
18333
|
this.nextToken();
|
|
18083
18334
|
this.skipVisualSpace();
|
|
18084
18335
|
}
|
|
18336
|
+
if (this.match("\\hspace")) {
|
|
18337
|
+
this.match("*");
|
|
18338
|
+
this.parseStringGroup();
|
|
18339
|
+
this.skipVisualSpace();
|
|
18340
|
+
}
|
|
18341
|
+
if (this.match("\\hskip") || this.match("\\kern")) {
|
|
18342
|
+
this.skipSpace();
|
|
18343
|
+
if (!this.match("-")) this.match("+");
|
|
18344
|
+
while (/^[\d.]$/.test(this.peek)) this.nextToken();
|
|
18345
|
+
for (const unit of [
|
|
18346
|
+
"pt",
|
|
18347
|
+
"em",
|
|
18348
|
+
"mu",
|
|
18349
|
+
"ex",
|
|
18350
|
+
"mm",
|
|
18351
|
+
"cm",
|
|
18352
|
+
"in",
|
|
18353
|
+
"bp",
|
|
18354
|
+
"sp",
|
|
18355
|
+
"dd",
|
|
18356
|
+
"cc",
|
|
18357
|
+
"pc",
|
|
18358
|
+
"nc",
|
|
18359
|
+
"nd"
|
|
18360
|
+
]) {
|
|
18361
|
+
if (this.matchAll([...unit])) break;
|
|
18362
|
+
}
|
|
18363
|
+
this.skipVisualSpace();
|
|
18364
|
+
}
|
|
18085
18365
|
this.skipSpace();
|
|
18086
18366
|
}
|
|
18087
18367
|
match(token) {
|
|
@@ -18419,7 +18699,8 @@ var ComputeEngineCore = (() => {
|
|
|
18419
18699
|
} else if (token === "<space>") {
|
|
18420
18700
|
result += " ";
|
|
18421
18701
|
} else if (token[0] === "\\") {
|
|
18422
|
-
|
|
18702
|
+
const unicode = getSymbolToUnicode().get(token);
|
|
18703
|
+
result += unicode ?? token;
|
|
18423
18704
|
} else {
|
|
18424
18705
|
result += token;
|
|
18425
18706
|
}
|
|
@@ -18573,6 +18854,19 @@ var ComputeEngineCore = (() => {
|
|
|
18573
18854
|
}
|
|
18574
18855
|
for (const def of defs) {
|
|
18575
18856
|
this.index = start;
|
|
18857
|
+
if (def.closeTokens.size > 0) {
|
|
18858
|
+
let found = false;
|
|
18859
|
+
const tokens = this._tokens;
|
|
18860
|
+
for (let i = start; i < tokens.length; i++) {
|
|
18861
|
+
if (def.closeTokens.has(tokens[i])) {
|
|
18862
|
+
found = true;
|
|
18863
|
+
break;
|
|
18864
|
+
}
|
|
18865
|
+
}
|
|
18866
|
+
if (!found) continue;
|
|
18867
|
+
}
|
|
18868
|
+
if (typeof def.openTrigger === "string" && def.openTrigger === "." && !OPEN_DELIMITER_PREFIX[currentToken])
|
|
18869
|
+
continue;
|
|
18576
18870
|
const matched = this.matchDelimiter(def.openTrigger, def.closeTrigger);
|
|
18577
18871
|
if (!matched) continue;
|
|
18578
18872
|
const bodyStart = this.index;
|
|
@@ -19779,7 +20073,7 @@ var ComputeEngineCore = (() => {
|
|
|
19779
20073
|
sansserif: (s) => `\\mathsf{${s}}`,
|
|
19780
20074
|
monospace: (s) => `\\mathtt{${s}}`
|
|
19781
20075
|
};
|
|
19782
|
-
var
|
|
20076
|
+
var Serializer5 = class {
|
|
19783
20077
|
options;
|
|
19784
20078
|
dictionary;
|
|
19785
20079
|
level = -1;
|
|
@@ -19794,11 +20088,18 @@ var ComputeEngineCore = (() => {
|
|
|
19794
20088
|
/**
|
|
19795
20089
|
* Serialize the expression, and if the expression is an operator
|
|
19796
20090
|
* of precedence less than or equal to prec, wrap it in some parens.
|
|
19797
|
-
*
|
|
20091
|
+
*
|
|
20092
|
+
* Skip wrapping for matchfix operators (Abs, Floor, Ceil, Norm, etc.)
|
|
20093
|
+
* and Delimiter since they already have visible delimiters.
|
|
19798
20094
|
*/
|
|
19799
20095
|
wrap(expr2, prec) {
|
|
19800
20096
|
if (expr2 === null || expr2 === void 0) return "";
|
|
19801
20097
|
if (prec === void 0) {
|
|
20098
|
+
const name2 = operator(expr2);
|
|
20099
|
+
if (name2) {
|
|
20100
|
+
const def = this.dictionary.ids.get(name2);
|
|
20101
|
+
if (def?.kind === "matchfix") return this.serialize(expr2);
|
|
20102
|
+
}
|
|
19802
20103
|
return this.wrapString(
|
|
19803
20104
|
this.serialize(expr2),
|
|
19804
20105
|
this.options.groupStyle(expr2, this.level + 1)
|
|
@@ -20092,7 +20393,7 @@ var ComputeEngineCore = (() => {
|
|
|
20092
20393
|
return body;
|
|
20093
20394
|
}
|
|
20094
20395
|
function serializeLatex(expr2, dict, options) {
|
|
20095
|
-
const serializer = new
|
|
20396
|
+
const serializer = new Serializer5(dict, options);
|
|
20096
20397
|
return serializer.serialize(expr2);
|
|
20097
20398
|
}
|
|
20098
20399
|
|
|
@@ -32128,6 +32429,29 @@ ${lines.join("\n")}`;
|
|
|
32128
32429
|
signature: "(value*) -> number | list",
|
|
32129
32430
|
evaluate: (xs, { engine }) => evaluateMinMax(engine, xs, "Infimum")
|
|
32130
32431
|
},
|
|
32432
|
+
Distance: {
|
|
32433
|
+
description: "Euclidean distance between two points (tuples of numbers).",
|
|
32434
|
+
complexity: 6e3,
|
|
32435
|
+
signature: "(tuple, tuple) -> number",
|
|
32436
|
+
evaluate: ([a, b], { engine: ce }) => {
|
|
32437
|
+
if (!isFunction2(a) || !isFunction2(b))
|
|
32438
|
+
return ce.error("incompatible-type");
|
|
32439
|
+
if (a.operator !== "Tuple" || b.operator !== "Tuple")
|
|
32440
|
+
return ce.error("incompatible-type");
|
|
32441
|
+
if (a.ops.length !== b.ops.length || a.ops.length === 0)
|
|
32442
|
+
return ce.error("incompatible-type");
|
|
32443
|
+
let sumSq = 0;
|
|
32444
|
+
for (let i = 0; i < a.ops.length; i++) {
|
|
32445
|
+
const ai = a.ops[i].re;
|
|
32446
|
+
const bi = b.ops[i].re;
|
|
32447
|
+
if (!Number.isFinite(ai) || !Number.isFinite(bi))
|
|
32448
|
+
return ce.error("expected-value");
|
|
32449
|
+
const d = ai - bi;
|
|
32450
|
+
sumSq += d * d;
|
|
32451
|
+
}
|
|
32452
|
+
return ce.number(Math.sqrt(sumSq));
|
|
32453
|
+
}
|
|
32454
|
+
},
|
|
32131
32455
|
Product: {
|
|
32132
32456
|
description: "`Product(f, a, b)` computes the product of `f` from `a` to `b`",
|
|
32133
32457
|
wikidata: "Q901718",
|
|
@@ -32660,16 +32984,11 @@ ${lines.join("\n")}`;
|
|
|
32660
32984
|
);
|
|
32661
32985
|
let condFn;
|
|
32662
32986
|
if (typeof condition === "string") {
|
|
32663
|
-
const
|
|
32664
|
-
|
|
32665
|
-
const
|
|
32666
|
-
|
|
32667
|
-
|
|
32668
|
-
condFn = (x, _ce) => {
|
|
32669
|
-
const evaluated = condPattern.subs(x).evaluate();
|
|
32670
|
-
return isSymbol2(evaluated, "True");
|
|
32671
|
-
};
|
|
32672
|
-
}
|
|
32987
|
+
const condPattern = ce.parse(condition) ?? ce.expr("Nothing");
|
|
32988
|
+
condFn = (x, _ce) => {
|
|
32989
|
+
const evaluated = condPattern.subs(x).evaluate();
|
|
32990
|
+
return isSymbol2(evaluated, "True");
|
|
32991
|
+
};
|
|
32673
32992
|
} else {
|
|
32674
32993
|
if (condition !== void 0 && typeof condition !== "function")
|
|
32675
32994
|
throw new Error(
|
|
@@ -32771,6 +33090,15 @@ ${e.message}
|
|
|
32771
33090
|
function applyRule(rule, expr2, substitution, options) {
|
|
32772
33091
|
if (!rule) return null;
|
|
32773
33092
|
let canonical2 = options?.canonical ?? (expr2.isCanonical || expr2.isStructural);
|
|
33093
|
+
let { match: match2, replace: replace2, condition, id, onMatch, onBeforeMatch } = rule;
|
|
33094
|
+
const because = id ?? "";
|
|
33095
|
+
const ce = expr2.engine;
|
|
33096
|
+
if (canonical2 && match2) {
|
|
33097
|
+
const awc = getWildcards(match2);
|
|
33098
|
+
const canonicalMatch = match2.canonical;
|
|
33099
|
+
const bwc = getWildcards(canonicalMatch);
|
|
33100
|
+
if (!awc.every((x) => bwc.includes(x))) return null;
|
|
33101
|
+
}
|
|
32774
33102
|
let operandsMatched = false;
|
|
32775
33103
|
if (isFunction2(expr2) && options?.recursive) {
|
|
32776
33104
|
const newOps = expr2.ops.map((op) => {
|
|
@@ -32782,20 +33110,11 @@ ${e.message}
|
|
|
32782
33110
|
if (operandsMatched) {
|
|
32783
33111
|
if (!canonical2 && options?.canonical === void 0 && newOps.every((x) => x.isCanonical))
|
|
32784
33112
|
canonical2 = true;
|
|
32785
|
-
expr2 =
|
|
33113
|
+
expr2 = ce.function(expr2.operator, newOps, {
|
|
32786
33114
|
form: canonical2 ? "canonical" : "raw"
|
|
32787
33115
|
});
|
|
32788
33116
|
}
|
|
32789
33117
|
}
|
|
32790
|
-
let { match: match2, replace: replace2, condition, id, onMatch, onBeforeMatch } = rule;
|
|
32791
|
-
const because = id ?? "";
|
|
32792
|
-
if (canonical2 && match2) {
|
|
32793
|
-
const awc = getWildcards(match2);
|
|
32794
|
-
const canonicalMatch = match2.canonical;
|
|
32795
|
-
const bwc = getWildcards(canonicalMatch);
|
|
32796
|
-
if (!awc.every((x) => bwc.includes(x)))
|
|
32797
|
-
return operandsMatched ? { value: expr2, because } : null;
|
|
32798
|
-
}
|
|
32799
33118
|
const useVariations = rule.useVariations ?? options?.useVariations ?? false;
|
|
32800
33119
|
const matchPermutations = options?.matchPermutations ?? true;
|
|
32801
33120
|
onBeforeMatch?.(rule, expr2);
|
|
@@ -32814,7 +33133,7 @@ ${e.message}
|
|
|
32814
33133
|
...sub2
|
|
32815
33134
|
};
|
|
32816
33135
|
try {
|
|
32817
|
-
if (!condition(conditionSub,
|
|
33136
|
+
if (!condition(conditionSub, ce))
|
|
32818
33137
|
return operandsMatched ? { value: expr2, because } : null;
|
|
32819
33138
|
} catch (e) {
|
|
32820
33139
|
console.error(
|
|
@@ -32829,7 +33148,8 @@ ${e.message}
|
|
|
32829
33148
|
if (!canonical2 && options?.canonical === void 0 && replace2 instanceof _BoxedExpression && replace2.isCanonical)
|
|
32830
33149
|
canonical2 = true;
|
|
32831
33150
|
const result = typeof replace2 === "function" ? replace2(expr2, sub2) : replace2.subs(sub2, { canonical: canonical2 });
|
|
32832
|
-
if (!result)
|
|
33151
|
+
if (!result)
|
|
33152
|
+
return operandsMatched ? { value: canonical2 ? expr2.canonical : expr2, because } : null;
|
|
32833
33153
|
onMatch?.(rule, expr2, result);
|
|
32834
33154
|
if (isRuleStep(result))
|
|
32835
33155
|
return canonical2 ? { ...result, value: result.value.canonical } : result;
|
|
@@ -38403,6 +38723,40 @@ ${e.message}
|
|
|
38403
38723
|
else h = ((r - g) / d + 4) / 6;
|
|
38404
38724
|
return { h: h * 360, s, l };
|
|
38405
38725
|
}
|
|
38726
|
+
function hsvToRgb(h, s, v) {
|
|
38727
|
+
h = (h % 360 + 360) % 360;
|
|
38728
|
+
s = Math.max(0, Math.min(1, s));
|
|
38729
|
+
v = Math.max(0, Math.min(1, v));
|
|
38730
|
+
const c = v * s;
|
|
38731
|
+
const x = c * (1 - Math.abs(h / 60 % 2 - 1));
|
|
38732
|
+
const m = v - c;
|
|
38733
|
+
let r = 0, g = 0, b = 0;
|
|
38734
|
+
if (h < 60) [r, g, b] = [c, x, 0];
|
|
38735
|
+
else if (h < 120) [r, g, b] = [x, c, 0];
|
|
38736
|
+
else if (h < 180) [r, g, b] = [0, c, x];
|
|
38737
|
+
else if (h < 240) [r, g, b] = [0, x, c];
|
|
38738
|
+
else if (h < 300) [r, g, b] = [x, 0, c];
|
|
38739
|
+
else [r, g, b] = [c, 0, x];
|
|
38740
|
+
return { r: (r + m) * 255, g: (g + m) * 255, b: (b + m) * 255 };
|
|
38741
|
+
}
|
|
38742
|
+
function rgbToHsv(r, g, b) {
|
|
38743
|
+
r /= 255;
|
|
38744
|
+
g /= 255;
|
|
38745
|
+
b /= 255;
|
|
38746
|
+
const max2 = Math.max(r, g, b);
|
|
38747
|
+
const min2 = Math.min(r, g, b);
|
|
38748
|
+
const d = max2 - min2;
|
|
38749
|
+
let h = 0;
|
|
38750
|
+
if (d > 0) {
|
|
38751
|
+
if (max2 === r) h = (g - b) / d % 6;
|
|
38752
|
+
else if (max2 === g) h = (b - r) / d + 2;
|
|
38753
|
+
else h = (r - g) / d + 4;
|
|
38754
|
+
h *= 60;
|
|
38755
|
+
if (h < 0) h += 360;
|
|
38756
|
+
}
|
|
38757
|
+
const s = max2 === 0 ? 0 : d / max2;
|
|
38758
|
+
return { h, s, v: max2 };
|
|
38759
|
+
}
|
|
38406
38760
|
function parseHexColor(s) {
|
|
38407
38761
|
const hex = s.startsWith("#") ? s.substring(1) : s;
|
|
38408
38762
|
let r, g, b;
|
|
@@ -38427,6 +38781,12 @@ ${e.message}
|
|
|
38427
38781
|
if (alpha !== void 0) result.alpha = alpha;
|
|
38428
38782
|
return result;
|
|
38429
38783
|
}
|
|
38784
|
+
function asOklch(color) {
|
|
38785
|
+
if (typeof color === "string") return rgbToOklch(parseHexColor(color));
|
|
38786
|
+
if ("C" in color) return color;
|
|
38787
|
+
if ("a" in color && "b" in color) return oklabToOklch(color);
|
|
38788
|
+
return rgbToOklch(color);
|
|
38789
|
+
}
|
|
38430
38790
|
function asRgb(color) {
|
|
38431
38791
|
if (typeof color === "number") {
|
|
38432
38792
|
return {
|
|
@@ -38858,6 +39218,13 @@ ${e.message}
|
|
|
38858
39218
|
};
|
|
38859
39219
|
function parseColor(s, darkMode) {
|
|
38860
39220
|
const str = s.trim().toLowerCase();
|
|
39221
|
+
const opacityMatch = str.match(/^(.+?)\s*\/\s*(\d+(?:\.\d+)?)%?\s*$/);
|
|
39222
|
+
if (opacityMatch) {
|
|
39223
|
+
const base = parseColor(opacityMatch[1].trim(), darkMode);
|
|
39224
|
+
const opacity = Math.max(0, Math.min(100, parseFloat(opacityMatch[2])));
|
|
39225
|
+
const alpha = Math.round(opacity / 100 * 255);
|
|
39226
|
+
return base & 4294967040 | alpha;
|
|
39227
|
+
}
|
|
38861
39228
|
if (str.startsWith("#")) {
|
|
38862
39229
|
const hex = str.substring(1);
|
|
38863
39230
|
let r, g, b, a = 255;
|
|
@@ -38990,14 +39357,6 @@ ${e.message}
|
|
|
38990
39357
|
console.warn(`parseColor: unrecognized color "${s}"`);
|
|
38991
39358
|
return 0;
|
|
38992
39359
|
}
|
|
38993
|
-
function parseColorToRgb01(s, darkMode) {
|
|
38994
|
-
const color = parseColor(s, darkMode);
|
|
38995
|
-
return [
|
|
38996
|
-
(color >>> 24 & 255) / 255,
|
|
38997
|
-
(color >>> 16 & 255) / 255,
|
|
38998
|
-
(color >>> 8 & 255) / 255
|
|
38999
|
-
];
|
|
39000
|
-
}
|
|
39001
39360
|
function apca(bgColor, fgColor) {
|
|
39002
39361
|
const bgRgb = asRgb(bgColor);
|
|
39003
39362
|
const fgRgb = asRgb(fgColor);
|
|
@@ -39056,6 +39415,12 @@ ${e.message}
|
|
|
39056
39415
|
const contrast2 = Math.abs(apca(fg2, bg));
|
|
39057
39416
|
return contrast1 >= contrast2 ? asColorNumber(fg1) : asColorNumber(fg2);
|
|
39058
39417
|
}
|
|
39418
|
+
function oklabDeltaE(a, b) {
|
|
39419
|
+
const dL = a.L - b.L;
|
|
39420
|
+
const da = a.a - b.a;
|
|
39421
|
+
const db = a.b - b.b;
|
|
39422
|
+
return Math.sqrt(dL * dL + da * da + db * db);
|
|
39423
|
+
}
|
|
39059
39424
|
function lerpOklch(c1, c2, f) {
|
|
39060
39425
|
const L = c1.L + (c2.L - c1.L) * f;
|
|
39061
39426
|
const C = c1.C + (c2.C - c1.C) * f;
|
|
@@ -41817,14 +42182,30 @@ ${e.message}
|
|
|
41817
42182
|
};
|
|
41818
42183
|
|
|
41819
42184
|
// src/compute-engine/library/colors.ts
|
|
41820
|
-
function
|
|
41821
|
-
|
|
41822
|
-
|
|
41823
|
-
|
|
41824
|
-
|
|
41825
|
-
|
|
41826
|
-
|
|
41827
|
-
|
|
42185
|
+
function normalizeAlpha(a) {
|
|
42186
|
+
if (a === void 0) return void 0;
|
|
42187
|
+
if (!Number.isFinite(a)) return void 0;
|
|
42188
|
+
if (Math.abs(a - 1) < 1e-9) return void 0;
|
|
42189
|
+
return a;
|
|
42190
|
+
}
|
|
42191
|
+
function normalizeColorHead(ce, expr2) {
|
|
42192
|
+
if (!isFunction2(expr2) || !expr2.ops || expr2.ops.length < 4) return expr2;
|
|
42193
|
+
const alphaExpr = expr2.ops[3];
|
|
42194
|
+
if (!isNumber(alphaExpr)) return expr2;
|
|
42195
|
+
if (normalizeAlpha(alphaExpr.re) === void 0) {
|
|
42196
|
+
return ce.function(expr2.operator, [expr2.ops[0], expr2.ops[1], expr2.ops[2]]);
|
|
42197
|
+
}
|
|
42198
|
+
return expr2;
|
|
42199
|
+
}
|
|
42200
|
+
function colorNumberToOklch(ce, color) {
|
|
42201
|
+
const r = color >>> 24 & 255;
|
|
42202
|
+
const g = color >>> 16 & 255;
|
|
42203
|
+
const b = color >>> 8 & 255;
|
|
42204
|
+
const a = normalizeAlpha((color & 255) / 255);
|
|
42205
|
+
const c = rgbToOklch({ r, g, b });
|
|
42206
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42207
|
+
if (a !== void 0) args.push(ce.number(a));
|
|
42208
|
+
return ce.function("Oklch", args);
|
|
41828
42209
|
}
|
|
41829
42210
|
var ALL_PALETTES = {
|
|
41830
42211
|
...SEQUENTIAL_PALETTES,
|
|
@@ -41835,45 +42216,139 @@ ${e.message}
|
|
|
41835
42216
|
t = Math.max(0, Math.min(1, t));
|
|
41836
42217
|
const n = palette.length;
|
|
41837
42218
|
if (n === 0) return ce.error("expected-value");
|
|
41838
|
-
if (n === 1) return
|
|
42219
|
+
if (n === 1) return colorNumberToOklch(ce, parseColor(palette[0]));
|
|
41839
42220
|
const pos = t * (n - 1);
|
|
41840
42221
|
const i = Math.floor(pos);
|
|
41841
42222
|
const frac = pos - i;
|
|
41842
|
-
if (i >= n - 1) return
|
|
41843
|
-
if (frac < 1e-9) return
|
|
41844
|
-
|
|
41845
|
-
|
|
41846
|
-
|
|
41847
|
-
|
|
41848
|
-
|
|
42223
|
+
if (i >= n - 1) return colorNumberToOklch(ce, parseColor(palette[n - 1]));
|
|
42224
|
+
if (frac < 1e-9) return colorNumberToOklch(ce, parseColor(palette[i]));
|
|
42225
|
+
return oklchToExpr(
|
|
42226
|
+
ce,
|
|
42227
|
+
asOklch(interpolateOklch(palette[i], palette[i + 1], frac))
|
|
42228
|
+
);
|
|
42229
|
+
}
|
|
42230
|
+
var COLOR_OPERATORS = /* @__PURE__ */ new Set(["Rgb", "Hsv", "Hsl", "Oklab", "Oklch"]);
|
|
42231
|
+
function readColorExpr(arg) {
|
|
42232
|
+
if (!isFunction2(arg)) return null;
|
|
42233
|
+
if (!COLOR_OPERATORS.has(arg.operator)) return null;
|
|
42234
|
+
if (!arg.ops || arg.ops.length < 3) return null;
|
|
42235
|
+
const c0 = arg.ops[0].re;
|
|
42236
|
+
const c1 = arg.ops[1].re;
|
|
42237
|
+
const c2 = arg.ops[2].re;
|
|
42238
|
+
if (!Number.isFinite(c0) || !Number.isFinite(c1) || !Number.isFinite(c2))
|
|
42239
|
+
return null;
|
|
42240
|
+
const alpha = arg.ops.length >= 4 ? normalizeAlpha(arg.ops[3].re) : void 0;
|
|
42241
|
+
return { space: arg.operator, c0, c1, c2, alpha };
|
|
42242
|
+
}
|
|
42243
|
+
function colorExprToRgb(arg) {
|
|
42244
|
+
const c = readColorExpr(arg);
|
|
42245
|
+
if (!c) return null;
|
|
42246
|
+
const withAlpha = (rgb) => c.alpha !== void 0 ? { ...rgb, alpha: c.alpha } : rgb;
|
|
42247
|
+
switch (c.space) {
|
|
42248
|
+
case "Rgb":
|
|
42249
|
+
return withAlpha({ r: c.c0 * 255, g: c.c1 * 255, b: c.c2 * 255 });
|
|
42250
|
+
case "Hsv":
|
|
42251
|
+
return withAlpha(hsvToRgb(c.c0, c.c1, c.c2));
|
|
42252
|
+
case "Hsl":
|
|
42253
|
+
return withAlpha(hslToRgb(c.c0, c.c1, c.c2));
|
|
42254
|
+
case "Oklab":
|
|
42255
|
+
return withAlpha(oklabToRgb({ L: c.c0, a: c.c1, b: c.c2 }));
|
|
42256
|
+
case "Oklch":
|
|
42257
|
+
return withAlpha(oklchToRgb({ L: c.c0, C: c.c1, H: c.c2 }));
|
|
42258
|
+
}
|
|
42259
|
+
return null;
|
|
42260
|
+
}
|
|
42261
|
+
function colorExprToOklch(arg) {
|
|
42262
|
+
const c = readColorExpr(arg);
|
|
42263
|
+
if (!c) return null;
|
|
42264
|
+
switch (c.space) {
|
|
42265
|
+
case "Oklch":
|
|
42266
|
+
return asOklch({ L: c.c0, C: c.c1, H: c.c2, alpha: c.alpha });
|
|
42267
|
+
case "Oklab":
|
|
42268
|
+
return asOklch({ L: c.c0, a: c.c1, b: c.c2, alpha: c.alpha });
|
|
42269
|
+
case "Rgb":
|
|
42270
|
+
return asOklch({
|
|
42271
|
+
r: c.c0 * 255,
|
|
42272
|
+
g: c.c1 * 255,
|
|
42273
|
+
b: c.c2 * 255,
|
|
42274
|
+
alpha: c.alpha
|
|
42275
|
+
});
|
|
42276
|
+
case "Hsv": {
|
|
42277
|
+
const rgb = hsvToRgb(c.c0, c.c1, c.c2);
|
|
42278
|
+
return asOklch({ ...rgb, alpha: c.alpha });
|
|
42279
|
+
}
|
|
42280
|
+
case "Hsl": {
|
|
42281
|
+
const rgb = hslToRgb(c.c0, c.c1, c.c2);
|
|
42282
|
+
return asOklch({ r: rgb.r, g: rgb.g, b: rgb.b, alpha: c.alpha });
|
|
42283
|
+
}
|
|
42284
|
+
}
|
|
42285
|
+
return null;
|
|
42286
|
+
}
|
|
42287
|
+
function toOklch(ce, arg) {
|
|
42288
|
+
const direct = colorExprToOklch(arg);
|
|
42289
|
+
if (direct) return direct;
|
|
42290
|
+
const rgb = extractRgb(ce, arg);
|
|
42291
|
+
return rgb ? asOklch(rgb) : null;
|
|
42292
|
+
}
|
|
42293
|
+
function lerpOklchColor(a, b, t) {
|
|
42294
|
+
const L = a.L + (b.L - a.L) * t;
|
|
42295
|
+
const C = a.C + (b.C - a.C) * t;
|
|
42296
|
+
const aAchromatic = a.C < 1e-6;
|
|
42297
|
+
const bAchromatic = b.C < 1e-6;
|
|
42298
|
+
let H;
|
|
42299
|
+
if (aAchromatic && bAchromatic) H = a.H;
|
|
42300
|
+
else if (aAchromatic) H = b.H;
|
|
42301
|
+
else if (bAchromatic) H = a.H;
|
|
42302
|
+
else {
|
|
42303
|
+
let dH = b.H - a.H;
|
|
42304
|
+
if (dH > 180) dH -= 360;
|
|
42305
|
+
if (dH < -180) dH += 360;
|
|
42306
|
+
H = a.H + dH * t;
|
|
42307
|
+
if (H < 0) H += 360;
|
|
42308
|
+
if (H >= 360) H -= 360;
|
|
42309
|
+
}
|
|
42310
|
+
const alphaA = a.alpha ?? 1;
|
|
42311
|
+
const alphaB = b.alpha ?? 1;
|
|
42312
|
+
return { L, C, H, alpha: normalizeAlpha(alphaA + (alphaB - alphaA) * t) };
|
|
42313
|
+
}
|
|
42314
|
+
function oklchToExpr(ce, c) {
|
|
42315
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42316
|
+
if (c.alpha !== void 0) args.push(ce.number(c.alpha));
|
|
42317
|
+
return ce.function("Oklch", args);
|
|
41849
42318
|
}
|
|
41850
42319
|
function extractRgb(ce, arg) {
|
|
41851
42320
|
if (isString(arg)) {
|
|
41852
42321
|
const s = arg.string;
|
|
41853
42322
|
if (!s) return void 0;
|
|
41854
42323
|
const color = parseColor(s);
|
|
41855
|
-
|
|
42324
|
+
const rgb = {
|
|
41856
42325
|
r: color >>> 24 & 255,
|
|
41857
42326
|
g: color >>> 16 & 255,
|
|
41858
|
-
b: color >>> 8 & 255
|
|
41859
|
-
alpha: (color & 255) / 255
|
|
42327
|
+
b: color >>> 8 & 255
|
|
41860
42328
|
};
|
|
42329
|
+
const alpha = normalizeAlpha((color & 255) / 255);
|
|
42330
|
+
if (alpha !== void 0) rgb.alpha = alpha;
|
|
42331
|
+
return rgb;
|
|
41861
42332
|
}
|
|
42333
|
+
const fromTyped = colorExprToRgb(arg);
|
|
42334
|
+
if (fromTyped) return fromTyped;
|
|
41862
42335
|
if (arg.operator === "Tuple" && arg.ops && arg.ops.length >= 3) {
|
|
41863
42336
|
const rgb = {
|
|
41864
42337
|
r: arg.ops[0].re * 255,
|
|
41865
42338
|
g: arg.ops[1].re * 255,
|
|
41866
42339
|
b: arg.ops[2].re * 255
|
|
41867
42340
|
};
|
|
41868
|
-
if (arg.ops.length >= 4)
|
|
42341
|
+
if (arg.ops.length >= 4) {
|
|
42342
|
+
const alpha = normalizeAlpha(arg.ops[3].re);
|
|
42343
|
+
if (alpha !== void 0) rgb.alpha = alpha;
|
|
42344
|
+
}
|
|
41869
42345
|
return rgb;
|
|
41870
42346
|
}
|
|
41871
42347
|
return void 0;
|
|
41872
42348
|
}
|
|
41873
42349
|
function componentsTuple(ce, components, alpha) {
|
|
41874
42350
|
const args = components.map((v) => ce.number(v));
|
|
41875
|
-
if (alpha !== void 0
|
|
41876
|
-
args.push(ce.number(alpha));
|
|
42351
|
+
if (alpha !== void 0) args.push(ce.number(alpha));
|
|
41877
42352
|
return ce.tuple(...args);
|
|
41878
42353
|
}
|
|
41879
42354
|
function rgbToHex(rgb) {
|
|
@@ -41881,7 +42356,7 @@ ${e.message}
|
|
|
41881
42356
|
const g = Math.round(Math.max(0, Math.min(255, rgb.g)));
|
|
41882
42357
|
const b = Math.round(Math.max(0, Math.min(255, rgb.b)));
|
|
41883
42358
|
const hex = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
41884
|
-
if (rgb.alpha !== void 0
|
|
42359
|
+
if (rgb.alpha !== void 0) {
|
|
41885
42360
|
const a = Math.round(Math.max(0, Math.min(255, rgb.alpha * 255)));
|
|
41886
42361
|
return hex + a.toString(16).padStart(2, "0");
|
|
41887
42362
|
}
|
|
@@ -41889,22 +42364,29 @@ ${e.message}
|
|
|
41889
42364
|
}
|
|
41890
42365
|
var COLORS_LIBRARY = {
|
|
41891
42366
|
Color: {
|
|
41892
|
-
description: "
|
|
42367
|
+
description: "Parse a CSS-style color string to an Oklch color",
|
|
41893
42368
|
complexity: 8e3,
|
|
41894
|
-
signature: "(string) ->
|
|
42369
|
+
signature: "(string) -> color",
|
|
41895
42370
|
evaluate: (ops, { engine: ce }) => {
|
|
41896
42371
|
const input = isString(ops[0]) ? ops[0].string : void 0;
|
|
41897
42372
|
if (!input) return ce.error("incompatible-type");
|
|
41898
42373
|
const color = parseColor(input);
|
|
41899
42374
|
if (color === 0 && input.trim().toLowerCase() !== "transparent")
|
|
41900
42375
|
return ce.error("incompatible-type");
|
|
41901
|
-
|
|
42376
|
+
const r = color >>> 24 & 255;
|
|
42377
|
+
const g = color >>> 16 & 255;
|
|
42378
|
+
const b = color >>> 8 & 255;
|
|
42379
|
+
const a = normalizeAlpha((color & 255) / 255);
|
|
42380
|
+
const c = rgbToOklch({ r, g, b });
|
|
42381
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42382
|
+
if (a !== void 0) args.push(ce.number(a));
|
|
42383
|
+
return ce.function("Oklch", args);
|
|
41902
42384
|
}
|
|
41903
42385
|
},
|
|
41904
42386
|
ColorToString: {
|
|
41905
42387
|
description: "Convert a color to a string in the specified format",
|
|
41906
42388
|
complexity: 8e3,
|
|
41907
|
-
signature: "(
|
|
42389
|
+
signature: "(color | string | tuple, string?) -> string",
|
|
41908
42390
|
evaluate: (ops, { engine: ce }) => {
|
|
41909
42391
|
const rgb = extractRgb(ce, ops[0]);
|
|
41910
42392
|
if (!rgb) return ce.error("incompatible-type");
|
|
@@ -41916,7 +42398,7 @@ ${e.message}
|
|
|
41916
42398
|
const r = Math.round(rgb.r);
|
|
41917
42399
|
const g = Math.round(rgb.g);
|
|
41918
42400
|
const b = Math.round(rgb.b);
|
|
41919
|
-
if (rgb.alpha !== void 0
|
|
42401
|
+
if (rgb.alpha !== void 0)
|
|
41920
42402
|
return ce.string(`rgb(${r} ${g} ${b} / ${rgb.alpha})`);
|
|
41921
42403
|
return ce.string(`rgb(${r} ${g} ${b})`);
|
|
41922
42404
|
}
|
|
@@ -41925,17 +42407,17 @@ ${e.message}
|
|
|
41925
42407
|
const h = Math.round(hsl.h * 10) / 10;
|
|
41926
42408
|
const s = Math.round(hsl.s * 1e3) / 10;
|
|
41927
42409
|
const l = Math.round(hsl.l * 1e3) / 10;
|
|
41928
|
-
if (rgb.alpha !== void 0
|
|
42410
|
+
if (rgb.alpha !== void 0)
|
|
41929
42411
|
return ce.string(`hsl(${h} ${s}% ${l}% / ${rgb.alpha})`);
|
|
41930
42412
|
return ce.string(`hsl(${h} ${s}% ${l}%)`);
|
|
41931
42413
|
}
|
|
41932
42414
|
case "oklch": {
|
|
41933
|
-
const c =
|
|
42415
|
+
const c = colorExprToOklch(ops[0]) ?? asOklch(rgb);
|
|
41934
42416
|
const L = Math.round(c.L * 1e3) / 1e3;
|
|
41935
42417
|
const C = Math.round(c.C * 1e3) / 1e3;
|
|
41936
42418
|
const H = Math.round(c.H * 10) / 10;
|
|
41937
|
-
if (
|
|
41938
|
-
return ce.string(`oklch(${L} ${C} ${H} / ${
|
|
42419
|
+
if (c.alpha !== void 0)
|
|
42420
|
+
return ce.string(`oklch(${L} ${C} ${H} / ${c.alpha})`);
|
|
41939
42421
|
return ce.string(`oklch(${L} ${C} ${H})`);
|
|
41940
42422
|
}
|
|
41941
42423
|
default:
|
|
@@ -41946,60 +42428,44 @@ ${e.message}
|
|
|
41946
42428
|
ColorMix: {
|
|
41947
42429
|
description: "Mix two colors in OKLCh space",
|
|
41948
42430
|
complexity: 8e3,
|
|
41949
|
-
signature: "(
|
|
42431
|
+
signature: "(color | string | tuple, color | string | tuple, number?) -> color",
|
|
41950
42432
|
evaluate: (ops, { engine: ce }) => {
|
|
41951
|
-
const rgb1 = extractRgb(ce, ops[0]);
|
|
41952
|
-
const rgb2 = extractRgb(ce, ops[1]);
|
|
41953
|
-
if (!rgb1 || !rgb2) return ce.error("incompatible-type");
|
|
41954
42433
|
let ratio = 0.5;
|
|
41955
42434
|
if (ops.length >= 3 && ops[2] !== void 0) {
|
|
41956
42435
|
ratio = ops[2].re;
|
|
41957
42436
|
if (!Number.isFinite(ratio)) return ce.error("expected-value");
|
|
41958
42437
|
ratio = Math.max(0, Math.min(1, ratio));
|
|
41959
42438
|
}
|
|
41960
|
-
const
|
|
41961
|
-
const
|
|
41962
|
-
|
|
41963
|
-
|
|
41964
|
-
const g = mixed.g / 255;
|
|
41965
|
-
const b = mixed.b / 255;
|
|
41966
|
-
const a1 = rgb1.alpha ?? 1;
|
|
41967
|
-
const a2 = rgb2.alpha ?? 1;
|
|
41968
|
-
const alpha = a1 + (a2 - a1) * ratio;
|
|
41969
|
-
if (Math.abs(alpha - 1) > 1e-4)
|
|
41970
|
-
return ce.tuple(
|
|
41971
|
-
ce.number(r),
|
|
41972
|
-
ce.number(g),
|
|
41973
|
-
ce.number(b),
|
|
41974
|
-
ce.number(alpha)
|
|
41975
|
-
);
|
|
41976
|
-
return ce.tuple(ce.number(r), ce.number(g), ce.number(b));
|
|
42439
|
+
const oklch1 = toOklch(ce, ops[0]);
|
|
42440
|
+
const oklch2 = toOklch(ce, ops[1]);
|
|
42441
|
+
if (!oklch1 || !oklch2) return ce.error("incompatible-type");
|
|
42442
|
+
return oklchToExpr(ce, lerpOklchColor(oklch1, oklch2, ratio));
|
|
41977
42443
|
}
|
|
41978
42444
|
},
|
|
41979
42445
|
Colormap: {
|
|
41980
42446
|
description: "Sample colors from a named palette",
|
|
41981
42447
|
complexity: 8e3,
|
|
41982
|
-
signature: "(string, number?) ->
|
|
42448
|
+
signature: "(string, number?) -> color | list<color>",
|
|
41983
42449
|
evaluate: (ops, { engine: ce }) => {
|
|
41984
42450
|
const name = isString(ops[0]) ? ops[0].string : void 0;
|
|
41985
42451
|
if (!name) return ce.error("incompatible-type");
|
|
41986
42452
|
const palette = ALL_PALETTES[name];
|
|
41987
42453
|
if (!palette) return ce.error("expected-value", name);
|
|
41988
42454
|
if (ops.length < 2 || ops[1] === void 0) {
|
|
41989
|
-
const
|
|
41990
|
-
(hex) =>
|
|
42455
|
+
const colors = palette.map(
|
|
42456
|
+
(hex) => colorNumberToOklch(ce, parseColor(hex))
|
|
41991
42457
|
);
|
|
41992
|
-
return ce.function("List",
|
|
42458
|
+
return ce.function("List", colors);
|
|
41993
42459
|
}
|
|
41994
42460
|
const val = ops[1].re;
|
|
41995
42461
|
if (!Number.isFinite(val)) return ce.error("expected-value");
|
|
41996
42462
|
if (Number.isInteger(val) && val >= 2) {
|
|
41997
42463
|
const n = val;
|
|
41998
|
-
const
|
|
42464
|
+
const colors = [];
|
|
41999
42465
|
for (let i = 0; i < n; i++) {
|
|
42000
|
-
|
|
42466
|
+
colors.push(samplePalette(ce, palette, i / (n - 1)));
|
|
42001
42467
|
}
|
|
42002
|
-
return ce.function("List",
|
|
42468
|
+
return ce.function("List", colors);
|
|
42003
42469
|
}
|
|
42004
42470
|
return samplePalette(ce, palette, val);
|
|
42005
42471
|
}
|
|
@@ -42007,12 +42473,25 @@ ${e.message}
|
|
|
42007
42473
|
ColorToColorspace: {
|
|
42008
42474
|
description: "Convert a color to components in a target color space",
|
|
42009
42475
|
complexity: 8e3,
|
|
42010
|
-
signature: "(
|
|
42476
|
+
signature: "(color | string | tuple, string) -> tuple",
|
|
42011
42477
|
evaluate: (ops, { engine: ce }) => {
|
|
42012
|
-
const rgb = extractRgb(ce, ops[0]);
|
|
42013
|
-
if (!rgb) return ce.error("incompatible-type");
|
|
42014
42478
|
const space = isString(ops[1]) ? ops[1].string?.toLowerCase() : void 0;
|
|
42015
42479
|
if (!space) return ce.error("incompatible-type");
|
|
42480
|
+
if (space === "oklch" || space === "oklab" || space === "lab") {
|
|
42481
|
+
const oklch2 = colorExprToOklch(ops[0]);
|
|
42482
|
+
if (oklch2) {
|
|
42483
|
+
if (space === "oklch")
|
|
42484
|
+
return componentsTuple(
|
|
42485
|
+
ce,
|
|
42486
|
+
[oklch2.L, oklch2.C, oklch2.H],
|
|
42487
|
+
oklch2.alpha
|
|
42488
|
+
);
|
|
42489
|
+
const lab = oklchToOklab(oklch2);
|
|
42490
|
+
return componentsTuple(ce, [lab.L, lab.a, lab.b], lab.alpha);
|
|
42491
|
+
}
|
|
42492
|
+
}
|
|
42493
|
+
const rgb = extractRgb(ce, ops[0]);
|
|
42494
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42016
42495
|
const alpha = rgb.alpha;
|
|
42017
42496
|
switch (space) {
|
|
42018
42497
|
case "rgb":
|
|
@@ -42042,17 +42521,27 @@ ${e.message}
|
|
|
42042
42521
|
ColorFromColorspace: {
|
|
42043
42522
|
description: "Convert color space components to a canonical sRGB tuple",
|
|
42044
42523
|
complexity: 8e3,
|
|
42045
|
-
signature: "(tuple, string) -> tuple",
|
|
42524
|
+
signature: "(color | tuple, string) -> tuple",
|
|
42046
42525
|
evaluate: (ops, { engine: ce }) => {
|
|
42047
|
-
const tuple = ops[0];
|
|
42048
|
-
if (!isFunction2(tuple) || tuple.operator !== "Tuple" || tuple.ops.length < 3)
|
|
42049
|
-
return ce.error("incompatible-type");
|
|
42050
|
-
const c0 = tuple.ops[0].re;
|
|
42051
|
-
const c1 = tuple.ops[1].re;
|
|
42052
|
-
const c2 = tuple.ops[2].re;
|
|
42053
|
-
const alpha = tuple.ops.length >= 4 ? tuple.ops[3].re : void 0;
|
|
42054
42526
|
const space = isString(ops[1]) ? ops[1].string?.toLowerCase() : void 0;
|
|
42055
42527
|
if (!space) return ce.error("incompatible-type");
|
|
42528
|
+
let c0, c1, c2;
|
|
42529
|
+
let alpha;
|
|
42530
|
+
const arg = ops[0];
|
|
42531
|
+
const typed = readColorExpr(arg);
|
|
42532
|
+
if (typed) {
|
|
42533
|
+
c0 = typed.c0;
|
|
42534
|
+
c1 = typed.c1;
|
|
42535
|
+
c2 = typed.c2;
|
|
42536
|
+
alpha = typed.alpha;
|
|
42537
|
+
} else if (isFunction2(arg) && arg.operator === "Tuple" && arg.ops.length >= 3) {
|
|
42538
|
+
c0 = arg.ops[0].re;
|
|
42539
|
+
c1 = arg.ops[1].re;
|
|
42540
|
+
c2 = arg.ops[2].re;
|
|
42541
|
+
alpha = arg.ops.length >= 4 ? arg.ops[3].re : void 0;
|
|
42542
|
+
} else {
|
|
42543
|
+
return ce.error("incompatible-type");
|
|
42544
|
+
}
|
|
42056
42545
|
let rgb;
|
|
42057
42546
|
switch (space) {
|
|
42058
42547
|
case "rgb":
|
|
@@ -42088,7 +42577,7 @@ ${e.message}
|
|
|
42088
42577
|
ColorContrast: {
|
|
42089
42578
|
description: "APCA contrast ratio between two colors",
|
|
42090
42579
|
complexity: 8e3,
|
|
42091
|
-
signature: "(
|
|
42580
|
+
signature: "(color | string | tuple, color | string | tuple) -> number",
|
|
42092
42581
|
evaluate: (ops, { engine: ce }) => {
|
|
42093
42582
|
const bgRgb = extractRgb(ce, ops[0]);
|
|
42094
42583
|
const fgRgb = extractRgb(ce, ops[1]);
|
|
@@ -42099,19 +42588,186 @@ ${e.message}
|
|
|
42099
42588
|
ContrastingColor: {
|
|
42100
42589
|
description: "Choose the foreground color with better APCA contrast against a background",
|
|
42101
42590
|
complexity: 8e3,
|
|
42102
|
-
signature: "(
|
|
42591
|
+
signature: "(color | string | tuple, (color | string | tuple)?, (color | string | tuple)?) -> color",
|
|
42103
42592
|
evaluate: (ops, { engine: ce }) => {
|
|
42104
42593
|
const bgRgb = extractRgb(ce, ops[0]);
|
|
42105
42594
|
if (!bgRgb) return ce.error("incompatible-type");
|
|
42595
|
+
let packed;
|
|
42106
42596
|
if (ops.length >= 3 && ops[1] !== void 0 && ops[2] !== void 0) {
|
|
42107
42597
|
const fg1 = extractRgb(ce, ops[1]);
|
|
42108
42598
|
const fg2 = extractRgb(ce, ops[2]);
|
|
42109
42599
|
if (!fg1 || !fg2) return ce.error("incompatible-type");
|
|
42110
|
-
|
|
42111
|
-
|
|
42600
|
+
packed = contrastingColor({ bg: bgRgb, fg1, fg2 });
|
|
42601
|
+
} else {
|
|
42602
|
+
packed = contrastingColor(bgRgb);
|
|
42603
|
+
}
|
|
42604
|
+
const r = (packed >>> 24 & 255) / 255;
|
|
42605
|
+
const g = (packed >>> 16 & 255) / 255;
|
|
42606
|
+
const b = (packed >>> 8 & 255) / 255;
|
|
42607
|
+
const alpha = normalizeAlpha((packed & 255) / 255);
|
|
42608
|
+
const args = [ce.number(r), ce.number(g), ce.number(b)];
|
|
42609
|
+
if (alpha !== void 0) args.push(ce.number(alpha));
|
|
42610
|
+
return ce.function("Rgb", args);
|
|
42611
|
+
}
|
|
42612
|
+
},
|
|
42613
|
+
// ---------------------------------------------------------------------------
|
|
42614
|
+
// Color constructors. Each preserves its colorspace on evaluation; the
|
|
42615
|
+
// operator name is the discriminator. Components are interpreted per
|
|
42616
|
+
// colorspace conventions (Rgb channels 0-1, Hsv/Hsl hue in degrees with
|
|
42617
|
+
// sat/value 0-1, Oklab/Oklch L 0-1 with standard a/b/C/H ranges). The
|
|
42618
|
+
// optional 4th argument is alpha in [0, 1]. No clamping at evaluation time.
|
|
42619
|
+
// ---------------------------------------------------------------------------
|
|
42620
|
+
Rgb: {
|
|
42621
|
+
description: "sRGB color (channels 0-1, optional alpha 0-1)",
|
|
42622
|
+
complexity: 8e3,
|
|
42623
|
+
signature: "(number, number, number, number?) -> color"
|
|
42624
|
+
},
|
|
42625
|
+
Hsv: {
|
|
42626
|
+
description: "HSV color (hue degrees, saturation/value 0-1, optional alpha)",
|
|
42627
|
+
complexity: 8e3,
|
|
42628
|
+
signature: "(number, number, number, number?) -> color"
|
|
42629
|
+
},
|
|
42630
|
+
Hsl: {
|
|
42631
|
+
description: "HSL color (hue degrees, saturation/lightness 0-1, optional alpha)",
|
|
42632
|
+
complexity: 8e3,
|
|
42633
|
+
signature: "(number, number, number, number?) -> color"
|
|
42634
|
+
},
|
|
42635
|
+
Oklab: {
|
|
42636
|
+
description: "OKLab color (L 0-1, a/b ~ -0.4..0.4, optional alpha)",
|
|
42637
|
+
complexity: 8e3,
|
|
42638
|
+
signature: "(number, number, number, number?) -> color"
|
|
42639
|
+
},
|
|
42640
|
+
Oklch: {
|
|
42641
|
+
description: "OKLCh color (L 0-1, C 0-~0.4, hue degrees, optional alpha)",
|
|
42642
|
+
complexity: 8e3,
|
|
42643
|
+
signature: "(number, number, number, number?) -> color"
|
|
42644
|
+
},
|
|
42645
|
+
// ---------------------------------------------------------------------------
|
|
42646
|
+
// Color-space conversions. Each accepts any of the five color heads and
|
|
42647
|
+
// returns the same color in the named space. If the input is already in
|
|
42648
|
+
// the target space, returns the input unchanged.
|
|
42649
|
+
// ---------------------------------------------------------------------------
|
|
42650
|
+
AsRgb: {
|
|
42651
|
+
description: "Convert any color to sRGB (channels 0-1)",
|
|
42652
|
+
complexity: 8e3,
|
|
42653
|
+
signature: "(color) -> color",
|
|
42654
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42655
|
+
const arg = ops[0];
|
|
42656
|
+
if (isFunction2(arg) && arg.operator === "Rgb")
|
|
42657
|
+
return normalizeColorHead(ce, arg);
|
|
42658
|
+
const rgb = colorExprToRgb(arg);
|
|
42659
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42660
|
+
const args = [
|
|
42661
|
+
ce.number(rgb.r / 255),
|
|
42662
|
+
ce.number(rgb.g / 255),
|
|
42663
|
+
ce.number(rgb.b / 255)
|
|
42664
|
+
];
|
|
42665
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42666
|
+
return ce.function("Rgb", args);
|
|
42667
|
+
}
|
|
42668
|
+
},
|
|
42669
|
+
AsHsv: {
|
|
42670
|
+
description: "Convert any color to HSV (hue degrees, s/v 0-1)",
|
|
42671
|
+
complexity: 8e3,
|
|
42672
|
+
signature: "(color) -> color",
|
|
42673
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42674
|
+
const arg = ops[0];
|
|
42675
|
+
if (isFunction2(arg) && arg.operator === "Hsv")
|
|
42676
|
+
return normalizeColorHead(ce, arg);
|
|
42677
|
+
const rgb = colorExprToRgb(arg);
|
|
42678
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42679
|
+
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
42680
|
+
const args = [ce.number(hsv.h), ce.number(hsv.s), ce.number(hsv.v)];
|
|
42681
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42682
|
+
return ce.function("Hsv", args);
|
|
42683
|
+
}
|
|
42684
|
+
},
|
|
42685
|
+
AsHsl: {
|
|
42686
|
+
description: "Convert any color to HSL (hue degrees, s/l 0-1)",
|
|
42687
|
+
complexity: 8e3,
|
|
42688
|
+
signature: "(color) -> color",
|
|
42689
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42690
|
+
const arg = ops[0];
|
|
42691
|
+
if (isFunction2(arg) && arg.operator === "Hsl")
|
|
42692
|
+
return normalizeColorHead(ce, arg);
|
|
42693
|
+
const rgb = colorExprToRgb(arg);
|
|
42694
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42695
|
+
const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
|
|
42696
|
+
const args = [ce.number(hsl.h), ce.number(hsl.s), ce.number(hsl.l)];
|
|
42697
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42698
|
+
return ce.function("Hsl", args);
|
|
42699
|
+
}
|
|
42700
|
+
},
|
|
42701
|
+
AsOklab: {
|
|
42702
|
+
description: "Convert any color to OKLab",
|
|
42703
|
+
complexity: 8e3,
|
|
42704
|
+
signature: "(color) -> color",
|
|
42705
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42706
|
+
const arg = ops[0];
|
|
42707
|
+
if (isFunction2(arg) && arg.operator === "Oklab")
|
|
42708
|
+
return normalizeColorHead(ce, arg);
|
|
42709
|
+
if (isFunction2(arg) && arg.operator === "Oklch") {
|
|
42710
|
+
const c = readColorExpr(arg);
|
|
42711
|
+
if (!c) return ce.error("incompatible-type");
|
|
42712
|
+
const lab2 = oklchToOklab({ L: c.c0, C: c.c1, H: c.c2, alpha: c.alpha });
|
|
42713
|
+
const args2 = [ce.number(lab2.L), ce.number(lab2.a), ce.number(lab2.b)];
|
|
42714
|
+
if (lab2.alpha !== void 0) args2.push(ce.number(lab2.alpha));
|
|
42715
|
+
return ce.function("Oklab", args2);
|
|
42716
|
+
}
|
|
42717
|
+
const rgb = colorExprToRgb(arg);
|
|
42718
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42719
|
+
const lab = rgbToOklab(rgb);
|
|
42720
|
+
const args = [ce.number(lab.L), ce.number(lab.a), ce.number(lab.b)];
|
|
42721
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42722
|
+
return ce.function("Oklab", args);
|
|
42723
|
+
}
|
|
42724
|
+
},
|
|
42725
|
+
AsOklch: {
|
|
42726
|
+
description: "Convert any color to OKLCh",
|
|
42727
|
+
complexity: 8e3,
|
|
42728
|
+
signature: "(color) -> color",
|
|
42729
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42730
|
+
const arg = ops[0];
|
|
42731
|
+
if (isFunction2(arg) && arg.operator === "Oklch")
|
|
42732
|
+
return normalizeColorHead(ce, arg);
|
|
42733
|
+
if (isFunction2(arg) && arg.operator === "Oklab") {
|
|
42734
|
+
const c2 = readColorExpr(arg);
|
|
42735
|
+
if (!c2) return ce.error("incompatible-type");
|
|
42736
|
+
const oklch2 = oklabToOklch({
|
|
42737
|
+
L: c2.c0,
|
|
42738
|
+
a: c2.c1,
|
|
42739
|
+
b: c2.c2,
|
|
42740
|
+
alpha: c2.alpha
|
|
42741
|
+
});
|
|
42742
|
+
const args2 = [
|
|
42743
|
+
ce.number(oklch2.L),
|
|
42744
|
+
ce.number(oklch2.C),
|
|
42745
|
+
ce.number(oklch2.H)
|
|
42746
|
+
];
|
|
42747
|
+
if (oklch2.alpha !== void 0) args2.push(ce.number(oklch2.alpha));
|
|
42748
|
+
return ce.function("Oklch", args2);
|
|
42112
42749
|
}
|
|
42113
|
-
const
|
|
42114
|
-
return
|
|
42750
|
+
const rgb = colorExprToRgb(arg);
|
|
42751
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42752
|
+
const c = rgbToOklch(rgb);
|
|
42753
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42754
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42755
|
+
return ce.function("Oklch", args);
|
|
42756
|
+
}
|
|
42757
|
+
},
|
|
42758
|
+
// ---------------------------------------------------------------------------
|
|
42759
|
+
// Perceptual difference. Returns ΔE_OK (Euclidean distance in OKLab),
|
|
42760
|
+
// an approximately perceptually uniform scalar.
|
|
42761
|
+
// ---------------------------------------------------------------------------
|
|
42762
|
+
ColorDelta: {
|
|
42763
|
+
description: "Perceptual color difference (\u0394E_OK) between two colors",
|
|
42764
|
+
complexity: 8e3,
|
|
42765
|
+
signature: "(color | string | tuple, color | string | tuple) -> number",
|
|
42766
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42767
|
+
const a = toOklch(ce, ops[0]);
|
|
42768
|
+
const b = toOklch(ce, ops[1]);
|
|
42769
|
+
if (!a || !b) return ce.error("incompatible-type");
|
|
42770
|
+
return ce.number(oklabDeltaE(oklchToOklab(a), oklchToOklab(b)));
|
|
42115
42771
|
}
|
|
42116
42772
|
}
|
|
42117
42773
|
};
|
|
@@ -42131,12 +42787,14 @@ ${e.message}
|
|
|
42131
42787
|
canonical: canonicalBlock,
|
|
42132
42788
|
evaluate: evaluateBlock
|
|
42133
42789
|
},
|
|
42134
|
-
// A condition expression tests for one or more conditions of an expression
|
|
42135
|
-
//
|
|
42790
|
+
// A condition expression tests for one or more conditions of an expression.
|
|
42791
|
+
// Two forms:
|
|
42792
|
+
// ['Condition', value, "positive"] — tests value against named condition(s)
|
|
42793
|
+
// ['Condition', predicate] — set-builder predicate (e.g. x > 0)
|
|
42136
42794
|
Condition: {
|
|
42137
42795
|
description: "Test whether a value satisfies one or more conditions.",
|
|
42138
42796
|
lazy: true,
|
|
42139
|
-
signature: "(
|
|
42797
|
+
signature: "(expression, symbol?) -> boolean",
|
|
42140
42798
|
evaluate: ([value, conds], { engine }) => {
|
|
42141
42799
|
let conditions = [];
|
|
42142
42800
|
if (isSymbol2(conds)) {
|
|
@@ -44589,6 +45247,34 @@ ${e.message}
|
|
|
44589
45247
|
signature: "() -> expression",
|
|
44590
45248
|
evaluate: (_ops, { engine }) => engine.expr(randomExpression())
|
|
44591
45249
|
}
|
|
45250
|
+
},
|
|
45251
|
+
// ---------------------------------------------------------------------------
|
|
45252
|
+
// Opaque typed heads — registered so the names are in the standard set
|
|
45253
|
+
// (consumers can branch on the operator name); CE itself does not evaluate
|
|
45254
|
+
// them. Geometric primitives `Triangle`/`Sphere`/`Segment` and the action
|
|
45255
|
+
// arrow `To` (`a \to b`).
|
|
45256
|
+
// ---------------------------------------------------------------------------
|
|
45257
|
+
{
|
|
45258
|
+
Triangle: {
|
|
45259
|
+
description: "Triangle primitive \u2014 opaque typed head.",
|
|
45260
|
+
signature: "(any+) -> expression"
|
|
45261
|
+
},
|
|
45262
|
+
GeometricVector: {
|
|
45263
|
+
description: "Geometric vector (directed segment between two points) \u2014 opaque typed head. Distinct from the column-vector `Vector` operator.",
|
|
45264
|
+
signature: "(any, any) -> expression"
|
|
45265
|
+
},
|
|
45266
|
+
Sphere: {
|
|
45267
|
+
description: "Sphere primitive \u2014 opaque typed head.",
|
|
45268
|
+
signature: "(any+) -> expression"
|
|
45269
|
+
},
|
|
45270
|
+
Segment: {
|
|
45271
|
+
description: "Segment primitive \u2014 opaque typed head.",
|
|
45272
|
+
signature: "(any+) -> expression"
|
|
45273
|
+
},
|
|
45274
|
+
To: {
|
|
45275
|
+
description: "Action arrow / mapping (`a \\to b`) \u2014 opaque typed head.",
|
|
45276
|
+
signature: "(any, any) -> nothing"
|
|
45277
|
+
}
|
|
44592
45278
|
}
|
|
44593
45279
|
];
|
|
44594
45280
|
|
|
@@ -51725,6 +52411,7 @@ Error in definition of "${name}"`,
|
|
|
51725
52411
|
|
|
51726
52412
|
// src/compute-engine/boxed-expression/cache.ts
|
|
51727
52413
|
function cachedValue(v, generation, fn) {
|
|
52414
|
+
if (v.generation === generation && v.value !== null) return v.value;
|
|
51728
52415
|
v.generation = generation;
|
|
51729
52416
|
v.value = fn();
|
|
51730
52417
|
return v.value;
|
|
@@ -53502,6 +54189,12 @@ Error in definition of "${name}"`,
|
|
|
53502
54189
|
function _escapeJsonString(s) {
|
|
53503
54190
|
return s;
|
|
53504
54191
|
}
|
|
54192
|
+
function _serializeLatexMetadata(ce, expr2) {
|
|
54193
|
+
const syntax = ce.latexSyntax;
|
|
54194
|
+
const opts = ce.latexOptions;
|
|
54195
|
+
if (Object.keys(opts).length === 0) return syntax.serialize(expr2);
|
|
54196
|
+
return syntax.serialize(expr2, { ...opts });
|
|
54197
|
+
}
|
|
53505
54198
|
function serializeSubtract(ce, a, b, options, metadata) {
|
|
53506
54199
|
if (isNumber(a) && a.isNegative) {
|
|
53507
54200
|
const v = a.numericValue;
|
|
@@ -53806,7 +54499,7 @@ Error in definition of "${name}"`,
|
|
|
53806
54499
|
];
|
|
53807
54500
|
const md = { ...metadata ?? {} };
|
|
53808
54501
|
if (options.metadata.includes("latex") && ce.latexSyntax) {
|
|
53809
|
-
md.latex = _escapeJsonString(md.latex ?? ce
|
|
54502
|
+
md.latex = _escapeJsonString(md.latex ?? _serializeLatexMetadata(ce, fn));
|
|
53810
54503
|
} else md.latex = "";
|
|
53811
54504
|
if (!options.metadata.includes("wikidata")) md.wikidata = "";
|
|
53812
54505
|
if (!md.latex && !md.wikidata && options.shorthands.includes("function"))
|
|
@@ -53831,7 +54524,7 @@ Error in definition of "${name}"`,
|
|
|
53831
54524
|
}
|
|
53832
54525
|
metadata = { ...metadata };
|
|
53833
54526
|
if (options.metadata.includes("latex") && ce.latexSyntax) {
|
|
53834
|
-
metadata.latex = metadata.latex ?? ce
|
|
54527
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, sym2);
|
|
53835
54528
|
if (metadata.latex !== void 0)
|
|
53836
54529
|
metadata.latex = _escapeJsonString(metadata.latex);
|
|
53837
54530
|
} else metadata.latex = void 0;
|
|
@@ -53993,7 +54686,7 @@ Error in definition of "${name}"`,
|
|
|
53993
54686
|
}
|
|
53994
54687
|
}
|
|
53995
54688
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
53996
|
-
metadata.latex = metadata.latex ?? ce
|
|
54689
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, result2 ?? { num });
|
|
53997
54690
|
if (result2) {
|
|
53998
54691
|
if (metadata.latex !== void 0)
|
|
53999
54692
|
return { sym: result2, latex: metadata.latex };
|
|
@@ -54009,7 +54702,7 @@ Error in definition of "${name}"`,
|
|
|
54009
54702
|
if (value.isNaN()) {
|
|
54010
54703
|
num = "NaN";
|
|
54011
54704
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
54012
|
-
metadata.latex = metadata.latex ?? ce
|
|
54705
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, { num });
|
|
54013
54706
|
return metadata.latex !== void 0 ? { num, latex: metadata.latex } : { num };
|
|
54014
54707
|
}
|
|
54015
54708
|
return serializeJsonFunction(
|
|
@@ -54043,7 +54736,7 @@ Error in definition of "${name}"`,
|
|
|
54043
54736
|
value = Number(value);
|
|
54044
54737
|
} else {
|
|
54045
54738
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
54046
|
-
metadata.latex = metadata.latex ?? ce
|
|
54739
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, {
|
|
54047
54740
|
num: value.toString()
|
|
54048
54741
|
});
|
|
54049
54742
|
if (metadata.latex !== void 0)
|
|
@@ -54057,7 +54750,7 @@ Error in definition of "${name}"`,
|
|
|
54057
54750
|
result = value > 0 ? "PositiveInfinity" : "NegativeInfinity";
|
|
54058
54751
|
else num = serializeRepeatingDecimals(value.toString(), options);
|
|
54059
54752
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
54060
|
-
metadata.latex = metadata.latex ?? ce
|
|
54753
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, { num });
|
|
54061
54754
|
if (result) {
|
|
54062
54755
|
if (metadata.latex !== void 0)
|
|
54063
54756
|
return { sym: result, latex: metadata.latex };
|
|
@@ -54810,8 +55503,7 @@ Error in definition of "${name}"`,
|
|
|
54810
55503
|
vars: options?.vars,
|
|
54811
55504
|
imports: options?.imports,
|
|
54812
55505
|
preamble: options?.preamble,
|
|
54813
|
-
realOnly: options?.realOnly
|
|
54814
|
-
hints: options?.hints
|
|
55506
|
+
realOnly: options?.realOnly
|
|
54815
55507
|
});
|
|
54816
55508
|
} catch (e) {
|
|
54817
55509
|
if (options?.fallback ?? true) {
|
|
@@ -54823,8 +55515,7 @@ Error in definition of "${name}"`,
|
|
|
54823
55515
|
ce.pushScope();
|
|
54824
55516
|
try {
|
|
54825
55517
|
if (vars && typeof vars === "object") {
|
|
54826
|
-
for (const [k, v] of Object.entries(vars))
|
|
54827
|
-
ce.assign(k, v);
|
|
55518
|
+
for (const [k, v] of Object.entries(vars)) ce.assign(k, v);
|
|
54828
55519
|
}
|
|
54829
55520
|
return expr2.evaluate().re;
|
|
54830
55521
|
} finally {
|
|
@@ -60054,8 +60745,7 @@ Error in definition of "${name}"`,
|
|
|
60054
60745
|
return { re: null, im: formatFloat(iScale) };
|
|
60055
60746
|
}
|
|
60056
60747
|
const compiledFactors = remaining.map((r) => compile3(r));
|
|
60057
|
-
if (iScale !== 1)
|
|
60058
|
-
compiledFactors.unshift(formatFloat(iScale));
|
|
60748
|
+
if (iScale !== 1) compiledFactors.unshift(formatFloat(iScale));
|
|
60059
60749
|
const imCode = foldTerms(compiledFactors, "1.0", "*");
|
|
60060
60750
|
return { re: null, im: imCode };
|
|
60061
60751
|
}
|
|
@@ -60659,39 +61349,130 @@ Error in definition of "${name}"`,
|
|
|
60659
61349
|
if (args.length >= 2)
|
|
60660
61350
|
return `_SYS.colormap(${compile3(args[0])}, ${compile3(args[1])})`;
|
|
60661
61351
|
return `_SYS.colormap(${compile3(args[0])})`;
|
|
61352
|
+
},
|
|
61353
|
+
// -----------------------------------------------------------------------
|
|
61354
|
+
// Color constructor heads. All compile to OKLCh arrays at runtime — the
|
|
61355
|
+
// canonical color representation in this target. The constructors take
|
|
61356
|
+
// their own colorspace's components and convert internally.
|
|
61357
|
+
// (Mirrors the GPU target's design: color values are vec3 OKLCh.)
|
|
61358
|
+
// -----------------------------------------------------------------------
|
|
61359
|
+
Rgb: (args, compile3) => {
|
|
61360
|
+
if (args.length < 3) throw new Error("Rgb: need 3 components");
|
|
61361
|
+
return `_SYS.rgb(${args.map(compile3).join(", ")})`;
|
|
61362
|
+
},
|
|
61363
|
+
Hsv: (args, compile3) => {
|
|
61364
|
+
if (args.length < 3) throw new Error("Hsv: need 3 components");
|
|
61365
|
+
return `_SYS.hsv(${args.map(compile3).join(", ")})`;
|
|
61366
|
+
},
|
|
61367
|
+
Hsl: (args, compile3) => {
|
|
61368
|
+
if (args.length < 3) throw new Error("Hsl: need 3 components");
|
|
61369
|
+
return `_SYS.hsl(${args.map(compile3).join(", ")})`;
|
|
61370
|
+
},
|
|
61371
|
+
Oklab: (args, compile3) => {
|
|
61372
|
+
if (args.length < 3) throw new Error("Oklab: need 3 components");
|
|
61373
|
+
return `_SYS.oklab(${args.map(compile3).join(", ")})`;
|
|
61374
|
+
},
|
|
61375
|
+
Oklch: (args, compile3) => {
|
|
61376
|
+
if (args.length < 3) throw new Error("Oklch: need 3 components");
|
|
61377
|
+
return `_SYS.oklch(${args.map(compile3).join(", ")})`;
|
|
61378
|
+
},
|
|
61379
|
+
// -----------------------------------------------------------------------
|
|
61380
|
+
// As* converters. Compile-time output convention matches the engine and
|
|
61381
|
+
// the GPU target: each returns components in the named space as a 3- or
|
|
61382
|
+
// 4-element array. `AsRgb` uses 0-1 sRGB channels (consistent across all
|
|
61383
|
+
// layers). `AsOklch` is the identity (canonical form).
|
|
61384
|
+
// -----------------------------------------------------------------------
|
|
61385
|
+
AsRgb: ([c], compile3) => {
|
|
61386
|
+
if (c === null) throw new Error("AsRgb: no argument");
|
|
61387
|
+
return `_SYS.asRgb(${compile3(c)})`;
|
|
61388
|
+
},
|
|
61389
|
+
AsHsv: ([c], compile3) => {
|
|
61390
|
+
if (c === null) throw new Error("AsHsv: no argument");
|
|
61391
|
+
return `_SYS.asHsv(${compile3(c)})`;
|
|
61392
|
+
},
|
|
61393
|
+
AsHsl: ([c], compile3) => {
|
|
61394
|
+
if (c === null) throw new Error("AsHsl: no argument");
|
|
61395
|
+
return `_SYS.asHsl(${compile3(c)})`;
|
|
61396
|
+
},
|
|
61397
|
+
AsOklab: ([c], compile3) => {
|
|
61398
|
+
if (c === null) throw new Error("AsOklab: no argument");
|
|
61399
|
+
return `_SYS.asOklab(${compile3(c)})`;
|
|
61400
|
+
},
|
|
61401
|
+
AsOklch: ([c], compile3) => {
|
|
61402
|
+
if (c === null) throw new Error("AsOklch: no argument");
|
|
61403
|
+
return compile3(c);
|
|
61404
|
+
},
|
|
61405
|
+
// Perceptual color difference (ΔE_OK).
|
|
61406
|
+
ColorDelta: ([a, b], compile3) => {
|
|
61407
|
+
if (a === null || b === null)
|
|
61408
|
+
throw new Error("ColorDelta: need two colors");
|
|
61409
|
+
return `_SYS.colorDelta(${compile3(a)}, ${compile3(b)})`;
|
|
61410
|
+
},
|
|
61411
|
+
// Euclidean distance between two tuples (any positive dimension).
|
|
61412
|
+
// The GPU target maps `Distance` to the GLSL/WGSL `distance()` builtin
|
|
61413
|
+
// (vec-only); this JS handler works on plain arrays of any length.
|
|
61414
|
+
Distance: ([a, b], compile3) => {
|
|
61415
|
+
if (a === null || b === null) throw new Error("Distance: need two points");
|
|
61416
|
+
return `_SYS.distance(${compile3(a)}, ${compile3(b)})`;
|
|
60662
61417
|
}
|
|
60663
61418
|
};
|
|
60664
61419
|
function toRI(c) {
|
|
60665
61420
|
return { re: c.re, im: c.im };
|
|
60666
61421
|
}
|
|
61422
|
+
function normalizeAlpha2(a) {
|
|
61423
|
+
if (a === void 0) return void 0;
|
|
61424
|
+
if (!Number.isFinite(a)) return void 0;
|
|
61425
|
+
if (Math.abs(a - 1) < 1e-9) return void 0;
|
|
61426
|
+
return a;
|
|
61427
|
+
}
|
|
60667
61428
|
function toRgb255(input) {
|
|
60668
61429
|
if (typeof input === "string") {
|
|
60669
61430
|
const c = parseColor(input);
|
|
60670
|
-
|
|
61431
|
+
const rgb2 = {
|
|
60671
61432
|
r: c >>> 24 & 255,
|
|
60672
61433
|
g: c >>> 16 & 255,
|
|
60673
|
-
b: c >>> 8 & 255
|
|
60674
|
-
alpha: (c & 255) / 255
|
|
61434
|
+
b: c >>> 8 & 255
|
|
60675
61435
|
};
|
|
61436
|
+
const alpha = normalizeAlpha2((c & 255) / 255);
|
|
61437
|
+
if (alpha !== void 0) rgb2.alpha = alpha;
|
|
61438
|
+
return rgb2;
|
|
61439
|
+
}
|
|
61440
|
+
const rgb = oklchToRgb({ L: input[0], C: input[1], H: input[2] });
|
|
61441
|
+
if (input.length >= 4) {
|
|
61442
|
+
const alpha = normalizeAlpha2(input[3]);
|
|
61443
|
+
if (alpha !== void 0) rgb.alpha = alpha;
|
|
60676
61444
|
}
|
|
60677
|
-
const rgb = {
|
|
60678
|
-
r: input[0] * 255,
|
|
60679
|
-
g: input[1] * 255,
|
|
60680
|
-
b: input[2] * 255
|
|
60681
|
-
};
|
|
60682
|
-
if (input.length >= 4) rgb.alpha = input[3];
|
|
60683
61445
|
return rgb;
|
|
60684
61446
|
}
|
|
60685
|
-
function
|
|
60686
|
-
|
|
60687
|
-
|
|
60688
|
-
|
|
60689
|
-
|
|
60690
|
-
|
|
61447
|
+
function toOklch2(input) {
|
|
61448
|
+
if (typeof input === "string") {
|
|
61449
|
+
const c = parseColor(input);
|
|
61450
|
+
const r = c >>> 24 & 255;
|
|
61451
|
+
const g = c >>> 16 & 255;
|
|
61452
|
+
const b = c >>> 8 & 255;
|
|
61453
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
61454
|
+
const alpha = normalizeAlpha2((c & 255) / 255);
|
|
61455
|
+
if (alpha !== void 0) oklch2.alpha = alpha;
|
|
61456
|
+
return oklch2;
|
|
61457
|
+
}
|
|
61458
|
+
return {
|
|
61459
|
+
L: input[0],
|
|
61460
|
+
C: input[1],
|
|
61461
|
+
H: input[2],
|
|
61462
|
+
alpha: input.length >= 4 ? normalizeAlpha2(input[3]) : void 0
|
|
61463
|
+
};
|
|
61464
|
+
}
|
|
61465
|
+
function packedToOklch(c) {
|
|
61466
|
+
const r = c >>> 24 & 255;
|
|
61467
|
+
const g = c >>> 16 & 255;
|
|
61468
|
+
const b = c >>> 8 & 255;
|
|
61469
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
61470
|
+
const alpha = normalizeAlpha2((c & 255) / 255);
|
|
61471
|
+
return alpha !== void 0 ? [oklch2.L, oklch2.C, oklch2.H, alpha] : [oklch2.L, oklch2.C, oklch2.H];
|
|
60691
61472
|
}
|
|
60692
61473
|
var colorHelpers = {
|
|
60693
61474
|
color(input) {
|
|
60694
|
-
return
|
|
61475
|
+
return packedToOklch(parseColor(input));
|
|
60695
61476
|
},
|
|
60696
61477
|
colorToString(input, format) {
|
|
60697
61478
|
const rgb = toRgb255(input);
|
|
@@ -60702,7 +61483,7 @@ Error in definition of "${name}"`,
|
|
|
60702
61483
|
const g = Math.round(Math.max(0, Math.min(255, rgb.g)));
|
|
60703
61484
|
const b = Math.round(Math.max(0, Math.min(255, rgb.b)));
|
|
60704
61485
|
let hex = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
60705
|
-
if (rgb.alpha !== void 0
|
|
61486
|
+
if (rgb.alpha !== void 0) {
|
|
60706
61487
|
const a = Math.round(Math.max(0, Math.min(255, rgb.alpha * 255)));
|
|
60707
61488
|
hex += a.toString(16).padStart(2, "0");
|
|
60708
61489
|
}
|
|
@@ -60712,7 +61493,7 @@ Error in definition of "${name}"`,
|
|
|
60712
61493
|
const r = Math.round(rgb.r);
|
|
60713
61494
|
const g = Math.round(rgb.g);
|
|
60714
61495
|
const b = Math.round(rgb.b);
|
|
60715
|
-
if (rgb.alpha !== void 0
|
|
61496
|
+
if (rgb.alpha !== void 0)
|
|
60716
61497
|
return `rgb(${r} ${g} ${b} / ${rgb.alpha})`;
|
|
60717
61498
|
return `rgb(${r} ${g} ${b})`;
|
|
60718
61499
|
}
|
|
@@ -60721,7 +61502,7 @@ Error in definition of "${name}"`,
|
|
|
60721
61502
|
const h = Math.round(hsl.h * 10) / 10;
|
|
60722
61503
|
const s = Math.round(hsl.s * 1e3) / 10;
|
|
60723
61504
|
const l = Math.round(hsl.l * 1e3) / 10;
|
|
60724
|
-
if (rgb.alpha !== void 0
|
|
61505
|
+
if (rgb.alpha !== void 0)
|
|
60725
61506
|
return `hsl(${h} ${s}% ${l}% / ${rgb.alpha})`;
|
|
60726
61507
|
return `hsl(${h} ${s}% ${l}%)`;
|
|
60727
61508
|
}
|
|
@@ -60730,7 +61511,7 @@ Error in definition of "${name}"`,
|
|
|
60730
61511
|
const L = Math.round(c.L * 1e3) / 1e3;
|
|
60731
61512
|
const C = Math.round(c.C * 1e3) / 1e3;
|
|
60732
61513
|
const H = Math.round(c.H * 10) / 10;
|
|
60733
|
-
if (rgb.alpha !== void 0
|
|
61514
|
+
if (rgb.alpha !== void 0)
|
|
60734
61515
|
return `oklch(${L} ${C} ${H} / ${rgb.alpha})`;
|
|
60735
61516
|
return `oklch(${L} ${C} ${H})`;
|
|
60736
61517
|
}
|
|
@@ -60739,29 +61520,29 @@ Error in definition of "${name}"`,
|
|
|
60739
61520
|
}
|
|
60740
61521
|
},
|
|
60741
61522
|
colorMix(input1, input2, ratio = 0.5) {
|
|
60742
|
-
const
|
|
60743
|
-
const
|
|
61523
|
+
const c1 = toOklch2(input1);
|
|
61524
|
+
const c2 = toOklch2(input2);
|
|
60744
61525
|
ratio = Math.max(0, Math.min(1, ratio));
|
|
60745
|
-
const
|
|
60746
|
-
const
|
|
60747
|
-
let
|
|
60748
|
-
if (
|
|
60749
|
-
if (
|
|
60750
|
-
|
|
60751
|
-
|
|
60752
|
-
|
|
60753
|
-
|
|
60754
|
-
|
|
60755
|
-
|
|
60756
|
-
H
|
|
60757
|
-
|
|
60758
|
-
|
|
60759
|
-
const
|
|
60760
|
-
const
|
|
60761
|
-
const a1 =
|
|
60762
|
-
const a2 =
|
|
60763
|
-
const alpha = a1 + (a2 - a1) * ratio;
|
|
60764
|
-
return
|
|
61526
|
+
const c1Achromatic = c1.C < 1e-6;
|
|
61527
|
+
const c2Achromatic = c2.C < 1e-6;
|
|
61528
|
+
let H;
|
|
61529
|
+
if (c1Achromatic && c2Achromatic) H = c1.H;
|
|
61530
|
+
else if (c1Achromatic) H = c2.H;
|
|
61531
|
+
else if (c2Achromatic) H = c1.H;
|
|
61532
|
+
else {
|
|
61533
|
+
let dh = c2.H - c1.H;
|
|
61534
|
+
if (dh > 180) dh -= 360;
|
|
61535
|
+
if (dh < -180) dh += 360;
|
|
61536
|
+
H = c1.H + dh * ratio;
|
|
61537
|
+
if (H < 0) H += 360;
|
|
61538
|
+
if (H >= 360) H -= 360;
|
|
61539
|
+
}
|
|
61540
|
+
const L = c1.L + (c2.L - c1.L) * ratio;
|
|
61541
|
+
const C = c1.C + (c2.C - c1.C) * ratio;
|
|
61542
|
+
const a1 = c1.alpha ?? 1;
|
|
61543
|
+
const a2 = c2.alpha ?? 1;
|
|
61544
|
+
const alpha = normalizeAlpha2(a1 + (a2 - a1) * ratio);
|
|
61545
|
+
return alpha !== void 0 ? [L, C, H, alpha] : [L, C, H];
|
|
60765
61546
|
},
|
|
60766
61547
|
colorContrast(bg, fg) {
|
|
60767
61548
|
return apca(toRgb255(bg), toRgb255(fg));
|
|
@@ -60769,11 +61550,11 @@ Error in definition of "${name}"`,
|
|
|
60769
61550
|
contrastingColor(bg, fg1, fg2) {
|
|
60770
61551
|
const bgRgb = toRgb255(bg);
|
|
60771
61552
|
if (fg1 !== void 0 && fg2 !== void 0) {
|
|
60772
|
-
return
|
|
61553
|
+
return packedToOklch(
|
|
60773
61554
|
contrastingColor({ bg: bgRgb, fg1: toRgb255(fg1), fg2: toRgb255(fg2) })
|
|
60774
61555
|
);
|
|
60775
61556
|
}
|
|
60776
|
-
return
|
|
61557
|
+
return packedToOklch(contrastingColor(bgRgb));
|
|
60777
61558
|
},
|
|
60778
61559
|
colorToColorspace(input, space) {
|
|
60779
61560
|
const rgb = toRgb255(input);
|
|
@@ -60802,7 +61583,7 @@ Error in definition of "${name}"`,
|
|
|
60802
61583
|
default:
|
|
60803
61584
|
throw new Error(`Unknown color space: ${space}`);
|
|
60804
61585
|
}
|
|
60805
|
-
if (alpha !== void 0
|
|
61586
|
+
if (alpha !== void 0) result.push(alpha);
|
|
60806
61587
|
return result;
|
|
60807
61588
|
},
|
|
60808
61589
|
colormap(name, arg) {
|
|
@@ -60814,7 +61595,7 @@ Error in definition of "${name}"`,
|
|
|
60814
61595
|
const palette = allPalettes[name];
|
|
60815
61596
|
if (!palette) throw new Error(`Unknown palette: ${name}`);
|
|
60816
61597
|
const colors = palette.map(
|
|
60817
|
-
(hex) =>
|
|
61598
|
+
(hex) => packedToOklch(parseColor(hex))
|
|
60818
61599
|
);
|
|
60819
61600
|
if (arg === void 0) return colors;
|
|
60820
61601
|
if (Number.isInteger(arg) && arg >= 2) {
|
|
@@ -60838,62 +61619,128 @@ Error in definition of "${name}"`,
|
|
|
60838
61619
|
const frac = pos - i;
|
|
60839
61620
|
if (frac === 0 || i >= colors.length - 1)
|
|
60840
61621
|
return [...colors[Math.min(i, colors.length - 1)]];
|
|
60841
|
-
const
|
|
60842
|
-
|
|
60843
|
-
|
|
60844
|
-
|
|
60845
|
-
|
|
60846
|
-
|
|
60847
|
-
|
|
60848
|
-
|
|
60849
|
-
|
|
60850
|
-
|
|
60851
|
-
|
|
60852
|
-
|
|
60853
|
-
|
|
60854
|
-
|
|
60855
|
-
|
|
60856
|
-
|
|
60857
|
-
|
|
60858
|
-
if (H >= 360) H -= 360;
|
|
60859
|
-
const mixed = oklchToRgb({
|
|
60860
|
-
L: c1.L + (c2.L - c1.L) * frac,
|
|
60861
|
-
C: c1.C + (c2.C - c1.C) * frac,
|
|
60862
|
-
H
|
|
60863
|
-
});
|
|
60864
|
-
return [mixed.r / 255, mixed.g / 255, mixed.b / 255];
|
|
61622
|
+
const [L1, C1, H1] = colors[i];
|
|
61623
|
+
const [L2, C2, H2] = colors[i + 1];
|
|
61624
|
+
const c1Achromatic = C1 < 1e-6;
|
|
61625
|
+
const c2Achromatic = C2 < 1e-6;
|
|
61626
|
+
let H;
|
|
61627
|
+
if (c1Achromatic && c2Achromatic) H = H1;
|
|
61628
|
+
else if (c1Achromatic) H = H2;
|
|
61629
|
+
else if (c2Achromatic) H = H1;
|
|
61630
|
+
else {
|
|
61631
|
+
let dh = H2 - H1;
|
|
61632
|
+
if (dh > 180) dh -= 360;
|
|
61633
|
+
if (dh < -180) dh += 360;
|
|
61634
|
+
H = H1 + dh * frac;
|
|
61635
|
+
if (H < 0) H += 360;
|
|
61636
|
+
if (H >= 360) H -= 360;
|
|
61637
|
+
}
|
|
61638
|
+
return [L1 + (L2 - L1) * frac, C1 + (C2 - C1) * frac, H];
|
|
60865
61639
|
},
|
|
60866
61640
|
colorFromColorspace(components, space) {
|
|
60867
61641
|
const c0 = components[0];
|
|
60868
61642
|
const c1 = components[1];
|
|
60869
61643
|
const c2 = components[2];
|
|
60870
61644
|
const alpha = components.length >= 4 ? components[3] : void 0;
|
|
60871
|
-
let
|
|
61645
|
+
let oklch2;
|
|
60872
61646
|
switch (space.toLowerCase()) {
|
|
60873
61647
|
case "rgb":
|
|
60874
|
-
|
|
61648
|
+
oklch2 = rgbToOklch({ r: c0 * 255, g: c1 * 255, b: c2 * 255 });
|
|
60875
61649
|
break;
|
|
60876
61650
|
case "hsl": {
|
|
60877
|
-
const
|
|
60878
|
-
|
|
61651
|
+
const rgb = hslToRgb(c0, c1, c2);
|
|
61652
|
+
oklch2 = rgbToOklch(rgb);
|
|
60879
61653
|
break;
|
|
60880
61654
|
}
|
|
60881
|
-
case "oklch":
|
|
60882
|
-
|
|
60883
|
-
result = [r.r / 255, r.g / 255, r.b / 255];
|
|
61655
|
+
case "oklch":
|
|
61656
|
+
oklch2 = { L: c0, C: c1, H: c2 };
|
|
60884
61657
|
break;
|
|
60885
|
-
}
|
|
60886
61658
|
case "oklab":
|
|
60887
|
-
case "lab":
|
|
60888
|
-
|
|
60889
|
-
result = [r.r / 255, r.g / 255, r.b / 255];
|
|
61659
|
+
case "lab":
|
|
61660
|
+
oklch2 = oklabToOklch({ L: c0, a: c1, b: c2 });
|
|
60890
61661
|
break;
|
|
60891
|
-
}
|
|
60892
61662
|
default:
|
|
60893
61663
|
throw new Error(`Unknown color space: ${space}`);
|
|
60894
61664
|
}
|
|
60895
|
-
|
|
60896
|
-
|
|
61665
|
+
return alpha !== void 0 ? [oklch2.L, oklch2.C, oklch2.H, alpha] : [oklch2.L, oklch2.C, oklch2.H];
|
|
61666
|
+
},
|
|
61667
|
+
// -----------------------------------------------------------------------
|
|
61668
|
+
// Color constructors. Each accepts components in its colorspace's natural
|
|
61669
|
+
// units and returns the canonical OKLCh array `[L, C, H]` (or with alpha).
|
|
61670
|
+
// -----------------------------------------------------------------------
|
|
61671
|
+
rgb(r, g, b, alpha) {
|
|
61672
|
+
const c = rgbToOklch({ r: r * 255, g: g * 255, b: b * 255 });
|
|
61673
|
+
const a = normalizeAlpha2(alpha);
|
|
61674
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
61675
|
+
},
|
|
61676
|
+
hsv(h, s, v, alpha) {
|
|
61677
|
+
const rgb = hsvToRgb(h, s, v);
|
|
61678
|
+
const c = rgbToOklch(rgb);
|
|
61679
|
+
const a = normalizeAlpha2(alpha);
|
|
61680
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
61681
|
+
},
|
|
61682
|
+
hsl(h, s, l, alpha) {
|
|
61683
|
+
const rgb = hslToRgb(h, s, l);
|
|
61684
|
+
const c = rgbToOklch({ r: rgb.r, g: rgb.g, b: rgb.b });
|
|
61685
|
+
const a = normalizeAlpha2(alpha);
|
|
61686
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
61687
|
+
},
|
|
61688
|
+
oklab(L, a, b, alpha) {
|
|
61689
|
+
const c = oklabToOklch({ L, a, b });
|
|
61690
|
+
const al = normalizeAlpha2(alpha);
|
|
61691
|
+
return al !== void 0 ? [c.L, c.C, c.H, al] : [c.L, c.C, c.H];
|
|
61692
|
+
},
|
|
61693
|
+
oklch(L, C, H, alpha) {
|
|
61694
|
+
const a = normalizeAlpha2(alpha);
|
|
61695
|
+
return a !== void 0 ? [L, C, H, a] : [L, C, H];
|
|
61696
|
+
},
|
|
61697
|
+
// -----------------------------------------------------------------------
|
|
61698
|
+
// As* converters. Inputs are anything `toOklch` accepts (string, packed
|
|
61699
|
+
// int, or OKLCh array). Outputs are 3- or 4-element arrays in the named
|
|
61700
|
+
// space. sRGB-based outputs (asRgb/asHsv/asHsl) use 0-1 channels for
|
|
61701
|
+
// consistency with the GPU target's shader convention.
|
|
61702
|
+
// -----------------------------------------------------------------------
|
|
61703
|
+
asRgb(input) {
|
|
61704
|
+
const rgb = toRgb255(input);
|
|
61705
|
+
const r = rgb.r / 255;
|
|
61706
|
+
const g = rgb.g / 255;
|
|
61707
|
+
const b = rgb.b / 255;
|
|
61708
|
+
return rgb.alpha !== void 0 ? [r, g, b, rgb.alpha] : [r, g, b];
|
|
61709
|
+
},
|
|
61710
|
+
asHsv(input) {
|
|
61711
|
+
const rgb = toRgb255(input);
|
|
61712
|
+
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
61713
|
+
return rgb.alpha !== void 0 ? [hsv.h, hsv.s, hsv.v, rgb.alpha] : [hsv.h, hsv.s, hsv.v];
|
|
61714
|
+
},
|
|
61715
|
+
asHsl(input) {
|
|
61716
|
+
const rgb = toRgb255(input);
|
|
61717
|
+
const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
|
|
61718
|
+
return rgb.alpha !== void 0 ? [hsl.h, hsl.s, hsl.l, rgb.alpha] : [hsl.h, hsl.s, hsl.l];
|
|
61719
|
+
},
|
|
61720
|
+
asOklab(input) {
|
|
61721
|
+
const c = toOklch2(input);
|
|
61722
|
+
const lab = oklchToOklab({ L: c.L, C: c.C, H: c.H });
|
|
61723
|
+
return c.alpha !== void 0 ? [lab.L, lab.a, lab.b, c.alpha] : [lab.L, lab.a, lab.b];
|
|
61724
|
+
},
|
|
61725
|
+
// asOklch is identity — handled at compile time as a pass-through
|
|
61726
|
+
// Perceptual color difference (ΔE_OK).
|
|
61727
|
+
colorDelta(a, b) {
|
|
61728
|
+
const labA = oklchToOklab(toOklch2(a));
|
|
61729
|
+
const labB = oklchToOklab(toOklch2(b));
|
|
61730
|
+
return oklabDeltaE(labA, labB);
|
|
61731
|
+
},
|
|
61732
|
+
// Euclidean distance between two tuples. Plain numeric — not a color
|
|
61733
|
+
// operation despite living in the same helpers block.
|
|
61734
|
+
distance(a, b) {
|
|
61735
|
+
if (!Array.isArray(a) || !Array.isArray(b))
|
|
61736
|
+
throw new Error("Distance: expected two arrays");
|
|
61737
|
+
if (a.length !== b.length) throw new Error("Distance: dimension mismatch");
|
|
61738
|
+
let sumSq = 0;
|
|
61739
|
+
for (let i = 0; i < a.length; i++) {
|
|
61740
|
+
const d = a[i] - b[i];
|
|
61741
|
+
sumSq += d * d;
|
|
61742
|
+
}
|
|
61743
|
+
return Math.sqrt(sumSq);
|
|
60897
61744
|
}
|
|
60898
61745
|
};
|
|
60899
61746
|
var SYS_HELPERS = {
|
|
@@ -61311,43 +62158,6 @@ Error in definition of "${name}"`,
|
|
|
61311
62158
|
return b;
|
|
61312
62159
|
}
|
|
61313
62160
|
|
|
61314
|
-
// src/compute-engine/compilation/fractal-orbit.ts
|
|
61315
|
-
function toBigDecimal(v) {
|
|
61316
|
-
if (typeof v === "object" && "hi" in v)
|
|
61317
|
-
return new BigDecimal(v.hi).add(new BigDecimal(v.lo));
|
|
61318
|
-
return new BigDecimal(v);
|
|
61319
|
-
}
|
|
61320
|
-
function hpToNumber(v) {
|
|
61321
|
-
if (typeof v === "number") return v;
|
|
61322
|
-
if (typeof v === "string") return Number(v);
|
|
61323
|
-
return v.hi + v.lo;
|
|
61324
|
-
}
|
|
61325
|
-
function computeReferenceOrbit(center, maxIter, precision) {
|
|
61326
|
-
const prevPrecision = BigDecimal.precision;
|
|
61327
|
-
BigDecimal.precision = precision;
|
|
61328
|
-
try {
|
|
61329
|
-
const cr = toBigDecimal(center[0]);
|
|
61330
|
-
const ci = toBigDecimal(center[1]);
|
|
61331
|
-
let zr = BigDecimal.ZERO;
|
|
61332
|
-
let zi = BigDecimal.ZERO;
|
|
61333
|
-
const ESCAPE = new BigDecimal(256);
|
|
61334
|
-
const points = [];
|
|
61335
|
-
for (let i = 0; i < maxIter; i++) {
|
|
61336
|
-
points.push(zr.toNumber(), zi.toNumber());
|
|
61337
|
-
const zr2 = zr.mul(zr).toPrecision(precision);
|
|
61338
|
-
const zi2 = zi.mul(zi).toPrecision(precision);
|
|
61339
|
-
const mag2 = zr2.add(zi2);
|
|
61340
|
-
if (mag2.cmp(ESCAPE) > 0) break;
|
|
61341
|
-
const new_zi = zr.mul(zi).toPrecision(precision).mul(2).add(ci);
|
|
61342
|
-
zr = zr2.sub(zi2).add(cr);
|
|
61343
|
-
zi = new_zi;
|
|
61344
|
-
}
|
|
61345
|
-
return new Float32Array(points);
|
|
61346
|
-
} finally {
|
|
61347
|
-
BigDecimal.precision = prevPrecision;
|
|
61348
|
-
}
|
|
61349
|
-
}
|
|
61350
|
-
|
|
61351
62161
|
// src/compute-engine/compilation/gpu-target.ts
|
|
61352
62162
|
var GPU_OPERATORS = {
|
|
61353
62163
|
Add: ["+", 11],
|
|
@@ -61369,6 +62179,13 @@ Error in definition of "${name}"`,
|
|
|
61369
62179
|
function gpuVec2(target) {
|
|
61370
62180
|
return target?.language === "wgsl" ? "vec2f" : "vec2";
|
|
61371
62181
|
}
|
|
62182
|
+
function gpuVec3(target) {
|
|
62183
|
+
return target?.language === "wgsl" ? "vec3f" : "vec3";
|
|
62184
|
+
}
|
|
62185
|
+
function readStringLiteral(expr2) {
|
|
62186
|
+
if (!isString(expr2)) return null;
|
|
62187
|
+
return expr2.string?.toLowerCase() ?? null;
|
|
62188
|
+
}
|
|
61372
62189
|
function compileIntArg(expr2, compile3, target) {
|
|
61373
62190
|
const c = tryGetConstant(expr2);
|
|
61374
62191
|
if (c !== void 0 && Number.isInteger(c)) return c.toString();
|
|
@@ -61427,17 +62244,10 @@ Error in definition of "${name}"`,
|
|
|
61427
62244
|
`for (${indexDecl} = ${lowerStr}; ${index} <= ${upperStr}; ${index}++) {`,
|
|
61428
62245
|
` ${acc} ${op}= ${body};`,
|
|
61429
62246
|
`}`,
|
|
61430
|
-
`return ${acc}
|
|
62247
|
+
`return ${acc};`
|
|
61431
62248
|
];
|
|
61432
62249
|
return lines.join("\n");
|
|
61433
62250
|
}
|
|
61434
|
-
function selectFractalStrategy(target) {
|
|
61435
|
-
const radius = target.hints?.viewport?.radius;
|
|
61436
|
-
if (radius === void 0) return "single";
|
|
61437
|
-
if (radius > 1e-6) return "single";
|
|
61438
|
-
if (radius > 1e-14) return "double";
|
|
61439
|
-
return "perturbation";
|
|
61440
|
-
}
|
|
61441
62251
|
var GPU_FUNCTIONS = {
|
|
61442
62252
|
// Variadic arithmetic (for function-call form, e.g., with vectors)
|
|
61443
62253
|
Add: (args, compile3, target) => {
|
|
@@ -61488,8 +62298,7 @@ Error in definition of "${name}"`,
|
|
|
61488
62298
|
const iScale = isSymbol2(iFactor, "ImaginaryUnit") ? 1 : iFactor.im;
|
|
61489
62299
|
const realFactors = args.filter((_, i) => i !== iIndex);
|
|
61490
62300
|
const v2 = gpuVec2(target);
|
|
61491
|
-
if (realFactors.length === 0)
|
|
61492
|
-
return `${v2}(0.0, ${formatFloat(iScale)})`;
|
|
62301
|
+
if (realFactors.length === 0) return `${v2}(0.0, ${formatFloat(iScale)})`;
|
|
61493
62302
|
const factors = realFactors.map((f) => compile3(f));
|
|
61494
62303
|
if (iScale !== 1) factors.unshift(formatFloat(iScale));
|
|
61495
62304
|
const imCode = foldTerms(factors, "1.0", "*");
|
|
@@ -61542,8 +62351,7 @@ Error in definition of "${name}"`,
|
|
|
61542
62351
|
if (isNumber(x) && x.im !== 0) {
|
|
61543
62352
|
return `${gpuVec2(target)}(${formatFloat(-x.re)}, ${formatFloat(-x.im)})`;
|
|
61544
62353
|
}
|
|
61545
|
-
if (isSymbol2(x, "ImaginaryUnit"))
|
|
61546
|
-
return `${gpuVec2(target)}(0.0, -1.0)`;
|
|
62354
|
+
if (isSymbol2(x, "ImaginaryUnit")) return `${gpuVec2(target)}(0.0, -1.0)`;
|
|
61547
62355
|
return `(-${compile3(x)})`;
|
|
61548
62356
|
},
|
|
61549
62357
|
// Standard math functions with complex dispatch
|
|
@@ -61916,49 +62724,139 @@ Error in definition of "${name}"`,
|
|
|
61916
62724
|
}
|
|
61917
62725
|
const isWGSL = target?.language === "wgsl";
|
|
61918
62726
|
const v3 = isWGSL ? "vec3f" : "vec3";
|
|
61919
|
-
|
|
62727
|
+
const black = `${v3}(0.0)`;
|
|
62728
|
+
const white = `${v3}(1.0, 0.0, 0.0)`;
|
|
62729
|
+
return `((_gpu_apca(${bg}, ${black}) > 50.0) ? ${black} : ${white})`;
|
|
61920
62730
|
},
|
|
61921
62731
|
ColorToColorspace: ([color, space], compile3) => {
|
|
61922
62732
|
if (color === null || space === null)
|
|
61923
62733
|
throw new Error("ColorToColorspace: need color and space");
|
|
61924
|
-
|
|
62734
|
+
const spaceName = readStringLiteral(space);
|
|
62735
|
+
if (spaceName === null)
|
|
62736
|
+
throw new Error("ColorToColorspace: space must be a string literal");
|
|
62737
|
+
const c = compile3(color);
|
|
62738
|
+
switch (spaceName) {
|
|
62739
|
+
case "oklch":
|
|
62740
|
+
return c;
|
|
62741
|
+
case "oklab":
|
|
62742
|
+
case "lab":
|
|
62743
|
+
return `_gpu_oklch_to_oklab(${c})`;
|
|
62744
|
+
case "rgb":
|
|
62745
|
+
return `_gpu_oklch_to_srgb(${c})`;
|
|
62746
|
+
case "hsl":
|
|
62747
|
+
return `_gpu_rgb_to_hsl(_gpu_oklch_to_srgb(${c}))`;
|
|
62748
|
+
case "hsv":
|
|
62749
|
+
return `_gpu_rgb_to_hsv(_gpu_oklch_to_srgb(${c}))`;
|
|
62750
|
+
default:
|
|
62751
|
+
throw new Error(
|
|
62752
|
+
`ColorToColorspace: unsupported space "${spaceName}" on GPU target`
|
|
62753
|
+
);
|
|
62754
|
+
}
|
|
61925
62755
|
},
|
|
61926
62756
|
ColorFromColorspace: ([components, space], compile3) => {
|
|
61927
62757
|
if (components === null || space === null)
|
|
61928
62758
|
throw new Error("ColorFromColorspace: need components and space");
|
|
61929
|
-
|
|
62759
|
+
const spaceName = readStringLiteral(space);
|
|
62760
|
+
if (spaceName === null)
|
|
62761
|
+
throw new Error("ColorFromColorspace: space must be a string literal");
|
|
62762
|
+
const c = compile3(components);
|
|
62763
|
+
switch (spaceName) {
|
|
62764
|
+
case "oklch":
|
|
62765
|
+
return c;
|
|
62766
|
+
case "oklab":
|
|
62767
|
+
case "lab":
|
|
62768
|
+
return `_gpu_oklab_to_oklch(${c})`;
|
|
62769
|
+
case "rgb":
|
|
62770
|
+
return `_gpu_srgb_to_oklch(${c})`;
|
|
62771
|
+
case "hsl":
|
|
62772
|
+
return `_gpu_srgb_to_oklch(_gpu_hsl_to_rgb(${c}))`;
|
|
62773
|
+
case "hsv":
|
|
62774
|
+
return `_gpu_srgb_to_oklch(_gpu_hsv_to_rgb(${c}))`;
|
|
62775
|
+
default:
|
|
62776
|
+
throw new Error(
|
|
62777
|
+
`ColorFromColorspace: unsupported space "${spaceName}" on GPU target`
|
|
62778
|
+
);
|
|
62779
|
+
}
|
|
62780
|
+
},
|
|
62781
|
+
// ---------------------------------------------------------------------------
|
|
62782
|
+
// Color literals. Each typed head compiles to a canonical OKLCh vec3.
|
|
62783
|
+
// Alpha (4th argument) is dropped — GPU color values are vec3 only. Pass
|
|
62784
|
+
// alpha as a separate uniform if it's needed at the framebuffer boundary.
|
|
62785
|
+
// ---------------------------------------------------------------------------
|
|
62786
|
+
Color: ([s], _compile2, target) => {
|
|
62787
|
+
if (s === null) throw new Error("Color: no argument");
|
|
62788
|
+
const str = readStringLiteral(s);
|
|
62789
|
+
if (str === null)
|
|
62790
|
+
throw new Error("Color: argument must be a string literal on GPU target");
|
|
62791
|
+
const packed = parseColor(str);
|
|
62792
|
+
if (packed === 0 && str.trim().toLowerCase() !== "transparent")
|
|
62793
|
+
throw new Error(`Color: invalid color string "${str}"`);
|
|
62794
|
+
const r = packed >>> 24 & 255;
|
|
62795
|
+
const g = packed >>> 16 & 255;
|
|
62796
|
+
const b = packed >>> 8 & 255;
|
|
62797
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
62798
|
+
return `${gpuVec3(target)}(${formatFloat(oklch2.L)}, ${formatFloat(oklch2.C)}, ${formatFloat(oklch2.H)})`;
|
|
62799
|
+
},
|
|
62800
|
+
Rgb: (args, compile3, target) => {
|
|
62801
|
+
if (args.length < 3) throw new Error("Rgb: need 3 components");
|
|
62802
|
+
const v3 = gpuVec3(target);
|
|
62803
|
+
return `_gpu_srgb_to_oklch(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])}))`;
|
|
62804
|
+
},
|
|
62805
|
+
Hsv: (args, compile3, target) => {
|
|
62806
|
+
if (args.length < 3) throw new Error("Hsv: need 3 components");
|
|
62807
|
+
const v3 = gpuVec3(target);
|
|
62808
|
+
return `_gpu_srgb_to_oklch(_gpu_hsv_to_rgb(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])})))`;
|
|
62809
|
+
},
|
|
62810
|
+
Hsl: (args, compile3, target) => {
|
|
62811
|
+
if (args.length < 3) throw new Error("Hsl: need 3 components");
|
|
62812
|
+
const v3 = gpuVec3(target);
|
|
62813
|
+
return `_gpu_srgb_to_oklch(_gpu_hsl_to_rgb(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])})))`;
|
|
62814
|
+
},
|
|
62815
|
+
Oklab: (args, compile3, target) => {
|
|
62816
|
+
if (args.length < 3) throw new Error("Oklab: need 3 components");
|
|
62817
|
+
const v3 = gpuVec3(target);
|
|
62818
|
+
return `_gpu_oklab_to_oklch(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])}))`;
|
|
62819
|
+
},
|
|
62820
|
+
Oklch: (args, compile3, target) => {
|
|
62821
|
+
if (args.length < 3) throw new Error("Oklch: need 3 components");
|
|
62822
|
+
const v3 = gpuVec3(target);
|
|
62823
|
+
return `${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])})`;
|
|
62824
|
+
},
|
|
62825
|
+
// ---------------------------------------------------------------------------
|
|
62826
|
+
// As* operators. AsOklch is identity (canonical). The other As* return
|
|
62827
|
+
// components in the named space, equivalent to ColorToColorspace(c, 'x').
|
|
62828
|
+
// ---------------------------------------------------------------------------
|
|
62829
|
+
AsOklch: ([c], compile3) => {
|
|
62830
|
+
if (c === null) throw new Error("AsOklch: no argument");
|
|
62831
|
+
return compile3(c);
|
|
62832
|
+
},
|
|
62833
|
+
AsOklab: ([c], compile3) => {
|
|
62834
|
+
if (c === null) throw new Error("AsOklab: no argument");
|
|
62835
|
+
return `_gpu_oklch_to_oklab(${compile3(c)})`;
|
|
62836
|
+
},
|
|
62837
|
+
AsRgb: ([c], compile3) => {
|
|
62838
|
+
if (c === null) throw new Error("AsRgb: no argument");
|
|
62839
|
+
return `_gpu_oklch_to_srgb(${compile3(c)})`;
|
|
62840
|
+
},
|
|
62841
|
+
AsHsv: ([c], compile3) => {
|
|
62842
|
+
if (c === null) throw new Error("AsHsv: no argument");
|
|
62843
|
+
return `_gpu_rgb_to_hsv(_gpu_oklch_to_srgb(${compile3(c)}))`;
|
|
62844
|
+
},
|
|
62845
|
+
AsHsl: ([c], compile3) => {
|
|
62846
|
+
if (c === null) throw new Error("AsHsl: no argument");
|
|
62847
|
+
return `_gpu_rgb_to_hsl(_gpu_oklch_to_srgb(${compile3(c)}))`;
|
|
61930
62848
|
},
|
|
61931
62849
|
// Fractal functions
|
|
61932
62850
|
Mandelbrot: ([c, maxIter], compile3, target) => {
|
|
61933
62851
|
if (c === null || maxIter === null)
|
|
61934
62852
|
throw new Error("Mandelbrot: missing arguments");
|
|
61935
62853
|
const iterCode = compileIntArg(maxIter, compile3, target);
|
|
61936
|
-
const strategy = selectFractalStrategy(target);
|
|
61937
|
-
if (strategy === "double") {
|
|
61938
|
-
const dpCoord = target?.language === "wgsl" ? "_dp_coord(v_uv)" : "_dp_coord()";
|
|
61939
|
-
return `_fractal_mandelbrot_dp(${dpCoord}, ${iterCode})`;
|
|
61940
|
-
}
|
|
61941
|
-
if (strategy === "perturbation") {
|
|
61942
|
-
const ptDelta = target?.language === "wgsl" ? "_pt_delta(v_uv)" : "_pt_delta()";
|
|
61943
|
-
return `_fractal_mandelbrot_pt(${ptDelta}, ${iterCode})`;
|
|
61944
|
-
}
|
|
61945
62854
|
return `_fractal_mandelbrot(${compile3(c)}, ${iterCode})`;
|
|
61946
62855
|
},
|
|
61947
62856
|
Julia: ([z, c, maxIter], compile3, target) => {
|
|
61948
62857
|
if (z === null || c === null || maxIter === null)
|
|
61949
62858
|
throw new Error("Julia: missing arguments");
|
|
61950
62859
|
const iterCode = compileIntArg(maxIter, compile3, target);
|
|
61951
|
-
const strategy = selectFractalStrategy(target);
|
|
61952
|
-
if (strategy === "double") {
|
|
61953
|
-
const dpCoord = target?.language === "wgsl" ? "_dp_coord(v_uv)" : "_dp_coord()";
|
|
61954
|
-
const cCode = compile3(c);
|
|
61955
|
-
return `_fractal_julia_dp(${dpCoord}, vec4(${cCode}, vec2(0.0)), ${iterCode})`;
|
|
61956
|
-
}
|
|
61957
|
-
if (strategy === "perturbation") {
|
|
61958
|
-
const ptDelta = target?.language === "wgsl" ? "_pt_delta(v_uv)" : "_pt_delta()";
|
|
61959
|
-
const cCode = compile3(c);
|
|
61960
|
-
return `_fractal_julia_pt(${ptDelta}, ${cCode}, ${iterCode})`;
|
|
61961
|
-
}
|
|
61962
62860
|
return `_fractal_julia(${compile3(z)}, ${compile3(c)}, ${iterCode})`;
|
|
61963
62861
|
},
|
|
61964
62862
|
// Vector/Matrix operations
|
|
@@ -62555,232 +63453,6 @@ fn _gpu_besselJ(n_in: i32, x_in: f32) -> f32 {
|
|
|
62555
63453
|
for (var k2: i32 = 2; k2 <= M; k2 += 2) { norm += 2.0 * vals[k2]; }
|
|
62556
63454
|
return sgn * vals[n] / norm;
|
|
62557
63455
|
}
|
|
62558
|
-
`;
|
|
62559
|
-
var GPU_DS_ARITHMETIC_PREAMBLE_GLSL = `
|
|
62560
|
-
// Split a float into high and low parts for exact multiplication
|
|
62561
|
-
vec2 ds_split(float a) {
|
|
62562
|
-
const float SPLIT = 4097.0; // 2^12 + 1
|
|
62563
|
-
float t = SPLIT * a;
|
|
62564
|
-
float hi = t - (t - a);
|
|
62565
|
-
float lo = a - hi;
|
|
62566
|
-
return vec2(hi, lo);
|
|
62567
|
-
}
|
|
62568
|
-
|
|
62569
|
-
// Create a double-single from a single float
|
|
62570
|
-
vec2 ds_from(float a) {
|
|
62571
|
-
return vec2(a, 0.0);
|
|
62572
|
-
}
|
|
62573
|
-
|
|
62574
|
-
// Error-free addition (Knuth TwoSum)
|
|
62575
|
-
vec2 ds_add(vec2 a, vec2 b) {
|
|
62576
|
-
float s = a.x + b.x;
|
|
62577
|
-
float v = s - a.x;
|
|
62578
|
-
float e = (a.x - (s - v)) + (b.x - v);
|
|
62579
|
-
float lo = (a.y + b.y) + e;
|
|
62580
|
-
float hi = s + lo;
|
|
62581
|
-
lo = lo - (hi - s);
|
|
62582
|
-
return vec2(hi, lo);
|
|
62583
|
-
}
|
|
62584
|
-
|
|
62585
|
-
// Double-single subtraction
|
|
62586
|
-
vec2 ds_sub(vec2 a, vec2 b) {
|
|
62587
|
-
return ds_add(a, vec2(-b.x, -b.y));
|
|
62588
|
-
}
|
|
62589
|
-
|
|
62590
|
-
// Error-free multiplication (Dekker TwoProduct)
|
|
62591
|
-
vec2 ds_mul(vec2 a, vec2 b) {
|
|
62592
|
-
float p = a.x * b.x;
|
|
62593
|
-
vec2 sa = ds_split(a.x);
|
|
62594
|
-
vec2 sb = ds_split(b.x);
|
|
62595
|
-
float err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
62596
|
-
err += a.x * b.y + a.y * b.x;
|
|
62597
|
-
float hi = p + err;
|
|
62598
|
-
float lo = err - (hi - p);
|
|
62599
|
-
return vec2(hi, lo);
|
|
62600
|
-
}
|
|
62601
|
-
|
|
62602
|
-
// Optimized self-multiply
|
|
62603
|
-
vec2 ds_sqr(vec2 a) {
|
|
62604
|
-
float p = a.x * a.x;
|
|
62605
|
-
vec2 sa = ds_split(a.x);
|
|
62606
|
-
float err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
62607
|
-
err += 2.0 * a.x * a.y;
|
|
62608
|
-
float hi = p + err;
|
|
62609
|
-
float lo = err - (hi - p);
|
|
62610
|
-
return vec2(hi, lo);
|
|
62611
|
-
}
|
|
62612
|
-
|
|
62613
|
-
// Compare magnitude: returns -1, 0, or 1
|
|
62614
|
-
float ds_cmp(vec2 a, vec2 b) {
|
|
62615
|
-
float d = a.x - b.x;
|
|
62616
|
-
if (d != 0.0) return sign(d);
|
|
62617
|
-
return sign(a.y - b.y);
|
|
62618
|
-
}
|
|
62619
|
-
`;
|
|
62620
|
-
var GPU_DS_ARITHMETIC_PREAMBLE_WGSL = `
|
|
62621
|
-
fn ds_split(a: f32) -> vec2f {
|
|
62622
|
-
const SPLIT: f32 = 4097.0;
|
|
62623
|
-
let t = SPLIT * a;
|
|
62624
|
-
let hi = t - (t - a);
|
|
62625
|
-
let lo = a - hi;
|
|
62626
|
-
return vec2f(hi, lo);
|
|
62627
|
-
}
|
|
62628
|
-
|
|
62629
|
-
fn ds_from(a: f32) -> vec2f {
|
|
62630
|
-
return vec2f(a, 0.0);
|
|
62631
|
-
}
|
|
62632
|
-
|
|
62633
|
-
fn ds_add(a: vec2f, b: vec2f) -> vec2f {
|
|
62634
|
-
let s = a.x + b.x;
|
|
62635
|
-
let v = s - a.x;
|
|
62636
|
-
let e = (a.x - (s - v)) + (b.x - v);
|
|
62637
|
-
let lo_t = (a.y + b.y) + e;
|
|
62638
|
-
let hi = s + lo_t;
|
|
62639
|
-
let lo = lo_t - (hi - s);
|
|
62640
|
-
return vec2f(hi, lo);
|
|
62641
|
-
}
|
|
62642
|
-
|
|
62643
|
-
fn ds_sub(a: vec2f, b: vec2f) -> vec2f {
|
|
62644
|
-
return ds_add(a, vec2f(-b.x, -b.y));
|
|
62645
|
-
}
|
|
62646
|
-
|
|
62647
|
-
fn ds_mul(a: vec2f, b: vec2f) -> vec2f {
|
|
62648
|
-
let p = a.x * b.x;
|
|
62649
|
-
let sa = ds_split(a.x);
|
|
62650
|
-
let sb = ds_split(b.x);
|
|
62651
|
-
var err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
62652
|
-
err += a.x * b.y + a.y * b.x;
|
|
62653
|
-
let hi = p + err;
|
|
62654
|
-
let lo = err - (hi - p);
|
|
62655
|
-
return vec2f(hi, lo);
|
|
62656
|
-
}
|
|
62657
|
-
|
|
62658
|
-
fn ds_sqr(a: vec2f) -> vec2f {
|
|
62659
|
-
let p = a.x * a.x;
|
|
62660
|
-
let sa = ds_split(a.x);
|
|
62661
|
-
var err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
62662
|
-
err += 2.0 * a.x * a.y;
|
|
62663
|
-
let hi = p + err;
|
|
62664
|
-
let lo = err - (hi - p);
|
|
62665
|
-
return vec2f(hi, lo);
|
|
62666
|
-
}
|
|
62667
|
-
|
|
62668
|
-
fn ds_cmp(a: vec2f, b: vec2f) -> f32 {
|
|
62669
|
-
let d = a.x - b.x;
|
|
62670
|
-
if (d != 0.0) { return sign(d); }
|
|
62671
|
-
return sign(a.y - b.y);
|
|
62672
|
-
}
|
|
62673
|
-
`;
|
|
62674
|
-
var GPU_FRACTAL_DP_PREAMBLE_GLSL = `
|
|
62675
|
-
uniform float _dp_cx_hi;
|
|
62676
|
-
uniform float _dp_cx_lo;
|
|
62677
|
-
uniform float _dp_cy_hi;
|
|
62678
|
-
uniform float _dp_cy_lo;
|
|
62679
|
-
uniform float _dp_w;
|
|
62680
|
-
uniform float _dp_h;
|
|
62681
|
-
|
|
62682
|
-
vec4 _dp_coord() {
|
|
62683
|
-
// Per-pixel offset from center \u2014 small, so float-precise
|
|
62684
|
-
float dx = (v_uv.x - 0.5) * _dp_w;
|
|
62685
|
-
float dy = (v_uv.y - 0.5) * _dp_h;
|
|
62686
|
-
// Combine center (hi+lo) + delta with emulated double precision
|
|
62687
|
-
vec2 cre = ds_add(vec2(_dp_cx_hi, _dp_cx_lo), ds_from(dx));
|
|
62688
|
-
vec2 cim = ds_add(vec2(_dp_cy_hi, _dp_cy_lo), ds_from(dy));
|
|
62689
|
-
return vec4(cre.x, cim.x, cre.y, cim.y);
|
|
62690
|
-
}
|
|
62691
|
-
|
|
62692
|
-
float _fractal_mandelbrot_dp(vec4 c, int maxIter) {
|
|
62693
|
-
// c = (re_hi, im_hi, re_lo, im_lo)
|
|
62694
|
-
vec2 cr = vec2(c.x, c.z); // real part as ds
|
|
62695
|
-
vec2 ci = vec2(c.y, c.w); // imag part as ds
|
|
62696
|
-
vec2 zr = vec2(0.0, 0.0);
|
|
62697
|
-
vec2 zi = vec2(0.0, 0.0);
|
|
62698
|
-
for (int i = 0; i < maxIter; i++) {
|
|
62699
|
-
vec2 zr2 = ds_sqr(zr);
|
|
62700
|
-
vec2 zi2 = ds_sqr(zi);
|
|
62701
|
-
// |z|^2 > 4.0 ?
|
|
62702
|
-
vec2 mag2 = ds_add(zr2, zi2);
|
|
62703
|
-
if (mag2.x > 4.0)
|
|
62704
|
-
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62705
|
-
// z = z^2 + c
|
|
62706
|
-
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci); // 2*zr*zi + ci
|
|
62707
|
-
zr = ds_add(ds_sub(zr2, zi2), cr); // zr^2 - zi^2 + cr
|
|
62708
|
-
zi = new_zi;
|
|
62709
|
-
}
|
|
62710
|
-
return 1.0;
|
|
62711
|
-
}
|
|
62712
|
-
|
|
62713
|
-
float _fractal_julia_dp(vec4 z_in, vec4 c, int maxIter) {
|
|
62714
|
-
vec2 zr = vec2(z_in.x, z_in.z);
|
|
62715
|
-
vec2 zi = vec2(z_in.y, z_in.w);
|
|
62716
|
-
vec2 cr = vec2(c.x, c.z);
|
|
62717
|
-
vec2 ci = vec2(c.y, c.w);
|
|
62718
|
-
for (int i = 0; i < maxIter; i++) {
|
|
62719
|
-
vec2 zr2 = ds_sqr(zr);
|
|
62720
|
-
vec2 zi2 = ds_sqr(zi);
|
|
62721
|
-
vec2 mag2 = ds_add(zr2, zi2);
|
|
62722
|
-
if (mag2.x > 4.0)
|
|
62723
|
-
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62724
|
-
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
62725
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
62726
|
-
zi = new_zi;
|
|
62727
|
-
}
|
|
62728
|
-
return 1.0;
|
|
62729
|
-
}
|
|
62730
|
-
`;
|
|
62731
|
-
var GPU_FRACTAL_DP_PREAMBLE_WGSL = `
|
|
62732
|
-
@group(0) @binding(10) var<uniform> _dp_cx_hi: f32;
|
|
62733
|
-
@group(0) @binding(11) var<uniform> _dp_cx_lo: f32;
|
|
62734
|
-
@group(0) @binding(12) var<uniform> _dp_cy_hi: f32;
|
|
62735
|
-
@group(0) @binding(13) var<uniform> _dp_cy_lo: f32;
|
|
62736
|
-
@group(0) @binding(14) var<uniform> _dp_w: f32;
|
|
62737
|
-
@group(0) @binding(15) var<uniform> _dp_h: f32;
|
|
62738
|
-
|
|
62739
|
-
fn _dp_coord(uv: vec2f) -> vec4f {
|
|
62740
|
-
let dx = (uv.x - 0.5) * _dp_w;
|
|
62741
|
-
let dy = (uv.y - 0.5) * _dp_h;
|
|
62742
|
-
let cre = ds_add(vec2f(_dp_cx_hi, _dp_cx_lo), ds_from(dx));
|
|
62743
|
-
let cim = ds_add(vec2f(_dp_cy_hi, _dp_cy_lo), ds_from(dy));
|
|
62744
|
-
return vec4f(cre.x, cim.x, cre.y, cim.y);
|
|
62745
|
-
}
|
|
62746
|
-
|
|
62747
|
-
fn _fractal_mandelbrot_dp(c: vec4f, maxIter: i32) -> f32 {
|
|
62748
|
-
let cr = vec2f(c.x, c.z);
|
|
62749
|
-
let ci = vec2f(c.y, c.w);
|
|
62750
|
-
var zr = vec2f(0.0, 0.0);
|
|
62751
|
-
var zi = vec2f(0.0, 0.0);
|
|
62752
|
-
for (var i: i32 = 0; i < maxIter; i++) {
|
|
62753
|
-
let zr2 = ds_sqr(zr);
|
|
62754
|
-
let zi2 = ds_sqr(zi);
|
|
62755
|
-
let mag2 = ds_add(zr2, zi2);
|
|
62756
|
-
if (mag2.x > 4.0) {
|
|
62757
|
-
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62758
|
-
}
|
|
62759
|
-
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
62760
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
62761
|
-
zi = new_zi;
|
|
62762
|
-
}
|
|
62763
|
-
return 1.0;
|
|
62764
|
-
}
|
|
62765
|
-
|
|
62766
|
-
fn _fractal_julia_dp(z_in: vec4f, c: vec4f, maxIter: i32) -> f32 {
|
|
62767
|
-
var zr = vec2f(z_in.x, z_in.z);
|
|
62768
|
-
var zi = vec2f(z_in.y, z_in.w);
|
|
62769
|
-
let cr = vec2f(c.x, c.z);
|
|
62770
|
-
let ci = vec2f(c.y, c.w);
|
|
62771
|
-
for (var i: i32 = 0; i < maxIter; i++) {
|
|
62772
|
-
let zr2 = ds_sqr(zr);
|
|
62773
|
-
let zi2 = ds_sqr(zi);
|
|
62774
|
-
let mag2 = ds_add(zr2, zi2);
|
|
62775
|
-
if (mag2.x > 4.0) {
|
|
62776
|
-
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62777
|
-
}
|
|
62778
|
-
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
62779
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
62780
|
-
zi = new_zi;
|
|
62781
|
-
}
|
|
62782
|
-
return 1.0;
|
|
62783
|
-
}
|
|
62784
63456
|
`;
|
|
62785
63457
|
var GPU_FRACTAL_PREAMBLE_GLSL = `
|
|
62786
63458
|
float _fractal_mandelbrot(vec2 c, int maxIter) {
|
|
@@ -62824,208 +63496,6 @@ fn _fractal_julia(z_in: vec2f, c: vec2f, maxIter: i32) -> f32 {
|
|
|
62824
63496
|
}
|
|
62825
63497
|
return 1.0;
|
|
62826
63498
|
}
|
|
62827
|
-
`;
|
|
62828
|
-
var GPU_FRACTAL_PT_PREAMBLE_GLSL = `
|
|
62829
|
-
uniform sampler2D _refOrbit;
|
|
62830
|
-
uniform int _refOrbitLen;
|
|
62831
|
-
uniform int _refOrbitTexWidth;
|
|
62832
|
-
uniform float _pt_offset_x;
|
|
62833
|
-
uniform float _pt_offset_y;
|
|
62834
|
-
uniform float _pt_w;
|
|
62835
|
-
uniform float _pt_h;
|
|
62836
|
-
|
|
62837
|
-
vec2 _pt_delta() {
|
|
62838
|
-
float dx = _pt_offset_x + (v_uv.x - 0.5) * _pt_w;
|
|
62839
|
-
float dy = _pt_offset_y + (v_uv.y - 0.5) * _pt_h;
|
|
62840
|
-
return vec2(dx, dy);
|
|
62841
|
-
}
|
|
62842
|
-
|
|
62843
|
-
vec2 _pt_fetch_orbit(int i) {
|
|
62844
|
-
int y = i / _refOrbitTexWidth;
|
|
62845
|
-
int x = i - y * _refOrbitTexWidth;
|
|
62846
|
-
return texelFetch(_refOrbit, ivec2(x, y), 0).rg;
|
|
62847
|
-
}
|
|
62848
|
-
|
|
62849
|
-
float _fractal_mandelbrot_pt(vec2 delta_c, int maxIter) {
|
|
62850
|
-
float dr = 0.0;
|
|
62851
|
-
float di = 0.0;
|
|
62852
|
-
int orbitLen = min(maxIter, _refOrbitLen);
|
|
62853
|
-
for (int i = 0; i < orbitLen; i++) {
|
|
62854
|
-
vec2 Zn = _pt_fetch_orbit(i);
|
|
62855
|
-
// delta_{n+1} = 2*Z_n*delta_n + delta_n^2 + delta_c
|
|
62856
|
-
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
62857
|
-
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
62858
|
-
dr = new_dr;
|
|
62859
|
-
di = new_di;
|
|
62860
|
-
// Full z = Z_{n+1} + delta for escape check
|
|
62861
|
-
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
62862
|
-
float zr = Zn1.x + dr;
|
|
62863
|
-
float zi = Zn1.y + di;
|
|
62864
|
-
float mag2 = zr * zr + zi * zi;
|
|
62865
|
-
if (mag2 > 4.0)
|
|
62866
|
-
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62867
|
-
// Glitch detection: |delta|^2 > |Z|^2
|
|
62868
|
-
float dmag2 = dr * dr + di * di;
|
|
62869
|
-
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
62870
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
62871
|
-
// Rebase to absolute coordinates and continue with single-float
|
|
62872
|
-
float abs_zr = Zn1.x + dr;
|
|
62873
|
-
float abs_zi = Zn1.y + di;
|
|
62874
|
-
// Reconstruct absolute c from reference + delta
|
|
62875
|
-
// (Use ds_from for the concept, but single-float suffices for fallback)
|
|
62876
|
-
float cx = abs_zr - dr + delta_c.x;
|
|
62877
|
-
float cy = abs_zi - di + delta_c.y;
|
|
62878
|
-
for (int j = i + 1; j < maxIter; j++) {
|
|
62879
|
-
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
62880
|
-
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
62881
|
-
abs_zr = new_zr;
|
|
62882
|
-
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
62883
|
-
if (mag2 > 4.0)
|
|
62884
|
-
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62885
|
-
}
|
|
62886
|
-
return 1.0;
|
|
62887
|
-
}
|
|
62888
|
-
}
|
|
62889
|
-
return 1.0;
|
|
62890
|
-
}
|
|
62891
|
-
|
|
62892
|
-
float _fractal_julia_pt(vec2 z_delta, vec2 delta_c, int maxIter) {
|
|
62893
|
-
float dr = z_delta.x;
|
|
62894
|
-
float di = z_delta.y;
|
|
62895
|
-
int orbitLen = min(maxIter, _refOrbitLen);
|
|
62896
|
-
for (int i = 0; i < orbitLen; i++) {
|
|
62897
|
-
vec2 Zn = _pt_fetch_orbit(i);
|
|
62898
|
-
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
62899
|
-
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
62900
|
-
dr = new_dr;
|
|
62901
|
-
di = new_di;
|
|
62902
|
-
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
62903
|
-
float zr = Zn1.x + dr;
|
|
62904
|
-
float zi = Zn1.y + di;
|
|
62905
|
-
float mag2 = zr * zr + zi * zi;
|
|
62906
|
-
if (mag2 > 4.0)
|
|
62907
|
-
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62908
|
-
float dmag2 = dr * dr + di * di;
|
|
62909
|
-
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
62910
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
62911
|
-
float abs_zr = Zn1.x + dr;
|
|
62912
|
-
float abs_zi = Zn1.y + di;
|
|
62913
|
-
float cx = delta_c.x;
|
|
62914
|
-
float cy = delta_c.y;
|
|
62915
|
-
for (int j = i + 1; j < maxIter; j++) {
|
|
62916
|
-
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
62917
|
-
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
62918
|
-
abs_zr = new_zr;
|
|
62919
|
-
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
62920
|
-
if (mag2 > 4.0)
|
|
62921
|
-
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62922
|
-
}
|
|
62923
|
-
return 1.0;
|
|
62924
|
-
}
|
|
62925
|
-
}
|
|
62926
|
-
return 1.0;
|
|
62927
|
-
}
|
|
62928
|
-
`;
|
|
62929
|
-
var GPU_FRACTAL_PT_PREAMBLE_WGSL = `
|
|
62930
|
-
@group(0) @binding(1) var _refOrbit: texture_2d<f32>;
|
|
62931
|
-
var<uniform> _refOrbitLen: i32;
|
|
62932
|
-
var<uniform> _refOrbitTexWidth: i32;
|
|
62933
|
-
var<uniform> _pt_offset_x: f32;
|
|
62934
|
-
var<uniform> _pt_offset_y: f32;
|
|
62935
|
-
var<uniform> _pt_w: f32;
|
|
62936
|
-
var<uniform> _pt_h: f32;
|
|
62937
|
-
|
|
62938
|
-
fn _pt_delta(uv: vec2f) -> vec2f {
|
|
62939
|
-
let dx = _pt_offset_x + (uv.x - 0.5) * _pt_w;
|
|
62940
|
-
let dy = _pt_offset_y + (uv.y - 0.5) * _pt_h;
|
|
62941
|
-
return vec2f(dx, dy);
|
|
62942
|
-
}
|
|
62943
|
-
|
|
62944
|
-
fn _pt_fetch_orbit(i: i32) -> vec2f {
|
|
62945
|
-
let y = i / _refOrbitTexWidth;
|
|
62946
|
-
let x = i - y * _refOrbitTexWidth;
|
|
62947
|
-
return textureLoad(_refOrbit, vec2i(x, y), 0).rg;
|
|
62948
|
-
}
|
|
62949
|
-
|
|
62950
|
-
fn _fractal_mandelbrot_pt(delta_c: vec2f, maxIter: i32) -> f32 {
|
|
62951
|
-
var dr: f32 = 0.0;
|
|
62952
|
-
var di: f32 = 0.0;
|
|
62953
|
-
let orbitLen = min(maxIter, _refOrbitLen);
|
|
62954
|
-
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
62955
|
-
let Zn = _pt_fetch_orbit(i);
|
|
62956
|
-
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
62957
|
-
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
62958
|
-
dr = new_dr;
|
|
62959
|
-
di = new_di;
|
|
62960
|
-
var Zn1 = vec2f(0.0);
|
|
62961
|
-
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
62962
|
-
let zr = Zn1.x + dr;
|
|
62963
|
-
let zi = Zn1.y + di;
|
|
62964
|
-
var mag2 = zr * zr + zi * zi;
|
|
62965
|
-
if (mag2 > 4.0) {
|
|
62966
|
-
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62967
|
-
}
|
|
62968
|
-
let dmag2 = dr * dr + di * di;
|
|
62969
|
-
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
62970
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
62971
|
-
var f_zr = Zn1.x + dr;
|
|
62972
|
-
var f_zi = Zn1.y + di;
|
|
62973
|
-
let cx = delta_c.x;
|
|
62974
|
-
let cy = delta_c.y;
|
|
62975
|
-
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
62976
|
-
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
62977
|
-
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
62978
|
-
f_zr = t_zr;
|
|
62979
|
-
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
62980
|
-
if (mag2 > 4.0) {
|
|
62981
|
-
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62982
|
-
}
|
|
62983
|
-
}
|
|
62984
|
-
return 1.0;
|
|
62985
|
-
}
|
|
62986
|
-
}
|
|
62987
|
-
return 1.0;
|
|
62988
|
-
}
|
|
62989
|
-
|
|
62990
|
-
fn _fractal_julia_pt(z_delta: vec2f, delta_c: vec2f, maxIter: i32) -> f32 {
|
|
62991
|
-
var dr = z_delta.x;
|
|
62992
|
-
var di = z_delta.y;
|
|
62993
|
-
let orbitLen = min(maxIter, _refOrbitLen);
|
|
62994
|
-
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
62995
|
-
let Zn = _pt_fetch_orbit(i);
|
|
62996
|
-
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
62997
|
-
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
62998
|
-
dr = new_dr;
|
|
62999
|
-
di = new_di;
|
|
63000
|
-
var Zn1 = vec2f(0.0);
|
|
63001
|
-
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
63002
|
-
let zr = Zn1.x + dr;
|
|
63003
|
-
let zi = Zn1.y + di;
|
|
63004
|
-
var mag2 = zr * zr + zi * zi;
|
|
63005
|
-
if (mag2 > 4.0) {
|
|
63006
|
-
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
63007
|
-
}
|
|
63008
|
-
let dmag2 = dr * dr + di * di;
|
|
63009
|
-
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
63010
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
63011
|
-
var f_zr = Zn1.x + dr;
|
|
63012
|
-
var f_zi = Zn1.y + di;
|
|
63013
|
-
let cx = delta_c.x;
|
|
63014
|
-
let cy = delta_c.y;
|
|
63015
|
-
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
63016
|
-
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
63017
|
-
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
63018
|
-
f_zr = t_zr;
|
|
63019
|
-
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
63020
|
-
if (mag2 > 4.0) {
|
|
63021
|
-
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
63022
|
-
}
|
|
63023
|
-
}
|
|
63024
|
-
return 1.0;
|
|
63025
|
-
}
|
|
63026
|
-
}
|
|
63027
|
-
return 1.0;
|
|
63028
|
-
}
|
|
63029
63499
|
`;
|
|
63030
63500
|
var GPU_COLOR_PREAMBLE_GLSL = `
|
|
63031
63501
|
float _gpu_srgb_to_linear(float c) {
|
|
@@ -63067,28 +63537,124 @@ vec3 _gpu_oklab_to_srgb(vec3 lab) {
|
|
|
63067
63537
|
|
|
63068
63538
|
vec3 _gpu_oklab_to_oklch(vec3 lab) {
|
|
63069
63539
|
float C = length(lab.yz);
|
|
63070
|
-
float H = atan(lab.z, lab.y);
|
|
63540
|
+
float H = atan(lab.z, lab.y) * (180.0 / 3.14159265359);
|
|
63541
|
+
if (H < 0.0) H += 360.0;
|
|
63071
63542
|
return vec3(lab.x, C, H);
|
|
63072
63543
|
}
|
|
63073
63544
|
|
|
63074
63545
|
vec3 _gpu_oklch_to_oklab(vec3 lch) {
|
|
63075
|
-
|
|
63546
|
+
float h_rad = lch.z * (3.14159265359 / 180.0);
|
|
63547
|
+
return vec3(lch.x, lch.y * cos(h_rad), lch.y * sin(h_rad));
|
|
63548
|
+
}
|
|
63549
|
+
|
|
63550
|
+
vec3 _gpu_srgb_to_oklch(vec3 rgb) {
|
|
63551
|
+
return _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb));
|
|
63552
|
+
}
|
|
63553
|
+
|
|
63554
|
+
vec3 _gpu_oklch_to_srgb(vec3 lch) {
|
|
63555
|
+
return _gpu_oklab_to_srgb(_gpu_oklch_to_oklab(lch));
|
|
63076
63556
|
}
|
|
63077
63557
|
|
|
63078
|
-
|
|
63079
|
-
|
|
63080
|
-
|
|
63558
|
+
// HSL conversion. Hue in degrees, saturation/lightness in 0-1.
|
|
63559
|
+
vec3 _gpu_hsl_to_rgb(vec3 hsl) {
|
|
63560
|
+
float h = hsl.x;
|
|
63561
|
+
float s = hsl.y;
|
|
63562
|
+
float l = hsl.z;
|
|
63563
|
+
float c = (1.0 - abs(2.0 * l - 1.0)) * s;
|
|
63564
|
+
float h6 = h / 60.0;
|
|
63565
|
+
float x = c * (1.0 - abs(mod(h6, 2.0) - 1.0));
|
|
63566
|
+
float r = 0.0;
|
|
63567
|
+
float g = 0.0;
|
|
63568
|
+
float b = 0.0;
|
|
63569
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63570
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63571
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63572
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63573
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63574
|
+
else { r = c; g = 0.0; b = x; }
|
|
63575
|
+
float m = l - c / 2.0;
|
|
63576
|
+
return vec3(r + m, g + m, b + m);
|
|
63577
|
+
}
|
|
63578
|
+
|
|
63579
|
+
vec3 _gpu_rgb_to_hsl(vec3 rgb) {
|
|
63580
|
+
float maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63581
|
+
float minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63582
|
+
float l = (maxc + minc) / 2.0;
|
|
63583
|
+
float d = maxc - minc;
|
|
63584
|
+
if (d < 1e-6) return vec3(0.0, 0.0, l);
|
|
63585
|
+
float s = d / (1.0 - abs(2.0 * l - 1.0));
|
|
63586
|
+
float h;
|
|
63587
|
+
if (maxc == rgb.x) h = mod((rgb.y - rgb.z) / d, 6.0);
|
|
63588
|
+
else if (maxc == rgb.y) h = (rgb.z - rgb.x) / d + 2.0;
|
|
63589
|
+
else h = (rgb.x - rgb.y) / d + 4.0;
|
|
63590
|
+
h *= 60.0;
|
|
63591
|
+
if (h < 0.0) h += 360.0;
|
|
63592
|
+
return vec3(h, s, l);
|
|
63593
|
+
}
|
|
63594
|
+
|
|
63595
|
+
// HSV conversion. Hue in degrees, saturation/value in 0-1.
|
|
63596
|
+
vec3 _gpu_hsv_to_rgb(vec3 hsv) {
|
|
63597
|
+
float h = hsv.x;
|
|
63598
|
+
float s = hsv.y;
|
|
63599
|
+
float v = hsv.z;
|
|
63600
|
+
float c = v * s;
|
|
63601
|
+
float h6 = h / 60.0;
|
|
63602
|
+
float x = c * (1.0 - abs(mod(h6, 2.0) - 1.0));
|
|
63603
|
+
float r = 0.0;
|
|
63604
|
+
float g = 0.0;
|
|
63605
|
+
float b = 0.0;
|
|
63606
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63607
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63608
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63609
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63610
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63611
|
+
else { r = c; g = 0.0; b = x; }
|
|
63612
|
+
float m = v - c;
|
|
63613
|
+
return vec3(r + m, g + m, b + m);
|
|
63614
|
+
}
|
|
63615
|
+
|
|
63616
|
+
vec3 _gpu_rgb_to_hsv(vec3 rgb) {
|
|
63617
|
+
float maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63618
|
+
float minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63619
|
+
float v = maxc;
|
|
63620
|
+
float d = maxc - minc;
|
|
63621
|
+
if (d < 1e-6) return vec3(0.0, 0.0, v);
|
|
63622
|
+
float s = (maxc < 1e-6) ? 0.0 : d / maxc;
|
|
63623
|
+
float h;
|
|
63624
|
+
if (maxc == rgb.x) h = mod((rgb.y - rgb.z) / d, 6.0);
|
|
63625
|
+
else if (maxc == rgb.y) h = (rgb.z - rgb.x) / d + 2.0;
|
|
63626
|
+
else h = (rgb.x - rgb.y) / d + 4.0;
|
|
63627
|
+
h *= 60.0;
|
|
63628
|
+
if (h < 0.0) h += 360.0;
|
|
63629
|
+
return vec3(h, s, v);
|
|
63630
|
+
}
|
|
63631
|
+
|
|
63632
|
+
vec3 _gpu_color_mix(vec3 lch1, vec3 lch2, float t) {
|
|
63081
63633
|
float L = mix(lch1.x, lch2.x, t);
|
|
63082
63634
|
float C = mix(lch1.y, lch2.y, t);
|
|
63083
|
-
|
|
63084
|
-
|
|
63085
|
-
|
|
63086
|
-
if (
|
|
63087
|
-
|
|
63088
|
-
|
|
63635
|
+
bool a1 = lch1.y < 1e-6;
|
|
63636
|
+
bool a2 = lch2.y < 1e-6;
|
|
63637
|
+
float H;
|
|
63638
|
+
if (a1 && a2) {
|
|
63639
|
+
H = lch1.z;
|
|
63640
|
+
} else if (a1) {
|
|
63641
|
+
H = lch2.z;
|
|
63642
|
+
} else if (a2) {
|
|
63643
|
+
H = lch1.z;
|
|
63644
|
+
} else {
|
|
63645
|
+
float dh = lch2.z - lch1.z;
|
|
63646
|
+
if (dh > 180.0) dh -= 360.0;
|
|
63647
|
+
if (dh < -180.0) dh += 360.0;
|
|
63648
|
+
H = lch1.z + dh * t;
|
|
63649
|
+
if (H < 0.0) H += 360.0;
|
|
63650
|
+
if (H >= 360.0) H -= 360.0;
|
|
63651
|
+
}
|
|
63652
|
+
return vec3(L, C, H);
|
|
63089
63653
|
}
|
|
63090
63654
|
|
|
63091
|
-
float _gpu_apca(vec3
|
|
63655
|
+
float _gpu_apca(vec3 lch_bg, vec3 lch_fg) {
|
|
63656
|
+
vec3 bg = _gpu_oklch_to_srgb(lch_bg);
|
|
63657
|
+
vec3 fg = _gpu_oklch_to_srgb(lch_fg);
|
|
63092
63658
|
float bgR = _gpu_srgb_to_linear(bg.x);
|
|
63093
63659
|
float bgG = _gpu_srgb_to_linear(bg.y);
|
|
63094
63660
|
float bgB = _gpu_srgb_to_linear(bg.z);
|
|
@@ -63099,9 +63665,7 @@ float _gpu_apca(vec3 bg, vec3 fg) {
|
|
|
63099
63665
|
float fgY = 0.2126729 * fgR + 0.7151522 * fgG + 0.0721750 * fgB;
|
|
63100
63666
|
float bgC = pow(bgY, 0.56);
|
|
63101
63667
|
float fgC = pow(fgY, 0.57);
|
|
63102
|
-
float contrast = (bgC
|
|
63103
|
-
? (bgC - fgC) * 1.14
|
|
63104
|
-
: (bgC - fgC) * 1.14;
|
|
63668
|
+
float contrast = (bgC - fgC) * 1.14;
|
|
63105
63669
|
return contrast * 100.0;
|
|
63106
63670
|
}
|
|
63107
63671
|
`;
|
|
@@ -63145,28 +63709,133 @@ fn _gpu_oklab_to_srgb(lab: vec3f) -> vec3f {
|
|
|
63145
63709
|
|
|
63146
63710
|
fn _gpu_oklab_to_oklch(lab: vec3f) -> vec3f {
|
|
63147
63711
|
let C = length(lab.yz);
|
|
63148
|
-
|
|
63712
|
+
var H = atan2(lab.z, lab.y) * (180.0 / 3.14159265359);
|
|
63713
|
+
if (H < 0.0) { H = H + 360.0; }
|
|
63149
63714
|
return vec3f(lab.x, C, H);
|
|
63150
63715
|
}
|
|
63151
63716
|
|
|
63152
63717
|
fn _gpu_oklch_to_oklab(lch: vec3f) -> vec3f {
|
|
63153
|
-
|
|
63718
|
+
let h_rad = lch.z * (3.14159265359 / 180.0);
|
|
63719
|
+
return vec3f(lch.x, lch.y * cos(h_rad), lch.y * sin(h_rad));
|
|
63720
|
+
}
|
|
63721
|
+
|
|
63722
|
+
fn _gpu_srgb_to_oklch(rgb: vec3f) -> vec3f {
|
|
63723
|
+
return _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb));
|
|
63724
|
+
}
|
|
63725
|
+
|
|
63726
|
+
fn _gpu_oklch_to_srgb(lch: vec3f) -> vec3f {
|
|
63727
|
+
return _gpu_oklab_to_srgb(_gpu_oklch_to_oklab(lch));
|
|
63728
|
+
}
|
|
63729
|
+
|
|
63730
|
+
fn _gpu_hsl_to_rgb(hsl: vec3f) -> vec3f {
|
|
63731
|
+
let h = hsl.x;
|
|
63732
|
+
let s = hsl.y;
|
|
63733
|
+
let l = hsl.z;
|
|
63734
|
+
let c = (1.0 - abs(2.0 * l - 1.0)) * s;
|
|
63735
|
+
let h6 = h / 60.0;
|
|
63736
|
+
let x = c * (1.0 - abs((h6 - 2.0 * floor(h6 / 2.0)) - 1.0));
|
|
63737
|
+
var r: f32 = 0.0;
|
|
63738
|
+
var g: f32 = 0.0;
|
|
63739
|
+
var b: f32 = 0.0;
|
|
63740
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63741
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63742
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63743
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63744
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63745
|
+
else { r = c; g = 0.0; b = x; }
|
|
63746
|
+
let m = l - c / 2.0;
|
|
63747
|
+
return vec3f(r + m, g + m, b + m);
|
|
63154
63748
|
}
|
|
63155
63749
|
|
|
63156
|
-
fn
|
|
63157
|
-
let
|
|
63158
|
-
let
|
|
63750
|
+
fn _gpu_rgb_to_hsl(rgb: vec3f) -> vec3f {
|
|
63751
|
+
let maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63752
|
+
let minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63753
|
+
let l = (maxc + minc) / 2.0;
|
|
63754
|
+
let d = maxc - minc;
|
|
63755
|
+
if (d < 1e-6) { return vec3f(0.0, 0.0, l); }
|
|
63756
|
+
let s = d / (1.0 - abs(2.0 * l - 1.0));
|
|
63757
|
+
var h: f32;
|
|
63758
|
+
if (maxc == rgb.x) {
|
|
63759
|
+
let v = (rgb.y - rgb.z) / d;
|
|
63760
|
+
h = v - 6.0 * floor(v / 6.0);
|
|
63761
|
+
} else if (maxc == rgb.y) {
|
|
63762
|
+
h = (rgb.z - rgb.x) / d + 2.0;
|
|
63763
|
+
} else {
|
|
63764
|
+
h = (rgb.x - rgb.y) / d + 4.0;
|
|
63765
|
+
}
|
|
63766
|
+
h = h * 60.0;
|
|
63767
|
+
if (h < 0.0) { h = h + 360.0; }
|
|
63768
|
+
return vec3f(h, s, l);
|
|
63769
|
+
}
|
|
63770
|
+
|
|
63771
|
+
fn _gpu_hsv_to_rgb(hsv: vec3f) -> vec3f {
|
|
63772
|
+
let h = hsv.x;
|
|
63773
|
+
let s = hsv.y;
|
|
63774
|
+
let v = hsv.z;
|
|
63775
|
+
let c = v * s;
|
|
63776
|
+
let h6 = h / 60.0;
|
|
63777
|
+
let x = c * (1.0 - abs((h6 - 2.0 * floor(h6 / 2.0)) - 1.0));
|
|
63778
|
+
var r: f32 = 0.0;
|
|
63779
|
+
var g: f32 = 0.0;
|
|
63780
|
+
var b: f32 = 0.0;
|
|
63781
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63782
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63783
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63784
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63785
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63786
|
+
else { r = c; g = 0.0; b = x; }
|
|
63787
|
+
let m = v - c;
|
|
63788
|
+
return vec3f(r + m, g + m, b + m);
|
|
63789
|
+
}
|
|
63790
|
+
|
|
63791
|
+
fn _gpu_rgb_to_hsv(rgb: vec3f) -> vec3f {
|
|
63792
|
+
let maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63793
|
+
let minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63794
|
+
let v = maxc;
|
|
63795
|
+
let d = maxc - minc;
|
|
63796
|
+
if (d < 1e-6) { return vec3f(0.0, 0.0, v); }
|
|
63797
|
+
var s: f32 = 0.0;
|
|
63798
|
+
if (maxc >= 1e-6) { s = d / maxc; }
|
|
63799
|
+
var h: f32;
|
|
63800
|
+
if (maxc == rgb.x) {
|
|
63801
|
+
let q = (rgb.y - rgb.z) / d;
|
|
63802
|
+
h = q - 6.0 * floor(q / 6.0);
|
|
63803
|
+
} else if (maxc == rgb.y) {
|
|
63804
|
+
h = (rgb.z - rgb.x) / d + 2.0;
|
|
63805
|
+
} else {
|
|
63806
|
+
h = (rgb.x - rgb.y) / d + 4.0;
|
|
63807
|
+
}
|
|
63808
|
+
h = h * 60.0;
|
|
63809
|
+
if (h < 0.0) { h = h + 360.0; }
|
|
63810
|
+
return vec3f(h, s, v);
|
|
63811
|
+
}
|
|
63812
|
+
|
|
63813
|
+
fn _gpu_color_mix(lch1: vec3f, lch2: vec3f, t: f32) -> vec3f {
|
|
63159
63814
|
let L = mix(lch1.x, lch2.x, t);
|
|
63160
63815
|
let C = mix(lch1.y, lch2.y, t);
|
|
63161
|
-
let
|
|
63162
|
-
|
|
63163
|
-
|
|
63164
|
-
if (
|
|
63165
|
-
|
|
63166
|
-
|
|
63816
|
+
let a1 = lch1.y < 1e-6;
|
|
63817
|
+
let a2 = lch2.y < 1e-6;
|
|
63818
|
+
var H: f32;
|
|
63819
|
+
if (a1 && a2) {
|
|
63820
|
+
H = lch1.z;
|
|
63821
|
+
} else if (a1) {
|
|
63822
|
+
H = lch2.z;
|
|
63823
|
+
} else if (a2) {
|
|
63824
|
+
H = lch1.z;
|
|
63825
|
+
} else {
|
|
63826
|
+
var dh = lch2.z - lch1.z;
|
|
63827
|
+
if (dh > 180.0) { dh = dh - 360.0; }
|
|
63828
|
+
if (dh < -180.0) { dh = dh + 360.0; }
|
|
63829
|
+
H = lch1.z + dh * t;
|
|
63830
|
+
if (H < 0.0) { H = H + 360.0; }
|
|
63831
|
+
if (H >= 360.0) { H = H - 360.0; }
|
|
63832
|
+
}
|
|
63833
|
+
return vec3f(L, C, H);
|
|
63167
63834
|
}
|
|
63168
63835
|
|
|
63169
|
-
fn _gpu_apca(
|
|
63836
|
+
fn _gpu_apca(lch_bg: vec3f, lch_fg: vec3f) -> f32 {
|
|
63837
|
+
let bg = _gpu_oklch_to_srgb(lch_bg);
|
|
63838
|
+
let fg = _gpu_oklch_to_srgb(lch_fg);
|
|
63170
63839
|
let bgR = _gpu_srgb_to_linear(bg.x);
|
|
63171
63840
|
let bgG = _gpu_srgb_to_linear(bg.y);
|
|
63172
63841
|
let bgB = _gpu_srgb_to_linear(bg.z);
|
|
@@ -63454,7 +64123,7 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
63454
64123
|
if (stmts.length === 0) return "";
|
|
63455
64124
|
const last = stmts.length - 1;
|
|
63456
64125
|
stmts[last] = `return ${stmts[last]}`;
|
|
63457
|
-
return stmts.join(";\n");
|
|
64126
|
+
return stmts.join(";\n") + ";";
|
|
63458
64127
|
},
|
|
63459
64128
|
...options
|
|
63460
64129
|
};
|
|
@@ -63465,7 +64134,6 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
63465
64134
|
const constants = this.getConstants();
|
|
63466
64135
|
const v2 = this.languageId === "wgsl" ? "vec2f" : "vec2";
|
|
63467
64136
|
const target = this.createTarget({
|
|
63468
|
-
hints: options.hints,
|
|
63469
64137
|
functions: (id) => {
|
|
63470
64138
|
if (userFunctions && id in userFunctions) {
|
|
63471
64139
|
const fn = userFunctions[id];
|
|
@@ -63504,89 +64172,12 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
63504
64172
|
if (code.includes("_gpu_besselJ"))
|
|
63505
64173
|
preamble += this.languageId === "wgsl" ? GPU_BESSELJ_PREAMBLE_WGSL : GPU_BESSELJ_PREAMBLE_GLSL;
|
|
63506
64174
|
if (code.includes("_fractal_")) {
|
|
63507
|
-
|
|
63508
|
-
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
63509
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PT_PREAMBLE_WGSL : GPU_FRACTAL_PT_PREAMBLE_GLSL;
|
|
63510
|
-
} else if (code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) {
|
|
63511
|
-
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
63512
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_DP_PREAMBLE_WGSL : GPU_FRACTAL_DP_PREAMBLE_GLSL;
|
|
63513
|
-
} else {
|
|
63514
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
63515
|
-
}
|
|
64175
|
+
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
63516
64176
|
}
|
|
63517
64177
|
if (code.includes("_gpu_srgb_to") || code.includes("_gpu_oklab") || code.includes("_gpu_oklch") || code.includes("_gpu_color_mix") || code.includes("_gpu_apca")) {
|
|
63518
64178
|
preamble += this.languageId === "wgsl" ? GPU_COLOR_PREAMBLE_WGSL : GPU_COLOR_PREAMBLE_GLSL;
|
|
63519
64179
|
}
|
|
63520
64180
|
if (preamble) result.preamble = preamble;
|
|
63521
|
-
if (code.includes("_fractal_") && options.hints?.viewport) {
|
|
63522
|
-
const strategy = selectFractalStrategy(target);
|
|
63523
|
-
const radius = options.hints.viewport.radius;
|
|
63524
|
-
switch (strategy) {
|
|
63525
|
-
case "single":
|
|
63526
|
-
result.staleWhen = { radiusBelow: 1e-6 };
|
|
63527
|
-
break;
|
|
63528
|
-
case "double":
|
|
63529
|
-
result.staleWhen = { radiusBelow: 1e-14, radiusAbove: 1e-5 };
|
|
63530
|
-
break;
|
|
63531
|
-
case "perturbation":
|
|
63532
|
-
result.staleWhen = {
|
|
63533
|
-
radiusAbove: 1e-5,
|
|
63534
|
-
radiusBelow: radius * 0.01,
|
|
63535
|
-
centerDistance: radius * 2
|
|
63536
|
-
};
|
|
63537
|
-
break;
|
|
63538
|
-
}
|
|
63539
|
-
}
|
|
63540
|
-
if ((code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) && options.hints?.viewport) {
|
|
63541
|
-
const cx = hpToNumber(options.hints.viewport.center[0]);
|
|
63542
|
-
const cy = hpToNumber(options.hints.viewport.center[1]);
|
|
63543
|
-
const size = options.hints.viewport.radius * 2;
|
|
63544
|
-
const cx_hi = Math.fround(cx);
|
|
63545
|
-
const cy_hi = Math.fround(cy);
|
|
63546
|
-
result.uniforms = {
|
|
63547
|
-
...result.uniforms,
|
|
63548
|
-
_dp_cx_hi: cx_hi,
|
|
63549
|
-
_dp_cx_lo: cx - cx_hi,
|
|
63550
|
-
_dp_cy_hi: cy_hi,
|
|
63551
|
-
_dp_cy_lo: cy - cy_hi,
|
|
63552
|
-
_dp_w: size,
|
|
63553
|
-
_dp_h: size
|
|
63554
|
-
};
|
|
63555
|
-
}
|
|
63556
|
-
if ((code.includes("_fractal_mandelbrot_pt") || code.includes("_fractal_julia_pt")) && options.hints?.viewport) {
|
|
63557
|
-
const viewport = options.hints.viewport;
|
|
63558
|
-
const size = viewport.radius * 2;
|
|
63559
|
-
result.uniforms = {
|
|
63560
|
-
...result.uniforms,
|
|
63561
|
-
_pt_offset_x: 0,
|
|
63562
|
-
_pt_offset_y: 0,
|
|
63563
|
-
_pt_w: size,
|
|
63564
|
-
_pt_h: size
|
|
63565
|
-
};
|
|
63566
|
-
const digits = Math.max(50, Math.ceil(-Math.log10(viewport.radius)) + 10);
|
|
63567
|
-
const maxIter = 1e3;
|
|
63568
|
-
const orbit = computeReferenceOrbit(
|
|
63569
|
-
viewport.center,
|
|
63570
|
-
maxIter,
|
|
63571
|
-
digits
|
|
63572
|
-
);
|
|
63573
|
-
const orbitLen = orbit.length / 2;
|
|
63574
|
-
const texWidth = Math.min(orbitLen, 4096);
|
|
63575
|
-
const texHeight = Math.ceil(orbitLen / texWidth);
|
|
63576
|
-
result.textures = {
|
|
63577
|
-
_refOrbit: {
|
|
63578
|
-
data: orbit,
|
|
63579
|
-
width: texWidth,
|
|
63580
|
-
height: texHeight,
|
|
63581
|
-
format: "rg32f"
|
|
63582
|
-
}
|
|
63583
|
-
};
|
|
63584
|
-
result.uniforms = {
|
|
63585
|
-
...result.uniforms,
|
|
63586
|
-
_refOrbitLen: orbitLen,
|
|
63587
|
-
_refOrbitTexWidth: texWidth
|
|
63588
|
-
};
|
|
63589
|
-
}
|
|
63590
64181
|
return result;
|
|
63591
64182
|
}
|
|
63592
64183
|
compileToSource(expr2, _options = {}) {
|
|
@@ -63631,7 +64222,7 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
63631
64222
|
if (body.includes("\n")) {
|
|
63632
64223
|
const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
|
|
63633
64224
|
return `${returnType} ${functionName}(${params}) {
|
|
63634
|
-
${indented}
|
|
64225
|
+
${indented}
|
|
63635
64226
|
}`;
|
|
63636
64227
|
}
|
|
63637
64228
|
return `${returnType} ${functionName}(${params}) {
|
|
@@ -63742,7 +64333,7 @@ ${indented};
|
|
|
63742
64333
|
return `fn ${functionName}(${params}) -> ${toWGSLType(
|
|
63743
64334
|
returnType
|
|
63744
64335
|
)} {
|
|
63745
|
-
${indented}
|
|
64336
|
+
${indented}
|
|
63746
64337
|
}`;
|
|
63747
64338
|
}
|
|
63748
64339
|
return `fn ${functionName}(${params}) -> ${toWGSLType(returnType)} {
|
|
@@ -67727,6 +68318,7 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
|
|
|
67727
68318
|
this.pushScope(void 0, "global");
|
|
67728
68319
|
this._compilationTargets.registerDefaults();
|
|
67729
68320
|
if (options?.latexSyntax) this._latexSyntax = options.latexSyntax;
|
|
68321
|
+
if (options?.latexOptions) this._latexOptions = { ...options.latexOptions };
|
|
67730
68322
|
hidePrivateProperties(this);
|
|
67731
68323
|
}
|
|
67732
68324
|
toJSON() {
|
|
@@ -68387,6 +68979,29 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
|
|
|
68387
68979
|
);
|
|
68388
68980
|
return this._latexSyntax;
|
|
68389
68981
|
}
|
|
68982
|
+
/** @internal Engine-wide LaTeX parse/serialize options (e.g. decimalSeparator).
|
|
68983
|
+
* Merged into every `parse()` and `toLatex()` call between the LatexSyntax
|
|
68984
|
+
* instance defaults and any per-call overrides. */
|
|
68985
|
+
_latexOptions = {};
|
|
68986
|
+
/** Engine-wide LaTeX parse/serialize options.
|
|
68987
|
+
*
|
|
68988
|
+
* These options are merged into every `parse()` and `toLatex()` call.
|
|
68989
|
+
* Precedence (most-specific wins):
|
|
68990
|
+
* 1. LatexSyntax instance defaults (set at its construction)
|
|
68991
|
+
* 2. `ce.latexOptions` (this property)
|
|
68992
|
+
* 3. Per-call options passed to `ce.parse()` / `expr.toLatex()`
|
|
68993
|
+
*
|
|
68994
|
+
* Assigning replaces the whole bag. Use spread to merge:
|
|
68995
|
+
* ```ts
|
|
68996
|
+
* ce.latexOptions = { ...ce.latexOptions, decimalSeparator: '{,}' };
|
|
68997
|
+
* ```
|
|
68998
|
+
*/
|
|
68999
|
+
get latexOptions() {
|
|
69000
|
+
return this._latexOptions;
|
|
69001
|
+
}
|
|
69002
|
+
set latexOptions(options) {
|
|
69003
|
+
this._latexOptions = { ...options };
|
|
69004
|
+
}
|
|
68390
69005
|
parse(latex, options) {
|
|
68391
69006
|
if (latex === null || latex === void 0) return null;
|
|
68392
69007
|
if (typeof latex !== "string")
|
|
@@ -68394,7 +69009,6 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
|
|
|
68394
69009
|
const syntax = this._requireLatexSyntax();
|
|
68395
69010
|
const { form, ...parseOpts } = options ?? {};
|
|
68396
69011
|
const result = syntax.parse(latex, {
|
|
68397
|
-
decimalSeparator: ".",
|
|
68398
69012
|
getSymbolType: (id) => {
|
|
68399
69013
|
const def = this.lookupDefinition(id);
|
|
68400
69014
|
if (!def) return BoxedType.unknown;
|
|
@@ -68406,6 +69020,7 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
|
|
|
68406
69020
|
const def = this.lookupDefinition(id);
|
|
68407
69021
|
return !!(isValueDef(def) && def.value.subscriptEvaluate);
|
|
68408
69022
|
},
|
|
69023
|
+
...this._latexOptions,
|
|
68409
69024
|
...parseOpts
|
|
68410
69025
|
});
|
|
68411
69026
|
if (result === null) return null;
|
|
@@ -68569,7 +69184,7 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
|
|
|
68569
69184
|
_setDefaultEngineFactory(() => new ComputeEngine());
|
|
68570
69185
|
|
|
68571
69186
|
// src/core.ts
|
|
68572
|
-
var version = "0.
|
|
69187
|
+
var version = "0.56.0";
|
|
68573
69188
|
return __toCommonJS(core_exports);
|
|
68574
69189
|
})();
|
|
68575
69190
|
/*! Bundled license information:
|