@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.umd.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Compile 0.
|
|
1
|
+
/** Compile 0.56.0 */
|
|
2
2
|
(function(global,factory){typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'],factory):(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Compile = {}));})(this, (function (exports) { 'use strict';
|
|
3
3
|
var Compile = (() => {
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1544,6 +1544,7 @@ var Compile = (() => {
|
|
|
1544
1544
|
];
|
|
1545
1545
|
var VALUE_TYPES = [
|
|
1546
1546
|
"value",
|
|
1547
|
+
"color",
|
|
1547
1548
|
...COLLECTION_TYPES,
|
|
1548
1549
|
...SCALAR_TYPES
|
|
1549
1550
|
];
|
|
@@ -3239,6 +3240,7 @@ var Compile = (() => {
|
|
|
3239
3240
|
symbol: [],
|
|
3240
3241
|
boolean: [],
|
|
3241
3242
|
string: [],
|
|
3243
|
+
color: [],
|
|
3242
3244
|
expression: EXPRESSION_TYPES
|
|
3243
3245
|
};
|
|
3244
3246
|
function isPrimitiveSubtype(lhs, rhs) {
|
|
@@ -6273,10 +6275,6 @@ var Compile = (() => {
|
|
|
6273
6275
|
// Lagrange notation
|
|
6274
6276
|
{
|
|
6275
6277
|
name: "Derivative",
|
|
6276
|
-
// @todo: Leibniz notation: {% latex " \\frac{d^n}{dx^n} f(x)" %}
|
|
6277
|
-
// @todo: Euler modified notation: This notation is used by Mathematica. The Euler notation uses `D` instead of
|
|
6278
|
-
// `\partial`: `\partial_{x} f`, `\partial_{x,y} f`
|
|
6279
|
-
// Newton notation (\dot{v}, \ddot{v}) is implemented below
|
|
6280
6278
|
serialize: (serializer, expr) => {
|
|
6281
6279
|
const degree = machineValue(operand(expr, 2)) ?? 1;
|
|
6282
6280
|
const base = serializer.serialize(operand(expr, 1));
|
|
@@ -7314,14 +7312,18 @@ var Compile = (() => {
|
|
|
7314
7312
|
return ["Complement", lhs];
|
|
7315
7313
|
}
|
|
7316
7314
|
// precedence: 240,
|
|
7317
|
-
// @todo: serialize for the multiple argument case
|
|
7318
7315
|
},
|
|
7319
7316
|
{
|
|
7320
7317
|
name: "Complement",
|
|
7321
7318
|
latexTrigger: ["^", "<{>", "\\complement", "<}>"],
|
|
7322
|
-
kind: "postfix"
|
|
7319
|
+
kind: "postfix",
|
|
7323
7320
|
// precedence: 240,
|
|
7324
|
-
|
|
7321
|
+
serialize: (serializer, expr) => {
|
|
7322
|
+
return joinLatex([
|
|
7323
|
+
serializer.serialize(operand(expr, 1)),
|
|
7324
|
+
"^\\complement"
|
|
7325
|
+
]);
|
|
7326
|
+
}
|
|
7325
7327
|
},
|
|
7326
7328
|
{
|
|
7327
7329
|
name: "Intersection",
|
|
@@ -7408,7 +7410,6 @@ var Compile = (() => {
|
|
|
7408
7410
|
// commands like \rbrack a, b \rbrack which are unambiguous.
|
|
7409
7411
|
{
|
|
7410
7412
|
name: "Multiple",
|
|
7411
|
-
// @todo: parse
|
|
7412
7413
|
serialize: serializeSet
|
|
7413
7414
|
},
|
|
7414
7415
|
{
|
|
@@ -7417,14 +7418,28 @@ var Compile = (() => {
|
|
|
7417
7418
|
kind: "infix",
|
|
7418
7419
|
precedence: 350
|
|
7419
7420
|
},
|
|
7421
|
+
// \mid as a separator/operator (used in set-builder notation: {x \mid x > 0})
|
|
7422
|
+
// Low precedence so it binds loosely — everything on each side is parsed first
|
|
7423
|
+
{
|
|
7424
|
+
name: "Divides",
|
|
7425
|
+
latexTrigger: ["\\mid"],
|
|
7426
|
+
kind: "infix",
|
|
7427
|
+
precedence: 160
|
|
7428
|
+
},
|
|
7420
7429
|
{
|
|
7421
7430
|
name: "Set",
|
|
7422
7431
|
kind: "matchfix",
|
|
7423
7432
|
openTrigger: "{",
|
|
7424
7433
|
closeTrigger: "}",
|
|
7425
|
-
// @todo: the set syntax can also include conditions...
|
|
7426
7434
|
parse: (_parser, body) => {
|
|
7427
7435
|
if (isEmptySequence(body)) return "EmptySet";
|
|
7436
|
+
const h = operator(body);
|
|
7437
|
+
if (h === "Divides" || h === "Colon") {
|
|
7438
|
+
const expr = operand(body, 1);
|
|
7439
|
+
const condition = operand(body, 2);
|
|
7440
|
+
if (expr !== null && condition !== null)
|
|
7441
|
+
return ["Set", expr, ["Condition", condition]];
|
|
7442
|
+
}
|
|
7428
7443
|
if (operator(body) == "Delimiter" && stringValue(operand(body, 2)) === ",") {
|
|
7429
7444
|
body = operand(body, 1);
|
|
7430
7445
|
}
|
|
@@ -7432,6 +7447,17 @@ var Compile = (() => {
|
|
|
7432
7447
|
return ["Set", ...operands(body)];
|
|
7433
7448
|
},
|
|
7434
7449
|
serialize: (serializer, expr) => {
|
|
7450
|
+
if (nops(expr) === 2 && operator(operand(expr, 2)) === "Condition") {
|
|
7451
|
+
const condition = operand(expr, 2);
|
|
7452
|
+
return joinLatex([
|
|
7453
|
+
"\\lbrace",
|
|
7454
|
+
serializer.serialize(operand(expr, 1)),
|
|
7455
|
+
"\\mid",
|
|
7456
|
+
// Serialize the inner expression of the Condition wrapper
|
|
7457
|
+
serializer.serialize(operand(condition, 1)),
|
|
7458
|
+
"\\rbrace"
|
|
7459
|
+
]);
|
|
7460
|
+
}
|
|
7435
7461
|
return joinLatex([
|
|
7436
7462
|
"\\lbrace",
|
|
7437
7463
|
operands(expr).map((x) => serializer.serialize(x)).join(", "),
|
|
@@ -7598,23 +7624,6 @@ var Compile = (() => {
|
|
|
7598
7624
|
if (expr === null) return "";
|
|
7599
7625
|
const h = operator(expr);
|
|
7600
7626
|
if (!h) return "";
|
|
7601
|
-
if (h === "Set") {
|
|
7602
|
-
if (nops(expr) === 0) return "\\emptyset";
|
|
7603
|
-
if (nops(expr) === 2 && operator(operand(expr, 2)) === "Condition") {
|
|
7604
|
-
return joinLatex([
|
|
7605
|
-
"\\left\\lbrace",
|
|
7606
|
-
serializer.serialize(operand(expr, 1)),
|
|
7607
|
-
"\\middle\\mid",
|
|
7608
|
-
serializer.serialize(operand(expr, 2)),
|
|
7609
|
-
"\\right\\rbrace"
|
|
7610
|
-
]);
|
|
7611
|
-
}
|
|
7612
|
-
return joinLatex([
|
|
7613
|
-
"\\left\\lbrace",
|
|
7614
|
-
...operands(expr).map((x) => serializer.serialize(x) + " ,"),
|
|
7615
|
-
"\\right\\rbrace"
|
|
7616
|
-
]);
|
|
7617
|
-
}
|
|
7618
7627
|
if (h === "Multiple") {
|
|
7619
7628
|
}
|
|
7620
7629
|
if (h === "Range") {
|
|
@@ -8732,11 +8741,13 @@ var Compile = (() => {
|
|
|
8732
8741
|
if (!parser.match("_")) return null;
|
|
8733
8742
|
const base = parser.parseGroup();
|
|
8734
8743
|
if (operator(base) !== "To") return null;
|
|
8735
|
-
const expr = parser.
|
|
8744
|
+
const expr = parser.parseExpression({
|
|
8745
|
+
minPrec: MULTIPLICATION_PRECEDENCE
|
|
8746
|
+
});
|
|
8736
8747
|
if (!expr) return null;
|
|
8737
8748
|
return [
|
|
8738
8749
|
"Limit",
|
|
8739
|
-
["Function", expr
|
|
8750
|
+
["Function", expr, operand(base, 1)],
|
|
8740
8751
|
operand(base, 2)
|
|
8741
8752
|
];
|
|
8742
8753
|
},
|
|
@@ -8817,6 +8828,8 @@ var Compile = (() => {
|
|
|
8817
8828
|
precedence: DIVISION_PRECEDENCE,
|
|
8818
8829
|
parse: "Mod"
|
|
8819
8830
|
},
|
|
8831
|
+
// Function-style alias: `\operatorname{mod}(a, b)`
|
|
8832
|
+
{ latexTrigger: "\\operatorname{mod}", parse: "Mod" },
|
|
8820
8833
|
{
|
|
8821
8834
|
latexTrigger: "\\pmod",
|
|
8822
8835
|
kind: "prefix",
|
|
@@ -9057,6 +9070,13 @@ var Compile = (() => {
|
|
|
9057
9070
|
const rhs = serializer.wrap(operand(expr, 2), ADDITION_PRECEDENCE + 3);
|
|
9058
9071
|
return joinLatex([lhs, "-", rhs]);
|
|
9059
9072
|
}
|
|
9073
|
+
},
|
|
9074
|
+
// Euclidean distance between two points (tuples of numbers).
|
|
9075
|
+
{
|
|
9076
|
+
name: "Distance",
|
|
9077
|
+
latexTrigger: ["\\operatorname{distance}"],
|
|
9078
|
+
kind: "function",
|
|
9079
|
+
serialize: (serializer, expr) => "\\operatorname{distance}" + serializer.wrapArguments(expr)
|
|
9060
9080
|
}
|
|
9061
9081
|
];
|
|
9062
9082
|
function getIndexAssignment(expr, upper) {
|
|
@@ -10481,7 +10501,9 @@ var Compile = (() => {
|
|
|
10481
10501
|
if (!expr || !symbol(expr)) return null;
|
|
10482
10502
|
return ["Mean", expr];
|
|
10483
10503
|
}
|
|
10484
|
-
}
|
|
10504
|
+
},
|
|
10505
|
+
// Function-style alias: `\operatorname{var}(...)`
|
|
10506
|
+
{ latexTrigger: "\\operatorname{var}", parse: "Variance" }
|
|
10485
10507
|
];
|
|
10486
10508
|
|
|
10487
10509
|
// src/compute-engine/numerics/unit-data.ts
|
|
@@ -10940,12 +10962,52 @@ var Compile = (() => {
|
|
|
10940
10962
|
];
|
|
10941
10963
|
|
|
10942
10964
|
// src/compute-engine/latex-syntax/dictionary/definitions-other.ts
|
|
10965
|
+
var TEX_UNITS = [
|
|
10966
|
+
"pt",
|
|
10967
|
+
"em",
|
|
10968
|
+
"mu",
|
|
10969
|
+
"ex",
|
|
10970
|
+
"mm",
|
|
10971
|
+
"cm",
|
|
10972
|
+
"in",
|
|
10973
|
+
"bp",
|
|
10974
|
+
"sp",
|
|
10975
|
+
"dd",
|
|
10976
|
+
"cc",
|
|
10977
|
+
"pc",
|
|
10978
|
+
"nc",
|
|
10979
|
+
"nd"
|
|
10980
|
+
];
|
|
10981
|
+
function skipTexDimension(parser) {
|
|
10982
|
+
parser.skipSpace();
|
|
10983
|
+
if (parser.peek === "-" || parser.peek === "+") parser.nextToken();
|
|
10984
|
+
while (/^[\d.]$/.test(parser.peek)) parser.nextToken();
|
|
10985
|
+
for (const unit of TEX_UNITS) {
|
|
10986
|
+
if (parser.matchAll([...unit])) return;
|
|
10987
|
+
}
|
|
10988
|
+
}
|
|
10943
10989
|
function parseSingleArg(cmd) {
|
|
10944
10990
|
return (parser) => {
|
|
10945
10991
|
const arg = parser.parseGroup();
|
|
10946
10992
|
return arg === null ? [cmd] : [cmd, arg];
|
|
10947
10993
|
};
|
|
10948
10994
|
}
|
|
10995
|
+
function parseMathStyleSwitch(mathStyle) {
|
|
10996
|
+
return (parser) => {
|
|
10997
|
+
const body = parser.parseExpression();
|
|
10998
|
+
if (body !== null && !isEmptySequence(body))
|
|
10999
|
+
return ["Annotated", body, { dict: { mathStyle } }];
|
|
11000
|
+
return "Nothing";
|
|
11001
|
+
};
|
|
11002
|
+
}
|
|
11003
|
+
function parseSizeSwitch(size) {
|
|
11004
|
+
return (parser) => {
|
|
11005
|
+
const body = parser.parseExpression();
|
|
11006
|
+
if (body !== null && !isEmptySequence(body))
|
|
11007
|
+
return ["Annotated", body, { dict: { size } }];
|
|
11008
|
+
return "Nothing";
|
|
11009
|
+
};
|
|
11010
|
+
}
|
|
10949
11011
|
var DEFINITIONS_OTHERS = [
|
|
10950
11012
|
{
|
|
10951
11013
|
name: "Overscript",
|
|
@@ -11185,80 +11247,71 @@ var Compile = (() => {
|
|
|
11185
11247
|
},
|
|
11186
11248
|
{
|
|
11187
11249
|
latexTrigger: ["\\displaystyle"],
|
|
11188
|
-
parse: (
|
|
11189
|
-
// @todo: parse as ['Annotated'...]
|
|
11250
|
+
parse: parseMathStyleSwitch("normal")
|
|
11190
11251
|
},
|
|
11191
11252
|
{
|
|
11192
11253
|
latexTrigger: ["\\textstyle"],
|
|
11193
|
-
parse: (
|
|
11194
|
-
// @todo: parse as ['Annotated'...]
|
|
11254
|
+
parse: parseMathStyleSwitch("compact")
|
|
11195
11255
|
},
|
|
11196
11256
|
{
|
|
11197
11257
|
latexTrigger: ["\\scriptstyle"],
|
|
11198
|
-
parse: (
|
|
11199
|
-
// @todo: parse as ['Annotated'...]
|
|
11258
|
+
parse: parseMathStyleSwitch("script")
|
|
11200
11259
|
},
|
|
11201
11260
|
{
|
|
11202
11261
|
latexTrigger: ["\\scriptscriptstyle"],
|
|
11203
|
-
parse: (
|
|
11204
|
-
// @todo: parse as ['Annotated'...]
|
|
11262
|
+
parse: parseMathStyleSwitch("scriptscript")
|
|
11205
11263
|
},
|
|
11206
11264
|
{
|
|
11207
11265
|
latexTrigger: ["\\color"],
|
|
11208
11266
|
parse: (parser) => {
|
|
11209
|
-
parser.
|
|
11267
|
+
const color = parser.parseStringGroup();
|
|
11268
|
+
if (color !== null) {
|
|
11269
|
+
const body = parser.parseExpression();
|
|
11270
|
+
if (body !== null && !isEmptySequence(body))
|
|
11271
|
+
return ["Annotated", body, { dict: { color } }];
|
|
11272
|
+
}
|
|
11210
11273
|
return "Nothing";
|
|
11211
11274
|
}
|
|
11212
11275
|
},
|
|
11213
11276
|
{
|
|
11214
11277
|
latexTrigger: ["\\tiny"],
|
|
11215
|
-
parse: ()
|
|
11216
|
-
// @todo: parse as ['Annotated'...]
|
|
11278
|
+
parse: parseSizeSwitch(1)
|
|
11217
11279
|
},
|
|
11218
11280
|
{
|
|
11219
11281
|
latexTrigger: ["\\scriptsize"],
|
|
11220
|
-
parse: ()
|
|
11221
|
-
// @todo: parse as ['Annotated'...]
|
|
11282
|
+
parse: parseSizeSwitch(2)
|
|
11222
11283
|
},
|
|
11223
11284
|
{
|
|
11224
11285
|
latexTrigger: ["\\footnotesize"],
|
|
11225
|
-
parse: ()
|
|
11226
|
-
// @todo: parse as ['Annotated'...]
|
|
11286
|
+
parse: parseSizeSwitch(3)
|
|
11227
11287
|
},
|
|
11228
11288
|
{
|
|
11229
11289
|
latexTrigger: ["\\small"],
|
|
11230
|
-
parse: ()
|
|
11231
|
-
// @todo: parse as ['Annotated'...]
|
|
11290
|
+
parse: parseSizeSwitch(4)
|
|
11232
11291
|
},
|
|
11233
11292
|
{
|
|
11234
11293
|
latexTrigger: ["\\normalsize"],
|
|
11235
|
-
parse: ()
|
|
11236
|
-
// @todo: parse as ['Annotated'...]
|
|
11294
|
+
parse: parseSizeSwitch(5)
|
|
11237
11295
|
},
|
|
11238
11296
|
{
|
|
11239
11297
|
latexTrigger: ["\\large"],
|
|
11240
|
-
parse: ()
|
|
11241
|
-
// @todo: parse as ['Annotated'...]
|
|
11298
|
+
parse: parseSizeSwitch(6)
|
|
11242
11299
|
},
|
|
11243
11300
|
{
|
|
11244
11301
|
latexTrigger: ["\\Large"],
|
|
11245
|
-
parse: ()
|
|
11246
|
-
// @todo: parse as ['Annotated'...]
|
|
11302
|
+
parse: parseSizeSwitch(7)
|
|
11247
11303
|
},
|
|
11248
11304
|
{
|
|
11249
11305
|
latexTrigger: ["\\LARGE"],
|
|
11250
|
-
parse: ()
|
|
11251
|
-
// @todo: parse as ['Annotated'...]
|
|
11306
|
+
parse: parseSizeSwitch(8)
|
|
11252
11307
|
},
|
|
11253
11308
|
{
|
|
11254
11309
|
latexTrigger: ["\\huge"],
|
|
11255
|
-
parse: ()
|
|
11256
|
-
// @todo: parse as ['Annotated'...]
|
|
11310
|
+
parse: parseSizeSwitch(9)
|
|
11257
11311
|
},
|
|
11258
11312
|
{
|
|
11259
11313
|
latexTrigger: ["\\Huge"],
|
|
11260
|
-
parse: ()
|
|
11261
|
-
// @todo: parse as ['Annotated'...]
|
|
11314
|
+
parse: parseSizeSwitch(10)
|
|
11262
11315
|
},
|
|
11263
11316
|
{
|
|
11264
11317
|
name: "Annotated",
|
|
@@ -11270,6 +11323,10 @@ var Compile = (() => {
|
|
|
11270
11323
|
result = joinLatex(["{\\displaystyle", result, "}"]);
|
|
11271
11324
|
else if (dict.dict.mathStyle === "compact")
|
|
11272
11325
|
result = joinLatex(["{\\textstyle", result, "}"]);
|
|
11326
|
+
else if (dict.dict.mathStyle === "script")
|
|
11327
|
+
result = joinLatex(["{\\scriptstyle", result, "}"]);
|
|
11328
|
+
else if (dict.dict.mathStyle === "scriptscript")
|
|
11329
|
+
result = joinLatex(["{\\scriptscriptstyle", result, "}"]);
|
|
11273
11330
|
const v = dict.dict.size;
|
|
11274
11331
|
if (v !== null && v >= 1 && v <= 10) {
|
|
11275
11332
|
result = joinLatex([
|
|
@@ -11357,6 +11414,28 @@ var Compile = (() => {
|
|
|
11357
11414
|
latexTrigger: ["\\enspace"],
|
|
11358
11415
|
parse: () => ["HorizontalSpacing", 9]
|
|
11359
11416
|
},
|
|
11417
|
+
{
|
|
11418
|
+
latexTrigger: ["\\hspace"],
|
|
11419
|
+
parse: (parser) => {
|
|
11420
|
+
if (parser.peek === "*") parser.nextToken();
|
|
11421
|
+
parser.parseStringGroup();
|
|
11422
|
+
return ["HorizontalSpacing", 0];
|
|
11423
|
+
}
|
|
11424
|
+
},
|
|
11425
|
+
{
|
|
11426
|
+
latexTrigger: ["\\hskip"],
|
|
11427
|
+
parse: (parser) => {
|
|
11428
|
+
skipTexDimension(parser);
|
|
11429
|
+
return ["HorizontalSpacing", 0];
|
|
11430
|
+
}
|
|
11431
|
+
},
|
|
11432
|
+
{
|
|
11433
|
+
latexTrigger: ["\\kern"],
|
|
11434
|
+
parse: (parser) => {
|
|
11435
|
+
skipTexDimension(parser);
|
|
11436
|
+
return ["HorizontalSpacing", 0];
|
|
11437
|
+
}
|
|
11438
|
+
},
|
|
11360
11439
|
{
|
|
11361
11440
|
latexTrigger: ["\\phantom"],
|
|
11362
11441
|
parse: (parser) => {
|
|
@@ -11407,7 +11486,17 @@ var Compile = (() => {
|
|
|
11407
11486
|
// `["HorizontalSpacing", expr, 'op'|'bin'|rel]` -> indicate a spacing around and expression, i.e. `\mathbin{x}`, etc...
|
|
11408
11487
|
serialize: (serializer, expr) => {
|
|
11409
11488
|
if (operand(expr, 2) !== null) {
|
|
11410
|
-
|
|
11489
|
+
const cls = stringValue(operand(expr, 2));
|
|
11490
|
+
const inner = serializer.serialize(operand(expr, 1));
|
|
11491
|
+
if (cls === "bin") return `\\mathbin{${inner}}`;
|
|
11492
|
+
if (cls === "op") return `\\mathop{${inner}}`;
|
|
11493
|
+
if (cls === "rel") return `\\mathrel{${inner}}`;
|
|
11494
|
+
if (cls === "ord") return `\\mathord{${inner}}`;
|
|
11495
|
+
if (cls === "open") return `\\mathopen{${inner}}`;
|
|
11496
|
+
if (cls === "close") return `\\mathclose{${inner}}`;
|
|
11497
|
+
if (cls === "punct") return `\\mathpunct{${inner}}`;
|
|
11498
|
+
if (cls === "inner") return `\\mathinner{${inner}}`;
|
|
11499
|
+
return inner;
|
|
11411
11500
|
}
|
|
11412
11501
|
const v = machineValue(operand(expr, 1));
|
|
11413
11502
|
if (v === null) return "";
|
|
@@ -11422,7 +11511,7 @@ var Compile = (() => {
|
|
|
11422
11511
|
36: "\\qquad"
|
|
11423
11512
|
}[v] ?? "";
|
|
11424
11513
|
}
|
|
11425
|
-
}
|
|
11514
|
+
},
|
|
11426
11515
|
// if (
|
|
11427
11516
|
// [
|
|
11428
11517
|
// '\\!',
|
|
@@ -11446,6 +11535,121 @@ var Compile = (() => {
|
|
|
11446
11535
|
// name: '',
|
|
11447
11536
|
// trigger: '\\check',
|
|
11448
11537
|
// },
|
|
11538
|
+
// ---------------------------------------------------------------------------
|
|
11539
|
+
// Function-style aliases for collection / random operators that some
|
|
11540
|
+
// notations write in lowercase (e.g. `\operatorname{shuffle}(L)`).
|
|
11541
|
+
// The capitalized library entries already exist; these are pure parse
|
|
11542
|
+
// aliases so the lowercase names don't land in `unsupported-operator`.
|
|
11543
|
+
// ---------------------------------------------------------------------------
|
|
11544
|
+
{ latexTrigger: "\\operatorname{random}", parse: "Random" },
|
|
11545
|
+
{ latexTrigger: "\\operatorname{shuffle}", parse: "Shuffle" },
|
|
11546
|
+
{ latexTrigger: "\\operatorname{repeat}", parse: "Repeat" },
|
|
11547
|
+
{ latexTrigger: "\\operatorname{join}", parse: "Join" },
|
|
11548
|
+
// ---------------------------------------------------------------------------
|
|
11549
|
+
// Geometric primitive heads. Registered as known typed heads so consumers
|
|
11550
|
+
// can branch on the operator name; CE itself doesn't render them. The
|
|
11551
|
+
// library entries (with no evaluator) live in `library/core.ts`.
|
|
11552
|
+
// ---------------------------------------------------------------------------
|
|
11553
|
+
{
|
|
11554
|
+
name: "Triangle",
|
|
11555
|
+
latexTrigger: ["\\operatorname{triangle}"],
|
|
11556
|
+
kind: "function",
|
|
11557
|
+
serialize: (serializer, expr) => "\\operatorname{triangle}" + serializer.wrapArguments(expr)
|
|
11558
|
+
},
|
|
11559
|
+
// Desmos's geometric `vector(p1, p2)` — a directed segment between two
|
|
11560
|
+
// points. Routed to a dedicated head (not the existing column-vector
|
|
11561
|
+
// `Vector`, which has a narrower `(number+) -> vector` signature).
|
|
11562
|
+
{
|
|
11563
|
+
name: "GeometricVector",
|
|
11564
|
+
latexTrigger: ["\\operatorname{vector}"],
|
|
11565
|
+
kind: "function",
|
|
11566
|
+
serialize: (serializer, expr) => "\\operatorname{vector}" + serializer.wrapArguments(expr)
|
|
11567
|
+
},
|
|
11568
|
+
{
|
|
11569
|
+
name: "Sphere",
|
|
11570
|
+
latexTrigger: ["\\operatorname{sphere}"],
|
|
11571
|
+
kind: "function",
|
|
11572
|
+
serialize: (serializer, expr) => "\\operatorname{sphere}" + serializer.wrapArguments(expr)
|
|
11573
|
+
},
|
|
11574
|
+
{
|
|
11575
|
+
name: "Segment",
|
|
11576
|
+
latexTrigger: ["\\operatorname{segment}"],
|
|
11577
|
+
kind: "function",
|
|
11578
|
+
serialize: (serializer, expr) => "\\operatorname{segment}" + serializer.wrapArguments(expr)
|
|
11579
|
+
}
|
|
11580
|
+
];
|
|
11581
|
+
|
|
11582
|
+
// src/compute-engine/latex-syntax/dictionary/definitions-colors.ts
|
|
11583
|
+
var DEFINITIONS_COLORS = [
|
|
11584
|
+
// Color constructors (one per colorspace, preserves space on evaluation)
|
|
11585
|
+
{
|
|
11586
|
+
name: "Rgb",
|
|
11587
|
+
latexTrigger: ["\\operatorname{rgb}"],
|
|
11588
|
+
kind: "function",
|
|
11589
|
+
serialize: (serializer, expr) => "\\operatorname{rgb}" + serializer.wrapArguments(expr)
|
|
11590
|
+
},
|
|
11591
|
+
{
|
|
11592
|
+
name: "Hsv",
|
|
11593
|
+
latexTrigger: ["\\operatorname{hsv}"],
|
|
11594
|
+
kind: "function",
|
|
11595
|
+
serialize: (serializer, expr) => "\\operatorname{hsv}" + serializer.wrapArguments(expr)
|
|
11596
|
+
},
|
|
11597
|
+
{
|
|
11598
|
+
name: "Hsl",
|
|
11599
|
+
latexTrigger: ["\\operatorname{hsl}"],
|
|
11600
|
+
kind: "function",
|
|
11601
|
+
serialize: (serializer, expr) => "\\operatorname{hsl}" + serializer.wrapArguments(expr)
|
|
11602
|
+
},
|
|
11603
|
+
{
|
|
11604
|
+
name: "Oklab",
|
|
11605
|
+
latexTrigger: ["\\operatorname{oklab}"],
|
|
11606
|
+
kind: "function",
|
|
11607
|
+
serialize: (serializer, expr) => "\\operatorname{oklab}" + serializer.wrapArguments(expr)
|
|
11608
|
+
},
|
|
11609
|
+
{
|
|
11610
|
+
name: "Oklch",
|
|
11611
|
+
latexTrigger: ["\\operatorname{oklch}"],
|
|
11612
|
+
kind: "function",
|
|
11613
|
+
serialize: (serializer, expr) => "\\operatorname{oklch}" + serializer.wrapArguments(expr)
|
|
11614
|
+
},
|
|
11615
|
+
// Conversion functions (color → color in the named space)
|
|
11616
|
+
{
|
|
11617
|
+
name: "AsRgb",
|
|
11618
|
+
latexTrigger: ["\\operatorname{asRgb}"],
|
|
11619
|
+
kind: "function",
|
|
11620
|
+
serialize: (serializer, expr) => "\\operatorname{asRgb}" + serializer.wrapArguments(expr)
|
|
11621
|
+
},
|
|
11622
|
+
{
|
|
11623
|
+
name: "AsHsv",
|
|
11624
|
+
latexTrigger: ["\\operatorname{asHsv}"],
|
|
11625
|
+
kind: "function",
|
|
11626
|
+
serialize: (serializer, expr) => "\\operatorname{asHsv}" + serializer.wrapArguments(expr)
|
|
11627
|
+
},
|
|
11628
|
+
{
|
|
11629
|
+
name: "AsHsl",
|
|
11630
|
+
latexTrigger: ["\\operatorname{asHsl}"],
|
|
11631
|
+
kind: "function",
|
|
11632
|
+
serialize: (serializer, expr) => "\\operatorname{asHsl}" + serializer.wrapArguments(expr)
|
|
11633
|
+
},
|
|
11634
|
+
{
|
|
11635
|
+
name: "AsOklab",
|
|
11636
|
+
latexTrigger: ["\\operatorname{asOklab}"],
|
|
11637
|
+
kind: "function",
|
|
11638
|
+
serialize: (serializer, expr) => "\\operatorname{asOklab}" + serializer.wrapArguments(expr)
|
|
11639
|
+
},
|
|
11640
|
+
{
|
|
11641
|
+
name: "AsOklch",
|
|
11642
|
+
latexTrigger: ["\\operatorname{asOklch}"],
|
|
11643
|
+
kind: "function",
|
|
11644
|
+
serialize: (serializer, expr) => "\\operatorname{asOklch}" + serializer.wrapArguments(expr)
|
|
11645
|
+
},
|
|
11646
|
+
// Perceptual difference (returns a scalar in [0, ~1])
|
|
11647
|
+
{
|
|
11648
|
+
name: "ColorDelta",
|
|
11649
|
+
latexTrigger: ["\\operatorname{colorDelta}"],
|
|
11650
|
+
kind: "function",
|
|
11651
|
+
serialize: (serializer, expr) => "\\operatorname{colorDelta}" + serializer.wrapArguments(expr)
|
|
11652
|
+
}
|
|
11449
11653
|
];
|
|
11450
11654
|
|
|
11451
11655
|
// src/compute-engine/latex-syntax/dictionary/default-dictionary.ts
|
|
@@ -11476,7 +11680,8 @@ var Compile = (() => {
|
|
|
11476
11680
|
...DEFINITIONS_STATISTICS,
|
|
11477
11681
|
...DEFINITIONS_UNITS,
|
|
11478
11682
|
...DEFINITIONS_OTHERS,
|
|
11479
|
-
...DEFINITIONS_PHYSICS
|
|
11683
|
+
...DEFINITIONS_PHYSICS,
|
|
11684
|
+
...DEFINITIONS_COLORS
|
|
11480
11685
|
];
|
|
11481
11686
|
|
|
11482
11687
|
// src/math-json/symbols.ts
|
|
@@ -15099,8 +15304,7 @@ ${lines.join("\n")}`;
|
|
|
15099
15304
|
vars: options?.vars,
|
|
15100
15305
|
imports: options?.imports,
|
|
15101
15306
|
preamble: options?.preamble,
|
|
15102
|
-
realOnly: options?.realOnly
|
|
15103
|
-
hints: options?.hints
|
|
15307
|
+
realOnly: options?.realOnly
|
|
15104
15308
|
});
|
|
15105
15309
|
} catch (e) {
|
|
15106
15310
|
if (options?.fallback ?? true) {
|
|
@@ -15112,8 +15316,7 @@ ${lines.join("\n")}`;
|
|
|
15112
15316
|
ce.pushScope();
|
|
15113
15317
|
try {
|
|
15114
15318
|
if (vars && typeof vars === "object") {
|
|
15115
|
-
for (const [k, v] of Object.entries(vars))
|
|
15116
|
-
ce.assign(k, v);
|
|
15319
|
+
for (const [k, v] of Object.entries(vars)) ce.assign(k, v);
|
|
15117
15320
|
}
|
|
15118
15321
|
return expr.evaluate().re;
|
|
15119
15322
|
} finally {
|
|
@@ -15200,8 +15403,7 @@ ${lines.join("\n")}`;
|
|
|
15200
15403
|
return { re: null, im: formatFloat(iScale) };
|
|
15201
15404
|
}
|
|
15202
15405
|
const compiledFactors = remaining.map((r) => compile2(r));
|
|
15203
|
-
if (iScale !== 1)
|
|
15204
|
-
compiledFactors.unshift(formatFloat(iScale));
|
|
15406
|
+
if (iScale !== 1) compiledFactors.unshift(formatFloat(iScale));
|
|
15205
15407
|
const imCode = foldTerms(compiledFactors, "1.0", "*");
|
|
15206
15408
|
return { re: null, im: imCode };
|
|
15207
15409
|
}
|
|
@@ -15266,6 +15468,40 @@ ${lines.join("\n")}`;
|
|
|
15266
15468
|
else h = ((r - g) / d + 4) / 6;
|
|
15267
15469
|
return { h: h * 360, s, l };
|
|
15268
15470
|
}
|
|
15471
|
+
function hsvToRgb(h, s, v) {
|
|
15472
|
+
h = (h % 360 + 360) % 360;
|
|
15473
|
+
s = Math.max(0, Math.min(1, s));
|
|
15474
|
+
v = Math.max(0, Math.min(1, v));
|
|
15475
|
+
const c = v * s;
|
|
15476
|
+
const x = c * (1 - Math.abs(h / 60 % 2 - 1));
|
|
15477
|
+
const m = v - c;
|
|
15478
|
+
let r = 0, g = 0, b = 0;
|
|
15479
|
+
if (h < 60) [r, g, b] = [c, x, 0];
|
|
15480
|
+
else if (h < 120) [r, g, b] = [x, c, 0];
|
|
15481
|
+
else if (h < 180) [r, g, b] = [0, c, x];
|
|
15482
|
+
else if (h < 240) [r, g, b] = [0, x, c];
|
|
15483
|
+
else if (h < 300) [r, g, b] = [x, 0, c];
|
|
15484
|
+
else [r, g, b] = [c, 0, x];
|
|
15485
|
+
return { r: (r + m) * 255, g: (g + m) * 255, b: (b + m) * 255 };
|
|
15486
|
+
}
|
|
15487
|
+
function rgbToHsv(r, g, b) {
|
|
15488
|
+
r /= 255;
|
|
15489
|
+
g /= 255;
|
|
15490
|
+
b /= 255;
|
|
15491
|
+
const max2 = Math.max(r, g, b);
|
|
15492
|
+
const min2 = Math.min(r, g, b);
|
|
15493
|
+
const d = max2 - min2;
|
|
15494
|
+
let h = 0;
|
|
15495
|
+
if (d > 0) {
|
|
15496
|
+
if (max2 === r) h = (g - b) / d % 6;
|
|
15497
|
+
else if (max2 === g) h = (b - r) / d + 2;
|
|
15498
|
+
else h = (r - g) / d + 4;
|
|
15499
|
+
h *= 60;
|
|
15500
|
+
if (h < 0) h += 360;
|
|
15501
|
+
}
|
|
15502
|
+
const s = max2 === 0 ? 0 : d / max2;
|
|
15503
|
+
return { h, s, v: max2 };
|
|
15504
|
+
}
|
|
15269
15505
|
function parseHexColor(s) {
|
|
15270
15506
|
const hex = s.startsWith("#") ? s.substring(1) : s;
|
|
15271
15507
|
let r, g, b;
|
|
@@ -15721,6 +15957,13 @@ ${lines.join("\n")}`;
|
|
|
15721
15957
|
};
|
|
15722
15958
|
function parseColor(s, darkMode) {
|
|
15723
15959
|
const str = s.trim().toLowerCase();
|
|
15960
|
+
const opacityMatch = str.match(/^(.+?)\s*\/\s*(\d+(?:\.\d+)?)%?\s*$/);
|
|
15961
|
+
if (opacityMatch) {
|
|
15962
|
+
const base = parseColor(opacityMatch[1].trim(), darkMode);
|
|
15963
|
+
const opacity = Math.max(0, Math.min(100, parseFloat(opacityMatch[2])));
|
|
15964
|
+
const alpha = Math.round(opacity / 100 * 255);
|
|
15965
|
+
return base & 4294967040 | alpha;
|
|
15966
|
+
}
|
|
15724
15967
|
if (str.startsWith("#")) {
|
|
15725
15968
|
const hex = str.substring(1);
|
|
15726
15969
|
let r, g, b, a = 255;
|
|
@@ -15853,14 +16096,6 @@ ${lines.join("\n")}`;
|
|
|
15853
16096
|
console.warn(`parseColor: unrecognized color "${s}"`);
|
|
15854
16097
|
return 0;
|
|
15855
16098
|
}
|
|
15856
|
-
function parseColorToRgb01(s, darkMode) {
|
|
15857
|
-
const color = parseColor(s, darkMode);
|
|
15858
|
-
return [
|
|
15859
|
-
(color >>> 24 & 255) / 255,
|
|
15860
|
-
(color >>> 16 & 255) / 255,
|
|
15861
|
-
(color >>> 8 & 255) / 255
|
|
15862
|
-
];
|
|
15863
|
-
}
|
|
15864
16099
|
function apca(bgColor, fgColor) {
|
|
15865
16100
|
const bgRgb = asRgb(bgColor);
|
|
15866
16101
|
const fgRgb = asRgb(fgColor);
|
|
@@ -15919,6 +16154,12 @@ ${lines.join("\n")}`;
|
|
|
15919
16154
|
const contrast2 = Math.abs(apca(fg2, bg));
|
|
15920
16155
|
return contrast1 >= contrast2 ? asColorNumber(fg1) : asColorNumber(fg2);
|
|
15921
16156
|
}
|
|
16157
|
+
function oklabDeltaE(a, b) {
|
|
16158
|
+
const dL = a.L - b.L;
|
|
16159
|
+
const da = a.a - b.a;
|
|
16160
|
+
const db = a.b - b.b;
|
|
16161
|
+
return Math.sqrt(dL * dL + da * da + db * db);
|
|
16162
|
+
}
|
|
15922
16163
|
var TYCHO_11 = [
|
|
15923
16164
|
"#4e79a7",
|
|
15924
16165
|
// Blue
|
|
@@ -20130,39 +20371,130 @@ ${lines.join("\n")}`;
|
|
|
20130
20371
|
if (args.length >= 2)
|
|
20131
20372
|
return `_SYS.colormap(${compile2(args[0])}, ${compile2(args[1])})`;
|
|
20132
20373
|
return `_SYS.colormap(${compile2(args[0])})`;
|
|
20374
|
+
},
|
|
20375
|
+
// -----------------------------------------------------------------------
|
|
20376
|
+
// Color constructor heads. All compile to OKLCh arrays at runtime — the
|
|
20377
|
+
// canonical color representation in this target. The constructors take
|
|
20378
|
+
// their own colorspace's components and convert internally.
|
|
20379
|
+
// (Mirrors the GPU target's design: color values are vec3 OKLCh.)
|
|
20380
|
+
// -----------------------------------------------------------------------
|
|
20381
|
+
Rgb: (args, compile2) => {
|
|
20382
|
+
if (args.length < 3) throw new Error("Rgb: need 3 components");
|
|
20383
|
+
return `_SYS.rgb(${args.map(compile2).join(", ")})`;
|
|
20384
|
+
},
|
|
20385
|
+
Hsv: (args, compile2) => {
|
|
20386
|
+
if (args.length < 3) throw new Error("Hsv: need 3 components");
|
|
20387
|
+
return `_SYS.hsv(${args.map(compile2).join(", ")})`;
|
|
20388
|
+
},
|
|
20389
|
+
Hsl: (args, compile2) => {
|
|
20390
|
+
if (args.length < 3) throw new Error("Hsl: need 3 components");
|
|
20391
|
+
return `_SYS.hsl(${args.map(compile2).join(", ")})`;
|
|
20392
|
+
},
|
|
20393
|
+
Oklab: (args, compile2) => {
|
|
20394
|
+
if (args.length < 3) throw new Error("Oklab: need 3 components");
|
|
20395
|
+
return `_SYS.oklab(${args.map(compile2).join(", ")})`;
|
|
20396
|
+
},
|
|
20397
|
+
Oklch: (args, compile2) => {
|
|
20398
|
+
if (args.length < 3) throw new Error("Oklch: need 3 components");
|
|
20399
|
+
return `_SYS.oklch(${args.map(compile2).join(", ")})`;
|
|
20400
|
+
},
|
|
20401
|
+
// -----------------------------------------------------------------------
|
|
20402
|
+
// As* converters. Compile-time output convention matches the engine and
|
|
20403
|
+
// the GPU target: each returns components in the named space as a 3- or
|
|
20404
|
+
// 4-element array. `AsRgb` uses 0-1 sRGB channels (consistent across all
|
|
20405
|
+
// layers). `AsOklch` is the identity (canonical form).
|
|
20406
|
+
// -----------------------------------------------------------------------
|
|
20407
|
+
AsRgb: ([c], compile2) => {
|
|
20408
|
+
if (c === null) throw new Error("AsRgb: no argument");
|
|
20409
|
+
return `_SYS.asRgb(${compile2(c)})`;
|
|
20410
|
+
},
|
|
20411
|
+
AsHsv: ([c], compile2) => {
|
|
20412
|
+
if (c === null) throw new Error("AsHsv: no argument");
|
|
20413
|
+
return `_SYS.asHsv(${compile2(c)})`;
|
|
20414
|
+
},
|
|
20415
|
+
AsHsl: ([c], compile2) => {
|
|
20416
|
+
if (c === null) throw new Error("AsHsl: no argument");
|
|
20417
|
+
return `_SYS.asHsl(${compile2(c)})`;
|
|
20418
|
+
},
|
|
20419
|
+
AsOklab: ([c], compile2) => {
|
|
20420
|
+
if (c === null) throw new Error("AsOklab: no argument");
|
|
20421
|
+
return `_SYS.asOklab(${compile2(c)})`;
|
|
20422
|
+
},
|
|
20423
|
+
AsOklch: ([c], compile2) => {
|
|
20424
|
+
if (c === null) throw new Error("AsOklch: no argument");
|
|
20425
|
+
return compile2(c);
|
|
20426
|
+
},
|
|
20427
|
+
// Perceptual color difference (ΔE_OK).
|
|
20428
|
+
ColorDelta: ([a, b], compile2) => {
|
|
20429
|
+
if (a === null || b === null)
|
|
20430
|
+
throw new Error("ColorDelta: need two colors");
|
|
20431
|
+
return `_SYS.colorDelta(${compile2(a)}, ${compile2(b)})`;
|
|
20432
|
+
},
|
|
20433
|
+
// Euclidean distance between two tuples (any positive dimension).
|
|
20434
|
+
// The GPU target maps `Distance` to the GLSL/WGSL `distance()` builtin
|
|
20435
|
+
// (vec-only); this JS handler works on plain arrays of any length.
|
|
20436
|
+
Distance: ([a, b], compile2) => {
|
|
20437
|
+
if (a === null || b === null) throw new Error("Distance: need two points");
|
|
20438
|
+
return `_SYS.distance(${compile2(a)}, ${compile2(b)})`;
|
|
20133
20439
|
}
|
|
20134
20440
|
};
|
|
20135
20441
|
function toRI(c) {
|
|
20136
20442
|
return { re: c.re, im: c.im };
|
|
20137
20443
|
}
|
|
20444
|
+
function normalizeAlpha(a) {
|
|
20445
|
+
if (a === void 0) return void 0;
|
|
20446
|
+
if (!Number.isFinite(a)) return void 0;
|
|
20447
|
+
if (Math.abs(a - 1) < 1e-9) return void 0;
|
|
20448
|
+
return a;
|
|
20449
|
+
}
|
|
20138
20450
|
function toRgb255(input) {
|
|
20139
20451
|
if (typeof input === "string") {
|
|
20140
20452
|
const c = parseColor(input);
|
|
20141
|
-
|
|
20453
|
+
const rgb2 = {
|
|
20142
20454
|
r: c >>> 24 & 255,
|
|
20143
20455
|
g: c >>> 16 & 255,
|
|
20144
|
-
b: c >>> 8 & 255
|
|
20145
|
-
alpha: (c & 255) / 255
|
|
20456
|
+
b: c >>> 8 & 255
|
|
20146
20457
|
};
|
|
20458
|
+
const alpha = normalizeAlpha((c & 255) / 255);
|
|
20459
|
+
if (alpha !== void 0) rgb2.alpha = alpha;
|
|
20460
|
+
return rgb2;
|
|
20461
|
+
}
|
|
20462
|
+
const rgb = oklchToRgb({ L: input[0], C: input[1], H: input[2] });
|
|
20463
|
+
if (input.length >= 4) {
|
|
20464
|
+
const alpha = normalizeAlpha(input[3]);
|
|
20465
|
+
if (alpha !== void 0) rgb.alpha = alpha;
|
|
20147
20466
|
}
|
|
20148
|
-
const rgb = {
|
|
20149
|
-
r: input[0] * 255,
|
|
20150
|
-
g: input[1] * 255,
|
|
20151
|
-
b: input[2] * 255
|
|
20152
|
-
};
|
|
20153
|
-
if (input.length >= 4) rgb.alpha = input[3];
|
|
20154
20467
|
return rgb;
|
|
20155
20468
|
}
|
|
20156
|
-
function
|
|
20157
|
-
|
|
20158
|
-
|
|
20159
|
-
|
|
20160
|
-
|
|
20161
|
-
|
|
20469
|
+
function toOklch(input) {
|
|
20470
|
+
if (typeof input === "string") {
|
|
20471
|
+
const c = parseColor(input);
|
|
20472
|
+
const r = c >>> 24 & 255;
|
|
20473
|
+
const g = c >>> 16 & 255;
|
|
20474
|
+
const b = c >>> 8 & 255;
|
|
20475
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
20476
|
+
const alpha = normalizeAlpha((c & 255) / 255);
|
|
20477
|
+
if (alpha !== void 0) oklch2.alpha = alpha;
|
|
20478
|
+
return oklch2;
|
|
20479
|
+
}
|
|
20480
|
+
return {
|
|
20481
|
+
L: input[0],
|
|
20482
|
+
C: input[1],
|
|
20483
|
+
H: input[2],
|
|
20484
|
+
alpha: input.length >= 4 ? normalizeAlpha(input[3]) : void 0
|
|
20485
|
+
};
|
|
20486
|
+
}
|
|
20487
|
+
function packedToOklch(c) {
|
|
20488
|
+
const r = c >>> 24 & 255;
|
|
20489
|
+
const g = c >>> 16 & 255;
|
|
20490
|
+
const b = c >>> 8 & 255;
|
|
20491
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
20492
|
+
const alpha = normalizeAlpha((c & 255) / 255);
|
|
20493
|
+
return alpha !== void 0 ? [oklch2.L, oklch2.C, oklch2.H, alpha] : [oklch2.L, oklch2.C, oklch2.H];
|
|
20162
20494
|
}
|
|
20163
20495
|
var colorHelpers = {
|
|
20164
20496
|
color(input) {
|
|
20165
|
-
return
|
|
20497
|
+
return packedToOklch(parseColor(input));
|
|
20166
20498
|
},
|
|
20167
20499
|
colorToString(input, format) {
|
|
20168
20500
|
const rgb = toRgb255(input);
|
|
@@ -20173,7 +20505,7 @@ ${lines.join("\n")}`;
|
|
|
20173
20505
|
const g = Math.round(Math.max(0, Math.min(255, rgb.g)));
|
|
20174
20506
|
const b = Math.round(Math.max(0, Math.min(255, rgb.b)));
|
|
20175
20507
|
let hex = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
20176
|
-
if (rgb.alpha !== void 0
|
|
20508
|
+
if (rgb.alpha !== void 0) {
|
|
20177
20509
|
const a = Math.round(Math.max(0, Math.min(255, rgb.alpha * 255)));
|
|
20178
20510
|
hex += a.toString(16).padStart(2, "0");
|
|
20179
20511
|
}
|
|
@@ -20183,7 +20515,7 @@ ${lines.join("\n")}`;
|
|
|
20183
20515
|
const r = Math.round(rgb.r);
|
|
20184
20516
|
const g = Math.round(rgb.g);
|
|
20185
20517
|
const b = Math.round(rgb.b);
|
|
20186
|
-
if (rgb.alpha !== void 0
|
|
20518
|
+
if (rgb.alpha !== void 0)
|
|
20187
20519
|
return `rgb(${r} ${g} ${b} / ${rgb.alpha})`;
|
|
20188
20520
|
return `rgb(${r} ${g} ${b})`;
|
|
20189
20521
|
}
|
|
@@ -20192,7 +20524,7 @@ ${lines.join("\n")}`;
|
|
|
20192
20524
|
const h = Math.round(hsl.h * 10) / 10;
|
|
20193
20525
|
const s = Math.round(hsl.s * 1e3) / 10;
|
|
20194
20526
|
const l = Math.round(hsl.l * 1e3) / 10;
|
|
20195
|
-
if (rgb.alpha !== void 0
|
|
20527
|
+
if (rgb.alpha !== void 0)
|
|
20196
20528
|
return `hsl(${h} ${s}% ${l}% / ${rgb.alpha})`;
|
|
20197
20529
|
return `hsl(${h} ${s}% ${l}%)`;
|
|
20198
20530
|
}
|
|
@@ -20201,7 +20533,7 @@ ${lines.join("\n")}`;
|
|
|
20201
20533
|
const L = Math.round(c.L * 1e3) / 1e3;
|
|
20202
20534
|
const C = Math.round(c.C * 1e3) / 1e3;
|
|
20203
20535
|
const H = Math.round(c.H * 10) / 10;
|
|
20204
|
-
if (rgb.alpha !== void 0
|
|
20536
|
+
if (rgb.alpha !== void 0)
|
|
20205
20537
|
return `oklch(${L} ${C} ${H} / ${rgb.alpha})`;
|
|
20206
20538
|
return `oklch(${L} ${C} ${H})`;
|
|
20207
20539
|
}
|
|
@@ -20210,29 +20542,29 @@ ${lines.join("\n")}`;
|
|
|
20210
20542
|
}
|
|
20211
20543
|
},
|
|
20212
20544
|
colorMix(input1, input2, ratio = 0.5) {
|
|
20213
|
-
const
|
|
20214
|
-
const
|
|
20545
|
+
const c1 = toOklch(input1);
|
|
20546
|
+
const c2 = toOklch(input2);
|
|
20215
20547
|
ratio = Math.max(0, Math.min(1, ratio));
|
|
20216
|
-
const
|
|
20217
|
-
const
|
|
20218
|
-
let
|
|
20219
|
-
if (
|
|
20220
|
-
if (
|
|
20221
|
-
|
|
20222
|
-
|
|
20223
|
-
|
|
20224
|
-
|
|
20225
|
-
|
|
20226
|
-
|
|
20227
|
-
H
|
|
20228
|
-
|
|
20229
|
-
|
|
20230
|
-
const
|
|
20231
|
-
const
|
|
20232
|
-
const a1 =
|
|
20233
|
-
const a2 =
|
|
20234
|
-
const alpha = a1 + (a2 - a1) * ratio;
|
|
20235
|
-
return
|
|
20548
|
+
const c1Achromatic = c1.C < 1e-6;
|
|
20549
|
+
const c2Achromatic = c2.C < 1e-6;
|
|
20550
|
+
let H;
|
|
20551
|
+
if (c1Achromatic && c2Achromatic) H = c1.H;
|
|
20552
|
+
else if (c1Achromatic) H = c2.H;
|
|
20553
|
+
else if (c2Achromatic) H = c1.H;
|
|
20554
|
+
else {
|
|
20555
|
+
let dh = c2.H - c1.H;
|
|
20556
|
+
if (dh > 180) dh -= 360;
|
|
20557
|
+
if (dh < -180) dh += 360;
|
|
20558
|
+
H = c1.H + dh * ratio;
|
|
20559
|
+
if (H < 0) H += 360;
|
|
20560
|
+
if (H >= 360) H -= 360;
|
|
20561
|
+
}
|
|
20562
|
+
const L = c1.L + (c2.L - c1.L) * ratio;
|
|
20563
|
+
const C = c1.C + (c2.C - c1.C) * ratio;
|
|
20564
|
+
const a1 = c1.alpha ?? 1;
|
|
20565
|
+
const a2 = c2.alpha ?? 1;
|
|
20566
|
+
const alpha = normalizeAlpha(a1 + (a2 - a1) * ratio);
|
|
20567
|
+
return alpha !== void 0 ? [L, C, H, alpha] : [L, C, H];
|
|
20236
20568
|
},
|
|
20237
20569
|
colorContrast(bg, fg) {
|
|
20238
20570
|
return apca(toRgb255(bg), toRgb255(fg));
|
|
@@ -20240,11 +20572,11 @@ ${lines.join("\n")}`;
|
|
|
20240
20572
|
contrastingColor(bg, fg1, fg2) {
|
|
20241
20573
|
const bgRgb = toRgb255(bg);
|
|
20242
20574
|
if (fg1 !== void 0 && fg2 !== void 0) {
|
|
20243
|
-
return
|
|
20575
|
+
return packedToOklch(
|
|
20244
20576
|
contrastingColor({ bg: bgRgb, fg1: toRgb255(fg1), fg2: toRgb255(fg2) })
|
|
20245
20577
|
);
|
|
20246
20578
|
}
|
|
20247
|
-
return
|
|
20579
|
+
return packedToOklch(contrastingColor(bgRgb));
|
|
20248
20580
|
},
|
|
20249
20581
|
colorToColorspace(input, space) {
|
|
20250
20582
|
const rgb = toRgb255(input);
|
|
@@ -20273,7 +20605,7 @@ ${lines.join("\n")}`;
|
|
|
20273
20605
|
default:
|
|
20274
20606
|
throw new Error(`Unknown color space: ${space}`);
|
|
20275
20607
|
}
|
|
20276
|
-
if (alpha !== void 0
|
|
20608
|
+
if (alpha !== void 0) result.push(alpha);
|
|
20277
20609
|
return result;
|
|
20278
20610
|
},
|
|
20279
20611
|
colormap(name, arg) {
|
|
@@ -20285,7 +20617,7 @@ ${lines.join("\n")}`;
|
|
|
20285
20617
|
const palette = allPalettes[name];
|
|
20286
20618
|
if (!palette) throw new Error(`Unknown palette: ${name}`);
|
|
20287
20619
|
const colors = palette.map(
|
|
20288
|
-
(hex) =>
|
|
20620
|
+
(hex) => packedToOklch(parseColor(hex))
|
|
20289
20621
|
);
|
|
20290
20622
|
if (arg === void 0) return colors;
|
|
20291
20623
|
if (Number.isInteger(arg) && arg >= 2) {
|
|
@@ -20309,62 +20641,128 @@ ${lines.join("\n")}`;
|
|
|
20309
20641
|
const frac = pos - i;
|
|
20310
20642
|
if (frac === 0 || i >= colors.length - 1)
|
|
20311
20643
|
return [...colors[Math.min(i, colors.length - 1)]];
|
|
20312
|
-
const
|
|
20313
|
-
|
|
20314
|
-
|
|
20315
|
-
|
|
20316
|
-
|
|
20317
|
-
|
|
20318
|
-
|
|
20319
|
-
|
|
20320
|
-
|
|
20321
|
-
|
|
20322
|
-
|
|
20323
|
-
|
|
20324
|
-
|
|
20325
|
-
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
20329
|
-
if (H >= 360) H -= 360;
|
|
20330
|
-
const mixed = oklchToRgb({
|
|
20331
|
-
L: c1.L + (c2.L - c1.L) * frac,
|
|
20332
|
-
C: c1.C + (c2.C - c1.C) * frac,
|
|
20333
|
-
H
|
|
20334
|
-
});
|
|
20335
|
-
return [mixed.r / 255, mixed.g / 255, mixed.b / 255];
|
|
20644
|
+
const [L1, C1, H1] = colors[i];
|
|
20645
|
+
const [L2, C2, H2] = colors[i + 1];
|
|
20646
|
+
const c1Achromatic = C1 < 1e-6;
|
|
20647
|
+
const c2Achromatic = C2 < 1e-6;
|
|
20648
|
+
let H;
|
|
20649
|
+
if (c1Achromatic && c2Achromatic) H = H1;
|
|
20650
|
+
else if (c1Achromatic) H = H2;
|
|
20651
|
+
else if (c2Achromatic) H = H1;
|
|
20652
|
+
else {
|
|
20653
|
+
let dh = H2 - H1;
|
|
20654
|
+
if (dh > 180) dh -= 360;
|
|
20655
|
+
if (dh < -180) dh += 360;
|
|
20656
|
+
H = H1 + dh * frac;
|
|
20657
|
+
if (H < 0) H += 360;
|
|
20658
|
+
if (H >= 360) H -= 360;
|
|
20659
|
+
}
|
|
20660
|
+
return [L1 + (L2 - L1) * frac, C1 + (C2 - C1) * frac, H];
|
|
20336
20661
|
},
|
|
20337
20662
|
colorFromColorspace(components, space) {
|
|
20338
20663
|
const c0 = components[0];
|
|
20339
20664
|
const c1 = components[1];
|
|
20340
20665
|
const c2 = components[2];
|
|
20341
20666
|
const alpha = components.length >= 4 ? components[3] : void 0;
|
|
20342
|
-
let
|
|
20667
|
+
let oklch2;
|
|
20343
20668
|
switch (space.toLowerCase()) {
|
|
20344
20669
|
case "rgb":
|
|
20345
|
-
|
|
20670
|
+
oklch2 = rgbToOklch({ r: c0 * 255, g: c1 * 255, b: c2 * 255 });
|
|
20346
20671
|
break;
|
|
20347
20672
|
case "hsl": {
|
|
20348
|
-
const
|
|
20349
|
-
|
|
20673
|
+
const rgb = hslToRgb(c0, c1, c2);
|
|
20674
|
+
oklch2 = rgbToOklch(rgb);
|
|
20350
20675
|
break;
|
|
20351
20676
|
}
|
|
20352
|
-
case "oklch":
|
|
20353
|
-
|
|
20354
|
-
result = [r.r / 255, r.g / 255, r.b / 255];
|
|
20677
|
+
case "oklch":
|
|
20678
|
+
oklch2 = { L: c0, C: c1, H: c2 };
|
|
20355
20679
|
break;
|
|
20356
|
-
}
|
|
20357
20680
|
case "oklab":
|
|
20358
|
-
case "lab":
|
|
20359
|
-
|
|
20360
|
-
result = [r.r / 255, r.g / 255, r.b / 255];
|
|
20681
|
+
case "lab":
|
|
20682
|
+
oklch2 = oklabToOklch({ L: c0, a: c1, b: c2 });
|
|
20361
20683
|
break;
|
|
20362
|
-
}
|
|
20363
20684
|
default:
|
|
20364
20685
|
throw new Error(`Unknown color space: ${space}`);
|
|
20365
20686
|
}
|
|
20366
|
-
|
|
20367
|
-
|
|
20687
|
+
return alpha !== void 0 ? [oklch2.L, oklch2.C, oklch2.H, alpha] : [oklch2.L, oklch2.C, oklch2.H];
|
|
20688
|
+
},
|
|
20689
|
+
// -----------------------------------------------------------------------
|
|
20690
|
+
// Color constructors. Each accepts components in its colorspace's natural
|
|
20691
|
+
// units and returns the canonical OKLCh array `[L, C, H]` (or with alpha).
|
|
20692
|
+
// -----------------------------------------------------------------------
|
|
20693
|
+
rgb(r, g, b, alpha) {
|
|
20694
|
+
const c = rgbToOklch({ r: r * 255, g: g * 255, b: b * 255 });
|
|
20695
|
+
const a = normalizeAlpha(alpha);
|
|
20696
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
20697
|
+
},
|
|
20698
|
+
hsv(h, s, v, alpha) {
|
|
20699
|
+
const rgb = hsvToRgb(h, s, v);
|
|
20700
|
+
const c = rgbToOklch(rgb);
|
|
20701
|
+
const a = normalizeAlpha(alpha);
|
|
20702
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
20703
|
+
},
|
|
20704
|
+
hsl(h, s, l, alpha) {
|
|
20705
|
+
const rgb = hslToRgb(h, s, l);
|
|
20706
|
+
const c = rgbToOklch({ r: rgb.r, g: rgb.g, b: rgb.b });
|
|
20707
|
+
const a = normalizeAlpha(alpha);
|
|
20708
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
20709
|
+
},
|
|
20710
|
+
oklab(L, a, b, alpha) {
|
|
20711
|
+
const c = oklabToOklch({ L, a, b });
|
|
20712
|
+
const al = normalizeAlpha(alpha);
|
|
20713
|
+
return al !== void 0 ? [c.L, c.C, c.H, al] : [c.L, c.C, c.H];
|
|
20714
|
+
},
|
|
20715
|
+
oklch(L, C, H, alpha) {
|
|
20716
|
+
const a = normalizeAlpha(alpha);
|
|
20717
|
+
return a !== void 0 ? [L, C, H, a] : [L, C, H];
|
|
20718
|
+
},
|
|
20719
|
+
// -----------------------------------------------------------------------
|
|
20720
|
+
// As* converters. Inputs are anything `toOklch` accepts (string, packed
|
|
20721
|
+
// int, or OKLCh array). Outputs are 3- or 4-element arrays in the named
|
|
20722
|
+
// space. sRGB-based outputs (asRgb/asHsv/asHsl) use 0-1 channels for
|
|
20723
|
+
// consistency with the GPU target's shader convention.
|
|
20724
|
+
// -----------------------------------------------------------------------
|
|
20725
|
+
asRgb(input) {
|
|
20726
|
+
const rgb = toRgb255(input);
|
|
20727
|
+
const r = rgb.r / 255;
|
|
20728
|
+
const g = rgb.g / 255;
|
|
20729
|
+
const b = rgb.b / 255;
|
|
20730
|
+
return rgb.alpha !== void 0 ? [r, g, b, rgb.alpha] : [r, g, b];
|
|
20731
|
+
},
|
|
20732
|
+
asHsv(input) {
|
|
20733
|
+
const rgb = toRgb255(input);
|
|
20734
|
+
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
20735
|
+
return rgb.alpha !== void 0 ? [hsv.h, hsv.s, hsv.v, rgb.alpha] : [hsv.h, hsv.s, hsv.v];
|
|
20736
|
+
},
|
|
20737
|
+
asHsl(input) {
|
|
20738
|
+
const rgb = toRgb255(input);
|
|
20739
|
+
const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
|
|
20740
|
+
return rgb.alpha !== void 0 ? [hsl.h, hsl.s, hsl.l, rgb.alpha] : [hsl.h, hsl.s, hsl.l];
|
|
20741
|
+
},
|
|
20742
|
+
asOklab(input) {
|
|
20743
|
+
const c = toOklch(input);
|
|
20744
|
+
const lab = oklchToOklab({ L: c.L, C: c.C, H: c.H });
|
|
20745
|
+
return c.alpha !== void 0 ? [lab.L, lab.a, lab.b, c.alpha] : [lab.L, lab.a, lab.b];
|
|
20746
|
+
},
|
|
20747
|
+
// asOklch is identity — handled at compile time as a pass-through
|
|
20748
|
+
// Perceptual color difference (ΔE_OK).
|
|
20749
|
+
colorDelta(a, b) {
|
|
20750
|
+
const labA = oklchToOklab(toOklch(a));
|
|
20751
|
+
const labB = oklchToOklab(toOklch(b));
|
|
20752
|
+
return oklabDeltaE(labA, labB);
|
|
20753
|
+
},
|
|
20754
|
+
// Euclidean distance between two tuples. Plain numeric — not a color
|
|
20755
|
+
// operation despite living in the same helpers block.
|
|
20756
|
+
distance(a, b) {
|
|
20757
|
+
if (!Array.isArray(a) || !Array.isArray(b))
|
|
20758
|
+
throw new Error("Distance: expected two arrays");
|
|
20759
|
+
if (a.length !== b.length) throw new Error("Distance: dimension mismatch");
|
|
20760
|
+
let sumSq = 0;
|
|
20761
|
+
for (let i = 0; i < a.length; i++) {
|
|
20762
|
+
const d = a[i] - b[i];
|
|
20763
|
+
sumSq += d * d;
|
|
20764
|
+
}
|
|
20765
|
+
return Math.sqrt(sumSq);
|
|
20368
20766
|
}
|
|
20369
20767
|
};
|
|
20370
20768
|
var SYS_HELPERS = {
|
|
@@ -20782,43 +21180,6 @@ ${lines.join("\n")}`;
|
|
|
20782
21180
|
return b;
|
|
20783
21181
|
}
|
|
20784
21182
|
|
|
20785
|
-
// src/compute-engine/compilation/fractal-orbit.ts
|
|
20786
|
-
function toBigDecimal(v) {
|
|
20787
|
-
if (typeof v === "object" && "hi" in v)
|
|
20788
|
-
return new BigDecimal(v.hi).add(new BigDecimal(v.lo));
|
|
20789
|
-
return new BigDecimal(v);
|
|
20790
|
-
}
|
|
20791
|
-
function hpToNumber(v) {
|
|
20792
|
-
if (typeof v === "number") return v;
|
|
20793
|
-
if (typeof v === "string") return Number(v);
|
|
20794
|
-
return v.hi + v.lo;
|
|
20795
|
-
}
|
|
20796
|
-
function computeReferenceOrbit(center, maxIter, precision) {
|
|
20797
|
-
const prevPrecision = BigDecimal.precision;
|
|
20798
|
-
BigDecimal.precision = precision;
|
|
20799
|
-
try {
|
|
20800
|
-
const cr = toBigDecimal(center[0]);
|
|
20801
|
-
const ci = toBigDecimal(center[1]);
|
|
20802
|
-
let zr = BigDecimal.ZERO;
|
|
20803
|
-
let zi = BigDecimal.ZERO;
|
|
20804
|
-
const ESCAPE = new BigDecimal(256);
|
|
20805
|
-
const points = [];
|
|
20806
|
-
for (let i = 0; i < maxIter; i++) {
|
|
20807
|
-
points.push(zr.toNumber(), zi.toNumber());
|
|
20808
|
-
const zr2 = zr.mul(zr).toPrecision(precision);
|
|
20809
|
-
const zi2 = zi.mul(zi).toPrecision(precision);
|
|
20810
|
-
const mag2 = zr2.add(zi2);
|
|
20811
|
-
if (mag2.cmp(ESCAPE) > 0) break;
|
|
20812
|
-
const new_zi = zr.mul(zi).toPrecision(precision).mul(2).add(ci);
|
|
20813
|
-
zr = zr2.sub(zi2).add(cr);
|
|
20814
|
-
zi = new_zi;
|
|
20815
|
-
}
|
|
20816
|
-
return new Float32Array(points);
|
|
20817
|
-
} finally {
|
|
20818
|
-
BigDecimal.precision = prevPrecision;
|
|
20819
|
-
}
|
|
20820
|
-
}
|
|
20821
|
-
|
|
20822
21183
|
// src/compute-engine/compilation/gpu-target.ts
|
|
20823
21184
|
var GPU_OPERATORS = {
|
|
20824
21185
|
Add: ["+", 11],
|
|
@@ -20840,6 +21201,13 @@ ${lines.join("\n")}`;
|
|
|
20840
21201
|
function gpuVec2(target) {
|
|
20841
21202
|
return target?.language === "wgsl" ? "vec2f" : "vec2";
|
|
20842
21203
|
}
|
|
21204
|
+
function gpuVec3(target) {
|
|
21205
|
+
return target?.language === "wgsl" ? "vec3f" : "vec3";
|
|
21206
|
+
}
|
|
21207
|
+
function readStringLiteral(expr) {
|
|
21208
|
+
if (!isString(expr)) return null;
|
|
21209
|
+
return expr.string?.toLowerCase() ?? null;
|
|
21210
|
+
}
|
|
20843
21211
|
function compileIntArg(expr, compile2, target) {
|
|
20844
21212
|
const c = tryGetConstant(expr);
|
|
20845
21213
|
if (c !== void 0 && Number.isInteger(c)) return c.toString();
|
|
@@ -20898,17 +21266,10 @@ ${lines.join("\n")}`;
|
|
|
20898
21266
|
`for (${indexDecl} = ${lowerStr}; ${index} <= ${upperStr}; ${index}++) {`,
|
|
20899
21267
|
` ${acc} ${op}= ${body};`,
|
|
20900
21268
|
`}`,
|
|
20901
|
-
`return ${acc}
|
|
21269
|
+
`return ${acc};`
|
|
20902
21270
|
];
|
|
20903
21271
|
return lines.join("\n");
|
|
20904
21272
|
}
|
|
20905
|
-
function selectFractalStrategy(target) {
|
|
20906
|
-
const radius = target.hints?.viewport?.radius;
|
|
20907
|
-
if (radius === void 0) return "single";
|
|
20908
|
-
if (radius > 1e-6) return "single";
|
|
20909
|
-
if (radius > 1e-14) return "double";
|
|
20910
|
-
return "perturbation";
|
|
20911
|
-
}
|
|
20912
21273
|
var GPU_FUNCTIONS = {
|
|
20913
21274
|
// Variadic arithmetic (for function-call form, e.g., with vectors)
|
|
20914
21275
|
Add: (args, compile2, target) => {
|
|
@@ -20959,8 +21320,7 @@ ${lines.join("\n")}`;
|
|
|
20959
21320
|
const iScale = isSymbol2(iFactor, "ImaginaryUnit") ? 1 : iFactor.im;
|
|
20960
21321
|
const realFactors = args.filter((_, i) => i !== iIndex);
|
|
20961
21322
|
const v2 = gpuVec2(target);
|
|
20962
|
-
if (realFactors.length === 0)
|
|
20963
|
-
return `${v2}(0.0, ${formatFloat(iScale)})`;
|
|
21323
|
+
if (realFactors.length === 0) return `${v2}(0.0, ${formatFloat(iScale)})`;
|
|
20964
21324
|
const factors = realFactors.map((f) => compile2(f));
|
|
20965
21325
|
if (iScale !== 1) factors.unshift(formatFloat(iScale));
|
|
20966
21326
|
const imCode = foldTerms(factors, "1.0", "*");
|
|
@@ -21013,8 +21373,7 @@ ${lines.join("\n")}`;
|
|
|
21013
21373
|
if (isNumber(x) && x.im !== 0) {
|
|
21014
21374
|
return `${gpuVec2(target)}(${formatFloat(-x.re)}, ${formatFloat(-x.im)})`;
|
|
21015
21375
|
}
|
|
21016
|
-
if (isSymbol2(x, "ImaginaryUnit"))
|
|
21017
|
-
return `${gpuVec2(target)}(0.0, -1.0)`;
|
|
21376
|
+
if (isSymbol2(x, "ImaginaryUnit")) return `${gpuVec2(target)}(0.0, -1.0)`;
|
|
21018
21377
|
return `(-${compile2(x)})`;
|
|
21019
21378
|
},
|
|
21020
21379
|
// Standard math functions with complex dispatch
|
|
@@ -21387,49 +21746,139 @@ ${lines.join("\n")}`;
|
|
|
21387
21746
|
}
|
|
21388
21747
|
const isWGSL = target?.language === "wgsl";
|
|
21389
21748
|
const v3 = isWGSL ? "vec3f" : "vec3";
|
|
21390
|
-
|
|
21749
|
+
const black = `${v3}(0.0)`;
|
|
21750
|
+
const white = `${v3}(1.0, 0.0, 0.0)`;
|
|
21751
|
+
return `((_gpu_apca(${bg}, ${black}) > 50.0) ? ${black} : ${white})`;
|
|
21391
21752
|
},
|
|
21392
21753
|
ColorToColorspace: ([color, space], compile2) => {
|
|
21393
21754
|
if (color === null || space === null)
|
|
21394
21755
|
throw new Error("ColorToColorspace: need color and space");
|
|
21395
|
-
|
|
21756
|
+
const spaceName = readStringLiteral(space);
|
|
21757
|
+
if (spaceName === null)
|
|
21758
|
+
throw new Error("ColorToColorspace: space must be a string literal");
|
|
21759
|
+
const c = compile2(color);
|
|
21760
|
+
switch (spaceName) {
|
|
21761
|
+
case "oklch":
|
|
21762
|
+
return c;
|
|
21763
|
+
case "oklab":
|
|
21764
|
+
case "lab":
|
|
21765
|
+
return `_gpu_oklch_to_oklab(${c})`;
|
|
21766
|
+
case "rgb":
|
|
21767
|
+
return `_gpu_oklch_to_srgb(${c})`;
|
|
21768
|
+
case "hsl":
|
|
21769
|
+
return `_gpu_rgb_to_hsl(_gpu_oklch_to_srgb(${c}))`;
|
|
21770
|
+
case "hsv":
|
|
21771
|
+
return `_gpu_rgb_to_hsv(_gpu_oklch_to_srgb(${c}))`;
|
|
21772
|
+
default:
|
|
21773
|
+
throw new Error(
|
|
21774
|
+
`ColorToColorspace: unsupported space "${spaceName}" on GPU target`
|
|
21775
|
+
);
|
|
21776
|
+
}
|
|
21396
21777
|
},
|
|
21397
21778
|
ColorFromColorspace: ([components, space], compile2) => {
|
|
21398
21779
|
if (components === null || space === null)
|
|
21399
21780
|
throw new Error("ColorFromColorspace: need components and space");
|
|
21400
|
-
|
|
21781
|
+
const spaceName = readStringLiteral(space);
|
|
21782
|
+
if (spaceName === null)
|
|
21783
|
+
throw new Error("ColorFromColorspace: space must be a string literal");
|
|
21784
|
+
const c = compile2(components);
|
|
21785
|
+
switch (spaceName) {
|
|
21786
|
+
case "oklch":
|
|
21787
|
+
return c;
|
|
21788
|
+
case "oklab":
|
|
21789
|
+
case "lab":
|
|
21790
|
+
return `_gpu_oklab_to_oklch(${c})`;
|
|
21791
|
+
case "rgb":
|
|
21792
|
+
return `_gpu_srgb_to_oklch(${c})`;
|
|
21793
|
+
case "hsl":
|
|
21794
|
+
return `_gpu_srgb_to_oklch(_gpu_hsl_to_rgb(${c}))`;
|
|
21795
|
+
case "hsv":
|
|
21796
|
+
return `_gpu_srgb_to_oklch(_gpu_hsv_to_rgb(${c}))`;
|
|
21797
|
+
default:
|
|
21798
|
+
throw new Error(
|
|
21799
|
+
`ColorFromColorspace: unsupported space "${spaceName}" on GPU target`
|
|
21800
|
+
);
|
|
21801
|
+
}
|
|
21802
|
+
},
|
|
21803
|
+
// ---------------------------------------------------------------------------
|
|
21804
|
+
// Color literals. Each typed head compiles to a canonical OKLCh vec3.
|
|
21805
|
+
// Alpha (4th argument) is dropped — GPU color values are vec3 only. Pass
|
|
21806
|
+
// alpha as a separate uniform if it's needed at the framebuffer boundary.
|
|
21807
|
+
// ---------------------------------------------------------------------------
|
|
21808
|
+
Color: ([s], _compile, target) => {
|
|
21809
|
+
if (s === null) throw new Error("Color: no argument");
|
|
21810
|
+
const str = readStringLiteral(s);
|
|
21811
|
+
if (str === null)
|
|
21812
|
+
throw new Error("Color: argument must be a string literal on GPU target");
|
|
21813
|
+
const packed = parseColor(str);
|
|
21814
|
+
if (packed === 0 && str.trim().toLowerCase() !== "transparent")
|
|
21815
|
+
throw new Error(`Color: invalid color string "${str}"`);
|
|
21816
|
+
const r = packed >>> 24 & 255;
|
|
21817
|
+
const g = packed >>> 16 & 255;
|
|
21818
|
+
const b = packed >>> 8 & 255;
|
|
21819
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
21820
|
+
return `${gpuVec3(target)}(${formatFloat(oklch2.L)}, ${formatFloat(oklch2.C)}, ${formatFloat(oklch2.H)})`;
|
|
21821
|
+
},
|
|
21822
|
+
Rgb: (args, compile2, target) => {
|
|
21823
|
+
if (args.length < 3) throw new Error("Rgb: need 3 components");
|
|
21824
|
+
const v3 = gpuVec3(target);
|
|
21825
|
+
return `_gpu_srgb_to_oklch(${v3}(${compile2(args[0])}, ${compile2(args[1])}, ${compile2(args[2])}))`;
|
|
21826
|
+
},
|
|
21827
|
+
Hsv: (args, compile2, target) => {
|
|
21828
|
+
if (args.length < 3) throw new Error("Hsv: need 3 components");
|
|
21829
|
+
const v3 = gpuVec3(target);
|
|
21830
|
+
return `_gpu_srgb_to_oklch(_gpu_hsv_to_rgb(${v3}(${compile2(args[0])}, ${compile2(args[1])}, ${compile2(args[2])})))`;
|
|
21831
|
+
},
|
|
21832
|
+
Hsl: (args, compile2, target) => {
|
|
21833
|
+
if (args.length < 3) throw new Error("Hsl: need 3 components");
|
|
21834
|
+
const v3 = gpuVec3(target);
|
|
21835
|
+
return `_gpu_srgb_to_oklch(_gpu_hsl_to_rgb(${v3}(${compile2(args[0])}, ${compile2(args[1])}, ${compile2(args[2])})))`;
|
|
21836
|
+
},
|
|
21837
|
+
Oklab: (args, compile2, target) => {
|
|
21838
|
+
if (args.length < 3) throw new Error("Oklab: need 3 components");
|
|
21839
|
+
const v3 = gpuVec3(target);
|
|
21840
|
+
return `_gpu_oklab_to_oklch(${v3}(${compile2(args[0])}, ${compile2(args[1])}, ${compile2(args[2])}))`;
|
|
21841
|
+
},
|
|
21842
|
+
Oklch: (args, compile2, target) => {
|
|
21843
|
+
if (args.length < 3) throw new Error("Oklch: need 3 components");
|
|
21844
|
+
const v3 = gpuVec3(target);
|
|
21845
|
+
return `${v3}(${compile2(args[0])}, ${compile2(args[1])}, ${compile2(args[2])})`;
|
|
21846
|
+
},
|
|
21847
|
+
// ---------------------------------------------------------------------------
|
|
21848
|
+
// As* operators. AsOklch is identity (canonical). The other As* return
|
|
21849
|
+
// components in the named space, equivalent to ColorToColorspace(c, 'x').
|
|
21850
|
+
// ---------------------------------------------------------------------------
|
|
21851
|
+
AsOklch: ([c], compile2) => {
|
|
21852
|
+
if (c === null) throw new Error("AsOklch: no argument");
|
|
21853
|
+
return compile2(c);
|
|
21854
|
+
},
|
|
21855
|
+
AsOklab: ([c], compile2) => {
|
|
21856
|
+
if (c === null) throw new Error("AsOklab: no argument");
|
|
21857
|
+
return `_gpu_oklch_to_oklab(${compile2(c)})`;
|
|
21858
|
+
},
|
|
21859
|
+
AsRgb: ([c], compile2) => {
|
|
21860
|
+
if (c === null) throw new Error("AsRgb: no argument");
|
|
21861
|
+
return `_gpu_oklch_to_srgb(${compile2(c)})`;
|
|
21862
|
+
},
|
|
21863
|
+
AsHsv: ([c], compile2) => {
|
|
21864
|
+
if (c === null) throw new Error("AsHsv: no argument");
|
|
21865
|
+
return `_gpu_rgb_to_hsv(_gpu_oklch_to_srgb(${compile2(c)}))`;
|
|
21866
|
+
},
|
|
21867
|
+
AsHsl: ([c], compile2) => {
|
|
21868
|
+
if (c === null) throw new Error("AsHsl: no argument");
|
|
21869
|
+
return `_gpu_rgb_to_hsl(_gpu_oklch_to_srgb(${compile2(c)}))`;
|
|
21401
21870
|
},
|
|
21402
21871
|
// Fractal functions
|
|
21403
21872
|
Mandelbrot: ([c, maxIter], compile2, target) => {
|
|
21404
21873
|
if (c === null || maxIter === null)
|
|
21405
21874
|
throw new Error("Mandelbrot: missing arguments");
|
|
21406
21875
|
const iterCode = compileIntArg(maxIter, compile2, target);
|
|
21407
|
-
const strategy = selectFractalStrategy(target);
|
|
21408
|
-
if (strategy === "double") {
|
|
21409
|
-
const dpCoord = target?.language === "wgsl" ? "_dp_coord(v_uv)" : "_dp_coord()";
|
|
21410
|
-
return `_fractal_mandelbrot_dp(${dpCoord}, ${iterCode})`;
|
|
21411
|
-
}
|
|
21412
|
-
if (strategy === "perturbation") {
|
|
21413
|
-
const ptDelta = target?.language === "wgsl" ? "_pt_delta(v_uv)" : "_pt_delta()";
|
|
21414
|
-
return `_fractal_mandelbrot_pt(${ptDelta}, ${iterCode})`;
|
|
21415
|
-
}
|
|
21416
21876
|
return `_fractal_mandelbrot(${compile2(c)}, ${iterCode})`;
|
|
21417
21877
|
},
|
|
21418
21878
|
Julia: ([z, c, maxIter], compile2, target) => {
|
|
21419
21879
|
if (z === null || c === null || maxIter === null)
|
|
21420
21880
|
throw new Error("Julia: missing arguments");
|
|
21421
21881
|
const iterCode = compileIntArg(maxIter, compile2, target);
|
|
21422
|
-
const strategy = selectFractalStrategy(target);
|
|
21423
|
-
if (strategy === "double") {
|
|
21424
|
-
const dpCoord = target?.language === "wgsl" ? "_dp_coord(v_uv)" : "_dp_coord()";
|
|
21425
|
-
const cCode = compile2(c);
|
|
21426
|
-
return `_fractal_julia_dp(${dpCoord}, vec4(${cCode}, vec2(0.0)), ${iterCode})`;
|
|
21427
|
-
}
|
|
21428
|
-
if (strategy === "perturbation") {
|
|
21429
|
-
const ptDelta = target?.language === "wgsl" ? "_pt_delta(v_uv)" : "_pt_delta()";
|
|
21430
|
-
const cCode = compile2(c);
|
|
21431
|
-
return `_fractal_julia_pt(${ptDelta}, ${cCode}, ${iterCode})`;
|
|
21432
|
-
}
|
|
21433
21882
|
return `_fractal_julia(${compile2(z)}, ${compile2(c)}, ${iterCode})`;
|
|
21434
21883
|
},
|
|
21435
21884
|
// Vector/Matrix operations
|
|
@@ -22026,232 +22475,6 @@ fn _gpu_besselJ(n_in: i32, x_in: f32) -> f32 {
|
|
|
22026
22475
|
for (var k2: i32 = 2; k2 <= M; k2 += 2) { norm += 2.0 * vals[k2]; }
|
|
22027
22476
|
return sgn * vals[n] / norm;
|
|
22028
22477
|
}
|
|
22029
|
-
`;
|
|
22030
|
-
var GPU_DS_ARITHMETIC_PREAMBLE_GLSL = `
|
|
22031
|
-
// Split a float into high and low parts for exact multiplication
|
|
22032
|
-
vec2 ds_split(float a) {
|
|
22033
|
-
const float SPLIT = 4097.0; // 2^12 + 1
|
|
22034
|
-
float t = SPLIT * a;
|
|
22035
|
-
float hi = t - (t - a);
|
|
22036
|
-
float lo = a - hi;
|
|
22037
|
-
return vec2(hi, lo);
|
|
22038
|
-
}
|
|
22039
|
-
|
|
22040
|
-
// Create a double-single from a single float
|
|
22041
|
-
vec2 ds_from(float a) {
|
|
22042
|
-
return vec2(a, 0.0);
|
|
22043
|
-
}
|
|
22044
|
-
|
|
22045
|
-
// Error-free addition (Knuth TwoSum)
|
|
22046
|
-
vec2 ds_add(vec2 a, vec2 b) {
|
|
22047
|
-
float s = a.x + b.x;
|
|
22048
|
-
float v = s - a.x;
|
|
22049
|
-
float e = (a.x - (s - v)) + (b.x - v);
|
|
22050
|
-
float lo = (a.y + b.y) + e;
|
|
22051
|
-
float hi = s + lo;
|
|
22052
|
-
lo = lo - (hi - s);
|
|
22053
|
-
return vec2(hi, lo);
|
|
22054
|
-
}
|
|
22055
|
-
|
|
22056
|
-
// Double-single subtraction
|
|
22057
|
-
vec2 ds_sub(vec2 a, vec2 b) {
|
|
22058
|
-
return ds_add(a, vec2(-b.x, -b.y));
|
|
22059
|
-
}
|
|
22060
|
-
|
|
22061
|
-
// Error-free multiplication (Dekker TwoProduct)
|
|
22062
|
-
vec2 ds_mul(vec2 a, vec2 b) {
|
|
22063
|
-
float p = a.x * b.x;
|
|
22064
|
-
vec2 sa = ds_split(a.x);
|
|
22065
|
-
vec2 sb = ds_split(b.x);
|
|
22066
|
-
float err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
22067
|
-
err += a.x * b.y + a.y * b.x;
|
|
22068
|
-
float hi = p + err;
|
|
22069
|
-
float lo = err - (hi - p);
|
|
22070
|
-
return vec2(hi, lo);
|
|
22071
|
-
}
|
|
22072
|
-
|
|
22073
|
-
// Optimized self-multiply
|
|
22074
|
-
vec2 ds_sqr(vec2 a) {
|
|
22075
|
-
float p = a.x * a.x;
|
|
22076
|
-
vec2 sa = ds_split(a.x);
|
|
22077
|
-
float err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
22078
|
-
err += 2.0 * a.x * a.y;
|
|
22079
|
-
float hi = p + err;
|
|
22080
|
-
float lo = err - (hi - p);
|
|
22081
|
-
return vec2(hi, lo);
|
|
22082
|
-
}
|
|
22083
|
-
|
|
22084
|
-
// Compare magnitude: returns -1, 0, or 1
|
|
22085
|
-
float ds_cmp(vec2 a, vec2 b) {
|
|
22086
|
-
float d = a.x - b.x;
|
|
22087
|
-
if (d != 0.0) return sign(d);
|
|
22088
|
-
return sign(a.y - b.y);
|
|
22089
|
-
}
|
|
22090
|
-
`;
|
|
22091
|
-
var GPU_DS_ARITHMETIC_PREAMBLE_WGSL = `
|
|
22092
|
-
fn ds_split(a: f32) -> vec2f {
|
|
22093
|
-
const SPLIT: f32 = 4097.0;
|
|
22094
|
-
let t = SPLIT * a;
|
|
22095
|
-
let hi = t - (t - a);
|
|
22096
|
-
let lo = a - hi;
|
|
22097
|
-
return vec2f(hi, lo);
|
|
22098
|
-
}
|
|
22099
|
-
|
|
22100
|
-
fn ds_from(a: f32) -> vec2f {
|
|
22101
|
-
return vec2f(a, 0.0);
|
|
22102
|
-
}
|
|
22103
|
-
|
|
22104
|
-
fn ds_add(a: vec2f, b: vec2f) -> vec2f {
|
|
22105
|
-
let s = a.x + b.x;
|
|
22106
|
-
let v = s - a.x;
|
|
22107
|
-
let e = (a.x - (s - v)) + (b.x - v);
|
|
22108
|
-
let lo_t = (a.y + b.y) + e;
|
|
22109
|
-
let hi = s + lo_t;
|
|
22110
|
-
let lo = lo_t - (hi - s);
|
|
22111
|
-
return vec2f(hi, lo);
|
|
22112
|
-
}
|
|
22113
|
-
|
|
22114
|
-
fn ds_sub(a: vec2f, b: vec2f) -> vec2f {
|
|
22115
|
-
return ds_add(a, vec2f(-b.x, -b.y));
|
|
22116
|
-
}
|
|
22117
|
-
|
|
22118
|
-
fn ds_mul(a: vec2f, b: vec2f) -> vec2f {
|
|
22119
|
-
let p = a.x * b.x;
|
|
22120
|
-
let sa = ds_split(a.x);
|
|
22121
|
-
let sb = ds_split(b.x);
|
|
22122
|
-
var err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
22123
|
-
err += a.x * b.y + a.y * b.x;
|
|
22124
|
-
let hi = p + err;
|
|
22125
|
-
let lo = err - (hi - p);
|
|
22126
|
-
return vec2f(hi, lo);
|
|
22127
|
-
}
|
|
22128
|
-
|
|
22129
|
-
fn ds_sqr(a: vec2f) -> vec2f {
|
|
22130
|
-
let p = a.x * a.x;
|
|
22131
|
-
let sa = ds_split(a.x);
|
|
22132
|
-
var err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
22133
|
-
err += 2.0 * a.x * a.y;
|
|
22134
|
-
let hi = p + err;
|
|
22135
|
-
let lo = err - (hi - p);
|
|
22136
|
-
return vec2f(hi, lo);
|
|
22137
|
-
}
|
|
22138
|
-
|
|
22139
|
-
fn ds_cmp(a: vec2f, b: vec2f) -> f32 {
|
|
22140
|
-
let d = a.x - b.x;
|
|
22141
|
-
if (d != 0.0) { return sign(d); }
|
|
22142
|
-
return sign(a.y - b.y);
|
|
22143
|
-
}
|
|
22144
|
-
`;
|
|
22145
|
-
var GPU_FRACTAL_DP_PREAMBLE_GLSL = `
|
|
22146
|
-
uniform float _dp_cx_hi;
|
|
22147
|
-
uniform float _dp_cx_lo;
|
|
22148
|
-
uniform float _dp_cy_hi;
|
|
22149
|
-
uniform float _dp_cy_lo;
|
|
22150
|
-
uniform float _dp_w;
|
|
22151
|
-
uniform float _dp_h;
|
|
22152
|
-
|
|
22153
|
-
vec4 _dp_coord() {
|
|
22154
|
-
// Per-pixel offset from center \u2014 small, so float-precise
|
|
22155
|
-
float dx = (v_uv.x - 0.5) * _dp_w;
|
|
22156
|
-
float dy = (v_uv.y - 0.5) * _dp_h;
|
|
22157
|
-
// Combine center (hi+lo) + delta with emulated double precision
|
|
22158
|
-
vec2 cre = ds_add(vec2(_dp_cx_hi, _dp_cx_lo), ds_from(dx));
|
|
22159
|
-
vec2 cim = ds_add(vec2(_dp_cy_hi, _dp_cy_lo), ds_from(dy));
|
|
22160
|
-
return vec4(cre.x, cim.x, cre.y, cim.y);
|
|
22161
|
-
}
|
|
22162
|
-
|
|
22163
|
-
float _fractal_mandelbrot_dp(vec4 c, int maxIter) {
|
|
22164
|
-
// c = (re_hi, im_hi, re_lo, im_lo)
|
|
22165
|
-
vec2 cr = vec2(c.x, c.z); // real part as ds
|
|
22166
|
-
vec2 ci = vec2(c.y, c.w); // imag part as ds
|
|
22167
|
-
vec2 zr = vec2(0.0, 0.0);
|
|
22168
|
-
vec2 zi = vec2(0.0, 0.0);
|
|
22169
|
-
for (int i = 0; i < maxIter; i++) {
|
|
22170
|
-
vec2 zr2 = ds_sqr(zr);
|
|
22171
|
-
vec2 zi2 = ds_sqr(zi);
|
|
22172
|
-
// |z|^2 > 4.0 ?
|
|
22173
|
-
vec2 mag2 = ds_add(zr2, zi2);
|
|
22174
|
-
if (mag2.x > 4.0)
|
|
22175
|
-
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22176
|
-
// z = z^2 + c
|
|
22177
|
-
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci); // 2*zr*zi + ci
|
|
22178
|
-
zr = ds_add(ds_sub(zr2, zi2), cr); // zr^2 - zi^2 + cr
|
|
22179
|
-
zi = new_zi;
|
|
22180
|
-
}
|
|
22181
|
-
return 1.0;
|
|
22182
|
-
}
|
|
22183
|
-
|
|
22184
|
-
float _fractal_julia_dp(vec4 z_in, vec4 c, int maxIter) {
|
|
22185
|
-
vec2 zr = vec2(z_in.x, z_in.z);
|
|
22186
|
-
vec2 zi = vec2(z_in.y, z_in.w);
|
|
22187
|
-
vec2 cr = vec2(c.x, c.z);
|
|
22188
|
-
vec2 ci = vec2(c.y, c.w);
|
|
22189
|
-
for (int i = 0; i < maxIter; i++) {
|
|
22190
|
-
vec2 zr2 = ds_sqr(zr);
|
|
22191
|
-
vec2 zi2 = ds_sqr(zi);
|
|
22192
|
-
vec2 mag2 = ds_add(zr2, zi2);
|
|
22193
|
-
if (mag2.x > 4.0)
|
|
22194
|
-
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22195
|
-
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
22196
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
22197
|
-
zi = new_zi;
|
|
22198
|
-
}
|
|
22199
|
-
return 1.0;
|
|
22200
|
-
}
|
|
22201
|
-
`;
|
|
22202
|
-
var GPU_FRACTAL_DP_PREAMBLE_WGSL = `
|
|
22203
|
-
@group(0) @binding(10) var<uniform> _dp_cx_hi: f32;
|
|
22204
|
-
@group(0) @binding(11) var<uniform> _dp_cx_lo: f32;
|
|
22205
|
-
@group(0) @binding(12) var<uniform> _dp_cy_hi: f32;
|
|
22206
|
-
@group(0) @binding(13) var<uniform> _dp_cy_lo: f32;
|
|
22207
|
-
@group(0) @binding(14) var<uniform> _dp_w: f32;
|
|
22208
|
-
@group(0) @binding(15) var<uniform> _dp_h: f32;
|
|
22209
|
-
|
|
22210
|
-
fn _dp_coord(uv: vec2f) -> vec4f {
|
|
22211
|
-
let dx = (uv.x - 0.5) * _dp_w;
|
|
22212
|
-
let dy = (uv.y - 0.5) * _dp_h;
|
|
22213
|
-
let cre = ds_add(vec2f(_dp_cx_hi, _dp_cx_lo), ds_from(dx));
|
|
22214
|
-
let cim = ds_add(vec2f(_dp_cy_hi, _dp_cy_lo), ds_from(dy));
|
|
22215
|
-
return vec4f(cre.x, cim.x, cre.y, cim.y);
|
|
22216
|
-
}
|
|
22217
|
-
|
|
22218
|
-
fn _fractal_mandelbrot_dp(c: vec4f, maxIter: i32) -> f32 {
|
|
22219
|
-
let cr = vec2f(c.x, c.z);
|
|
22220
|
-
let ci = vec2f(c.y, c.w);
|
|
22221
|
-
var zr = vec2f(0.0, 0.0);
|
|
22222
|
-
var zi = vec2f(0.0, 0.0);
|
|
22223
|
-
for (var i: i32 = 0; i < maxIter; i++) {
|
|
22224
|
-
let zr2 = ds_sqr(zr);
|
|
22225
|
-
let zi2 = ds_sqr(zi);
|
|
22226
|
-
let mag2 = ds_add(zr2, zi2);
|
|
22227
|
-
if (mag2.x > 4.0) {
|
|
22228
|
-
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22229
|
-
}
|
|
22230
|
-
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
22231
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
22232
|
-
zi = new_zi;
|
|
22233
|
-
}
|
|
22234
|
-
return 1.0;
|
|
22235
|
-
}
|
|
22236
|
-
|
|
22237
|
-
fn _fractal_julia_dp(z_in: vec4f, c: vec4f, maxIter: i32) -> f32 {
|
|
22238
|
-
var zr = vec2f(z_in.x, z_in.z);
|
|
22239
|
-
var zi = vec2f(z_in.y, z_in.w);
|
|
22240
|
-
let cr = vec2f(c.x, c.z);
|
|
22241
|
-
let ci = vec2f(c.y, c.w);
|
|
22242
|
-
for (var i: i32 = 0; i < maxIter; i++) {
|
|
22243
|
-
let zr2 = ds_sqr(zr);
|
|
22244
|
-
let zi2 = ds_sqr(zi);
|
|
22245
|
-
let mag2 = ds_add(zr2, zi2);
|
|
22246
|
-
if (mag2.x > 4.0) {
|
|
22247
|
-
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22248
|
-
}
|
|
22249
|
-
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
22250
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
22251
|
-
zi = new_zi;
|
|
22252
|
-
}
|
|
22253
|
-
return 1.0;
|
|
22254
|
-
}
|
|
22255
22478
|
`;
|
|
22256
22479
|
var GPU_FRACTAL_PREAMBLE_GLSL = `
|
|
22257
22480
|
float _fractal_mandelbrot(vec2 c, int maxIter) {
|
|
@@ -22295,208 +22518,6 @@ fn _fractal_julia(z_in: vec2f, c: vec2f, maxIter: i32) -> f32 {
|
|
|
22295
22518
|
}
|
|
22296
22519
|
return 1.0;
|
|
22297
22520
|
}
|
|
22298
|
-
`;
|
|
22299
|
-
var GPU_FRACTAL_PT_PREAMBLE_GLSL = `
|
|
22300
|
-
uniform sampler2D _refOrbit;
|
|
22301
|
-
uniform int _refOrbitLen;
|
|
22302
|
-
uniform int _refOrbitTexWidth;
|
|
22303
|
-
uniform float _pt_offset_x;
|
|
22304
|
-
uniform float _pt_offset_y;
|
|
22305
|
-
uniform float _pt_w;
|
|
22306
|
-
uniform float _pt_h;
|
|
22307
|
-
|
|
22308
|
-
vec2 _pt_delta() {
|
|
22309
|
-
float dx = _pt_offset_x + (v_uv.x - 0.5) * _pt_w;
|
|
22310
|
-
float dy = _pt_offset_y + (v_uv.y - 0.5) * _pt_h;
|
|
22311
|
-
return vec2(dx, dy);
|
|
22312
|
-
}
|
|
22313
|
-
|
|
22314
|
-
vec2 _pt_fetch_orbit(int i) {
|
|
22315
|
-
int y = i / _refOrbitTexWidth;
|
|
22316
|
-
int x = i - y * _refOrbitTexWidth;
|
|
22317
|
-
return texelFetch(_refOrbit, ivec2(x, y), 0).rg;
|
|
22318
|
-
}
|
|
22319
|
-
|
|
22320
|
-
float _fractal_mandelbrot_pt(vec2 delta_c, int maxIter) {
|
|
22321
|
-
float dr = 0.0;
|
|
22322
|
-
float di = 0.0;
|
|
22323
|
-
int orbitLen = min(maxIter, _refOrbitLen);
|
|
22324
|
-
for (int i = 0; i < orbitLen; i++) {
|
|
22325
|
-
vec2 Zn = _pt_fetch_orbit(i);
|
|
22326
|
-
// delta_{n+1} = 2*Z_n*delta_n + delta_n^2 + delta_c
|
|
22327
|
-
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22328
|
-
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22329
|
-
dr = new_dr;
|
|
22330
|
-
di = new_di;
|
|
22331
|
-
// Full z = Z_{n+1} + delta for escape check
|
|
22332
|
-
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
22333
|
-
float zr = Zn1.x + dr;
|
|
22334
|
-
float zi = Zn1.y + di;
|
|
22335
|
-
float mag2 = zr * zr + zi * zi;
|
|
22336
|
-
if (mag2 > 4.0)
|
|
22337
|
-
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22338
|
-
// Glitch detection: |delta|^2 > |Z|^2
|
|
22339
|
-
float dmag2 = dr * dr + di * di;
|
|
22340
|
-
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22341
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22342
|
-
// Rebase to absolute coordinates and continue with single-float
|
|
22343
|
-
float abs_zr = Zn1.x + dr;
|
|
22344
|
-
float abs_zi = Zn1.y + di;
|
|
22345
|
-
// Reconstruct absolute c from reference + delta
|
|
22346
|
-
// (Use ds_from for the concept, but single-float suffices for fallback)
|
|
22347
|
-
float cx = abs_zr - dr + delta_c.x;
|
|
22348
|
-
float cy = abs_zi - di + delta_c.y;
|
|
22349
|
-
for (int j = i + 1; j < maxIter; j++) {
|
|
22350
|
-
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
22351
|
-
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
22352
|
-
abs_zr = new_zr;
|
|
22353
|
-
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
22354
|
-
if (mag2 > 4.0)
|
|
22355
|
-
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22356
|
-
}
|
|
22357
|
-
return 1.0;
|
|
22358
|
-
}
|
|
22359
|
-
}
|
|
22360
|
-
return 1.0;
|
|
22361
|
-
}
|
|
22362
|
-
|
|
22363
|
-
float _fractal_julia_pt(vec2 z_delta, vec2 delta_c, int maxIter) {
|
|
22364
|
-
float dr = z_delta.x;
|
|
22365
|
-
float di = z_delta.y;
|
|
22366
|
-
int orbitLen = min(maxIter, _refOrbitLen);
|
|
22367
|
-
for (int i = 0; i < orbitLen; i++) {
|
|
22368
|
-
vec2 Zn = _pt_fetch_orbit(i);
|
|
22369
|
-
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22370
|
-
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22371
|
-
dr = new_dr;
|
|
22372
|
-
di = new_di;
|
|
22373
|
-
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
22374
|
-
float zr = Zn1.x + dr;
|
|
22375
|
-
float zi = Zn1.y + di;
|
|
22376
|
-
float mag2 = zr * zr + zi * zi;
|
|
22377
|
-
if (mag2 > 4.0)
|
|
22378
|
-
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22379
|
-
float dmag2 = dr * dr + di * di;
|
|
22380
|
-
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22381
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22382
|
-
float abs_zr = Zn1.x + dr;
|
|
22383
|
-
float abs_zi = Zn1.y + di;
|
|
22384
|
-
float cx = delta_c.x;
|
|
22385
|
-
float cy = delta_c.y;
|
|
22386
|
-
for (int j = i + 1; j < maxIter; j++) {
|
|
22387
|
-
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
22388
|
-
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
22389
|
-
abs_zr = new_zr;
|
|
22390
|
-
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
22391
|
-
if (mag2 > 4.0)
|
|
22392
|
-
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22393
|
-
}
|
|
22394
|
-
return 1.0;
|
|
22395
|
-
}
|
|
22396
|
-
}
|
|
22397
|
-
return 1.0;
|
|
22398
|
-
}
|
|
22399
|
-
`;
|
|
22400
|
-
var GPU_FRACTAL_PT_PREAMBLE_WGSL = `
|
|
22401
|
-
@group(0) @binding(1) var _refOrbit: texture_2d<f32>;
|
|
22402
|
-
var<uniform> _refOrbitLen: i32;
|
|
22403
|
-
var<uniform> _refOrbitTexWidth: i32;
|
|
22404
|
-
var<uniform> _pt_offset_x: f32;
|
|
22405
|
-
var<uniform> _pt_offset_y: f32;
|
|
22406
|
-
var<uniform> _pt_w: f32;
|
|
22407
|
-
var<uniform> _pt_h: f32;
|
|
22408
|
-
|
|
22409
|
-
fn _pt_delta(uv: vec2f) -> vec2f {
|
|
22410
|
-
let dx = _pt_offset_x + (uv.x - 0.5) * _pt_w;
|
|
22411
|
-
let dy = _pt_offset_y + (uv.y - 0.5) * _pt_h;
|
|
22412
|
-
return vec2f(dx, dy);
|
|
22413
|
-
}
|
|
22414
|
-
|
|
22415
|
-
fn _pt_fetch_orbit(i: i32) -> vec2f {
|
|
22416
|
-
let y = i / _refOrbitTexWidth;
|
|
22417
|
-
let x = i - y * _refOrbitTexWidth;
|
|
22418
|
-
return textureLoad(_refOrbit, vec2i(x, y), 0).rg;
|
|
22419
|
-
}
|
|
22420
|
-
|
|
22421
|
-
fn _fractal_mandelbrot_pt(delta_c: vec2f, maxIter: i32) -> f32 {
|
|
22422
|
-
var dr: f32 = 0.0;
|
|
22423
|
-
var di: f32 = 0.0;
|
|
22424
|
-
let orbitLen = min(maxIter, _refOrbitLen);
|
|
22425
|
-
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
22426
|
-
let Zn = _pt_fetch_orbit(i);
|
|
22427
|
-
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22428
|
-
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22429
|
-
dr = new_dr;
|
|
22430
|
-
di = new_di;
|
|
22431
|
-
var Zn1 = vec2f(0.0);
|
|
22432
|
-
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
22433
|
-
let zr = Zn1.x + dr;
|
|
22434
|
-
let zi = Zn1.y + di;
|
|
22435
|
-
var mag2 = zr * zr + zi * zi;
|
|
22436
|
-
if (mag2 > 4.0) {
|
|
22437
|
-
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22438
|
-
}
|
|
22439
|
-
let dmag2 = dr * dr + di * di;
|
|
22440
|
-
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22441
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22442
|
-
var f_zr = Zn1.x + dr;
|
|
22443
|
-
var f_zi = Zn1.y + di;
|
|
22444
|
-
let cx = delta_c.x;
|
|
22445
|
-
let cy = delta_c.y;
|
|
22446
|
-
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
22447
|
-
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
22448
|
-
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
22449
|
-
f_zr = t_zr;
|
|
22450
|
-
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
22451
|
-
if (mag2 > 4.0) {
|
|
22452
|
-
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22453
|
-
}
|
|
22454
|
-
}
|
|
22455
|
-
return 1.0;
|
|
22456
|
-
}
|
|
22457
|
-
}
|
|
22458
|
-
return 1.0;
|
|
22459
|
-
}
|
|
22460
|
-
|
|
22461
|
-
fn _fractal_julia_pt(z_delta: vec2f, delta_c: vec2f, maxIter: i32) -> f32 {
|
|
22462
|
-
var dr = z_delta.x;
|
|
22463
|
-
var di = z_delta.y;
|
|
22464
|
-
let orbitLen = min(maxIter, _refOrbitLen);
|
|
22465
|
-
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
22466
|
-
let Zn = _pt_fetch_orbit(i);
|
|
22467
|
-
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22468
|
-
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22469
|
-
dr = new_dr;
|
|
22470
|
-
di = new_di;
|
|
22471
|
-
var Zn1 = vec2f(0.0);
|
|
22472
|
-
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
22473
|
-
let zr = Zn1.x + dr;
|
|
22474
|
-
let zi = Zn1.y + di;
|
|
22475
|
-
var mag2 = zr * zr + zi * zi;
|
|
22476
|
-
if (mag2 > 4.0) {
|
|
22477
|
-
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22478
|
-
}
|
|
22479
|
-
let dmag2 = dr * dr + di * di;
|
|
22480
|
-
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22481
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22482
|
-
var f_zr = Zn1.x + dr;
|
|
22483
|
-
var f_zi = Zn1.y + di;
|
|
22484
|
-
let cx = delta_c.x;
|
|
22485
|
-
let cy = delta_c.y;
|
|
22486
|
-
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
22487
|
-
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
22488
|
-
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
22489
|
-
f_zr = t_zr;
|
|
22490
|
-
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
22491
|
-
if (mag2 > 4.0) {
|
|
22492
|
-
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22493
|
-
}
|
|
22494
|
-
}
|
|
22495
|
-
return 1.0;
|
|
22496
|
-
}
|
|
22497
|
-
}
|
|
22498
|
-
return 1.0;
|
|
22499
|
-
}
|
|
22500
22521
|
`;
|
|
22501
22522
|
var GPU_COLOR_PREAMBLE_GLSL = `
|
|
22502
22523
|
float _gpu_srgb_to_linear(float c) {
|
|
@@ -22538,28 +22559,124 @@ vec3 _gpu_oklab_to_srgb(vec3 lab) {
|
|
|
22538
22559
|
|
|
22539
22560
|
vec3 _gpu_oklab_to_oklch(vec3 lab) {
|
|
22540
22561
|
float C = length(lab.yz);
|
|
22541
|
-
float H = atan(lab.z, lab.y);
|
|
22562
|
+
float H = atan(lab.z, lab.y) * (180.0 / 3.14159265359);
|
|
22563
|
+
if (H < 0.0) H += 360.0;
|
|
22542
22564
|
return vec3(lab.x, C, H);
|
|
22543
22565
|
}
|
|
22544
22566
|
|
|
22545
22567
|
vec3 _gpu_oklch_to_oklab(vec3 lch) {
|
|
22546
|
-
|
|
22568
|
+
float h_rad = lch.z * (3.14159265359 / 180.0);
|
|
22569
|
+
return vec3(lch.x, lch.y * cos(h_rad), lch.y * sin(h_rad));
|
|
22570
|
+
}
|
|
22571
|
+
|
|
22572
|
+
vec3 _gpu_srgb_to_oklch(vec3 rgb) {
|
|
22573
|
+
return _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb));
|
|
22547
22574
|
}
|
|
22548
22575
|
|
|
22549
|
-
vec3
|
|
22550
|
-
|
|
22551
|
-
|
|
22576
|
+
vec3 _gpu_oklch_to_srgb(vec3 lch) {
|
|
22577
|
+
return _gpu_oklab_to_srgb(_gpu_oklch_to_oklab(lch));
|
|
22578
|
+
}
|
|
22579
|
+
|
|
22580
|
+
// HSL conversion. Hue in degrees, saturation/lightness in 0-1.
|
|
22581
|
+
vec3 _gpu_hsl_to_rgb(vec3 hsl) {
|
|
22582
|
+
float h = hsl.x;
|
|
22583
|
+
float s = hsl.y;
|
|
22584
|
+
float l = hsl.z;
|
|
22585
|
+
float c = (1.0 - abs(2.0 * l - 1.0)) * s;
|
|
22586
|
+
float h6 = h / 60.0;
|
|
22587
|
+
float x = c * (1.0 - abs(mod(h6, 2.0) - 1.0));
|
|
22588
|
+
float r = 0.0;
|
|
22589
|
+
float g = 0.0;
|
|
22590
|
+
float b = 0.0;
|
|
22591
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
22592
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
22593
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
22594
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
22595
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
22596
|
+
else { r = c; g = 0.0; b = x; }
|
|
22597
|
+
float m = l - c / 2.0;
|
|
22598
|
+
return vec3(r + m, g + m, b + m);
|
|
22599
|
+
}
|
|
22600
|
+
|
|
22601
|
+
vec3 _gpu_rgb_to_hsl(vec3 rgb) {
|
|
22602
|
+
float maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
22603
|
+
float minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
22604
|
+
float l = (maxc + minc) / 2.0;
|
|
22605
|
+
float d = maxc - minc;
|
|
22606
|
+
if (d < 1e-6) return vec3(0.0, 0.0, l);
|
|
22607
|
+
float s = d / (1.0 - abs(2.0 * l - 1.0));
|
|
22608
|
+
float h;
|
|
22609
|
+
if (maxc == rgb.x) h = mod((rgb.y - rgb.z) / d, 6.0);
|
|
22610
|
+
else if (maxc == rgb.y) h = (rgb.z - rgb.x) / d + 2.0;
|
|
22611
|
+
else h = (rgb.x - rgb.y) / d + 4.0;
|
|
22612
|
+
h *= 60.0;
|
|
22613
|
+
if (h < 0.0) h += 360.0;
|
|
22614
|
+
return vec3(h, s, l);
|
|
22615
|
+
}
|
|
22616
|
+
|
|
22617
|
+
// HSV conversion. Hue in degrees, saturation/value in 0-1.
|
|
22618
|
+
vec3 _gpu_hsv_to_rgb(vec3 hsv) {
|
|
22619
|
+
float h = hsv.x;
|
|
22620
|
+
float s = hsv.y;
|
|
22621
|
+
float v = hsv.z;
|
|
22622
|
+
float c = v * s;
|
|
22623
|
+
float h6 = h / 60.0;
|
|
22624
|
+
float x = c * (1.0 - abs(mod(h6, 2.0) - 1.0));
|
|
22625
|
+
float r = 0.0;
|
|
22626
|
+
float g = 0.0;
|
|
22627
|
+
float b = 0.0;
|
|
22628
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
22629
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
22630
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
22631
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
22632
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
22633
|
+
else { r = c; g = 0.0; b = x; }
|
|
22634
|
+
float m = v - c;
|
|
22635
|
+
return vec3(r + m, g + m, b + m);
|
|
22636
|
+
}
|
|
22637
|
+
|
|
22638
|
+
vec3 _gpu_rgb_to_hsv(vec3 rgb) {
|
|
22639
|
+
float maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
22640
|
+
float minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
22641
|
+
float v = maxc;
|
|
22642
|
+
float d = maxc - minc;
|
|
22643
|
+
if (d < 1e-6) return vec3(0.0, 0.0, v);
|
|
22644
|
+
float s = (maxc < 1e-6) ? 0.0 : d / maxc;
|
|
22645
|
+
float h;
|
|
22646
|
+
if (maxc == rgb.x) h = mod((rgb.y - rgb.z) / d, 6.0);
|
|
22647
|
+
else if (maxc == rgb.y) h = (rgb.z - rgb.x) / d + 2.0;
|
|
22648
|
+
else h = (rgb.x - rgb.y) / d + 4.0;
|
|
22649
|
+
h *= 60.0;
|
|
22650
|
+
if (h < 0.0) h += 360.0;
|
|
22651
|
+
return vec3(h, s, v);
|
|
22652
|
+
}
|
|
22653
|
+
|
|
22654
|
+
vec3 _gpu_color_mix(vec3 lch1, vec3 lch2, float t) {
|
|
22552
22655
|
float L = mix(lch1.x, lch2.x, t);
|
|
22553
22656
|
float C = mix(lch1.y, lch2.y, t);
|
|
22554
|
-
|
|
22555
|
-
|
|
22556
|
-
|
|
22557
|
-
if (
|
|
22558
|
-
|
|
22559
|
-
|
|
22657
|
+
bool a1 = lch1.y < 1e-6;
|
|
22658
|
+
bool a2 = lch2.y < 1e-6;
|
|
22659
|
+
float H;
|
|
22660
|
+
if (a1 && a2) {
|
|
22661
|
+
H = lch1.z;
|
|
22662
|
+
} else if (a1) {
|
|
22663
|
+
H = lch2.z;
|
|
22664
|
+
} else if (a2) {
|
|
22665
|
+
H = lch1.z;
|
|
22666
|
+
} else {
|
|
22667
|
+
float dh = lch2.z - lch1.z;
|
|
22668
|
+
if (dh > 180.0) dh -= 360.0;
|
|
22669
|
+
if (dh < -180.0) dh += 360.0;
|
|
22670
|
+
H = lch1.z + dh * t;
|
|
22671
|
+
if (H < 0.0) H += 360.0;
|
|
22672
|
+
if (H >= 360.0) H -= 360.0;
|
|
22673
|
+
}
|
|
22674
|
+
return vec3(L, C, H);
|
|
22560
22675
|
}
|
|
22561
22676
|
|
|
22562
|
-
float _gpu_apca(vec3
|
|
22677
|
+
float _gpu_apca(vec3 lch_bg, vec3 lch_fg) {
|
|
22678
|
+
vec3 bg = _gpu_oklch_to_srgb(lch_bg);
|
|
22679
|
+
vec3 fg = _gpu_oklch_to_srgb(lch_fg);
|
|
22563
22680
|
float bgR = _gpu_srgb_to_linear(bg.x);
|
|
22564
22681
|
float bgG = _gpu_srgb_to_linear(bg.y);
|
|
22565
22682
|
float bgB = _gpu_srgb_to_linear(bg.z);
|
|
@@ -22570,9 +22687,7 @@ float _gpu_apca(vec3 bg, vec3 fg) {
|
|
|
22570
22687
|
float fgY = 0.2126729 * fgR + 0.7151522 * fgG + 0.0721750 * fgB;
|
|
22571
22688
|
float bgC = pow(bgY, 0.56);
|
|
22572
22689
|
float fgC = pow(fgY, 0.57);
|
|
22573
|
-
float contrast = (bgC
|
|
22574
|
-
? (bgC - fgC) * 1.14
|
|
22575
|
-
: (bgC - fgC) * 1.14;
|
|
22690
|
+
float contrast = (bgC - fgC) * 1.14;
|
|
22576
22691
|
return contrast * 100.0;
|
|
22577
22692
|
}
|
|
22578
22693
|
`;
|
|
@@ -22616,28 +22731,133 @@ fn _gpu_oklab_to_srgb(lab: vec3f) -> vec3f {
|
|
|
22616
22731
|
|
|
22617
22732
|
fn _gpu_oklab_to_oklch(lab: vec3f) -> vec3f {
|
|
22618
22733
|
let C = length(lab.yz);
|
|
22619
|
-
|
|
22734
|
+
var H = atan2(lab.z, lab.y) * (180.0 / 3.14159265359);
|
|
22735
|
+
if (H < 0.0) { H = H + 360.0; }
|
|
22620
22736
|
return vec3f(lab.x, C, H);
|
|
22621
22737
|
}
|
|
22622
22738
|
|
|
22623
22739
|
fn _gpu_oklch_to_oklab(lch: vec3f) -> vec3f {
|
|
22624
|
-
|
|
22740
|
+
let h_rad = lch.z * (3.14159265359 / 180.0);
|
|
22741
|
+
return vec3f(lch.x, lch.y * cos(h_rad), lch.y * sin(h_rad));
|
|
22625
22742
|
}
|
|
22626
22743
|
|
|
22627
|
-
fn
|
|
22628
|
-
|
|
22629
|
-
|
|
22744
|
+
fn _gpu_srgb_to_oklch(rgb: vec3f) -> vec3f {
|
|
22745
|
+
return _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb));
|
|
22746
|
+
}
|
|
22747
|
+
|
|
22748
|
+
fn _gpu_oklch_to_srgb(lch: vec3f) -> vec3f {
|
|
22749
|
+
return _gpu_oklab_to_srgb(_gpu_oklch_to_oklab(lch));
|
|
22750
|
+
}
|
|
22751
|
+
|
|
22752
|
+
fn _gpu_hsl_to_rgb(hsl: vec3f) -> vec3f {
|
|
22753
|
+
let h = hsl.x;
|
|
22754
|
+
let s = hsl.y;
|
|
22755
|
+
let l = hsl.z;
|
|
22756
|
+
let c = (1.0 - abs(2.0 * l - 1.0)) * s;
|
|
22757
|
+
let h6 = h / 60.0;
|
|
22758
|
+
let x = c * (1.0 - abs((h6 - 2.0 * floor(h6 / 2.0)) - 1.0));
|
|
22759
|
+
var r: f32 = 0.0;
|
|
22760
|
+
var g: f32 = 0.0;
|
|
22761
|
+
var b: f32 = 0.0;
|
|
22762
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
22763
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
22764
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
22765
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
22766
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
22767
|
+
else { r = c; g = 0.0; b = x; }
|
|
22768
|
+
let m = l - c / 2.0;
|
|
22769
|
+
return vec3f(r + m, g + m, b + m);
|
|
22770
|
+
}
|
|
22771
|
+
|
|
22772
|
+
fn _gpu_rgb_to_hsl(rgb: vec3f) -> vec3f {
|
|
22773
|
+
let maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
22774
|
+
let minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
22775
|
+
let l = (maxc + minc) / 2.0;
|
|
22776
|
+
let d = maxc - minc;
|
|
22777
|
+
if (d < 1e-6) { return vec3f(0.0, 0.0, l); }
|
|
22778
|
+
let s = d / (1.0 - abs(2.0 * l - 1.0));
|
|
22779
|
+
var h: f32;
|
|
22780
|
+
if (maxc == rgb.x) {
|
|
22781
|
+
let v = (rgb.y - rgb.z) / d;
|
|
22782
|
+
h = v - 6.0 * floor(v / 6.0);
|
|
22783
|
+
} else if (maxc == rgb.y) {
|
|
22784
|
+
h = (rgb.z - rgb.x) / d + 2.0;
|
|
22785
|
+
} else {
|
|
22786
|
+
h = (rgb.x - rgb.y) / d + 4.0;
|
|
22787
|
+
}
|
|
22788
|
+
h = h * 60.0;
|
|
22789
|
+
if (h < 0.0) { h = h + 360.0; }
|
|
22790
|
+
return vec3f(h, s, l);
|
|
22791
|
+
}
|
|
22792
|
+
|
|
22793
|
+
fn _gpu_hsv_to_rgb(hsv: vec3f) -> vec3f {
|
|
22794
|
+
let h = hsv.x;
|
|
22795
|
+
let s = hsv.y;
|
|
22796
|
+
let v = hsv.z;
|
|
22797
|
+
let c = v * s;
|
|
22798
|
+
let h6 = h / 60.0;
|
|
22799
|
+
let x = c * (1.0 - abs((h6 - 2.0 * floor(h6 / 2.0)) - 1.0));
|
|
22800
|
+
var r: f32 = 0.0;
|
|
22801
|
+
var g: f32 = 0.0;
|
|
22802
|
+
var b: f32 = 0.0;
|
|
22803
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
22804
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
22805
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
22806
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
22807
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
22808
|
+
else { r = c; g = 0.0; b = x; }
|
|
22809
|
+
let m = v - c;
|
|
22810
|
+
return vec3f(r + m, g + m, b + m);
|
|
22811
|
+
}
|
|
22812
|
+
|
|
22813
|
+
fn _gpu_rgb_to_hsv(rgb: vec3f) -> vec3f {
|
|
22814
|
+
let maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
22815
|
+
let minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
22816
|
+
let v = maxc;
|
|
22817
|
+
let d = maxc - minc;
|
|
22818
|
+
if (d < 1e-6) { return vec3f(0.0, 0.0, v); }
|
|
22819
|
+
var s: f32 = 0.0;
|
|
22820
|
+
if (maxc >= 1e-6) { s = d / maxc; }
|
|
22821
|
+
var h: f32;
|
|
22822
|
+
if (maxc == rgb.x) {
|
|
22823
|
+
let q = (rgb.y - rgb.z) / d;
|
|
22824
|
+
h = q - 6.0 * floor(q / 6.0);
|
|
22825
|
+
} else if (maxc == rgb.y) {
|
|
22826
|
+
h = (rgb.z - rgb.x) / d + 2.0;
|
|
22827
|
+
} else {
|
|
22828
|
+
h = (rgb.x - rgb.y) / d + 4.0;
|
|
22829
|
+
}
|
|
22830
|
+
h = h * 60.0;
|
|
22831
|
+
if (h < 0.0) { h = h + 360.0; }
|
|
22832
|
+
return vec3f(h, s, v);
|
|
22833
|
+
}
|
|
22834
|
+
|
|
22835
|
+
fn _gpu_color_mix(lch1: vec3f, lch2: vec3f, t: f32) -> vec3f {
|
|
22630
22836
|
let L = mix(lch1.x, lch2.x, t);
|
|
22631
22837
|
let C = mix(lch1.y, lch2.y, t);
|
|
22632
|
-
let
|
|
22633
|
-
|
|
22634
|
-
|
|
22635
|
-
if (
|
|
22636
|
-
|
|
22637
|
-
|
|
22838
|
+
let a1 = lch1.y < 1e-6;
|
|
22839
|
+
let a2 = lch2.y < 1e-6;
|
|
22840
|
+
var H: f32;
|
|
22841
|
+
if (a1 && a2) {
|
|
22842
|
+
H = lch1.z;
|
|
22843
|
+
} else if (a1) {
|
|
22844
|
+
H = lch2.z;
|
|
22845
|
+
} else if (a2) {
|
|
22846
|
+
H = lch1.z;
|
|
22847
|
+
} else {
|
|
22848
|
+
var dh = lch2.z - lch1.z;
|
|
22849
|
+
if (dh > 180.0) { dh = dh - 360.0; }
|
|
22850
|
+
if (dh < -180.0) { dh = dh + 360.0; }
|
|
22851
|
+
H = lch1.z + dh * t;
|
|
22852
|
+
if (H < 0.0) { H = H + 360.0; }
|
|
22853
|
+
if (H >= 360.0) { H = H - 360.0; }
|
|
22854
|
+
}
|
|
22855
|
+
return vec3f(L, C, H);
|
|
22638
22856
|
}
|
|
22639
22857
|
|
|
22640
|
-
fn _gpu_apca(
|
|
22858
|
+
fn _gpu_apca(lch_bg: vec3f, lch_fg: vec3f) -> f32 {
|
|
22859
|
+
let bg = _gpu_oklch_to_srgb(lch_bg);
|
|
22860
|
+
let fg = _gpu_oklch_to_srgb(lch_fg);
|
|
22641
22861
|
let bgR = _gpu_srgb_to_linear(bg.x);
|
|
22642
22862
|
let bgG = _gpu_srgb_to_linear(bg.y);
|
|
22643
22863
|
let bgB = _gpu_srgb_to_linear(bg.z);
|
|
@@ -22925,7 +23145,7 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
22925
23145
|
if (stmts.length === 0) return "";
|
|
22926
23146
|
const last = stmts.length - 1;
|
|
22927
23147
|
stmts[last] = `return ${stmts[last]}`;
|
|
22928
|
-
return stmts.join(";\n");
|
|
23148
|
+
return stmts.join(";\n") + ";";
|
|
22929
23149
|
},
|
|
22930
23150
|
...options
|
|
22931
23151
|
};
|
|
@@ -22936,7 +23156,6 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
22936
23156
|
const constants = this.getConstants();
|
|
22937
23157
|
const v2 = this.languageId === "wgsl" ? "vec2f" : "vec2";
|
|
22938
23158
|
const target = this.createTarget({
|
|
22939
|
-
hints: options.hints,
|
|
22940
23159
|
functions: (id) => {
|
|
22941
23160
|
if (userFunctions && id in userFunctions) {
|
|
22942
23161
|
const fn = userFunctions[id];
|
|
@@ -22975,89 +23194,12 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
22975
23194
|
if (code.includes("_gpu_besselJ"))
|
|
22976
23195
|
preamble += this.languageId === "wgsl" ? GPU_BESSELJ_PREAMBLE_WGSL : GPU_BESSELJ_PREAMBLE_GLSL;
|
|
22977
23196
|
if (code.includes("_fractal_")) {
|
|
22978
|
-
|
|
22979
|
-
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
22980
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PT_PREAMBLE_WGSL : GPU_FRACTAL_PT_PREAMBLE_GLSL;
|
|
22981
|
-
} else if (code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) {
|
|
22982
|
-
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
22983
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_DP_PREAMBLE_WGSL : GPU_FRACTAL_DP_PREAMBLE_GLSL;
|
|
22984
|
-
} else {
|
|
22985
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
22986
|
-
}
|
|
23197
|
+
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
22987
23198
|
}
|
|
22988
23199
|
if (code.includes("_gpu_srgb_to") || code.includes("_gpu_oklab") || code.includes("_gpu_oklch") || code.includes("_gpu_color_mix") || code.includes("_gpu_apca")) {
|
|
22989
23200
|
preamble += this.languageId === "wgsl" ? GPU_COLOR_PREAMBLE_WGSL : GPU_COLOR_PREAMBLE_GLSL;
|
|
22990
23201
|
}
|
|
22991
23202
|
if (preamble) result.preamble = preamble;
|
|
22992
|
-
if (code.includes("_fractal_") && options.hints?.viewport) {
|
|
22993
|
-
const strategy = selectFractalStrategy(target);
|
|
22994
|
-
const radius = options.hints.viewport.radius;
|
|
22995
|
-
switch (strategy) {
|
|
22996
|
-
case "single":
|
|
22997
|
-
result.staleWhen = { radiusBelow: 1e-6 };
|
|
22998
|
-
break;
|
|
22999
|
-
case "double":
|
|
23000
|
-
result.staleWhen = { radiusBelow: 1e-14, radiusAbove: 1e-5 };
|
|
23001
|
-
break;
|
|
23002
|
-
case "perturbation":
|
|
23003
|
-
result.staleWhen = {
|
|
23004
|
-
radiusAbove: 1e-5,
|
|
23005
|
-
radiusBelow: radius * 0.01,
|
|
23006
|
-
centerDistance: radius * 2
|
|
23007
|
-
};
|
|
23008
|
-
break;
|
|
23009
|
-
}
|
|
23010
|
-
}
|
|
23011
|
-
if ((code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) && options.hints?.viewport) {
|
|
23012
|
-
const cx = hpToNumber(options.hints.viewport.center[0]);
|
|
23013
|
-
const cy = hpToNumber(options.hints.viewport.center[1]);
|
|
23014
|
-
const size = options.hints.viewport.radius * 2;
|
|
23015
|
-
const cx_hi = Math.fround(cx);
|
|
23016
|
-
const cy_hi = Math.fround(cy);
|
|
23017
|
-
result.uniforms = {
|
|
23018
|
-
...result.uniforms,
|
|
23019
|
-
_dp_cx_hi: cx_hi,
|
|
23020
|
-
_dp_cx_lo: cx - cx_hi,
|
|
23021
|
-
_dp_cy_hi: cy_hi,
|
|
23022
|
-
_dp_cy_lo: cy - cy_hi,
|
|
23023
|
-
_dp_w: size,
|
|
23024
|
-
_dp_h: size
|
|
23025
|
-
};
|
|
23026
|
-
}
|
|
23027
|
-
if ((code.includes("_fractal_mandelbrot_pt") || code.includes("_fractal_julia_pt")) && options.hints?.viewport) {
|
|
23028
|
-
const viewport = options.hints.viewport;
|
|
23029
|
-
const size = viewport.radius * 2;
|
|
23030
|
-
result.uniforms = {
|
|
23031
|
-
...result.uniforms,
|
|
23032
|
-
_pt_offset_x: 0,
|
|
23033
|
-
_pt_offset_y: 0,
|
|
23034
|
-
_pt_w: size,
|
|
23035
|
-
_pt_h: size
|
|
23036
|
-
};
|
|
23037
|
-
const digits = Math.max(50, Math.ceil(-Math.log10(viewport.radius)) + 10);
|
|
23038
|
-
const maxIter = 1e3;
|
|
23039
|
-
const orbit = computeReferenceOrbit(
|
|
23040
|
-
viewport.center,
|
|
23041
|
-
maxIter,
|
|
23042
|
-
digits
|
|
23043
|
-
);
|
|
23044
|
-
const orbitLen = orbit.length / 2;
|
|
23045
|
-
const texWidth = Math.min(orbitLen, 4096);
|
|
23046
|
-
const texHeight = Math.ceil(orbitLen / texWidth);
|
|
23047
|
-
result.textures = {
|
|
23048
|
-
_refOrbit: {
|
|
23049
|
-
data: orbit,
|
|
23050
|
-
width: texWidth,
|
|
23051
|
-
height: texHeight,
|
|
23052
|
-
format: "rg32f"
|
|
23053
|
-
}
|
|
23054
|
-
};
|
|
23055
|
-
result.uniforms = {
|
|
23056
|
-
...result.uniforms,
|
|
23057
|
-
_refOrbitLen: orbitLen,
|
|
23058
|
-
_refOrbitTexWidth: texWidth
|
|
23059
|
-
};
|
|
23060
|
-
}
|
|
23061
23203
|
return result;
|
|
23062
23204
|
}
|
|
23063
23205
|
compileToSource(expr, _options = {}) {
|
|
@@ -23102,7 +23244,7 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
23102
23244
|
if (body.includes("\n")) {
|
|
23103
23245
|
const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
|
|
23104
23246
|
return `${returnType} ${functionName}(${params}) {
|
|
23105
|
-
${indented}
|
|
23247
|
+
${indented}
|
|
23106
23248
|
}`;
|
|
23107
23249
|
}
|
|
23108
23250
|
return `${returnType} ${functionName}(${params}) {
|
|
@@ -23213,7 +23355,7 @@ ${indented};
|
|
|
23213
23355
|
return `fn ${functionName}(${params}) -> ${toWGSLType(
|
|
23214
23356
|
returnType
|
|
23215
23357
|
)} {
|
|
23216
|
-
${indented}
|
|
23358
|
+
${indented}
|
|
23217
23359
|
}`;
|
|
23218
23360
|
}
|
|
23219
23361
|
return `fn ${functionName}(${params}) -> ${toWGSLType(returnType)} {
|
|
@@ -25392,7 +25534,7 @@ ${code}`;
|
|
|
25392
25534
|
}
|
|
25393
25535
|
|
|
25394
25536
|
// src/compile.ts
|
|
25395
|
-
var version = "0.
|
|
25537
|
+
var version = "0.56.0";
|
|
25396
25538
|
return __toCommonJS(compile_exports);
|
|
25397
25539
|
})();
|
|
25398
25540
|
/*! Bundled license information:
|