@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/compile.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Compute Engine 0.
|
|
1
|
+
/** Compute Engine 0.56.0 */
|
|
2
2
|
|
|
3
3
|
// src/compute-engine/numerics/richardson.ts
|
|
4
4
|
function extrapolate(f, x0, options = {}) {
|
|
@@ -1511,6 +1511,7 @@ var SCALAR_TYPES = [
|
|
|
1511
1511
|
];
|
|
1512
1512
|
var VALUE_TYPES = [
|
|
1513
1513
|
"value",
|
|
1514
|
+
"color",
|
|
1514
1515
|
...COLLECTION_TYPES,
|
|
1515
1516
|
...SCALAR_TYPES
|
|
1516
1517
|
];
|
|
@@ -3206,6 +3207,7 @@ var PRIMITIVE_SUBTYPES = {
|
|
|
3206
3207
|
symbol: [],
|
|
3207
3208
|
boolean: [],
|
|
3208
3209
|
string: [],
|
|
3210
|
+
color: [],
|
|
3209
3211
|
expression: EXPRESSION_TYPES
|
|
3210
3212
|
};
|
|
3211
3213
|
function isPrimitiveSubtype(lhs, rhs) {
|
|
@@ -6240,10 +6242,6 @@ var DEFINITIONS_CORE = [
|
|
|
6240
6242
|
// Lagrange notation
|
|
6241
6243
|
{
|
|
6242
6244
|
name: "Derivative",
|
|
6243
|
-
// @todo: Leibniz notation: {% latex " \\frac{d^n}{dx^n} f(x)" %}
|
|
6244
|
-
// @todo: Euler modified notation: This notation is used by Mathematica. The Euler notation uses `D` instead of
|
|
6245
|
-
// `\partial`: `\partial_{x} f`, `\partial_{x,y} f`
|
|
6246
|
-
// Newton notation (\dot{v}, \ddot{v}) is implemented below
|
|
6247
6245
|
serialize: (serializer, expr) => {
|
|
6248
6246
|
const degree = machineValue(operand(expr, 2)) ?? 1;
|
|
6249
6247
|
const base = serializer.serialize(operand(expr, 1));
|
|
@@ -7281,14 +7279,18 @@ var DEFINITIONS_SETS = [
|
|
|
7281
7279
|
return ["Complement", lhs];
|
|
7282
7280
|
}
|
|
7283
7281
|
// precedence: 240,
|
|
7284
|
-
// @todo: serialize for the multiple argument case
|
|
7285
7282
|
},
|
|
7286
7283
|
{
|
|
7287
7284
|
name: "Complement",
|
|
7288
7285
|
latexTrigger: ["^", "<{>", "\\complement", "<}>"],
|
|
7289
|
-
kind: "postfix"
|
|
7286
|
+
kind: "postfix",
|
|
7290
7287
|
// precedence: 240,
|
|
7291
|
-
|
|
7288
|
+
serialize: (serializer, expr) => {
|
|
7289
|
+
return joinLatex([
|
|
7290
|
+
serializer.serialize(operand(expr, 1)),
|
|
7291
|
+
"^\\complement"
|
|
7292
|
+
]);
|
|
7293
|
+
}
|
|
7292
7294
|
},
|
|
7293
7295
|
{
|
|
7294
7296
|
name: "Intersection",
|
|
@@ -7375,7 +7377,6 @@ var DEFINITIONS_SETS = [
|
|
|
7375
7377
|
// commands like \rbrack a, b \rbrack which are unambiguous.
|
|
7376
7378
|
{
|
|
7377
7379
|
name: "Multiple",
|
|
7378
|
-
// @todo: parse
|
|
7379
7380
|
serialize: serializeSet
|
|
7380
7381
|
},
|
|
7381
7382
|
{
|
|
@@ -7384,14 +7385,28 @@ var DEFINITIONS_SETS = [
|
|
|
7384
7385
|
kind: "infix",
|
|
7385
7386
|
precedence: 350
|
|
7386
7387
|
},
|
|
7388
|
+
// \mid as a separator/operator (used in set-builder notation: {x \mid x > 0})
|
|
7389
|
+
// Low precedence so it binds loosely — everything on each side is parsed first
|
|
7390
|
+
{
|
|
7391
|
+
name: "Divides",
|
|
7392
|
+
latexTrigger: ["\\mid"],
|
|
7393
|
+
kind: "infix",
|
|
7394
|
+
precedence: 160
|
|
7395
|
+
},
|
|
7387
7396
|
{
|
|
7388
7397
|
name: "Set",
|
|
7389
7398
|
kind: "matchfix",
|
|
7390
7399
|
openTrigger: "{",
|
|
7391
7400
|
closeTrigger: "}",
|
|
7392
|
-
// @todo: the set syntax can also include conditions...
|
|
7393
7401
|
parse: (_parser, body) => {
|
|
7394
7402
|
if (isEmptySequence(body)) return "EmptySet";
|
|
7403
|
+
const h = operator(body);
|
|
7404
|
+
if (h === "Divides" || h === "Colon") {
|
|
7405
|
+
const expr = operand(body, 1);
|
|
7406
|
+
const condition = operand(body, 2);
|
|
7407
|
+
if (expr !== null && condition !== null)
|
|
7408
|
+
return ["Set", expr, ["Condition", condition]];
|
|
7409
|
+
}
|
|
7395
7410
|
if (operator(body) == "Delimiter" && stringValue(operand(body, 2)) === ",") {
|
|
7396
7411
|
body = operand(body, 1);
|
|
7397
7412
|
}
|
|
@@ -7399,6 +7414,17 @@ var DEFINITIONS_SETS = [
|
|
|
7399
7414
|
return ["Set", ...operands(body)];
|
|
7400
7415
|
},
|
|
7401
7416
|
serialize: (serializer, expr) => {
|
|
7417
|
+
if (nops(expr) === 2 && operator(operand(expr, 2)) === "Condition") {
|
|
7418
|
+
const condition = operand(expr, 2);
|
|
7419
|
+
return joinLatex([
|
|
7420
|
+
"\\lbrace",
|
|
7421
|
+
serializer.serialize(operand(expr, 1)),
|
|
7422
|
+
"\\mid",
|
|
7423
|
+
// Serialize the inner expression of the Condition wrapper
|
|
7424
|
+
serializer.serialize(operand(condition, 1)),
|
|
7425
|
+
"\\rbrace"
|
|
7426
|
+
]);
|
|
7427
|
+
}
|
|
7402
7428
|
return joinLatex([
|
|
7403
7429
|
"\\lbrace",
|
|
7404
7430
|
operands(expr).map((x) => serializer.serialize(x)).join(", "),
|
|
@@ -7565,23 +7591,6 @@ function serializeSet(serializer, expr) {
|
|
|
7565
7591
|
if (expr === null) return "";
|
|
7566
7592
|
const h = operator(expr);
|
|
7567
7593
|
if (!h) return "";
|
|
7568
|
-
if (h === "Set") {
|
|
7569
|
-
if (nops(expr) === 0) return "\\emptyset";
|
|
7570
|
-
if (nops(expr) === 2 && operator(operand(expr, 2)) === "Condition") {
|
|
7571
|
-
return joinLatex([
|
|
7572
|
-
"\\left\\lbrace",
|
|
7573
|
-
serializer.serialize(operand(expr, 1)),
|
|
7574
|
-
"\\middle\\mid",
|
|
7575
|
-
serializer.serialize(operand(expr, 2)),
|
|
7576
|
-
"\\right\\rbrace"
|
|
7577
|
-
]);
|
|
7578
|
-
}
|
|
7579
|
-
return joinLatex([
|
|
7580
|
-
"\\left\\lbrace",
|
|
7581
|
-
...operands(expr).map((x) => serializer.serialize(x) + " ,"),
|
|
7582
|
-
"\\right\\rbrace"
|
|
7583
|
-
]);
|
|
7584
|
-
}
|
|
7585
7594
|
if (h === "Multiple") {
|
|
7586
7595
|
}
|
|
7587
7596
|
if (h === "Range") {
|
|
@@ -8699,11 +8708,13 @@ var DEFINITIONS_ARITHMETIC = [
|
|
|
8699
8708
|
if (!parser.match("_")) return null;
|
|
8700
8709
|
const base = parser.parseGroup();
|
|
8701
8710
|
if (operator(base) !== "To") return null;
|
|
8702
|
-
const expr = parser.
|
|
8711
|
+
const expr = parser.parseExpression({
|
|
8712
|
+
minPrec: MULTIPLICATION_PRECEDENCE
|
|
8713
|
+
});
|
|
8703
8714
|
if (!expr) return null;
|
|
8704
8715
|
return [
|
|
8705
8716
|
"Limit",
|
|
8706
|
-
["Function", expr
|
|
8717
|
+
["Function", expr, operand(base, 1)],
|
|
8707
8718
|
operand(base, 2)
|
|
8708
8719
|
];
|
|
8709
8720
|
},
|
|
@@ -8784,6 +8795,8 @@ var DEFINITIONS_ARITHMETIC = [
|
|
|
8784
8795
|
precedence: DIVISION_PRECEDENCE,
|
|
8785
8796
|
parse: "Mod"
|
|
8786
8797
|
},
|
|
8798
|
+
// Function-style alias: `\operatorname{mod}(a, b)`
|
|
8799
|
+
{ latexTrigger: "\\operatorname{mod}", parse: "Mod" },
|
|
8787
8800
|
{
|
|
8788
8801
|
latexTrigger: "\\pmod",
|
|
8789
8802
|
kind: "prefix",
|
|
@@ -9024,6 +9037,13 @@ var DEFINITIONS_ARITHMETIC = [
|
|
|
9024
9037
|
const rhs = serializer.wrap(operand(expr, 2), ADDITION_PRECEDENCE + 3);
|
|
9025
9038
|
return joinLatex([lhs, "-", rhs]);
|
|
9026
9039
|
}
|
|
9040
|
+
},
|
|
9041
|
+
// Euclidean distance between two points (tuples of numbers).
|
|
9042
|
+
{
|
|
9043
|
+
name: "Distance",
|
|
9044
|
+
latexTrigger: ["\\operatorname{distance}"],
|
|
9045
|
+
kind: "function",
|
|
9046
|
+
serialize: (serializer, expr) => "\\operatorname{distance}" + serializer.wrapArguments(expr)
|
|
9027
9047
|
}
|
|
9028
9048
|
];
|
|
9029
9049
|
function getIndexAssignment(expr, upper) {
|
|
@@ -10448,7 +10468,9 @@ var DEFINITIONS_STATISTICS = [
|
|
|
10448
10468
|
if (!expr || !symbol(expr)) return null;
|
|
10449
10469
|
return ["Mean", expr];
|
|
10450
10470
|
}
|
|
10451
|
-
}
|
|
10471
|
+
},
|
|
10472
|
+
// Function-style alias: `\operatorname{var}(...)`
|
|
10473
|
+
{ latexTrigger: "\\operatorname{var}", parse: "Variance" }
|
|
10452
10474
|
];
|
|
10453
10475
|
|
|
10454
10476
|
// src/compute-engine/numerics/unit-data.ts
|
|
@@ -10907,12 +10929,52 @@ var DEFINITIONS_UNITS = [
|
|
|
10907
10929
|
];
|
|
10908
10930
|
|
|
10909
10931
|
// src/compute-engine/latex-syntax/dictionary/definitions-other.ts
|
|
10932
|
+
var TEX_UNITS = [
|
|
10933
|
+
"pt",
|
|
10934
|
+
"em",
|
|
10935
|
+
"mu",
|
|
10936
|
+
"ex",
|
|
10937
|
+
"mm",
|
|
10938
|
+
"cm",
|
|
10939
|
+
"in",
|
|
10940
|
+
"bp",
|
|
10941
|
+
"sp",
|
|
10942
|
+
"dd",
|
|
10943
|
+
"cc",
|
|
10944
|
+
"pc",
|
|
10945
|
+
"nc",
|
|
10946
|
+
"nd"
|
|
10947
|
+
];
|
|
10948
|
+
function skipTexDimension(parser) {
|
|
10949
|
+
parser.skipSpace();
|
|
10950
|
+
if (parser.peek === "-" || parser.peek === "+") parser.nextToken();
|
|
10951
|
+
while (/^[\d.]$/.test(parser.peek)) parser.nextToken();
|
|
10952
|
+
for (const unit of TEX_UNITS) {
|
|
10953
|
+
if (parser.matchAll([...unit])) return;
|
|
10954
|
+
}
|
|
10955
|
+
}
|
|
10910
10956
|
function parseSingleArg(cmd) {
|
|
10911
10957
|
return (parser) => {
|
|
10912
10958
|
const arg = parser.parseGroup();
|
|
10913
10959
|
return arg === null ? [cmd] : [cmd, arg];
|
|
10914
10960
|
};
|
|
10915
10961
|
}
|
|
10962
|
+
function parseMathStyleSwitch(mathStyle) {
|
|
10963
|
+
return (parser) => {
|
|
10964
|
+
const body = parser.parseExpression();
|
|
10965
|
+
if (body !== null && !isEmptySequence(body))
|
|
10966
|
+
return ["Annotated", body, { dict: { mathStyle } }];
|
|
10967
|
+
return "Nothing";
|
|
10968
|
+
};
|
|
10969
|
+
}
|
|
10970
|
+
function parseSizeSwitch(size) {
|
|
10971
|
+
return (parser) => {
|
|
10972
|
+
const body = parser.parseExpression();
|
|
10973
|
+
if (body !== null && !isEmptySequence(body))
|
|
10974
|
+
return ["Annotated", body, { dict: { size } }];
|
|
10975
|
+
return "Nothing";
|
|
10976
|
+
};
|
|
10977
|
+
}
|
|
10916
10978
|
var DEFINITIONS_OTHERS = [
|
|
10917
10979
|
{
|
|
10918
10980
|
name: "Overscript",
|
|
@@ -11152,80 +11214,71 @@ var DEFINITIONS_OTHERS = [
|
|
|
11152
11214
|
},
|
|
11153
11215
|
{
|
|
11154
11216
|
latexTrigger: ["\\displaystyle"],
|
|
11155
|
-
parse: (
|
|
11156
|
-
// @todo: parse as ['Annotated'...]
|
|
11217
|
+
parse: parseMathStyleSwitch("normal")
|
|
11157
11218
|
},
|
|
11158
11219
|
{
|
|
11159
11220
|
latexTrigger: ["\\textstyle"],
|
|
11160
|
-
parse: (
|
|
11161
|
-
// @todo: parse as ['Annotated'...]
|
|
11221
|
+
parse: parseMathStyleSwitch("compact")
|
|
11162
11222
|
},
|
|
11163
11223
|
{
|
|
11164
11224
|
latexTrigger: ["\\scriptstyle"],
|
|
11165
|
-
parse: (
|
|
11166
|
-
// @todo: parse as ['Annotated'...]
|
|
11225
|
+
parse: parseMathStyleSwitch("script")
|
|
11167
11226
|
},
|
|
11168
11227
|
{
|
|
11169
11228
|
latexTrigger: ["\\scriptscriptstyle"],
|
|
11170
|
-
parse: (
|
|
11171
|
-
// @todo: parse as ['Annotated'...]
|
|
11229
|
+
parse: parseMathStyleSwitch("scriptscript")
|
|
11172
11230
|
},
|
|
11173
11231
|
{
|
|
11174
11232
|
latexTrigger: ["\\color"],
|
|
11175
11233
|
parse: (parser) => {
|
|
11176
|
-
parser.
|
|
11234
|
+
const color = parser.parseStringGroup();
|
|
11235
|
+
if (color !== null) {
|
|
11236
|
+
const body = parser.parseExpression();
|
|
11237
|
+
if (body !== null && !isEmptySequence(body))
|
|
11238
|
+
return ["Annotated", body, { dict: { color } }];
|
|
11239
|
+
}
|
|
11177
11240
|
return "Nothing";
|
|
11178
11241
|
}
|
|
11179
11242
|
},
|
|
11180
11243
|
{
|
|
11181
11244
|
latexTrigger: ["\\tiny"],
|
|
11182
|
-
parse: ()
|
|
11183
|
-
// @todo: parse as ['Annotated'...]
|
|
11245
|
+
parse: parseSizeSwitch(1)
|
|
11184
11246
|
},
|
|
11185
11247
|
{
|
|
11186
11248
|
latexTrigger: ["\\scriptsize"],
|
|
11187
|
-
parse: ()
|
|
11188
|
-
// @todo: parse as ['Annotated'...]
|
|
11249
|
+
parse: parseSizeSwitch(2)
|
|
11189
11250
|
},
|
|
11190
11251
|
{
|
|
11191
11252
|
latexTrigger: ["\\footnotesize"],
|
|
11192
|
-
parse: ()
|
|
11193
|
-
// @todo: parse as ['Annotated'...]
|
|
11253
|
+
parse: parseSizeSwitch(3)
|
|
11194
11254
|
},
|
|
11195
11255
|
{
|
|
11196
11256
|
latexTrigger: ["\\small"],
|
|
11197
|
-
parse: ()
|
|
11198
|
-
// @todo: parse as ['Annotated'...]
|
|
11257
|
+
parse: parseSizeSwitch(4)
|
|
11199
11258
|
},
|
|
11200
11259
|
{
|
|
11201
11260
|
latexTrigger: ["\\normalsize"],
|
|
11202
|
-
parse: ()
|
|
11203
|
-
// @todo: parse as ['Annotated'...]
|
|
11261
|
+
parse: parseSizeSwitch(5)
|
|
11204
11262
|
},
|
|
11205
11263
|
{
|
|
11206
11264
|
latexTrigger: ["\\large"],
|
|
11207
|
-
parse: ()
|
|
11208
|
-
// @todo: parse as ['Annotated'...]
|
|
11265
|
+
parse: parseSizeSwitch(6)
|
|
11209
11266
|
},
|
|
11210
11267
|
{
|
|
11211
11268
|
latexTrigger: ["\\Large"],
|
|
11212
|
-
parse: ()
|
|
11213
|
-
// @todo: parse as ['Annotated'...]
|
|
11269
|
+
parse: parseSizeSwitch(7)
|
|
11214
11270
|
},
|
|
11215
11271
|
{
|
|
11216
11272
|
latexTrigger: ["\\LARGE"],
|
|
11217
|
-
parse: ()
|
|
11218
|
-
// @todo: parse as ['Annotated'...]
|
|
11273
|
+
parse: parseSizeSwitch(8)
|
|
11219
11274
|
},
|
|
11220
11275
|
{
|
|
11221
11276
|
latexTrigger: ["\\huge"],
|
|
11222
|
-
parse: ()
|
|
11223
|
-
// @todo: parse as ['Annotated'...]
|
|
11277
|
+
parse: parseSizeSwitch(9)
|
|
11224
11278
|
},
|
|
11225
11279
|
{
|
|
11226
11280
|
latexTrigger: ["\\Huge"],
|
|
11227
|
-
parse: ()
|
|
11228
|
-
// @todo: parse as ['Annotated'...]
|
|
11281
|
+
parse: parseSizeSwitch(10)
|
|
11229
11282
|
},
|
|
11230
11283
|
{
|
|
11231
11284
|
name: "Annotated",
|
|
@@ -11237,6 +11290,10 @@ var DEFINITIONS_OTHERS = [
|
|
|
11237
11290
|
result = joinLatex(["{\\displaystyle", result, "}"]);
|
|
11238
11291
|
else if (dict.dict.mathStyle === "compact")
|
|
11239
11292
|
result = joinLatex(["{\\textstyle", result, "}"]);
|
|
11293
|
+
else if (dict.dict.mathStyle === "script")
|
|
11294
|
+
result = joinLatex(["{\\scriptstyle", result, "}"]);
|
|
11295
|
+
else if (dict.dict.mathStyle === "scriptscript")
|
|
11296
|
+
result = joinLatex(["{\\scriptscriptstyle", result, "}"]);
|
|
11240
11297
|
const v = dict.dict.size;
|
|
11241
11298
|
if (v !== null && v >= 1 && v <= 10) {
|
|
11242
11299
|
result = joinLatex([
|
|
@@ -11324,6 +11381,28 @@ var DEFINITIONS_OTHERS = [
|
|
|
11324
11381
|
latexTrigger: ["\\enspace"],
|
|
11325
11382
|
parse: () => ["HorizontalSpacing", 9]
|
|
11326
11383
|
},
|
|
11384
|
+
{
|
|
11385
|
+
latexTrigger: ["\\hspace"],
|
|
11386
|
+
parse: (parser) => {
|
|
11387
|
+
if (parser.peek === "*") parser.nextToken();
|
|
11388
|
+
parser.parseStringGroup();
|
|
11389
|
+
return ["HorizontalSpacing", 0];
|
|
11390
|
+
}
|
|
11391
|
+
},
|
|
11392
|
+
{
|
|
11393
|
+
latexTrigger: ["\\hskip"],
|
|
11394
|
+
parse: (parser) => {
|
|
11395
|
+
skipTexDimension(parser);
|
|
11396
|
+
return ["HorizontalSpacing", 0];
|
|
11397
|
+
}
|
|
11398
|
+
},
|
|
11399
|
+
{
|
|
11400
|
+
latexTrigger: ["\\kern"],
|
|
11401
|
+
parse: (parser) => {
|
|
11402
|
+
skipTexDimension(parser);
|
|
11403
|
+
return ["HorizontalSpacing", 0];
|
|
11404
|
+
}
|
|
11405
|
+
},
|
|
11327
11406
|
{
|
|
11328
11407
|
latexTrigger: ["\\phantom"],
|
|
11329
11408
|
parse: (parser) => {
|
|
@@ -11374,7 +11453,17 @@ var DEFINITIONS_OTHERS = [
|
|
|
11374
11453
|
// `["HorizontalSpacing", expr, 'op'|'bin'|rel]` -> indicate a spacing around and expression, i.e. `\mathbin{x}`, etc...
|
|
11375
11454
|
serialize: (serializer, expr) => {
|
|
11376
11455
|
if (operand(expr, 2) !== null) {
|
|
11377
|
-
|
|
11456
|
+
const cls = stringValue(operand(expr, 2));
|
|
11457
|
+
const inner = serializer.serialize(operand(expr, 1));
|
|
11458
|
+
if (cls === "bin") return `\\mathbin{${inner}}`;
|
|
11459
|
+
if (cls === "op") return `\\mathop{${inner}}`;
|
|
11460
|
+
if (cls === "rel") return `\\mathrel{${inner}}`;
|
|
11461
|
+
if (cls === "ord") return `\\mathord{${inner}}`;
|
|
11462
|
+
if (cls === "open") return `\\mathopen{${inner}}`;
|
|
11463
|
+
if (cls === "close") return `\\mathclose{${inner}}`;
|
|
11464
|
+
if (cls === "punct") return `\\mathpunct{${inner}}`;
|
|
11465
|
+
if (cls === "inner") return `\\mathinner{${inner}}`;
|
|
11466
|
+
return inner;
|
|
11378
11467
|
}
|
|
11379
11468
|
const v = machineValue(operand(expr, 1));
|
|
11380
11469
|
if (v === null) return "";
|
|
@@ -11389,7 +11478,7 @@ var DEFINITIONS_OTHERS = [
|
|
|
11389
11478
|
36: "\\qquad"
|
|
11390
11479
|
}[v] ?? "";
|
|
11391
11480
|
}
|
|
11392
|
-
}
|
|
11481
|
+
},
|
|
11393
11482
|
// if (
|
|
11394
11483
|
// [
|
|
11395
11484
|
// '\\!',
|
|
@@ -11413,6 +11502,121 @@ var DEFINITIONS_OTHERS = [
|
|
|
11413
11502
|
// name: '',
|
|
11414
11503
|
// trigger: '\\check',
|
|
11415
11504
|
// },
|
|
11505
|
+
// ---------------------------------------------------------------------------
|
|
11506
|
+
// Function-style aliases for collection / random operators that some
|
|
11507
|
+
// notations write in lowercase (e.g. `\operatorname{shuffle}(L)`).
|
|
11508
|
+
// The capitalized library entries already exist; these are pure parse
|
|
11509
|
+
// aliases so the lowercase names don't land in `unsupported-operator`.
|
|
11510
|
+
// ---------------------------------------------------------------------------
|
|
11511
|
+
{ latexTrigger: "\\operatorname{random}", parse: "Random" },
|
|
11512
|
+
{ latexTrigger: "\\operatorname{shuffle}", parse: "Shuffle" },
|
|
11513
|
+
{ latexTrigger: "\\operatorname{repeat}", parse: "Repeat" },
|
|
11514
|
+
{ latexTrigger: "\\operatorname{join}", parse: "Join" },
|
|
11515
|
+
// ---------------------------------------------------------------------------
|
|
11516
|
+
// Geometric primitive heads. Registered as known typed heads so consumers
|
|
11517
|
+
// can branch on the operator name; CE itself doesn't render them. The
|
|
11518
|
+
// library entries (with no evaluator) live in `library/core.ts`.
|
|
11519
|
+
// ---------------------------------------------------------------------------
|
|
11520
|
+
{
|
|
11521
|
+
name: "Triangle",
|
|
11522
|
+
latexTrigger: ["\\operatorname{triangle}"],
|
|
11523
|
+
kind: "function",
|
|
11524
|
+
serialize: (serializer, expr) => "\\operatorname{triangle}" + serializer.wrapArguments(expr)
|
|
11525
|
+
},
|
|
11526
|
+
// Desmos's geometric `vector(p1, p2)` — a directed segment between two
|
|
11527
|
+
// points. Routed to a dedicated head (not the existing column-vector
|
|
11528
|
+
// `Vector`, which has a narrower `(number+) -> vector` signature).
|
|
11529
|
+
{
|
|
11530
|
+
name: "GeometricVector",
|
|
11531
|
+
latexTrigger: ["\\operatorname{vector}"],
|
|
11532
|
+
kind: "function",
|
|
11533
|
+
serialize: (serializer, expr) => "\\operatorname{vector}" + serializer.wrapArguments(expr)
|
|
11534
|
+
},
|
|
11535
|
+
{
|
|
11536
|
+
name: "Sphere",
|
|
11537
|
+
latexTrigger: ["\\operatorname{sphere}"],
|
|
11538
|
+
kind: "function",
|
|
11539
|
+
serialize: (serializer, expr) => "\\operatorname{sphere}" + serializer.wrapArguments(expr)
|
|
11540
|
+
},
|
|
11541
|
+
{
|
|
11542
|
+
name: "Segment",
|
|
11543
|
+
latexTrigger: ["\\operatorname{segment}"],
|
|
11544
|
+
kind: "function",
|
|
11545
|
+
serialize: (serializer, expr) => "\\operatorname{segment}" + serializer.wrapArguments(expr)
|
|
11546
|
+
}
|
|
11547
|
+
];
|
|
11548
|
+
|
|
11549
|
+
// src/compute-engine/latex-syntax/dictionary/definitions-colors.ts
|
|
11550
|
+
var DEFINITIONS_COLORS = [
|
|
11551
|
+
// Color constructors (one per colorspace, preserves space on evaluation)
|
|
11552
|
+
{
|
|
11553
|
+
name: "Rgb",
|
|
11554
|
+
latexTrigger: ["\\operatorname{rgb}"],
|
|
11555
|
+
kind: "function",
|
|
11556
|
+
serialize: (serializer, expr) => "\\operatorname{rgb}" + serializer.wrapArguments(expr)
|
|
11557
|
+
},
|
|
11558
|
+
{
|
|
11559
|
+
name: "Hsv",
|
|
11560
|
+
latexTrigger: ["\\operatorname{hsv}"],
|
|
11561
|
+
kind: "function",
|
|
11562
|
+
serialize: (serializer, expr) => "\\operatorname{hsv}" + serializer.wrapArguments(expr)
|
|
11563
|
+
},
|
|
11564
|
+
{
|
|
11565
|
+
name: "Hsl",
|
|
11566
|
+
latexTrigger: ["\\operatorname{hsl}"],
|
|
11567
|
+
kind: "function",
|
|
11568
|
+
serialize: (serializer, expr) => "\\operatorname{hsl}" + serializer.wrapArguments(expr)
|
|
11569
|
+
},
|
|
11570
|
+
{
|
|
11571
|
+
name: "Oklab",
|
|
11572
|
+
latexTrigger: ["\\operatorname{oklab}"],
|
|
11573
|
+
kind: "function",
|
|
11574
|
+
serialize: (serializer, expr) => "\\operatorname{oklab}" + serializer.wrapArguments(expr)
|
|
11575
|
+
},
|
|
11576
|
+
{
|
|
11577
|
+
name: "Oklch",
|
|
11578
|
+
latexTrigger: ["\\operatorname{oklch}"],
|
|
11579
|
+
kind: "function",
|
|
11580
|
+
serialize: (serializer, expr) => "\\operatorname{oklch}" + serializer.wrapArguments(expr)
|
|
11581
|
+
},
|
|
11582
|
+
// Conversion functions (color → color in the named space)
|
|
11583
|
+
{
|
|
11584
|
+
name: "AsRgb",
|
|
11585
|
+
latexTrigger: ["\\operatorname{asRgb}"],
|
|
11586
|
+
kind: "function",
|
|
11587
|
+
serialize: (serializer, expr) => "\\operatorname{asRgb}" + serializer.wrapArguments(expr)
|
|
11588
|
+
},
|
|
11589
|
+
{
|
|
11590
|
+
name: "AsHsv",
|
|
11591
|
+
latexTrigger: ["\\operatorname{asHsv}"],
|
|
11592
|
+
kind: "function",
|
|
11593
|
+
serialize: (serializer, expr) => "\\operatorname{asHsv}" + serializer.wrapArguments(expr)
|
|
11594
|
+
},
|
|
11595
|
+
{
|
|
11596
|
+
name: "AsHsl",
|
|
11597
|
+
latexTrigger: ["\\operatorname{asHsl}"],
|
|
11598
|
+
kind: "function",
|
|
11599
|
+
serialize: (serializer, expr) => "\\operatorname{asHsl}" + serializer.wrapArguments(expr)
|
|
11600
|
+
},
|
|
11601
|
+
{
|
|
11602
|
+
name: "AsOklab",
|
|
11603
|
+
latexTrigger: ["\\operatorname{asOklab}"],
|
|
11604
|
+
kind: "function",
|
|
11605
|
+
serialize: (serializer, expr) => "\\operatorname{asOklab}" + serializer.wrapArguments(expr)
|
|
11606
|
+
},
|
|
11607
|
+
{
|
|
11608
|
+
name: "AsOklch",
|
|
11609
|
+
latexTrigger: ["\\operatorname{asOklch}"],
|
|
11610
|
+
kind: "function",
|
|
11611
|
+
serialize: (serializer, expr) => "\\operatorname{asOklch}" + serializer.wrapArguments(expr)
|
|
11612
|
+
},
|
|
11613
|
+
// Perceptual difference (returns a scalar in [0, ~1])
|
|
11614
|
+
{
|
|
11615
|
+
name: "ColorDelta",
|
|
11616
|
+
latexTrigger: ["\\operatorname{colorDelta}"],
|
|
11617
|
+
kind: "function",
|
|
11618
|
+
serialize: (serializer, expr) => "\\operatorname{colorDelta}" + serializer.wrapArguments(expr)
|
|
11619
|
+
}
|
|
11416
11620
|
];
|
|
11417
11621
|
|
|
11418
11622
|
// src/compute-engine/latex-syntax/dictionary/default-dictionary.ts
|
|
@@ -11443,7 +11647,8 @@ var LATEX_DICTIONARY = [
|
|
|
11443
11647
|
...DEFINITIONS_STATISTICS,
|
|
11444
11648
|
...DEFINITIONS_UNITS,
|
|
11445
11649
|
...DEFINITIONS_OTHERS,
|
|
11446
|
-
...DEFINITIONS_PHYSICS
|
|
11650
|
+
...DEFINITIONS_PHYSICS,
|
|
11651
|
+
...DEFINITIONS_COLORS
|
|
11447
11652
|
];
|
|
11448
11653
|
|
|
11449
11654
|
// src/math-json/symbols.ts
|
|
@@ -15066,8 +15271,7 @@ function compile(expr, options) {
|
|
|
15066
15271
|
vars: options?.vars,
|
|
15067
15272
|
imports: options?.imports,
|
|
15068
15273
|
preamble: options?.preamble,
|
|
15069
|
-
realOnly: options?.realOnly
|
|
15070
|
-
hints: options?.hints
|
|
15274
|
+
realOnly: options?.realOnly
|
|
15071
15275
|
});
|
|
15072
15276
|
} catch (e) {
|
|
15073
15277
|
if (options?.fallback ?? true) {
|
|
@@ -15079,8 +15283,7 @@ function compile(expr, options) {
|
|
|
15079
15283
|
ce.pushScope();
|
|
15080
15284
|
try {
|
|
15081
15285
|
if (vars && typeof vars === "object") {
|
|
15082
|
-
for (const [k, v] of Object.entries(vars))
|
|
15083
|
-
ce.assign(k, v);
|
|
15286
|
+
for (const [k, v] of Object.entries(vars)) ce.assign(k, v);
|
|
15084
15287
|
}
|
|
15085
15288
|
return expr.evaluate().re;
|
|
15086
15289
|
} finally {
|
|
@@ -15167,8 +15370,7 @@ function tryGetComplexParts(expr, compile2) {
|
|
|
15167
15370
|
return { re: null, im: formatFloat(iScale) };
|
|
15168
15371
|
}
|
|
15169
15372
|
const compiledFactors = remaining.map((r) => compile2(r));
|
|
15170
|
-
if (iScale !== 1)
|
|
15171
|
-
compiledFactors.unshift(formatFloat(iScale));
|
|
15373
|
+
if (iScale !== 1) compiledFactors.unshift(formatFloat(iScale));
|
|
15172
15374
|
const imCode = foldTerms(compiledFactors, "1.0", "*");
|
|
15173
15375
|
return { re: null, im: imCode };
|
|
15174
15376
|
}
|
|
@@ -15233,6 +15435,40 @@ function rgbToHsl(r, g, b) {
|
|
|
15233
15435
|
else h = ((r - g) / d + 4) / 6;
|
|
15234
15436
|
return { h: h * 360, s, l };
|
|
15235
15437
|
}
|
|
15438
|
+
function hsvToRgb(h, s, v) {
|
|
15439
|
+
h = (h % 360 + 360) % 360;
|
|
15440
|
+
s = Math.max(0, Math.min(1, s));
|
|
15441
|
+
v = Math.max(0, Math.min(1, v));
|
|
15442
|
+
const c = v * s;
|
|
15443
|
+
const x = c * (1 - Math.abs(h / 60 % 2 - 1));
|
|
15444
|
+
const m = v - c;
|
|
15445
|
+
let r = 0, g = 0, b = 0;
|
|
15446
|
+
if (h < 60) [r, g, b] = [c, x, 0];
|
|
15447
|
+
else if (h < 120) [r, g, b] = [x, c, 0];
|
|
15448
|
+
else if (h < 180) [r, g, b] = [0, c, x];
|
|
15449
|
+
else if (h < 240) [r, g, b] = [0, x, c];
|
|
15450
|
+
else if (h < 300) [r, g, b] = [x, 0, c];
|
|
15451
|
+
else [r, g, b] = [c, 0, x];
|
|
15452
|
+
return { r: (r + m) * 255, g: (g + m) * 255, b: (b + m) * 255 };
|
|
15453
|
+
}
|
|
15454
|
+
function rgbToHsv(r, g, b) {
|
|
15455
|
+
r /= 255;
|
|
15456
|
+
g /= 255;
|
|
15457
|
+
b /= 255;
|
|
15458
|
+
const max2 = Math.max(r, g, b);
|
|
15459
|
+
const min2 = Math.min(r, g, b);
|
|
15460
|
+
const d = max2 - min2;
|
|
15461
|
+
let h = 0;
|
|
15462
|
+
if (d > 0) {
|
|
15463
|
+
if (max2 === r) h = (g - b) / d % 6;
|
|
15464
|
+
else if (max2 === g) h = (b - r) / d + 2;
|
|
15465
|
+
else h = (r - g) / d + 4;
|
|
15466
|
+
h *= 60;
|
|
15467
|
+
if (h < 0) h += 360;
|
|
15468
|
+
}
|
|
15469
|
+
const s = max2 === 0 ? 0 : d / max2;
|
|
15470
|
+
return { h, s, v: max2 };
|
|
15471
|
+
}
|
|
15236
15472
|
function parseHexColor(s) {
|
|
15237
15473
|
const hex = s.startsWith("#") ? s.substring(1) : s;
|
|
15238
15474
|
let r, g, b;
|
|
@@ -15688,6 +15924,13 @@ var NAMED_COLORS = {
|
|
|
15688
15924
|
};
|
|
15689
15925
|
function parseColor(s, darkMode) {
|
|
15690
15926
|
const str = s.trim().toLowerCase();
|
|
15927
|
+
const opacityMatch = str.match(/^(.+?)\s*\/\s*(\d+(?:\.\d+)?)%?\s*$/);
|
|
15928
|
+
if (opacityMatch) {
|
|
15929
|
+
const base = parseColor(opacityMatch[1].trim(), darkMode);
|
|
15930
|
+
const opacity = Math.max(0, Math.min(100, parseFloat(opacityMatch[2])));
|
|
15931
|
+
const alpha = Math.round(opacity / 100 * 255);
|
|
15932
|
+
return base & 4294967040 | alpha;
|
|
15933
|
+
}
|
|
15691
15934
|
if (str.startsWith("#")) {
|
|
15692
15935
|
const hex = str.substring(1);
|
|
15693
15936
|
let r, g, b, a = 255;
|
|
@@ -15820,14 +16063,6 @@ function parseColor(s, darkMode) {
|
|
|
15820
16063
|
console.warn(`parseColor: unrecognized color "${s}"`);
|
|
15821
16064
|
return 0;
|
|
15822
16065
|
}
|
|
15823
|
-
function parseColorToRgb01(s, darkMode) {
|
|
15824
|
-
const color = parseColor(s, darkMode);
|
|
15825
|
-
return [
|
|
15826
|
-
(color >>> 24 & 255) / 255,
|
|
15827
|
-
(color >>> 16 & 255) / 255,
|
|
15828
|
-
(color >>> 8 & 255) / 255
|
|
15829
|
-
];
|
|
15830
|
-
}
|
|
15831
16066
|
function apca(bgColor, fgColor) {
|
|
15832
16067
|
const bgRgb = asRgb(bgColor);
|
|
15833
16068
|
const fgRgb = asRgb(fgColor);
|
|
@@ -15886,6 +16121,12 @@ function contrastingColor(arg) {
|
|
|
15886
16121
|
const contrast2 = Math.abs(apca(fg2, bg));
|
|
15887
16122
|
return contrast1 >= contrast2 ? asColorNumber(fg1) : asColorNumber(fg2);
|
|
15888
16123
|
}
|
|
16124
|
+
function oklabDeltaE(a, b) {
|
|
16125
|
+
const dL = a.L - b.L;
|
|
16126
|
+
const da = a.a - b.a;
|
|
16127
|
+
const db = a.b - b.b;
|
|
16128
|
+
return Math.sqrt(dL * dL + da * da + db * db);
|
|
16129
|
+
}
|
|
15889
16130
|
var TYCHO_11 = [
|
|
15890
16131
|
"#4e79a7",
|
|
15891
16132
|
// Blue
|
|
@@ -20097,39 +20338,130 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
20097
20338
|
if (args.length >= 2)
|
|
20098
20339
|
return `_SYS.colormap(${compile2(args[0])}, ${compile2(args[1])})`;
|
|
20099
20340
|
return `_SYS.colormap(${compile2(args[0])})`;
|
|
20341
|
+
},
|
|
20342
|
+
// -----------------------------------------------------------------------
|
|
20343
|
+
// Color constructor heads. All compile to OKLCh arrays at runtime — the
|
|
20344
|
+
// canonical color representation in this target. The constructors take
|
|
20345
|
+
// their own colorspace's components and convert internally.
|
|
20346
|
+
// (Mirrors the GPU target's design: color values are vec3 OKLCh.)
|
|
20347
|
+
// -----------------------------------------------------------------------
|
|
20348
|
+
Rgb: (args, compile2) => {
|
|
20349
|
+
if (args.length < 3) throw new Error("Rgb: need 3 components");
|
|
20350
|
+
return `_SYS.rgb(${args.map(compile2).join(", ")})`;
|
|
20351
|
+
},
|
|
20352
|
+
Hsv: (args, compile2) => {
|
|
20353
|
+
if (args.length < 3) throw new Error("Hsv: need 3 components");
|
|
20354
|
+
return `_SYS.hsv(${args.map(compile2).join(", ")})`;
|
|
20355
|
+
},
|
|
20356
|
+
Hsl: (args, compile2) => {
|
|
20357
|
+
if (args.length < 3) throw new Error("Hsl: need 3 components");
|
|
20358
|
+
return `_SYS.hsl(${args.map(compile2).join(", ")})`;
|
|
20359
|
+
},
|
|
20360
|
+
Oklab: (args, compile2) => {
|
|
20361
|
+
if (args.length < 3) throw new Error("Oklab: need 3 components");
|
|
20362
|
+
return `_SYS.oklab(${args.map(compile2).join(", ")})`;
|
|
20363
|
+
},
|
|
20364
|
+
Oklch: (args, compile2) => {
|
|
20365
|
+
if (args.length < 3) throw new Error("Oklch: need 3 components");
|
|
20366
|
+
return `_SYS.oklch(${args.map(compile2).join(", ")})`;
|
|
20367
|
+
},
|
|
20368
|
+
// -----------------------------------------------------------------------
|
|
20369
|
+
// As* converters. Compile-time output convention matches the engine and
|
|
20370
|
+
// the GPU target: each returns components in the named space as a 3- or
|
|
20371
|
+
// 4-element array. `AsRgb` uses 0-1 sRGB channels (consistent across all
|
|
20372
|
+
// layers). `AsOklch` is the identity (canonical form).
|
|
20373
|
+
// -----------------------------------------------------------------------
|
|
20374
|
+
AsRgb: ([c], compile2) => {
|
|
20375
|
+
if (c === null) throw new Error("AsRgb: no argument");
|
|
20376
|
+
return `_SYS.asRgb(${compile2(c)})`;
|
|
20377
|
+
},
|
|
20378
|
+
AsHsv: ([c], compile2) => {
|
|
20379
|
+
if (c === null) throw new Error("AsHsv: no argument");
|
|
20380
|
+
return `_SYS.asHsv(${compile2(c)})`;
|
|
20381
|
+
},
|
|
20382
|
+
AsHsl: ([c], compile2) => {
|
|
20383
|
+
if (c === null) throw new Error("AsHsl: no argument");
|
|
20384
|
+
return `_SYS.asHsl(${compile2(c)})`;
|
|
20385
|
+
},
|
|
20386
|
+
AsOklab: ([c], compile2) => {
|
|
20387
|
+
if (c === null) throw new Error("AsOklab: no argument");
|
|
20388
|
+
return `_SYS.asOklab(${compile2(c)})`;
|
|
20389
|
+
},
|
|
20390
|
+
AsOklch: ([c], compile2) => {
|
|
20391
|
+
if (c === null) throw new Error("AsOklch: no argument");
|
|
20392
|
+
return compile2(c);
|
|
20393
|
+
},
|
|
20394
|
+
// Perceptual color difference (ΔE_OK).
|
|
20395
|
+
ColorDelta: ([a, b], compile2) => {
|
|
20396
|
+
if (a === null || b === null)
|
|
20397
|
+
throw new Error("ColorDelta: need two colors");
|
|
20398
|
+
return `_SYS.colorDelta(${compile2(a)}, ${compile2(b)})`;
|
|
20399
|
+
},
|
|
20400
|
+
// Euclidean distance between two tuples (any positive dimension).
|
|
20401
|
+
// The GPU target maps `Distance` to the GLSL/WGSL `distance()` builtin
|
|
20402
|
+
// (vec-only); this JS handler works on plain arrays of any length.
|
|
20403
|
+
Distance: ([a, b], compile2) => {
|
|
20404
|
+
if (a === null || b === null) throw new Error("Distance: need two points");
|
|
20405
|
+
return `_SYS.distance(${compile2(a)}, ${compile2(b)})`;
|
|
20100
20406
|
}
|
|
20101
20407
|
};
|
|
20102
20408
|
function toRI(c) {
|
|
20103
20409
|
return { re: c.re, im: c.im };
|
|
20104
20410
|
}
|
|
20411
|
+
function normalizeAlpha(a) {
|
|
20412
|
+
if (a === void 0) return void 0;
|
|
20413
|
+
if (!Number.isFinite(a)) return void 0;
|
|
20414
|
+
if (Math.abs(a - 1) < 1e-9) return void 0;
|
|
20415
|
+
return a;
|
|
20416
|
+
}
|
|
20105
20417
|
function toRgb255(input) {
|
|
20106
20418
|
if (typeof input === "string") {
|
|
20107
20419
|
const c = parseColor(input);
|
|
20108
|
-
|
|
20420
|
+
const rgb2 = {
|
|
20109
20421
|
r: c >>> 24 & 255,
|
|
20110
20422
|
g: c >>> 16 & 255,
|
|
20111
|
-
b: c >>> 8 & 255
|
|
20112
|
-
alpha: (c & 255) / 255
|
|
20423
|
+
b: c >>> 8 & 255
|
|
20113
20424
|
};
|
|
20425
|
+
const alpha = normalizeAlpha((c & 255) / 255);
|
|
20426
|
+
if (alpha !== void 0) rgb2.alpha = alpha;
|
|
20427
|
+
return rgb2;
|
|
20428
|
+
}
|
|
20429
|
+
const rgb = oklchToRgb({ L: input[0], C: input[1], H: input[2] });
|
|
20430
|
+
if (input.length >= 4) {
|
|
20431
|
+
const alpha = normalizeAlpha(input[3]);
|
|
20432
|
+
if (alpha !== void 0) rgb.alpha = alpha;
|
|
20114
20433
|
}
|
|
20115
|
-
const rgb = {
|
|
20116
|
-
r: input[0] * 255,
|
|
20117
|
-
g: input[1] * 255,
|
|
20118
|
-
b: input[2] * 255
|
|
20119
|
-
};
|
|
20120
|
-
if (input.length >= 4) rgb.alpha = input[3];
|
|
20121
20434
|
return rgb;
|
|
20122
20435
|
}
|
|
20123
|
-
function
|
|
20124
|
-
|
|
20125
|
-
|
|
20126
|
-
|
|
20127
|
-
|
|
20128
|
-
|
|
20436
|
+
function toOklch(input) {
|
|
20437
|
+
if (typeof input === "string") {
|
|
20438
|
+
const c = parseColor(input);
|
|
20439
|
+
const r = c >>> 24 & 255;
|
|
20440
|
+
const g = c >>> 16 & 255;
|
|
20441
|
+
const b = c >>> 8 & 255;
|
|
20442
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
20443
|
+
const alpha = normalizeAlpha((c & 255) / 255);
|
|
20444
|
+
if (alpha !== void 0) oklch2.alpha = alpha;
|
|
20445
|
+
return oklch2;
|
|
20446
|
+
}
|
|
20447
|
+
return {
|
|
20448
|
+
L: input[0],
|
|
20449
|
+
C: input[1],
|
|
20450
|
+
H: input[2],
|
|
20451
|
+
alpha: input.length >= 4 ? normalizeAlpha(input[3]) : void 0
|
|
20452
|
+
};
|
|
20453
|
+
}
|
|
20454
|
+
function packedToOklch(c) {
|
|
20455
|
+
const r = c >>> 24 & 255;
|
|
20456
|
+
const g = c >>> 16 & 255;
|
|
20457
|
+
const b = c >>> 8 & 255;
|
|
20458
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
20459
|
+
const alpha = normalizeAlpha((c & 255) / 255);
|
|
20460
|
+
return alpha !== void 0 ? [oklch2.L, oklch2.C, oklch2.H, alpha] : [oklch2.L, oklch2.C, oklch2.H];
|
|
20129
20461
|
}
|
|
20130
20462
|
var colorHelpers = {
|
|
20131
20463
|
color(input) {
|
|
20132
|
-
return
|
|
20464
|
+
return packedToOklch(parseColor(input));
|
|
20133
20465
|
},
|
|
20134
20466
|
colorToString(input, format) {
|
|
20135
20467
|
const rgb = toRgb255(input);
|
|
@@ -20140,7 +20472,7 @@ var colorHelpers = {
|
|
|
20140
20472
|
const g = Math.round(Math.max(0, Math.min(255, rgb.g)));
|
|
20141
20473
|
const b = Math.round(Math.max(0, Math.min(255, rgb.b)));
|
|
20142
20474
|
let hex = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
20143
|
-
if (rgb.alpha !== void 0
|
|
20475
|
+
if (rgb.alpha !== void 0) {
|
|
20144
20476
|
const a = Math.round(Math.max(0, Math.min(255, rgb.alpha * 255)));
|
|
20145
20477
|
hex += a.toString(16).padStart(2, "0");
|
|
20146
20478
|
}
|
|
@@ -20150,7 +20482,7 @@ var colorHelpers = {
|
|
|
20150
20482
|
const r = Math.round(rgb.r);
|
|
20151
20483
|
const g = Math.round(rgb.g);
|
|
20152
20484
|
const b = Math.round(rgb.b);
|
|
20153
|
-
if (rgb.alpha !== void 0
|
|
20485
|
+
if (rgb.alpha !== void 0)
|
|
20154
20486
|
return `rgb(${r} ${g} ${b} / ${rgb.alpha})`;
|
|
20155
20487
|
return `rgb(${r} ${g} ${b})`;
|
|
20156
20488
|
}
|
|
@@ -20159,7 +20491,7 @@ var colorHelpers = {
|
|
|
20159
20491
|
const h = Math.round(hsl.h * 10) / 10;
|
|
20160
20492
|
const s = Math.round(hsl.s * 1e3) / 10;
|
|
20161
20493
|
const l = Math.round(hsl.l * 1e3) / 10;
|
|
20162
|
-
if (rgb.alpha !== void 0
|
|
20494
|
+
if (rgb.alpha !== void 0)
|
|
20163
20495
|
return `hsl(${h} ${s}% ${l}% / ${rgb.alpha})`;
|
|
20164
20496
|
return `hsl(${h} ${s}% ${l}%)`;
|
|
20165
20497
|
}
|
|
@@ -20168,7 +20500,7 @@ var colorHelpers = {
|
|
|
20168
20500
|
const L = Math.round(c.L * 1e3) / 1e3;
|
|
20169
20501
|
const C = Math.round(c.C * 1e3) / 1e3;
|
|
20170
20502
|
const H = Math.round(c.H * 10) / 10;
|
|
20171
|
-
if (rgb.alpha !== void 0
|
|
20503
|
+
if (rgb.alpha !== void 0)
|
|
20172
20504
|
return `oklch(${L} ${C} ${H} / ${rgb.alpha})`;
|
|
20173
20505
|
return `oklch(${L} ${C} ${H})`;
|
|
20174
20506
|
}
|
|
@@ -20177,29 +20509,29 @@ var colorHelpers = {
|
|
|
20177
20509
|
}
|
|
20178
20510
|
},
|
|
20179
20511
|
colorMix(input1, input2, ratio = 0.5) {
|
|
20180
|
-
const
|
|
20181
|
-
const
|
|
20512
|
+
const c1 = toOklch(input1);
|
|
20513
|
+
const c2 = toOklch(input2);
|
|
20182
20514
|
ratio = Math.max(0, Math.min(1, ratio));
|
|
20183
|
-
const
|
|
20184
|
-
const
|
|
20185
|
-
let
|
|
20186
|
-
if (
|
|
20187
|
-
if (
|
|
20188
|
-
|
|
20189
|
-
|
|
20190
|
-
|
|
20191
|
-
|
|
20192
|
-
|
|
20193
|
-
|
|
20194
|
-
H
|
|
20195
|
-
|
|
20196
|
-
|
|
20197
|
-
const
|
|
20198
|
-
const
|
|
20199
|
-
const a1 =
|
|
20200
|
-
const a2 =
|
|
20201
|
-
const alpha = a1 + (a2 - a1) * ratio;
|
|
20202
|
-
return
|
|
20515
|
+
const c1Achromatic = c1.C < 1e-6;
|
|
20516
|
+
const c2Achromatic = c2.C < 1e-6;
|
|
20517
|
+
let H;
|
|
20518
|
+
if (c1Achromatic && c2Achromatic) H = c1.H;
|
|
20519
|
+
else if (c1Achromatic) H = c2.H;
|
|
20520
|
+
else if (c2Achromatic) H = c1.H;
|
|
20521
|
+
else {
|
|
20522
|
+
let dh = c2.H - c1.H;
|
|
20523
|
+
if (dh > 180) dh -= 360;
|
|
20524
|
+
if (dh < -180) dh += 360;
|
|
20525
|
+
H = c1.H + dh * ratio;
|
|
20526
|
+
if (H < 0) H += 360;
|
|
20527
|
+
if (H >= 360) H -= 360;
|
|
20528
|
+
}
|
|
20529
|
+
const L = c1.L + (c2.L - c1.L) * ratio;
|
|
20530
|
+
const C = c1.C + (c2.C - c1.C) * ratio;
|
|
20531
|
+
const a1 = c1.alpha ?? 1;
|
|
20532
|
+
const a2 = c2.alpha ?? 1;
|
|
20533
|
+
const alpha = normalizeAlpha(a1 + (a2 - a1) * ratio);
|
|
20534
|
+
return alpha !== void 0 ? [L, C, H, alpha] : [L, C, H];
|
|
20203
20535
|
},
|
|
20204
20536
|
colorContrast(bg, fg) {
|
|
20205
20537
|
return apca(toRgb255(bg), toRgb255(fg));
|
|
@@ -20207,11 +20539,11 @@ var colorHelpers = {
|
|
|
20207
20539
|
contrastingColor(bg, fg1, fg2) {
|
|
20208
20540
|
const bgRgb = toRgb255(bg);
|
|
20209
20541
|
if (fg1 !== void 0 && fg2 !== void 0) {
|
|
20210
|
-
return
|
|
20542
|
+
return packedToOklch(
|
|
20211
20543
|
contrastingColor({ bg: bgRgb, fg1: toRgb255(fg1), fg2: toRgb255(fg2) })
|
|
20212
20544
|
);
|
|
20213
20545
|
}
|
|
20214
|
-
return
|
|
20546
|
+
return packedToOklch(contrastingColor(bgRgb));
|
|
20215
20547
|
},
|
|
20216
20548
|
colorToColorspace(input, space) {
|
|
20217
20549
|
const rgb = toRgb255(input);
|
|
@@ -20240,7 +20572,7 @@ var colorHelpers = {
|
|
|
20240
20572
|
default:
|
|
20241
20573
|
throw new Error(`Unknown color space: ${space}`);
|
|
20242
20574
|
}
|
|
20243
|
-
if (alpha !== void 0
|
|
20575
|
+
if (alpha !== void 0) result.push(alpha);
|
|
20244
20576
|
return result;
|
|
20245
20577
|
},
|
|
20246
20578
|
colormap(name, arg) {
|
|
@@ -20252,7 +20584,7 @@ var colorHelpers = {
|
|
|
20252
20584
|
const palette = allPalettes[name];
|
|
20253
20585
|
if (!palette) throw new Error(`Unknown palette: ${name}`);
|
|
20254
20586
|
const colors = palette.map(
|
|
20255
|
-
(hex) =>
|
|
20587
|
+
(hex) => packedToOklch(parseColor(hex))
|
|
20256
20588
|
);
|
|
20257
20589
|
if (arg === void 0) return colors;
|
|
20258
20590
|
if (Number.isInteger(arg) && arg >= 2) {
|
|
@@ -20276,62 +20608,128 @@ var colorHelpers = {
|
|
|
20276
20608
|
const frac = pos - i;
|
|
20277
20609
|
if (frac === 0 || i >= colors.length - 1)
|
|
20278
20610
|
return [...colors[Math.min(i, colors.length - 1)]];
|
|
20279
|
-
const
|
|
20280
|
-
|
|
20281
|
-
|
|
20282
|
-
|
|
20283
|
-
|
|
20284
|
-
|
|
20285
|
-
|
|
20286
|
-
|
|
20287
|
-
|
|
20288
|
-
|
|
20289
|
-
|
|
20290
|
-
|
|
20291
|
-
|
|
20292
|
-
|
|
20293
|
-
|
|
20294
|
-
|
|
20295
|
-
|
|
20296
|
-
if (H >= 360) H -= 360;
|
|
20297
|
-
const mixed = oklchToRgb({
|
|
20298
|
-
L: c1.L + (c2.L - c1.L) * frac,
|
|
20299
|
-
C: c1.C + (c2.C - c1.C) * frac,
|
|
20300
|
-
H
|
|
20301
|
-
});
|
|
20302
|
-
return [mixed.r / 255, mixed.g / 255, mixed.b / 255];
|
|
20611
|
+
const [L1, C1, H1] = colors[i];
|
|
20612
|
+
const [L2, C2, H2] = colors[i + 1];
|
|
20613
|
+
const c1Achromatic = C1 < 1e-6;
|
|
20614
|
+
const c2Achromatic = C2 < 1e-6;
|
|
20615
|
+
let H;
|
|
20616
|
+
if (c1Achromatic && c2Achromatic) H = H1;
|
|
20617
|
+
else if (c1Achromatic) H = H2;
|
|
20618
|
+
else if (c2Achromatic) H = H1;
|
|
20619
|
+
else {
|
|
20620
|
+
let dh = H2 - H1;
|
|
20621
|
+
if (dh > 180) dh -= 360;
|
|
20622
|
+
if (dh < -180) dh += 360;
|
|
20623
|
+
H = H1 + dh * frac;
|
|
20624
|
+
if (H < 0) H += 360;
|
|
20625
|
+
if (H >= 360) H -= 360;
|
|
20626
|
+
}
|
|
20627
|
+
return [L1 + (L2 - L1) * frac, C1 + (C2 - C1) * frac, H];
|
|
20303
20628
|
},
|
|
20304
20629
|
colorFromColorspace(components, space) {
|
|
20305
20630
|
const c0 = components[0];
|
|
20306
20631
|
const c1 = components[1];
|
|
20307
20632
|
const c2 = components[2];
|
|
20308
20633
|
const alpha = components.length >= 4 ? components[3] : void 0;
|
|
20309
|
-
let
|
|
20634
|
+
let oklch2;
|
|
20310
20635
|
switch (space.toLowerCase()) {
|
|
20311
20636
|
case "rgb":
|
|
20312
|
-
|
|
20637
|
+
oklch2 = rgbToOklch({ r: c0 * 255, g: c1 * 255, b: c2 * 255 });
|
|
20313
20638
|
break;
|
|
20314
20639
|
case "hsl": {
|
|
20315
|
-
const
|
|
20316
|
-
|
|
20640
|
+
const rgb = hslToRgb(c0, c1, c2);
|
|
20641
|
+
oklch2 = rgbToOklch(rgb);
|
|
20317
20642
|
break;
|
|
20318
20643
|
}
|
|
20319
|
-
case "oklch":
|
|
20320
|
-
|
|
20321
|
-
result = [r.r / 255, r.g / 255, r.b / 255];
|
|
20644
|
+
case "oklch":
|
|
20645
|
+
oklch2 = { L: c0, C: c1, H: c2 };
|
|
20322
20646
|
break;
|
|
20323
|
-
}
|
|
20324
20647
|
case "oklab":
|
|
20325
|
-
case "lab":
|
|
20326
|
-
|
|
20327
|
-
result = [r.r / 255, r.g / 255, r.b / 255];
|
|
20648
|
+
case "lab":
|
|
20649
|
+
oklch2 = oklabToOklch({ L: c0, a: c1, b: c2 });
|
|
20328
20650
|
break;
|
|
20329
|
-
}
|
|
20330
20651
|
default:
|
|
20331
20652
|
throw new Error(`Unknown color space: ${space}`);
|
|
20332
20653
|
}
|
|
20333
|
-
|
|
20334
|
-
|
|
20654
|
+
return alpha !== void 0 ? [oklch2.L, oklch2.C, oklch2.H, alpha] : [oklch2.L, oklch2.C, oklch2.H];
|
|
20655
|
+
},
|
|
20656
|
+
// -----------------------------------------------------------------------
|
|
20657
|
+
// Color constructors. Each accepts components in its colorspace's natural
|
|
20658
|
+
// units and returns the canonical OKLCh array `[L, C, H]` (or with alpha).
|
|
20659
|
+
// -----------------------------------------------------------------------
|
|
20660
|
+
rgb(r, g, b, alpha) {
|
|
20661
|
+
const c = rgbToOklch({ r: r * 255, g: g * 255, b: b * 255 });
|
|
20662
|
+
const a = normalizeAlpha(alpha);
|
|
20663
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
20664
|
+
},
|
|
20665
|
+
hsv(h, s, v, alpha) {
|
|
20666
|
+
const rgb = hsvToRgb(h, s, v);
|
|
20667
|
+
const c = rgbToOklch(rgb);
|
|
20668
|
+
const a = normalizeAlpha(alpha);
|
|
20669
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
20670
|
+
},
|
|
20671
|
+
hsl(h, s, l, alpha) {
|
|
20672
|
+
const rgb = hslToRgb(h, s, l);
|
|
20673
|
+
const c = rgbToOklch({ r: rgb.r, g: rgb.g, b: rgb.b });
|
|
20674
|
+
const a = normalizeAlpha(alpha);
|
|
20675
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
20676
|
+
},
|
|
20677
|
+
oklab(L, a, b, alpha) {
|
|
20678
|
+
const c = oklabToOklch({ L, a, b });
|
|
20679
|
+
const al = normalizeAlpha(alpha);
|
|
20680
|
+
return al !== void 0 ? [c.L, c.C, c.H, al] : [c.L, c.C, c.H];
|
|
20681
|
+
},
|
|
20682
|
+
oklch(L, C, H, alpha) {
|
|
20683
|
+
const a = normalizeAlpha(alpha);
|
|
20684
|
+
return a !== void 0 ? [L, C, H, a] : [L, C, H];
|
|
20685
|
+
},
|
|
20686
|
+
// -----------------------------------------------------------------------
|
|
20687
|
+
// As* converters. Inputs are anything `toOklch` accepts (string, packed
|
|
20688
|
+
// int, or OKLCh array). Outputs are 3- or 4-element arrays in the named
|
|
20689
|
+
// space. sRGB-based outputs (asRgb/asHsv/asHsl) use 0-1 channels for
|
|
20690
|
+
// consistency with the GPU target's shader convention.
|
|
20691
|
+
// -----------------------------------------------------------------------
|
|
20692
|
+
asRgb(input) {
|
|
20693
|
+
const rgb = toRgb255(input);
|
|
20694
|
+
const r = rgb.r / 255;
|
|
20695
|
+
const g = rgb.g / 255;
|
|
20696
|
+
const b = rgb.b / 255;
|
|
20697
|
+
return rgb.alpha !== void 0 ? [r, g, b, rgb.alpha] : [r, g, b];
|
|
20698
|
+
},
|
|
20699
|
+
asHsv(input) {
|
|
20700
|
+
const rgb = toRgb255(input);
|
|
20701
|
+
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
20702
|
+
return rgb.alpha !== void 0 ? [hsv.h, hsv.s, hsv.v, rgb.alpha] : [hsv.h, hsv.s, hsv.v];
|
|
20703
|
+
},
|
|
20704
|
+
asHsl(input) {
|
|
20705
|
+
const rgb = toRgb255(input);
|
|
20706
|
+
const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
|
|
20707
|
+
return rgb.alpha !== void 0 ? [hsl.h, hsl.s, hsl.l, rgb.alpha] : [hsl.h, hsl.s, hsl.l];
|
|
20708
|
+
},
|
|
20709
|
+
asOklab(input) {
|
|
20710
|
+
const c = toOklch(input);
|
|
20711
|
+
const lab = oklchToOklab({ L: c.L, C: c.C, H: c.H });
|
|
20712
|
+
return c.alpha !== void 0 ? [lab.L, lab.a, lab.b, c.alpha] : [lab.L, lab.a, lab.b];
|
|
20713
|
+
},
|
|
20714
|
+
// asOklch is identity — handled at compile time as a pass-through
|
|
20715
|
+
// Perceptual color difference (ΔE_OK).
|
|
20716
|
+
colorDelta(a, b) {
|
|
20717
|
+
const labA = oklchToOklab(toOklch(a));
|
|
20718
|
+
const labB = oklchToOklab(toOklch(b));
|
|
20719
|
+
return oklabDeltaE(labA, labB);
|
|
20720
|
+
},
|
|
20721
|
+
// Euclidean distance between two tuples. Plain numeric — not a color
|
|
20722
|
+
// operation despite living in the same helpers block.
|
|
20723
|
+
distance(a, b) {
|
|
20724
|
+
if (!Array.isArray(a) || !Array.isArray(b))
|
|
20725
|
+
throw new Error("Distance: expected two arrays");
|
|
20726
|
+
if (a.length !== b.length) throw new Error("Distance: dimension mismatch");
|
|
20727
|
+
let sumSq = 0;
|
|
20728
|
+
for (let i = 0; i < a.length; i++) {
|
|
20729
|
+
const d = a[i] - b[i];
|
|
20730
|
+
sumSq += d * d;
|
|
20731
|
+
}
|
|
20732
|
+
return Math.sqrt(sumSq);
|
|
20335
20733
|
}
|
|
20336
20734
|
};
|
|
20337
20735
|
var SYS_HELPERS = {
|
|
@@ -20749,43 +21147,6 @@ function fibonacci(n) {
|
|
|
20749
21147
|
return b;
|
|
20750
21148
|
}
|
|
20751
21149
|
|
|
20752
|
-
// src/compute-engine/compilation/fractal-orbit.ts
|
|
20753
|
-
function toBigDecimal(v) {
|
|
20754
|
-
if (typeof v === "object" && "hi" in v)
|
|
20755
|
-
return new BigDecimal(v.hi).add(new BigDecimal(v.lo));
|
|
20756
|
-
return new BigDecimal(v);
|
|
20757
|
-
}
|
|
20758
|
-
function hpToNumber(v) {
|
|
20759
|
-
if (typeof v === "number") return v;
|
|
20760
|
-
if (typeof v === "string") return Number(v);
|
|
20761
|
-
return v.hi + v.lo;
|
|
20762
|
-
}
|
|
20763
|
-
function computeReferenceOrbit(center, maxIter, precision) {
|
|
20764
|
-
const prevPrecision = BigDecimal.precision;
|
|
20765
|
-
BigDecimal.precision = precision;
|
|
20766
|
-
try {
|
|
20767
|
-
const cr = toBigDecimal(center[0]);
|
|
20768
|
-
const ci = toBigDecimal(center[1]);
|
|
20769
|
-
let zr = BigDecimal.ZERO;
|
|
20770
|
-
let zi = BigDecimal.ZERO;
|
|
20771
|
-
const ESCAPE = new BigDecimal(256);
|
|
20772
|
-
const points = [];
|
|
20773
|
-
for (let i = 0; i < maxIter; i++) {
|
|
20774
|
-
points.push(zr.toNumber(), zi.toNumber());
|
|
20775
|
-
const zr2 = zr.mul(zr).toPrecision(precision);
|
|
20776
|
-
const zi2 = zi.mul(zi).toPrecision(precision);
|
|
20777
|
-
const mag2 = zr2.add(zi2);
|
|
20778
|
-
if (mag2.cmp(ESCAPE) > 0) break;
|
|
20779
|
-
const new_zi = zr.mul(zi).toPrecision(precision).mul(2).add(ci);
|
|
20780
|
-
zr = zr2.sub(zi2).add(cr);
|
|
20781
|
-
zi = new_zi;
|
|
20782
|
-
}
|
|
20783
|
-
return new Float32Array(points);
|
|
20784
|
-
} finally {
|
|
20785
|
-
BigDecimal.precision = prevPrecision;
|
|
20786
|
-
}
|
|
20787
|
-
}
|
|
20788
|
-
|
|
20789
21150
|
// src/compute-engine/compilation/gpu-target.ts
|
|
20790
21151
|
var GPU_OPERATORS = {
|
|
20791
21152
|
Add: ["+", 11],
|
|
@@ -20807,6 +21168,13 @@ var GPU_OPERATORS = {
|
|
|
20807
21168
|
function gpuVec2(target) {
|
|
20808
21169
|
return target?.language === "wgsl" ? "vec2f" : "vec2";
|
|
20809
21170
|
}
|
|
21171
|
+
function gpuVec3(target) {
|
|
21172
|
+
return target?.language === "wgsl" ? "vec3f" : "vec3";
|
|
21173
|
+
}
|
|
21174
|
+
function readStringLiteral(expr) {
|
|
21175
|
+
if (!isString(expr)) return null;
|
|
21176
|
+
return expr.string?.toLowerCase() ?? null;
|
|
21177
|
+
}
|
|
20810
21178
|
function compileIntArg(expr, compile2, target) {
|
|
20811
21179
|
const c = tryGetConstant(expr);
|
|
20812
21180
|
if (c !== void 0 && Number.isInteger(c)) return c.toString();
|
|
@@ -20865,17 +21233,10 @@ function compileGPUSumProduct(kind, args, _compile, target) {
|
|
|
20865
21233
|
`for (${indexDecl} = ${lowerStr}; ${index} <= ${upperStr}; ${index}++) {`,
|
|
20866
21234
|
` ${acc} ${op}= ${body};`,
|
|
20867
21235
|
`}`,
|
|
20868
|
-
`return ${acc}
|
|
21236
|
+
`return ${acc};`
|
|
20869
21237
|
];
|
|
20870
21238
|
return lines.join("\n");
|
|
20871
21239
|
}
|
|
20872
|
-
function selectFractalStrategy(target) {
|
|
20873
|
-
const radius = target.hints?.viewport?.radius;
|
|
20874
|
-
if (radius === void 0) return "single";
|
|
20875
|
-
if (radius > 1e-6) return "single";
|
|
20876
|
-
if (radius > 1e-14) return "double";
|
|
20877
|
-
return "perturbation";
|
|
20878
|
-
}
|
|
20879
21240
|
var GPU_FUNCTIONS = {
|
|
20880
21241
|
// Variadic arithmetic (for function-call form, e.g., with vectors)
|
|
20881
21242
|
Add: (args, compile2, target) => {
|
|
@@ -20926,8 +21287,7 @@ var GPU_FUNCTIONS = {
|
|
|
20926
21287
|
const iScale = isSymbol2(iFactor, "ImaginaryUnit") ? 1 : iFactor.im;
|
|
20927
21288
|
const realFactors = args.filter((_, i) => i !== iIndex);
|
|
20928
21289
|
const v2 = gpuVec2(target);
|
|
20929
|
-
if (realFactors.length === 0)
|
|
20930
|
-
return `${v2}(0.0, ${formatFloat(iScale)})`;
|
|
21290
|
+
if (realFactors.length === 0) return `${v2}(0.0, ${formatFloat(iScale)})`;
|
|
20931
21291
|
const factors = realFactors.map((f) => compile2(f));
|
|
20932
21292
|
if (iScale !== 1) factors.unshift(formatFloat(iScale));
|
|
20933
21293
|
const imCode = foldTerms(factors, "1.0", "*");
|
|
@@ -20980,8 +21340,7 @@ var GPU_FUNCTIONS = {
|
|
|
20980
21340
|
if (isNumber(x) && x.im !== 0) {
|
|
20981
21341
|
return `${gpuVec2(target)}(${formatFloat(-x.re)}, ${formatFloat(-x.im)})`;
|
|
20982
21342
|
}
|
|
20983
|
-
if (isSymbol2(x, "ImaginaryUnit"))
|
|
20984
|
-
return `${gpuVec2(target)}(0.0, -1.0)`;
|
|
21343
|
+
if (isSymbol2(x, "ImaginaryUnit")) return `${gpuVec2(target)}(0.0, -1.0)`;
|
|
20985
21344
|
return `(-${compile2(x)})`;
|
|
20986
21345
|
},
|
|
20987
21346
|
// Standard math functions with complex dispatch
|
|
@@ -21354,49 +21713,139 @@ var GPU_FUNCTIONS = {
|
|
|
21354
21713
|
}
|
|
21355
21714
|
const isWGSL = target?.language === "wgsl";
|
|
21356
21715
|
const v3 = isWGSL ? "vec3f" : "vec3";
|
|
21357
|
-
|
|
21716
|
+
const black = `${v3}(0.0)`;
|
|
21717
|
+
const white = `${v3}(1.0, 0.0, 0.0)`;
|
|
21718
|
+
return `((_gpu_apca(${bg}, ${black}) > 50.0) ? ${black} : ${white})`;
|
|
21358
21719
|
},
|
|
21359
21720
|
ColorToColorspace: ([color, space], compile2) => {
|
|
21360
21721
|
if (color === null || space === null)
|
|
21361
21722
|
throw new Error("ColorToColorspace: need color and space");
|
|
21362
|
-
|
|
21723
|
+
const spaceName = readStringLiteral(space);
|
|
21724
|
+
if (spaceName === null)
|
|
21725
|
+
throw new Error("ColorToColorspace: space must be a string literal");
|
|
21726
|
+
const c = compile2(color);
|
|
21727
|
+
switch (spaceName) {
|
|
21728
|
+
case "oklch":
|
|
21729
|
+
return c;
|
|
21730
|
+
case "oklab":
|
|
21731
|
+
case "lab":
|
|
21732
|
+
return `_gpu_oklch_to_oklab(${c})`;
|
|
21733
|
+
case "rgb":
|
|
21734
|
+
return `_gpu_oklch_to_srgb(${c})`;
|
|
21735
|
+
case "hsl":
|
|
21736
|
+
return `_gpu_rgb_to_hsl(_gpu_oklch_to_srgb(${c}))`;
|
|
21737
|
+
case "hsv":
|
|
21738
|
+
return `_gpu_rgb_to_hsv(_gpu_oklch_to_srgb(${c}))`;
|
|
21739
|
+
default:
|
|
21740
|
+
throw new Error(
|
|
21741
|
+
`ColorToColorspace: unsupported space "${spaceName}" on GPU target`
|
|
21742
|
+
);
|
|
21743
|
+
}
|
|
21363
21744
|
},
|
|
21364
21745
|
ColorFromColorspace: ([components, space], compile2) => {
|
|
21365
21746
|
if (components === null || space === null)
|
|
21366
21747
|
throw new Error("ColorFromColorspace: need components and space");
|
|
21367
|
-
|
|
21748
|
+
const spaceName = readStringLiteral(space);
|
|
21749
|
+
if (spaceName === null)
|
|
21750
|
+
throw new Error("ColorFromColorspace: space must be a string literal");
|
|
21751
|
+
const c = compile2(components);
|
|
21752
|
+
switch (spaceName) {
|
|
21753
|
+
case "oklch":
|
|
21754
|
+
return c;
|
|
21755
|
+
case "oklab":
|
|
21756
|
+
case "lab":
|
|
21757
|
+
return `_gpu_oklab_to_oklch(${c})`;
|
|
21758
|
+
case "rgb":
|
|
21759
|
+
return `_gpu_srgb_to_oklch(${c})`;
|
|
21760
|
+
case "hsl":
|
|
21761
|
+
return `_gpu_srgb_to_oklch(_gpu_hsl_to_rgb(${c}))`;
|
|
21762
|
+
case "hsv":
|
|
21763
|
+
return `_gpu_srgb_to_oklch(_gpu_hsv_to_rgb(${c}))`;
|
|
21764
|
+
default:
|
|
21765
|
+
throw new Error(
|
|
21766
|
+
`ColorFromColorspace: unsupported space "${spaceName}" on GPU target`
|
|
21767
|
+
);
|
|
21768
|
+
}
|
|
21769
|
+
},
|
|
21770
|
+
// ---------------------------------------------------------------------------
|
|
21771
|
+
// Color literals. Each typed head compiles to a canonical OKLCh vec3.
|
|
21772
|
+
// Alpha (4th argument) is dropped — GPU color values are vec3 only. Pass
|
|
21773
|
+
// alpha as a separate uniform if it's needed at the framebuffer boundary.
|
|
21774
|
+
// ---------------------------------------------------------------------------
|
|
21775
|
+
Color: ([s], _compile, target) => {
|
|
21776
|
+
if (s === null) throw new Error("Color: no argument");
|
|
21777
|
+
const str = readStringLiteral(s);
|
|
21778
|
+
if (str === null)
|
|
21779
|
+
throw new Error("Color: argument must be a string literal on GPU target");
|
|
21780
|
+
const packed = parseColor(str);
|
|
21781
|
+
if (packed === 0 && str.trim().toLowerCase() !== "transparent")
|
|
21782
|
+
throw new Error(`Color: invalid color string "${str}"`);
|
|
21783
|
+
const r = packed >>> 24 & 255;
|
|
21784
|
+
const g = packed >>> 16 & 255;
|
|
21785
|
+
const b = packed >>> 8 & 255;
|
|
21786
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
21787
|
+
return `${gpuVec3(target)}(${formatFloat(oklch2.L)}, ${formatFloat(oklch2.C)}, ${formatFloat(oklch2.H)})`;
|
|
21788
|
+
},
|
|
21789
|
+
Rgb: (args, compile2, target) => {
|
|
21790
|
+
if (args.length < 3) throw new Error("Rgb: need 3 components");
|
|
21791
|
+
const v3 = gpuVec3(target);
|
|
21792
|
+
return `_gpu_srgb_to_oklch(${v3}(${compile2(args[0])}, ${compile2(args[1])}, ${compile2(args[2])}))`;
|
|
21793
|
+
},
|
|
21794
|
+
Hsv: (args, compile2, target) => {
|
|
21795
|
+
if (args.length < 3) throw new Error("Hsv: need 3 components");
|
|
21796
|
+
const v3 = gpuVec3(target);
|
|
21797
|
+
return `_gpu_srgb_to_oklch(_gpu_hsv_to_rgb(${v3}(${compile2(args[0])}, ${compile2(args[1])}, ${compile2(args[2])})))`;
|
|
21798
|
+
},
|
|
21799
|
+
Hsl: (args, compile2, target) => {
|
|
21800
|
+
if (args.length < 3) throw new Error("Hsl: need 3 components");
|
|
21801
|
+
const v3 = gpuVec3(target);
|
|
21802
|
+
return `_gpu_srgb_to_oklch(_gpu_hsl_to_rgb(${v3}(${compile2(args[0])}, ${compile2(args[1])}, ${compile2(args[2])})))`;
|
|
21803
|
+
},
|
|
21804
|
+
Oklab: (args, compile2, target) => {
|
|
21805
|
+
if (args.length < 3) throw new Error("Oklab: need 3 components");
|
|
21806
|
+
const v3 = gpuVec3(target);
|
|
21807
|
+
return `_gpu_oklab_to_oklch(${v3}(${compile2(args[0])}, ${compile2(args[1])}, ${compile2(args[2])}))`;
|
|
21808
|
+
},
|
|
21809
|
+
Oklch: (args, compile2, target) => {
|
|
21810
|
+
if (args.length < 3) throw new Error("Oklch: need 3 components");
|
|
21811
|
+
const v3 = gpuVec3(target);
|
|
21812
|
+
return `${v3}(${compile2(args[0])}, ${compile2(args[1])}, ${compile2(args[2])})`;
|
|
21813
|
+
},
|
|
21814
|
+
// ---------------------------------------------------------------------------
|
|
21815
|
+
// As* operators. AsOklch is identity (canonical). The other As* return
|
|
21816
|
+
// components in the named space, equivalent to ColorToColorspace(c, 'x').
|
|
21817
|
+
// ---------------------------------------------------------------------------
|
|
21818
|
+
AsOklch: ([c], compile2) => {
|
|
21819
|
+
if (c === null) throw new Error("AsOklch: no argument");
|
|
21820
|
+
return compile2(c);
|
|
21821
|
+
},
|
|
21822
|
+
AsOklab: ([c], compile2) => {
|
|
21823
|
+
if (c === null) throw new Error("AsOklab: no argument");
|
|
21824
|
+
return `_gpu_oklch_to_oklab(${compile2(c)})`;
|
|
21825
|
+
},
|
|
21826
|
+
AsRgb: ([c], compile2) => {
|
|
21827
|
+
if (c === null) throw new Error("AsRgb: no argument");
|
|
21828
|
+
return `_gpu_oklch_to_srgb(${compile2(c)})`;
|
|
21829
|
+
},
|
|
21830
|
+
AsHsv: ([c], compile2) => {
|
|
21831
|
+
if (c === null) throw new Error("AsHsv: no argument");
|
|
21832
|
+
return `_gpu_rgb_to_hsv(_gpu_oklch_to_srgb(${compile2(c)}))`;
|
|
21833
|
+
},
|
|
21834
|
+
AsHsl: ([c], compile2) => {
|
|
21835
|
+
if (c === null) throw new Error("AsHsl: no argument");
|
|
21836
|
+
return `_gpu_rgb_to_hsl(_gpu_oklch_to_srgb(${compile2(c)}))`;
|
|
21368
21837
|
},
|
|
21369
21838
|
// Fractal functions
|
|
21370
21839
|
Mandelbrot: ([c, maxIter], compile2, target) => {
|
|
21371
21840
|
if (c === null || maxIter === null)
|
|
21372
21841
|
throw new Error("Mandelbrot: missing arguments");
|
|
21373
21842
|
const iterCode = compileIntArg(maxIter, compile2, target);
|
|
21374
|
-
const strategy = selectFractalStrategy(target);
|
|
21375
|
-
if (strategy === "double") {
|
|
21376
|
-
const dpCoord = target?.language === "wgsl" ? "_dp_coord(v_uv)" : "_dp_coord()";
|
|
21377
|
-
return `_fractal_mandelbrot_dp(${dpCoord}, ${iterCode})`;
|
|
21378
|
-
}
|
|
21379
|
-
if (strategy === "perturbation") {
|
|
21380
|
-
const ptDelta = target?.language === "wgsl" ? "_pt_delta(v_uv)" : "_pt_delta()";
|
|
21381
|
-
return `_fractal_mandelbrot_pt(${ptDelta}, ${iterCode})`;
|
|
21382
|
-
}
|
|
21383
21843
|
return `_fractal_mandelbrot(${compile2(c)}, ${iterCode})`;
|
|
21384
21844
|
},
|
|
21385
21845
|
Julia: ([z, c, maxIter], compile2, target) => {
|
|
21386
21846
|
if (z === null || c === null || maxIter === null)
|
|
21387
21847
|
throw new Error("Julia: missing arguments");
|
|
21388
21848
|
const iterCode = compileIntArg(maxIter, compile2, target);
|
|
21389
|
-
const strategy = selectFractalStrategy(target);
|
|
21390
|
-
if (strategy === "double") {
|
|
21391
|
-
const dpCoord = target?.language === "wgsl" ? "_dp_coord(v_uv)" : "_dp_coord()";
|
|
21392
|
-
const cCode = compile2(c);
|
|
21393
|
-
return `_fractal_julia_dp(${dpCoord}, vec4(${cCode}, vec2(0.0)), ${iterCode})`;
|
|
21394
|
-
}
|
|
21395
|
-
if (strategy === "perturbation") {
|
|
21396
|
-
const ptDelta = target?.language === "wgsl" ? "_pt_delta(v_uv)" : "_pt_delta()";
|
|
21397
|
-
const cCode = compile2(c);
|
|
21398
|
-
return `_fractal_julia_pt(${ptDelta}, ${cCode}, ${iterCode})`;
|
|
21399
|
-
}
|
|
21400
21849
|
return `_fractal_julia(${compile2(z)}, ${compile2(c)}, ${iterCode})`;
|
|
21401
21850
|
},
|
|
21402
21851
|
// Vector/Matrix operations
|
|
@@ -21994,232 +22443,6 @@ fn _gpu_besselJ(n_in: i32, x_in: f32) -> f32 {
|
|
|
21994
22443
|
return sgn * vals[n] / norm;
|
|
21995
22444
|
}
|
|
21996
22445
|
`;
|
|
21997
|
-
var GPU_DS_ARITHMETIC_PREAMBLE_GLSL = `
|
|
21998
|
-
// Split a float into high and low parts for exact multiplication
|
|
21999
|
-
vec2 ds_split(float a) {
|
|
22000
|
-
const float SPLIT = 4097.0; // 2^12 + 1
|
|
22001
|
-
float t = SPLIT * a;
|
|
22002
|
-
float hi = t - (t - a);
|
|
22003
|
-
float lo = a - hi;
|
|
22004
|
-
return vec2(hi, lo);
|
|
22005
|
-
}
|
|
22006
|
-
|
|
22007
|
-
// Create a double-single from a single float
|
|
22008
|
-
vec2 ds_from(float a) {
|
|
22009
|
-
return vec2(a, 0.0);
|
|
22010
|
-
}
|
|
22011
|
-
|
|
22012
|
-
// Error-free addition (Knuth TwoSum)
|
|
22013
|
-
vec2 ds_add(vec2 a, vec2 b) {
|
|
22014
|
-
float s = a.x + b.x;
|
|
22015
|
-
float v = s - a.x;
|
|
22016
|
-
float e = (a.x - (s - v)) + (b.x - v);
|
|
22017
|
-
float lo = (a.y + b.y) + e;
|
|
22018
|
-
float hi = s + lo;
|
|
22019
|
-
lo = lo - (hi - s);
|
|
22020
|
-
return vec2(hi, lo);
|
|
22021
|
-
}
|
|
22022
|
-
|
|
22023
|
-
// Double-single subtraction
|
|
22024
|
-
vec2 ds_sub(vec2 a, vec2 b) {
|
|
22025
|
-
return ds_add(a, vec2(-b.x, -b.y));
|
|
22026
|
-
}
|
|
22027
|
-
|
|
22028
|
-
// Error-free multiplication (Dekker TwoProduct)
|
|
22029
|
-
vec2 ds_mul(vec2 a, vec2 b) {
|
|
22030
|
-
float p = a.x * b.x;
|
|
22031
|
-
vec2 sa = ds_split(a.x);
|
|
22032
|
-
vec2 sb = ds_split(b.x);
|
|
22033
|
-
float err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
22034
|
-
err += a.x * b.y + a.y * b.x;
|
|
22035
|
-
float hi = p + err;
|
|
22036
|
-
float lo = err - (hi - p);
|
|
22037
|
-
return vec2(hi, lo);
|
|
22038
|
-
}
|
|
22039
|
-
|
|
22040
|
-
// Optimized self-multiply
|
|
22041
|
-
vec2 ds_sqr(vec2 a) {
|
|
22042
|
-
float p = a.x * a.x;
|
|
22043
|
-
vec2 sa = ds_split(a.x);
|
|
22044
|
-
float err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
22045
|
-
err += 2.0 * a.x * a.y;
|
|
22046
|
-
float hi = p + err;
|
|
22047
|
-
float lo = err - (hi - p);
|
|
22048
|
-
return vec2(hi, lo);
|
|
22049
|
-
}
|
|
22050
|
-
|
|
22051
|
-
// Compare magnitude: returns -1, 0, or 1
|
|
22052
|
-
float ds_cmp(vec2 a, vec2 b) {
|
|
22053
|
-
float d = a.x - b.x;
|
|
22054
|
-
if (d != 0.0) return sign(d);
|
|
22055
|
-
return sign(a.y - b.y);
|
|
22056
|
-
}
|
|
22057
|
-
`;
|
|
22058
|
-
var GPU_DS_ARITHMETIC_PREAMBLE_WGSL = `
|
|
22059
|
-
fn ds_split(a: f32) -> vec2f {
|
|
22060
|
-
const SPLIT: f32 = 4097.0;
|
|
22061
|
-
let t = SPLIT * a;
|
|
22062
|
-
let hi = t - (t - a);
|
|
22063
|
-
let lo = a - hi;
|
|
22064
|
-
return vec2f(hi, lo);
|
|
22065
|
-
}
|
|
22066
|
-
|
|
22067
|
-
fn ds_from(a: f32) -> vec2f {
|
|
22068
|
-
return vec2f(a, 0.0);
|
|
22069
|
-
}
|
|
22070
|
-
|
|
22071
|
-
fn ds_add(a: vec2f, b: vec2f) -> vec2f {
|
|
22072
|
-
let s = a.x + b.x;
|
|
22073
|
-
let v = s - a.x;
|
|
22074
|
-
let e = (a.x - (s - v)) + (b.x - v);
|
|
22075
|
-
let lo_t = (a.y + b.y) + e;
|
|
22076
|
-
let hi = s + lo_t;
|
|
22077
|
-
let lo = lo_t - (hi - s);
|
|
22078
|
-
return vec2f(hi, lo);
|
|
22079
|
-
}
|
|
22080
|
-
|
|
22081
|
-
fn ds_sub(a: vec2f, b: vec2f) -> vec2f {
|
|
22082
|
-
return ds_add(a, vec2f(-b.x, -b.y));
|
|
22083
|
-
}
|
|
22084
|
-
|
|
22085
|
-
fn ds_mul(a: vec2f, b: vec2f) -> vec2f {
|
|
22086
|
-
let p = a.x * b.x;
|
|
22087
|
-
let sa = ds_split(a.x);
|
|
22088
|
-
let sb = ds_split(b.x);
|
|
22089
|
-
var err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
22090
|
-
err += a.x * b.y + a.y * b.x;
|
|
22091
|
-
let hi = p + err;
|
|
22092
|
-
let lo = err - (hi - p);
|
|
22093
|
-
return vec2f(hi, lo);
|
|
22094
|
-
}
|
|
22095
|
-
|
|
22096
|
-
fn ds_sqr(a: vec2f) -> vec2f {
|
|
22097
|
-
let p = a.x * a.x;
|
|
22098
|
-
let sa = ds_split(a.x);
|
|
22099
|
-
var err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
22100
|
-
err += 2.0 * a.x * a.y;
|
|
22101
|
-
let hi = p + err;
|
|
22102
|
-
let lo = err - (hi - p);
|
|
22103
|
-
return vec2f(hi, lo);
|
|
22104
|
-
}
|
|
22105
|
-
|
|
22106
|
-
fn ds_cmp(a: vec2f, b: vec2f) -> f32 {
|
|
22107
|
-
let d = a.x - b.x;
|
|
22108
|
-
if (d != 0.0) { return sign(d); }
|
|
22109
|
-
return sign(a.y - b.y);
|
|
22110
|
-
}
|
|
22111
|
-
`;
|
|
22112
|
-
var GPU_FRACTAL_DP_PREAMBLE_GLSL = `
|
|
22113
|
-
uniform float _dp_cx_hi;
|
|
22114
|
-
uniform float _dp_cx_lo;
|
|
22115
|
-
uniform float _dp_cy_hi;
|
|
22116
|
-
uniform float _dp_cy_lo;
|
|
22117
|
-
uniform float _dp_w;
|
|
22118
|
-
uniform float _dp_h;
|
|
22119
|
-
|
|
22120
|
-
vec4 _dp_coord() {
|
|
22121
|
-
// Per-pixel offset from center \u2014 small, so float-precise
|
|
22122
|
-
float dx = (v_uv.x - 0.5) * _dp_w;
|
|
22123
|
-
float dy = (v_uv.y - 0.5) * _dp_h;
|
|
22124
|
-
// Combine center (hi+lo) + delta with emulated double precision
|
|
22125
|
-
vec2 cre = ds_add(vec2(_dp_cx_hi, _dp_cx_lo), ds_from(dx));
|
|
22126
|
-
vec2 cim = ds_add(vec2(_dp_cy_hi, _dp_cy_lo), ds_from(dy));
|
|
22127
|
-
return vec4(cre.x, cim.x, cre.y, cim.y);
|
|
22128
|
-
}
|
|
22129
|
-
|
|
22130
|
-
float _fractal_mandelbrot_dp(vec4 c, int maxIter) {
|
|
22131
|
-
// c = (re_hi, im_hi, re_lo, im_lo)
|
|
22132
|
-
vec2 cr = vec2(c.x, c.z); // real part as ds
|
|
22133
|
-
vec2 ci = vec2(c.y, c.w); // imag part as ds
|
|
22134
|
-
vec2 zr = vec2(0.0, 0.0);
|
|
22135
|
-
vec2 zi = vec2(0.0, 0.0);
|
|
22136
|
-
for (int i = 0; i < maxIter; i++) {
|
|
22137
|
-
vec2 zr2 = ds_sqr(zr);
|
|
22138
|
-
vec2 zi2 = ds_sqr(zi);
|
|
22139
|
-
// |z|^2 > 4.0 ?
|
|
22140
|
-
vec2 mag2 = ds_add(zr2, zi2);
|
|
22141
|
-
if (mag2.x > 4.0)
|
|
22142
|
-
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22143
|
-
// z = z^2 + c
|
|
22144
|
-
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci); // 2*zr*zi + ci
|
|
22145
|
-
zr = ds_add(ds_sub(zr2, zi2), cr); // zr^2 - zi^2 + cr
|
|
22146
|
-
zi = new_zi;
|
|
22147
|
-
}
|
|
22148
|
-
return 1.0;
|
|
22149
|
-
}
|
|
22150
|
-
|
|
22151
|
-
float _fractal_julia_dp(vec4 z_in, vec4 c, int maxIter) {
|
|
22152
|
-
vec2 zr = vec2(z_in.x, z_in.z);
|
|
22153
|
-
vec2 zi = vec2(z_in.y, z_in.w);
|
|
22154
|
-
vec2 cr = vec2(c.x, c.z);
|
|
22155
|
-
vec2 ci = vec2(c.y, c.w);
|
|
22156
|
-
for (int i = 0; i < maxIter; i++) {
|
|
22157
|
-
vec2 zr2 = ds_sqr(zr);
|
|
22158
|
-
vec2 zi2 = ds_sqr(zi);
|
|
22159
|
-
vec2 mag2 = ds_add(zr2, zi2);
|
|
22160
|
-
if (mag2.x > 4.0)
|
|
22161
|
-
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22162
|
-
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
22163
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
22164
|
-
zi = new_zi;
|
|
22165
|
-
}
|
|
22166
|
-
return 1.0;
|
|
22167
|
-
}
|
|
22168
|
-
`;
|
|
22169
|
-
var GPU_FRACTAL_DP_PREAMBLE_WGSL = `
|
|
22170
|
-
@group(0) @binding(10) var<uniform> _dp_cx_hi: f32;
|
|
22171
|
-
@group(0) @binding(11) var<uniform> _dp_cx_lo: f32;
|
|
22172
|
-
@group(0) @binding(12) var<uniform> _dp_cy_hi: f32;
|
|
22173
|
-
@group(0) @binding(13) var<uniform> _dp_cy_lo: f32;
|
|
22174
|
-
@group(0) @binding(14) var<uniform> _dp_w: f32;
|
|
22175
|
-
@group(0) @binding(15) var<uniform> _dp_h: f32;
|
|
22176
|
-
|
|
22177
|
-
fn _dp_coord(uv: vec2f) -> vec4f {
|
|
22178
|
-
let dx = (uv.x - 0.5) * _dp_w;
|
|
22179
|
-
let dy = (uv.y - 0.5) * _dp_h;
|
|
22180
|
-
let cre = ds_add(vec2f(_dp_cx_hi, _dp_cx_lo), ds_from(dx));
|
|
22181
|
-
let cim = ds_add(vec2f(_dp_cy_hi, _dp_cy_lo), ds_from(dy));
|
|
22182
|
-
return vec4f(cre.x, cim.x, cre.y, cim.y);
|
|
22183
|
-
}
|
|
22184
|
-
|
|
22185
|
-
fn _fractal_mandelbrot_dp(c: vec4f, maxIter: i32) -> f32 {
|
|
22186
|
-
let cr = vec2f(c.x, c.z);
|
|
22187
|
-
let ci = vec2f(c.y, c.w);
|
|
22188
|
-
var zr = vec2f(0.0, 0.0);
|
|
22189
|
-
var zi = vec2f(0.0, 0.0);
|
|
22190
|
-
for (var i: i32 = 0; i < maxIter; i++) {
|
|
22191
|
-
let zr2 = ds_sqr(zr);
|
|
22192
|
-
let zi2 = ds_sqr(zi);
|
|
22193
|
-
let mag2 = ds_add(zr2, zi2);
|
|
22194
|
-
if (mag2.x > 4.0) {
|
|
22195
|
-
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22196
|
-
}
|
|
22197
|
-
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
22198
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
22199
|
-
zi = new_zi;
|
|
22200
|
-
}
|
|
22201
|
-
return 1.0;
|
|
22202
|
-
}
|
|
22203
|
-
|
|
22204
|
-
fn _fractal_julia_dp(z_in: vec4f, c: vec4f, maxIter: i32) -> f32 {
|
|
22205
|
-
var zr = vec2f(z_in.x, z_in.z);
|
|
22206
|
-
var zi = vec2f(z_in.y, z_in.w);
|
|
22207
|
-
let cr = vec2f(c.x, c.z);
|
|
22208
|
-
let ci = vec2f(c.y, c.w);
|
|
22209
|
-
for (var i: i32 = 0; i < maxIter; i++) {
|
|
22210
|
-
let zr2 = ds_sqr(zr);
|
|
22211
|
-
let zi2 = ds_sqr(zi);
|
|
22212
|
-
let mag2 = ds_add(zr2, zi2);
|
|
22213
|
-
if (mag2.x > 4.0) {
|
|
22214
|
-
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22215
|
-
}
|
|
22216
|
-
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
22217
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
22218
|
-
zi = new_zi;
|
|
22219
|
-
}
|
|
22220
|
-
return 1.0;
|
|
22221
|
-
}
|
|
22222
|
-
`;
|
|
22223
22446
|
var GPU_FRACTAL_PREAMBLE_GLSL = `
|
|
22224
22447
|
float _fractal_mandelbrot(vec2 c, int maxIter) {
|
|
22225
22448
|
vec2 z = vec2(0.0, 0.0);
|
|
@@ -22263,208 +22486,6 @@ fn _fractal_julia(z_in: vec2f, c: vec2f, maxIter: i32) -> f32 {
|
|
|
22263
22486
|
return 1.0;
|
|
22264
22487
|
}
|
|
22265
22488
|
`;
|
|
22266
|
-
var GPU_FRACTAL_PT_PREAMBLE_GLSL = `
|
|
22267
|
-
uniform sampler2D _refOrbit;
|
|
22268
|
-
uniform int _refOrbitLen;
|
|
22269
|
-
uniform int _refOrbitTexWidth;
|
|
22270
|
-
uniform float _pt_offset_x;
|
|
22271
|
-
uniform float _pt_offset_y;
|
|
22272
|
-
uniform float _pt_w;
|
|
22273
|
-
uniform float _pt_h;
|
|
22274
|
-
|
|
22275
|
-
vec2 _pt_delta() {
|
|
22276
|
-
float dx = _pt_offset_x + (v_uv.x - 0.5) * _pt_w;
|
|
22277
|
-
float dy = _pt_offset_y + (v_uv.y - 0.5) * _pt_h;
|
|
22278
|
-
return vec2(dx, dy);
|
|
22279
|
-
}
|
|
22280
|
-
|
|
22281
|
-
vec2 _pt_fetch_orbit(int i) {
|
|
22282
|
-
int y = i / _refOrbitTexWidth;
|
|
22283
|
-
int x = i - y * _refOrbitTexWidth;
|
|
22284
|
-
return texelFetch(_refOrbit, ivec2(x, y), 0).rg;
|
|
22285
|
-
}
|
|
22286
|
-
|
|
22287
|
-
float _fractal_mandelbrot_pt(vec2 delta_c, int maxIter) {
|
|
22288
|
-
float dr = 0.0;
|
|
22289
|
-
float di = 0.0;
|
|
22290
|
-
int orbitLen = min(maxIter, _refOrbitLen);
|
|
22291
|
-
for (int i = 0; i < orbitLen; i++) {
|
|
22292
|
-
vec2 Zn = _pt_fetch_orbit(i);
|
|
22293
|
-
// delta_{n+1} = 2*Z_n*delta_n + delta_n^2 + delta_c
|
|
22294
|
-
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22295
|
-
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22296
|
-
dr = new_dr;
|
|
22297
|
-
di = new_di;
|
|
22298
|
-
// Full z = Z_{n+1} + delta for escape check
|
|
22299
|
-
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
22300
|
-
float zr = Zn1.x + dr;
|
|
22301
|
-
float zi = Zn1.y + di;
|
|
22302
|
-
float mag2 = zr * zr + zi * zi;
|
|
22303
|
-
if (mag2 > 4.0)
|
|
22304
|
-
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22305
|
-
// Glitch detection: |delta|^2 > |Z|^2
|
|
22306
|
-
float dmag2 = dr * dr + di * di;
|
|
22307
|
-
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22308
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22309
|
-
// Rebase to absolute coordinates and continue with single-float
|
|
22310
|
-
float abs_zr = Zn1.x + dr;
|
|
22311
|
-
float abs_zi = Zn1.y + di;
|
|
22312
|
-
// Reconstruct absolute c from reference + delta
|
|
22313
|
-
// (Use ds_from for the concept, but single-float suffices for fallback)
|
|
22314
|
-
float cx = abs_zr - dr + delta_c.x;
|
|
22315
|
-
float cy = abs_zi - di + delta_c.y;
|
|
22316
|
-
for (int j = i + 1; j < maxIter; j++) {
|
|
22317
|
-
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
22318
|
-
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
22319
|
-
abs_zr = new_zr;
|
|
22320
|
-
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
22321
|
-
if (mag2 > 4.0)
|
|
22322
|
-
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22323
|
-
}
|
|
22324
|
-
return 1.0;
|
|
22325
|
-
}
|
|
22326
|
-
}
|
|
22327
|
-
return 1.0;
|
|
22328
|
-
}
|
|
22329
|
-
|
|
22330
|
-
float _fractal_julia_pt(vec2 z_delta, vec2 delta_c, int maxIter) {
|
|
22331
|
-
float dr = z_delta.x;
|
|
22332
|
-
float di = z_delta.y;
|
|
22333
|
-
int orbitLen = min(maxIter, _refOrbitLen);
|
|
22334
|
-
for (int i = 0; i < orbitLen; i++) {
|
|
22335
|
-
vec2 Zn = _pt_fetch_orbit(i);
|
|
22336
|
-
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22337
|
-
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22338
|
-
dr = new_dr;
|
|
22339
|
-
di = new_di;
|
|
22340
|
-
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
22341
|
-
float zr = Zn1.x + dr;
|
|
22342
|
-
float zi = Zn1.y + di;
|
|
22343
|
-
float mag2 = zr * zr + zi * zi;
|
|
22344
|
-
if (mag2 > 4.0)
|
|
22345
|
-
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22346
|
-
float dmag2 = dr * dr + di * di;
|
|
22347
|
-
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22348
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22349
|
-
float abs_zr = Zn1.x + dr;
|
|
22350
|
-
float abs_zi = Zn1.y + di;
|
|
22351
|
-
float cx = delta_c.x;
|
|
22352
|
-
float cy = delta_c.y;
|
|
22353
|
-
for (int j = i + 1; j < maxIter; j++) {
|
|
22354
|
-
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
22355
|
-
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
22356
|
-
abs_zr = new_zr;
|
|
22357
|
-
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
22358
|
-
if (mag2 > 4.0)
|
|
22359
|
-
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22360
|
-
}
|
|
22361
|
-
return 1.0;
|
|
22362
|
-
}
|
|
22363
|
-
}
|
|
22364
|
-
return 1.0;
|
|
22365
|
-
}
|
|
22366
|
-
`;
|
|
22367
|
-
var GPU_FRACTAL_PT_PREAMBLE_WGSL = `
|
|
22368
|
-
@group(0) @binding(1) var _refOrbit: texture_2d<f32>;
|
|
22369
|
-
var<uniform> _refOrbitLen: i32;
|
|
22370
|
-
var<uniform> _refOrbitTexWidth: i32;
|
|
22371
|
-
var<uniform> _pt_offset_x: f32;
|
|
22372
|
-
var<uniform> _pt_offset_y: f32;
|
|
22373
|
-
var<uniform> _pt_w: f32;
|
|
22374
|
-
var<uniform> _pt_h: f32;
|
|
22375
|
-
|
|
22376
|
-
fn _pt_delta(uv: vec2f) -> vec2f {
|
|
22377
|
-
let dx = _pt_offset_x + (uv.x - 0.5) * _pt_w;
|
|
22378
|
-
let dy = _pt_offset_y + (uv.y - 0.5) * _pt_h;
|
|
22379
|
-
return vec2f(dx, dy);
|
|
22380
|
-
}
|
|
22381
|
-
|
|
22382
|
-
fn _pt_fetch_orbit(i: i32) -> vec2f {
|
|
22383
|
-
let y = i / _refOrbitTexWidth;
|
|
22384
|
-
let x = i - y * _refOrbitTexWidth;
|
|
22385
|
-
return textureLoad(_refOrbit, vec2i(x, y), 0).rg;
|
|
22386
|
-
}
|
|
22387
|
-
|
|
22388
|
-
fn _fractal_mandelbrot_pt(delta_c: vec2f, maxIter: i32) -> f32 {
|
|
22389
|
-
var dr: f32 = 0.0;
|
|
22390
|
-
var di: f32 = 0.0;
|
|
22391
|
-
let orbitLen = min(maxIter, _refOrbitLen);
|
|
22392
|
-
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
22393
|
-
let Zn = _pt_fetch_orbit(i);
|
|
22394
|
-
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22395
|
-
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22396
|
-
dr = new_dr;
|
|
22397
|
-
di = new_di;
|
|
22398
|
-
var Zn1 = vec2f(0.0);
|
|
22399
|
-
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
22400
|
-
let zr = Zn1.x + dr;
|
|
22401
|
-
let zi = Zn1.y + di;
|
|
22402
|
-
var mag2 = zr * zr + zi * zi;
|
|
22403
|
-
if (mag2 > 4.0) {
|
|
22404
|
-
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22405
|
-
}
|
|
22406
|
-
let dmag2 = dr * dr + di * di;
|
|
22407
|
-
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22408
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22409
|
-
var f_zr = Zn1.x + dr;
|
|
22410
|
-
var f_zi = Zn1.y + di;
|
|
22411
|
-
let cx = delta_c.x;
|
|
22412
|
-
let cy = delta_c.y;
|
|
22413
|
-
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
22414
|
-
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
22415
|
-
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
22416
|
-
f_zr = t_zr;
|
|
22417
|
-
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
22418
|
-
if (mag2 > 4.0) {
|
|
22419
|
-
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22420
|
-
}
|
|
22421
|
-
}
|
|
22422
|
-
return 1.0;
|
|
22423
|
-
}
|
|
22424
|
-
}
|
|
22425
|
-
return 1.0;
|
|
22426
|
-
}
|
|
22427
|
-
|
|
22428
|
-
fn _fractal_julia_pt(z_delta: vec2f, delta_c: vec2f, maxIter: i32) -> f32 {
|
|
22429
|
-
var dr = z_delta.x;
|
|
22430
|
-
var di = z_delta.y;
|
|
22431
|
-
let orbitLen = min(maxIter, _refOrbitLen);
|
|
22432
|
-
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
22433
|
-
let Zn = _pt_fetch_orbit(i);
|
|
22434
|
-
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22435
|
-
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22436
|
-
dr = new_dr;
|
|
22437
|
-
di = new_di;
|
|
22438
|
-
var Zn1 = vec2f(0.0);
|
|
22439
|
-
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
22440
|
-
let zr = Zn1.x + dr;
|
|
22441
|
-
let zi = Zn1.y + di;
|
|
22442
|
-
var mag2 = zr * zr + zi * zi;
|
|
22443
|
-
if (mag2 > 4.0) {
|
|
22444
|
-
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22445
|
-
}
|
|
22446
|
-
let dmag2 = dr * dr + di * di;
|
|
22447
|
-
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22448
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22449
|
-
var f_zr = Zn1.x + dr;
|
|
22450
|
-
var f_zi = Zn1.y + di;
|
|
22451
|
-
let cx = delta_c.x;
|
|
22452
|
-
let cy = delta_c.y;
|
|
22453
|
-
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
22454
|
-
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
22455
|
-
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
22456
|
-
f_zr = t_zr;
|
|
22457
|
-
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
22458
|
-
if (mag2 > 4.0) {
|
|
22459
|
-
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22460
|
-
}
|
|
22461
|
-
}
|
|
22462
|
-
return 1.0;
|
|
22463
|
-
}
|
|
22464
|
-
}
|
|
22465
|
-
return 1.0;
|
|
22466
|
-
}
|
|
22467
|
-
`;
|
|
22468
22489
|
var GPU_COLOR_PREAMBLE_GLSL = `
|
|
22469
22490
|
float _gpu_srgb_to_linear(float c) {
|
|
22470
22491
|
if (c <= 0.04045) return c / 12.92;
|
|
@@ -22505,28 +22526,124 @@ vec3 _gpu_oklab_to_srgb(vec3 lab) {
|
|
|
22505
22526
|
|
|
22506
22527
|
vec3 _gpu_oklab_to_oklch(vec3 lab) {
|
|
22507
22528
|
float C = length(lab.yz);
|
|
22508
|
-
float H = atan(lab.z, lab.y);
|
|
22529
|
+
float H = atan(lab.z, lab.y) * (180.0 / 3.14159265359);
|
|
22530
|
+
if (H < 0.0) H += 360.0;
|
|
22509
22531
|
return vec3(lab.x, C, H);
|
|
22510
22532
|
}
|
|
22511
22533
|
|
|
22512
22534
|
vec3 _gpu_oklch_to_oklab(vec3 lch) {
|
|
22513
|
-
|
|
22535
|
+
float h_rad = lch.z * (3.14159265359 / 180.0);
|
|
22536
|
+
return vec3(lch.x, lch.y * cos(h_rad), lch.y * sin(h_rad));
|
|
22514
22537
|
}
|
|
22515
22538
|
|
|
22516
|
-
vec3
|
|
22517
|
-
|
|
22518
|
-
|
|
22539
|
+
vec3 _gpu_srgb_to_oklch(vec3 rgb) {
|
|
22540
|
+
return _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb));
|
|
22541
|
+
}
|
|
22542
|
+
|
|
22543
|
+
vec3 _gpu_oklch_to_srgb(vec3 lch) {
|
|
22544
|
+
return _gpu_oklab_to_srgb(_gpu_oklch_to_oklab(lch));
|
|
22545
|
+
}
|
|
22546
|
+
|
|
22547
|
+
// HSL conversion. Hue in degrees, saturation/lightness in 0-1.
|
|
22548
|
+
vec3 _gpu_hsl_to_rgb(vec3 hsl) {
|
|
22549
|
+
float h = hsl.x;
|
|
22550
|
+
float s = hsl.y;
|
|
22551
|
+
float l = hsl.z;
|
|
22552
|
+
float c = (1.0 - abs(2.0 * l - 1.0)) * s;
|
|
22553
|
+
float h6 = h / 60.0;
|
|
22554
|
+
float x = c * (1.0 - abs(mod(h6, 2.0) - 1.0));
|
|
22555
|
+
float r = 0.0;
|
|
22556
|
+
float g = 0.0;
|
|
22557
|
+
float b = 0.0;
|
|
22558
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
22559
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
22560
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
22561
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
22562
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
22563
|
+
else { r = c; g = 0.0; b = x; }
|
|
22564
|
+
float m = l - c / 2.0;
|
|
22565
|
+
return vec3(r + m, g + m, b + m);
|
|
22566
|
+
}
|
|
22567
|
+
|
|
22568
|
+
vec3 _gpu_rgb_to_hsl(vec3 rgb) {
|
|
22569
|
+
float maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
22570
|
+
float minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
22571
|
+
float l = (maxc + minc) / 2.0;
|
|
22572
|
+
float d = maxc - minc;
|
|
22573
|
+
if (d < 1e-6) return vec3(0.0, 0.0, l);
|
|
22574
|
+
float s = d / (1.0 - abs(2.0 * l - 1.0));
|
|
22575
|
+
float h;
|
|
22576
|
+
if (maxc == rgb.x) h = mod((rgb.y - rgb.z) / d, 6.0);
|
|
22577
|
+
else if (maxc == rgb.y) h = (rgb.z - rgb.x) / d + 2.0;
|
|
22578
|
+
else h = (rgb.x - rgb.y) / d + 4.0;
|
|
22579
|
+
h *= 60.0;
|
|
22580
|
+
if (h < 0.0) h += 360.0;
|
|
22581
|
+
return vec3(h, s, l);
|
|
22582
|
+
}
|
|
22583
|
+
|
|
22584
|
+
// HSV conversion. Hue in degrees, saturation/value in 0-1.
|
|
22585
|
+
vec3 _gpu_hsv_to_rgb(vec3 hsv) {
|
|
22586
|
+
float h = hsv.x;
|
|
22587
|
+
float s = hsv.y;
|
|
22588
|
+
float v = hsv.z;
|
|
22589
|
+
float c = v * s;
|
|
22590
|
+
float h6 = h / 60.0;
|
|
22591
|
+
float x = c * (1.0 - abs(mod(h6, 2.0) - 1.0));
|
|
22592
|
+
float r = 0.0;
|
|
22593
|
+
float g = 0.0;
|
|
22594
|
+
float b = 0.0;
|
|
22595
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
22596
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
22597
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
22598
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
22599
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
22600
|
+
else { r = c; g = 0.0; b = x; }
|
|
22601
|
+
float m = v - c;
|
|
22602
|
+
return vec3(r + m, g + m, b + m);
|
|
22603
|
+
}
|
|
22604
|
+
|
|
22605
|
+
vec3 _gpu_rgb_to_hsv(vec3 rgb) {
|
|
22606
|
+
float maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
22607
|
+
float minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
22608
|
+
float v = maxc;
|
|
22609
|
+
float d = maxc - minc;
|
|
22610
|
+
if (d < 1e-6) return vec3(0.0, 0.0, v);
|
|
22611
|
+
float s = (maxc < 1e-6) ? 0.0 : d / maxc;
|
|
22612
|
+
float h;
|
|
22613
|
+
if (maxc == rgb.x) h = mod((rgb.y - rgb.z) / d, 6.0);
|
|
22614
|
+
else if (maxc == rgb.y) h = (rgb.z - rgb.x) / d + 2.0;
|
|
22615
|
+
else h = (rgb.x - rgb.y) / d + 4.0;
|
|
22616
|
+
h *= 60.0;
|
|
22617
|
+
if (h < 0.0) h += 360.0;
|
|
22618
|
+
return vec3(h, s, v);
|
|
22619
|
+
}
|
|
22620
|
+
|
|
22621
|
+
vec3 _gpu_color_mix(vec3 lch1, vec3 lch2, float t) {
|
|
22519
22622
|
float L = mix(lch1.x, lch2.x, t);
|
|
22520
22623
|
float C = mix(lch1.y, lch2.y, t);
|
|
22521
|
-
|
|
22522
|
-
|
|
22523
|
-
|
|
22524
|
-
if (
|
|
22525
|
-
|
|
22526
|
-
|
|
22624
|
+
bool a1 = lch1.y < 1e-6;
|
|
22625
|
+
bool a2 = lch2.y < 1e-6;
|
|
22626
|
+
float H;
|
|
22627
|
+
if (a1 && a2) {
|
|
22628
|
+
H = lch1.z;
|
|
22629
|
+
} else if (a1) {
|
|
22630
|
+
H = lch2.z;
|
|
22631
|
+
} else if (a2) {
|
|
22632
|
+
H = lch1.z;
|
|
22633
|
+
} else {
|
|
22634
|
+
float dh = lch2.z - lch1.z;
|
|
22635
|
+
if (dh > 180.0) dh -= 360.0;
|
|
22636
|
+
if (dh < -180.0) dh += 360.0;
|
|
22637
|
+
H = lch1.z + dh * t;
|
|
22638
|
+
if (H < 0.0) H += 360.0;
|
|
22639
|
+
if (H >= 360.0) H -= 360.0;
|
|
22640
|
+
}
|
|
22641
|
+
return vec3(L, C, H);
|
|
22527
22642
|
}
|
|
22528
22643
|
|
|
22529
|
-
float _gpu_apca(vec3
|
|
22644
|
+
float _gpu_apca(vec3 lch_bg, vec3 lch_fg) {
|
|
22645
|
+
vec3 bg = _gpu_oklch_to_srgb(lch_bg);
|
|
22646
|
+
vec3 fg = _gpu_oklch_to_srgb(lch_fg);
|
|
22530
22647
|
float bgR = _gpu_srgb_to_linear(bg.x);
|
|
22531
22648
|
float bgG = _gpu_srgb_to_linear(bg.y);
|
|
22532
22649
|
float bgB = _gpu_srgb_to_linear(bg.z);
|
|
@@ -22537,9 +22654,7 @@ float _gpu_apca(vec3 bg, vec3 fg) {
|
|
|
22537
22654
|
float fgY = 0.2126729 * fgR + 0.7151522 * fgG + 0.0721750 * fgB;
|
|
22538
22655
|
float bgC = pow(bgY, 0.56);
|
|
22539
22656
|
float fgC = pow(fgY, 0.57);
|
|
22540
|
-
float contrast = (bgC
|
|
22541
|
-
? (bgC - fgC) * 1.14
|
|
22542
|
-
: (bgC - fgC) * 1.14;
|
|
22657
|
+
float contrast = (bgC - fgC) * 1.14;
|
|
22543
22658
|
return contrast * 100.0;
|
|
22544
22659
|
}
|
|
22545
22660
|
`;
|
|
@@ -22583,28 +22698,133 @@ fn _gpu_oklab_to_srgb(lab: vec3f) -> vec3f {
|
|
|
22583
22698
|
|
|
22584
22699
|
fn _gpu_oklab_to_oklch(lab: vec3f) -> vec3f {
|
|
22585
22700
|
let C = length(lab.yz);
|
|
22586
|
-
|
|
22701
|
+
var H = atan2(lab.z, lab.y) * (180.0 / 3.14159265359);
|
|
22702
|
+
if (H < 0.0) { H = H + 360.0; }
|
|
22587
22703
|
return vec3f(lab.x, C, H);
|
|
22588
22704
|
}
|
|
22589
22705
|
|
|
22590
22706
|
fn _gpu_oklch_to_oklab(lch: vec3f) -> vec3f {
|
|
22591
|
-
|
|
22707
|
+
let h_rad = lch.z * (3.14159265359 / 180.0);
|
|
22708
|
+
return vec3f(lch.x, lch.y * cos(h_rad), lch.y * sin(h_rad));
|
|
22709
|
+
}
|
|
22710
|
+
|
|
22711
|
+
fn _gpu_srgb_to_oklch(rgb: vec3f) -> vec3f {
|
|
22712
|
+
return _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb));
|
|
22713
|
+
}
|
|
22714
|
+
|
|
22715
|
+
fn _gpu_oklch_to_srgb(lch: vec3f) -> vec3f {
|
|
22716
|
+
return _gpu_oklab_to_srgb(_gpu_oklch_to_oklab(lch));
|
|
22717
|
+
}
|
|
22718
|
+
|
|
22719
|
+
fn _gpu_hsl_to_rgb(hsl: vec3f) -> vec3f {
|
|
22720
|
+
let h = hsl.x;
|
|
22721
|
+
let s = hsl.y;
|
|
22722
|
+
let l = hsl.z;
|
|
22723
|
+
let c = (1.0 - abs(2.0 * l - 1.0)) * s;
|
|
22724
|
+
let h6 = h / 60.0;
|
|
22725
|
+
let x = c * (1.0 - abs((h6 - 2.0 * floor(h6 / 2.0)) - 1.0));
|
|
22726
|
+
var r: f32 = 0.0;
|
|
22727
|
+
var g: f32 = 0.0;
|
|
22728
|
+
var b: f32 = 0.0;
|
|
22729
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
22730
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
22731
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
22732
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
22733
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
22734
|
+
else { r = c; g = 0.0; b = x; }
|
|
22735
|
+
let m = l - c / 2.0;
|
|
22736
|
+
return vec3f(r + m, g + m, b + m);
|
|
22737
|
+
}
|
|
22738
|
+
|
|
22739
|
+
fn _gpu_rgb_to_hsl(rgb: vec3f) -> vec3f {
|
|
22740
|
+
let maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
22741
|
+
let minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
22742
|
+
let l = (maxc + minc) / 2.0;
|
|
22743
|
+
let d = maxc - minc;
|
|
22744
|
+
if (d < 1e-6) { return vec3f(0.0, 0.0, l); }
|
|
22745
|
+
let s = d / (1.0 - abs(2.0 * l - 1.0));
|
|
22746
|
+
var h: f32;
|
|
22747
|
+
if (maxc == rgb.x) {
|
|
22748
|
+
let v = (rgb.y - rgb.z) / d;
|
|
22749
|
+
h = v - 6.0 * floor(v / 6.0);
|
|
22750
|
+
} else if (maxc == rgb.y) {
|
|
22751
|
+
h = (rgb.z - rgb.x) / d + 2.0;
|
|
22752
|
+
} else {
|
|
22753
|
+
h = (rgb.x - rgb.y) / d + 4.0;
|
|
22754
|
+
}
|
|
22755
|
+
h = h * 60.0;
|
|
22756
|
+
if (h < 0.0) { h = h + 360.0; }
|
|
22757
|
+
return vec3f(h, s, l);
|
|
22758
|
+
}
|
|
22759
|
+
|
|
22760
|
+
fn _gpu_hsv_to_rgb(hsv: vec3f) -> vec3f {
|
|
22761
|
+
let h = hsv.x;
|
|
22762
|
+
let s = hsv.y;
|
|
22763
|
+
let v = hsv.z;
|
|
22764
|
+
let c = v * s;
|
|
22765
|
+
let h6 = h / 60.0;
|
|
22766
|
+
let x = c * (1.0 - abs((h6 - 2.0 * floor(h6 / 2.0)) - 1.0));
|
|
22767
|
+
var r: f32 = 0.0;
|
|
22768
|
+
var g: f32 = 0.0;
|
|
22769
|
+
var b: f32 = 0.0;
|
|
22770
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
22771
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
22772
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
22773
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
22774
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
22775
|
+
else { r = c; g = 0.0; b = x; }
|
|
22776
|
+
let m = v - c;
|
|
22777
|
+
return vec3f(r + m, g + m, b + m);
|
|
22778
|
+
}
|
|
22779
|
+
|
|
22780
|
+
fn _gpu_rgb_to_hsv(rgb: vec3f) -> vec3f {
|
|
22781
|
+
let maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
22782
|
+
let minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
22783
|
+
let v = maxc;
|
|
22784
|
+
let d = maxc - minc;
|
|
22785
|
+
if (d < 1e-6) { return vec3f(0.0, 0.0, v); }
|
|
22786
|
+
var s: f32 = 0.0;
|
|
22787
|
+
if (maxc >= 1e-6) { s = d / maxc; }
|
|
22788
|
+
var h: f32;
|
|
22789
|
+
if (maxc == rgb.x) {
|
|
22790
|
+
let q = (rgb.y - rgb.z) / d;
|
|
22791
|
+
h = q - 6.0 * floor(q / 6.0);
|
|
22792
|
+
} else if (maxc == rgb.y) {
|
|
22793
|
+
h = (rgb.z - rgb.x) / d + 2.0;
|
|
22794
|
+
} else {
|
|
22795
|
+
h = (rgb.x - rgb.y) / d + 4.0;
|
|
22796
|
+
}
|
|
22797
|
+
h = h * 60.0;
|
|
22798
|
+
if (h < 0.0) { h = h + 360.0; }
|
|
22799
|
+
return vec3f(h, s, v);
|
|
22592
22800
|
}
|
|
22593
22801
|
|
|
22594
|
-
fn _gpu_color_mix(
|
|
22595
|
-
let lch1 = _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb1));
|
|
22596
|
-
let lch2 = _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb2));
|
|
22802
|
+
fn _gpu_color_mix(lch1: vec3f, lch2: vec3f, t: f32) -> vec3f {
|
|
22597
22803
|
let L = mix(lch1.x, lch2.x, t);
|
|
22598
22804
|
let C = mix(lch1.y, lch2.y, t);
|
|
22599
|
-
let
|
|
22600
|
-
|
|
22601
|
-
|
|
22602
|
-
if (
|
|
22603
|
-
|
|
22604
|
-
|
|
22805
|
+
let a1 = lch1.y < 1e-6;
|
|
22806
|
+
let a2 = lch2.y < 1e-6;
|
|
22807
|
+
var H: f32;
|
|
22808
|
+
if (a1 && a2) {
|
|
22809
|
+
H = lch1.z;
|
|
22810
|
+
} else if (a1) {
|
|
22811
|
+
H = lch2.z;
|
|
22812
|
+
} else if (a2) {
|
|
22813
|
+
H = lch1.z;
|
|
22814
|
+
} else {
|
|
22815
|
+
var dh = lch2.z - lch1.z;
|
|
22816
|
+
if (dh > 180.0) { dh = dh - 360.0; }
|
|
22817
|
+
if (dh < -180.0) { dh = dh + 360.0; }
|
|
22818
|
+
H = lch1.z + dh * t;
|
|
22819
|
+
if (H < 0.0) { H = H + 360.0; }
|
|
22820
|
+
if (H >= 360.0) { H = H - 360.0; }
|
|
22821
|
+
}
|
|
22822
|
+
return vec3f(L, C, H);
|
|
22605
22823
|
}
|
|
22606
22824
|
|
|
22607
|
-
fn _gpu_apca(
|
|
22825
|
+
fn _gpu_apca(lch_bg: vec3f, lch_fg: vec3f) -> f32 {
|
|
22826
|
+
let bg = _gpu_oklch_to_srgb(lch_bg);
|
|
22827
|
+
let fg = _gpu_oklch_to_srgb(lch_fg);
|
|
22608
22828
|
let bgR = _gpu_srgb_to_linear(bg.x);
|
|
22609
22829
|
let bgG = _gpu_srgb_to_linear(bg.y);
|
|
22610
22830
|
let bgB = _gpu_srgb_to_linear(bg.z);
|
|
@@ -22892,7 +23112,7 @@ var GPUShaderTarget = class {
|
|
|
22892
23112
|
if (stmts.length === 0) return "";
|
|
22893
23113
|
const last = stmts.length - 1;
|
|
22894
23114
|
stmts[last] = `return ${stmts[last]}`;
|
|
22895
|
-
return stmts.join(";\n");
|
|
23115
|
+
return stmts.join(";\n") + ";";
|
|
22896
23116
|
},
|
|
22897
23117
|
...options
|
|
22898
23118
|
};
|
|
@@ -22903,7 +23123,6 @@ var GPUShaderTarget = class {
|
|
|
22903
23123
|
const constants = this.getConstants();
|
|
22904
23124
|
const v2 = this.languageId === "wgsl" ? "vec2f" : "vec2";
|
|
22905
23125
|
const target = this.createTarget({
|
|
22906
|
-
hints: options.hints,
|
|
22907
23126
|
functions: (id) => {
|
|
22908
23127
|
if (userFunctions && id in userFunctions) {
|
|
22909
23128
|
const fn = userFunctions[id];
|
|
@@ -22942,89 +23161,12 @@ var GPUShaderTarget = class {
|
|
|
22942
23161
|
if (code.includes("_gpu_besselJ"))
|
|
22943
23162
|
preamble += this.languageId === "wgsl" ? GPU_BESSELJ_PREAMBLE_WGSL : GPU_BESSELJ_PREAMBLE_GLSL;
|
|
22944
23163
|
if (code.includes("_fractal_")) {
|
|
22945
|
-
|
|
22946
|
-
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
22947
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PT_PREAMBLE_WGSL : GPU_FRACTAL_PT_PREAMBLE_GLSL;
|
|
22948
|
-
} else if (code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) {
|
|
22949
|
-
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
22950
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_DP_PREAMBLE_WGSL : GPU_FRACTAL_DP_PREAMBLE_GLSL;
|
|
22951
|
-
} else {
|
|
22952
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
22953
|
-
}
|
|
23164
|
+
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
22954
23165
|
}
|
|
22955
23166
|
if (code.includes("_gpu_srgb_to") || code.includes("_gpu_oklab") || code.includes("_gpu_oklch") || code.includes("_gpu_color_mix") || code.includes("_gpu_apca")) {
|
|
22956
23167
|
preamble += this.languageId === "wgsl" ? GPU_COLOR_PREAMBLE_WGSL : GPU_COLOR_PREAMBLE_GLSL;
|
|
22957
23168
|
}
|
|
22958
23169
|
if (preamble) result.preamble = preamble;
|
|
22959
|
-
if (code.includes("_fractal_") && options.hints?.viewport) {
|
|
22960
|
-
const strategy = selectFractalStrategy(target);
|
|
22961
|
-
const radius = options.hints.viewport.radius;
|
|
22962
|
-
switch (strategy) {
|
|
22963
|
-
case "single":
|
|
22964
|
-
result.staleWhen = { radiusBelow: 1e-6 };
|
|
22965
|
-
break;
|
|
22966
|
-
case "double":
|
|
22967
|
-
result.staleWhen = { radiusBelow: 1e-14, radiusAbove: 1e-5 };
|
|
22968
|
-
break;
|
|
22969
|
-
case "perturbation":
|
|
22970
|
-
result.staleWhen = {
|
|
22971
|
-
radiusAbove: 1e-5,
|
|
22972
|
-
radiusBelow: radius * 0.01,
|
|
22973
|
-
centerDistance: radius * 2
|
|
22974
|
-
};
|
|
22975
|
-
break;
|
|
22976
|
-
}
|
|
22977
|
-
}
|
|
22978
|
-
if ((code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) && options.hints?.viewport) {
|
|
22979
|
-
const cx = hpToNumber(options.hints.viewport.center[0]);
|
|
22980
|
-
const cy = hpToNumber(options.hints.viewport.center[1]);
|
|
22981
|
-
const size = options.hints.viewport.radius * 2;
|
|
22982
|
-
const cx_hi = Math.fround(cx);
|
|
22983
|
-
const cy_hi = Math.fround(cy);
|
|
22984
|
-
result.uniforms = {
|
|
22985
|
-
...result.uniforms,
|
|
22986
|
-
_dp_cx_hi: cx_hi,
|
|
22987
|
-
_dp_cx_lo: cx - cx_hi,
|
|
22988
|
-
_dp_cy_hi: cy_hi,
|
|
22989
|
-
_dp_cy_lo: cy - cy_hi,
|
|
22990
|
-
_dp_w: size,
|
|
22991
|
-
_dp_h: size
|
|
22992
|
-
};
|
|
22993
|
-
}
|
|
22994
|
-
if ((code.includes("_fractal_mandelbrot_pt") || code.includes("_fractal_julia_pt")) && options.hints?.viewport) {
|
|
22995
|
-
const viewport = options.hints.viewport;
|
|
22996
|
-
const size = viewport.radius * 2;
|
|
22997
|
-
result.uniforms = {
|
|
22998
|
-
...result.uniforms,
|
|
22999
|
-
_pt_offset_x: 0,
|
|
23000
|
-
_pt_offset_y: 0,
|
|
23001
|
-
_pt_w: size,
|
|
23002
|
-
_pt_h: size
|
|
23003
|
-
};
|
|
23004
|
-
const digits = Math.max(50, Math.ceil(-Math.log10(viewport.radius)) + 10);
|
|
23005
|
-
const maxIter = 1e3;
|
|
23006
|
-
const orbit = computeReferenceOrbit(
|
|
23007
|
-
viewport.center,
|
|
23008
|
-
maxIter,
|
|
23009
|
-
digits
|
|
23010
|
-
);
|
|
23011
|
-
const orbitLen = orbit.length / 2;
|
|
23012
|
-
const texWidth = Math.min(orbitLen, 4096);
|
|
23013
|
-
const texHeight = Math.ceil(orbitLen / texWidth);
|
|
23014
|
-
result.textures = {
|
|
23015
|
-
_refOrbit: {
|
|
23016
|
-
data: orbit,
|
|
23017
|
-
width: texWidth,
|
|
23018
|
-
height: texHeight,
|
|
23019
|
-
format: "rg32f"
|
|
23020
|
-
}
|
|
23021
|
-
};
|
|
23022
|
-
result.uniforms = {
|
|
23023
|
-
...result.uniforms,
|
|
23024
|
-
_refOrbitLen: orbitLen,
|
|
23025
|
-
_refOrbitTexWidth: texWidth
|
|
23026
|
-
};
|
|
23027
|
-
}
|
|
23028
23170
|
return result;
|
|
23029
23171
|
}
|
|
23030
23172
|
compileToSource(expr, _options = {}) {
|
|
@@ -23069,7 +23211,7 @@ var GLSLTarget = class extends GPUShaderTarget {
|
|
|
23069
23211
|
if (body.includes("\n")) {
|
|
23070
23212
|
const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
|
|
23071
23213
|
return `${returnType} ${functionName}(${params}) {
|
|
23072
|
-
${indented}
|
|
23214
|
+
${indented}
|
|
23073
23215
|
}`;
|
|
23074
23216
|
}
|
|
23075
23217
|
return `${returnType} ${functionName}(${params}) {
|
|
@@ -23180,7 +23322,7 @@ var WGSLTarget = class extends GPUShaderTarget {
|
|
|
23180
23322
|
return `fn ${functionName}(${params}) -> ${toWGSLType(
|
|
23181
23323
|
returnType
|
|
23182
23324
|
)} {
|
|
23183
|
-
${indented}
|
|
23325
|
+
${indented}
|
|
23184
23326
|
}`;
|
|
23185
23327
|
}
|
|
23186
23328
|
return `fn ${functionName}(${params}) -> ${toWGSLType(returnType)} {
|
|
@@ -25359,7 +25501,7 @@ function compileToIntervalTarget(expr, target) {
|
|
|
25359
25501
|
}
|
|
25360
25502
|
|
|
25361
25503
|
// src/compile.ts
|
|
25362
|
-
var version = "0.
|
|
25504
|
+
var version = "0.56.0";
|
|
25363
25505
|
export {
|
|
25364
25506
|
BaseCompiler,
|
|
25365
25507
|
GLSLTarget,
|