@field/cascade 0.2.22 → 0.3.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/AGENTS.md +47 -7
- package/ARCHITECTURE.md +30 -2
- package/CHANGELOG.md +89 -0
- package/DESIGN.md +10 -5
- package/README.md +103 -7
- package/dist/assets/CodeEditor-BADFbTJS.js +623 -0
- package/dist/assets/CodePanel-faK6PRfz.js +2 -0
- package/dist/assets/CustomNodeDialog-DhlKuviy.js +1 -0
- package/dist/assets/{ExportDialog-DWN4nhXI.js → ExportDialog-BJu2Bpvv.js} +2 -2
- package/dist/assets/ProjectSettings-D6a6kjqR.js +2 -0
- package/dist/assets/SettingsDialog-DJZdIvLC.js +1 -0
- package/dist/assets/VersionHistoryDialog-C1X3HOhc.js +3 -0
- package/dist/assets/{core-Bji4aZUU.js → core-CiuiuWZi.js} +29 -38
- package/dist/assets/{cssMode-B6Z_Q1Kh.js → cssMode-D-NwZSMJ.js} +1 -1
- package/dist/assets/{editor.api-jMoW_43X.js → editor.api-DT3WEvBd.js} +1 -1
- package/dist/assets/{freemarker2-DvvPV6m5.js → freemarker2-eKNYQaiz.js} +1 -1
- package/dist/assets/geo-DUvVbLnx.js +1 -0
- package/dist/assets/{handlebars-B8rfuSIa.js → handlebars-C2w1ggK2.js} +1 -1
- package/dist/assets/{html-DyHm6JCp.js → html-DQb41jyo.js} +1 -1
- package/dist/assets/{htmlMode-E9XLWE5u.js → htmlMode-IhNlh6Lv.js} +1 -1
- package/dist/assets/{image-BUcQC7PG.js → image-DMCXBY-_.js} +26 -40
- package/dist/assets/index-BDV5xGBZ.css +1 -0
- package/dist/assets/index-HTCN44kj.js +212 -0
- package/dist/assets/index-client-BoJgsN9M.js +1 -0
- package/dist/assets/{javascript-C_bM5PCN.js → javascript-BIT6jMLC.js} +1 -1
- package/dist/assets/{jsonMode-BdyVS7G4.js → jsonMode-CNfyB1ro.js} +1 -1
- package/dist/assets/{legacy-DIu3XRwl.js → legacy-CAj2_7QE.js} +2 -2
- package/dist/assets/{liquid-CDkn3spA.js → liquid-CmSmJmOG.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-AB5DMAsr.js → lspLanguageFeatures-BqMm3uMP.js} +1 -1
- package/dist/assets/{mdx-BvH_NjDN.js → mdx-6r6YgOFw.js} +1 -1
- package/dist/assets/{nodeTypeUtils-CweA3NHd.js → nodeTypeUtils-BBA1JqHx.js} +1 -1
- package/dist/assets/{python-B7uii4fi.js → python-x1H0TQuI.js} +1 -1
- package/dist/assets/{razor-Z48fWdJc.js → razor-Dzl1vZFm.js} +1 -1
- package/dist/assets/{tsMode-BDgacVG4.js → tsMode-n6DMMe3a.js} +1 -1
- package/dist/assets/{typescript-Derb6Oqa.js → typescript-ziEz65xN.js} +1 -1
- package/dist/assets/{workers-BtoMX_pm.js → workers-D-qUdp-r.js} +1 -1
- package/dist/assets/{xml-B1CaFSrG.js → xml-DMZjt5lE.js} +1 -1
- package/dist/assets/{yaml-HmIeA0KH.js → yaml-DFe5qZSO.js} +1 -1
- package/dist/cli/index.js +16194 -10195
- package/dist/cli/runtime/io.ts +93 -7
- package/dist/contracts/animation.d.ts +40 -0
- package/dist/contracts/animation.js +14 -0
- package/dist/contracts/definition.d.ts +39 -1
- package/dist/contracts/document.d.ts +15 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/validate.d.ts +10 -1
- package/dist/contracts/validate.js +9 -1
- package/dist/graphs/default.cascade +1 -1
- package/dist/index.html +5 -5
- package/dist/io.d.ts +196 -0
- package/dist/io.js +303 -0
- package/dist/net.d.ts +1 -0
- package/dist/net.js +28 -0
- package/dist/runtime/animation/channel.d.ts +108 -0
- package/dist/runtime/animation/channel.js +204 -0
- package/dist/runtime/animation/frameRange.d.ts +78 -0
- package/dist/runtime/animation/frameRange.js +76 -0
- package/dist/runtime/animation/index.d.ts +10 -0
- package/dist/runtime/animation/index.js +8 -0
- package/dist/runtime/builtins/core/random.d.ts +1 -1
- package/dist/runtime/builtins/core/remap.d.ts +1 -1
- package/dist/runtime/builtins/geo/copyToPoints.d.ts +1 -1
- package/dist/runtime/builtins/geo/copyToPoints.js +1 -1
- package/dist/runtime/builtins/geo/generators.d.ts +1 -1
- package/dist/runtime/builtins/geo/merge.d.ts +1 -1
- package/dist/runtime/builtins/geo/svgExport.d.ts +1 -1
- package/dist/runtime/builtins/geo/svgExport.js +1 -1
- package/dist/runtime/builtins/geo/transform.d.ts +1 -1
- package/dist/runtime/builtins/geo/transform.js +1 -1
- package/dist/runtime/definition/architecture.d.ts +1 -1
- package/dist/runtime/definition/extract.d.ts +1 -1
- package/dist/runtime/definition/extract.js +1 -1
- package/dist/runtime/error.d.ts +1 -1
- package/dist/runtime/expressions/evaluator.d.ts +53 -0
- package/dist/runtime/expressions/evaluator.js +193 -0
- package/dist/runtime/expressions/index.d.ts +15 -0
- package/dist/runtime/expressions/index.js +12 -0
- package/dist/runtime/expressions/math.d.ts +75 -0
- package/dist/runtime/expressions/math.js +140 -0
- package/dist/runtime/expressions/preprocess.d.ts +33 -0
- package/dist/runtime/expressions/preprocess.js +102 -0
- package/dist/runtime/expressions/scope.d.ts +27 -0
- package/dist/runtime/expressions/scope.js +10 -0
- package/dist/runtime/expressions/time.d.ts +54 -0
- package/dist/runtime/expressions/time.js +71 -0
- package/dist/runtime/expressions/types.d.ts +66 -0
- package/dist/runtime/expressions/types.js +9 -0
- package/dist/runtime/geometry/attributes.d.ts +2 -2
- package/dist/runtime/geometry/attributes.js +1 -1
- package/dist/runtime/geometry/builder.d.ts +1 -1
- package/dist/runtime/geometry/builder.js +1 -1
- package/dist/runtime/geometry/copy.d.ts +1 -1
- package/dist/runtime/geometry/copy.js +1 -1
- package/dist/runtime/geometry/generate.d.ts +1 -1
- package/dist/runtime/geometry/groups.d.ts +1 -1
- package/dist/runtime/geometry/groups.js +1 -1
- package/dist/runtime/geometry/matrix.d.ts +1 -1
- package/dist/runtime/geometry/merge.d.ts +1 -1
- package/dist/runtime/geometry/merge.js +1 -1
- package/dist/runtime/geometry/primitives.d.ts +1 -1
- package/dist/runtime/geometry/primitives.js +1 -1
- package/dist/runtime/geometry/promote.d.ts +1 -1
- package/dist/runtime/geometry/promote.js +1 -1
- package/dist/runtime/geometry/resample.d.ts +1 -1
- package/dist/runtime/geometry/resample.js +1 -1
- package/dist/runtime/geometry/svg.d.ts +1 -1
- package/dist/runtime/geometry/svg.js +1 -1
- package/dist/runtime/geometry/transform.d.ts +1 -1
- package/dist/runtime/geometry/transform.js +1 -1
- package/dist/runtime/index.d.ts +4 -1
- package/dist/runtime/index.js +4 -1
- package/dist/runtime/params/animator.d.ts +74 -0
- package/dist/runtime/params/animator.js +137 -0
- package/dist/runtime/params/index.d.ts +11 -0
- package/dist/runtime/params/index.js +9 -0
- package/dist/runtime/params/resolve.d.ts +73 -0
- package/dist/runtime/params/resolve.js +62 -0
- package/dist/runtime/runtime.d.ts +22 -0
- package/dist/runtime/runtime.js +242 -14
- package/dist/runtime/types.d.ts +30 -4
- package/dist/shell.d.ts +3 -3
- package/doc/NODE_REFERENCE.md +395 -0
- package/doc/PROJECT_AUTHORING.md +148 -6
- package/package.json +26 -3
- package/dist/assets/CodeEditor-DoaNEUaM.js +0 -641
- package/dist/assets/CodePanel-B0_2XJ-t.js +0 -2
- package/dist/assets/CustomNodeDialog-026lzecD.js +0 -1
- package/dist/assets/ProjectSettings-BzT164Yx.js +0 -2
- package/dist/assets/SettingsDialog-DmHb1V0r.js +0 -1
- package/dist/assets/VersionHistoryDialog-hH6VsXLX.js +0 -3
- package/dist/assets/geo-CXmCtzMM.js +0 -2
- package/dist/assets/index-BXYXSdgh.js +0 -224
- package/dist/assets/index-CrNke7SW.css +0 -1
- package/dist/assets/index-client-DN_FvjN8.js +0 -1
- package/dist/assets/quill-DjZ69wL_.js +0 -121
- package/dist/cli/index.js.map +0 -7
- package/dist/contracts/capabilities.d.ts.map +0 -1
- package/dist/contracts/capabilities.js.map +0 -1
- package/dist/contracts/color.d.ts.map +0 -1
- package/dist/contracts/color.js.map +0 -1
- package/dist/contracts/definition.d.ts.map +0 -1
- package/dist/contracts/definition.js.map +0 -1
- package/dist/contracts/document.d.ts.map +0 -1
- package/dist/contracts/document.js.map +0 -1
- package/dist/contracts/geometry.d.ts.map +0 -1
- package/dist/contracts/geometry.js.map +0 -1
- package/dist/contracts/index.d.ts.map +0 -1
- package/dist/contracts/index.js.map +0 -1
- package/dist/contracts/schema.d.ts.map +0 -1
- package/dist/contracts/schema.js.map +0 -1
- package/dist/contracts/validate.d.ts.map +0 -1
- package/dist/contracts/validate.js.map +0 -1
- package/dist/contracts/values.d.ts.map +0 -1
- package/dist/contracts/values.js.map +0 -1
- package/dist/graphs/default-orig.cascade +0 -128
- package/dist/runtime/browser.d.ts.map +0 -1
- package/dist/runtime/browser.js.map +0 -1
- package/dist/runtime/builtins/core/index.d.ts.map +0 -1
- package/dist/runtime/builtins/core/index.js.map +0 -1
- package/dist/runtime/builtins/core/random.d.ts.map +0 -1
- package/dist/runtime/builtins/core/random.js.map +0 -1
- package/dist/runtime/builtins/core/remap.d.ts.map +0 -1
- package/dist/runtime/builtins/core/remap.js.map +0 -1
- package/dist/runtime/builtins/core/routing.d.ts.map +0 -1
- package/dist/runtime/builtins/core/routing.js.map +0 -1
- package/dist/runtime/builtins/core/structural.d.ts.map +0 -1
- package/dist/runtime/builtins/core/structural.js.map +0 -1
- package/dist/runtime/builtins/geo/copyToPoints.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/copyToPoints.js.map +0 -1
- package/dist/runtime/builtins/geo/definitions.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/definitions.js.map +0 -1
- package/dist/runtime/builtins/geo/generators.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/generators.js.map +0 -1
- package/dist/runtime/builtins/geo/index.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/index.js.map +0 -1
- package/dist/runtime/builtins/geo/merge.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/merge.js.map +0 -1
- package/dist/runtime/builtins/geo/namespace.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/namespace.js.map +0 -1
- package/dist/runtime/builtins/geo/svgExport.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/svgExport.js.map +0 -1
- package/dist/runtime/builtins/geo/transform.d.ts.map +0 -1
- package/dist/runtime/builtins/geo/transform.js.map +0 -1
- package/dist/runtime/builtins/index.d.ts.map +0 -1
- package/dist/runtime/builtins/index.js.map +0 -1
- package/dist/runtime/definition/architecture.d.ts.map +0 -1
- package/dist/runtime/definition/architecture.js.map +0 -1
- package/dist/runtime/definition/extract.d.ts.map +0 -1
- package/dist/runtime/definition/extract.js.map +0 -1
- package/dist/runtime/error.d.ts.map +0 -1
- package/dist/runtime/error.js.map +0 -1
- package/dist/runtime/geometry/attributes.d.ts.map +0 -1
- package/dist/runtime/geometry/attributes.js.map +0 -1
- package/dist/runtime/geometry/builder.d.ts.map +0 -1
- package/dist/runtime/geometry/builder.js.map +0 -1
- package/dist/runtime/geometry/copy.d.ts.map +0 -1
- package/dist/runtime/geometry/copy.js.map +0 -1
- package/dist/runtime/geometry/generate.d.ts.map +0 -1
- package/dist/runtime/geometry/generate.js.map +0 -1
- package/dist/runtime/geometry/groups.d.ts.map +0 -1
- package/dist/runtime/geometry/groups.js.map +0 -1
- package/dist/runtime/geometry/index.d.ts.map +0 -1
- package/dist/runtime/geometry/index.js.map +0 -1
- package/dist/runtime/geometry/matrix.d.ts.map +0 -1
- package/dist/runtime/geometry/matrix.js.map +0 -1
- package/dist/runtime/geometry/merge.d.ts.map +0 -1
- package/dist/runtime/geometry/merge.js.map +0 -1
- package/dist/runtime/geometry/primitives.d.ts.map +0 -1
- package/dist/runtime/geometry/primitives.js.map +0 -1
- package/dist/runtime/geometry/promote.d.ts.map +0 -1
- package/dist/runtime/geometry/promote.js.map +0 -1
- package/dist/runtime/geometry/resample.d.ts.map +0 -1
- package/dist/runtime/geometry/resample.js.map +0 -1
- package/dist/runtime/geometry/svg.d.ts.map +0 -1
- package/dist/runtime/geometry/svg.js.map +0 -1
- package/dist/runtime/geometry/transform.d.ts.map +0 -1
- package/dist/runtime/geometry/transform.js.map +0 -1
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/node.d.ts.map +0 -1
- package/dist/runtime/node.js.map +0 -1
- package/dist/runtime/runtime.d.ts.map +0 -1
- package/dist/runtime/runtime.js.map +0 -1
- package/dist/runtime/types.d.ts.map +0 -1
- package/dist/runtime/types.js.map +0 -1
- package/dist/shell.js.map +0 -7
- package/dist/stage.js.map +0 -7
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expression math utilities.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions, no ambient state, deterministic for a given input — the same
|
|
5
|
+
* contract the rest of the runtime holds. `noise` and `random` are seeded
|
|
6
|
+
* closed forms rather than anything drawn from process state.
|
|
7
|
+
*/
|
|
8
|
+
/** Remap a value from one range to another. */
|
|
9
|
+
export function fit(value, oldMin, oldMax, newMin, newMax) {
|
|
10
|
+
if (oldMax === oldMin)
|
|
11
|
+
return newMin;
|
|
12
|
+
const t = (value - oldMin) / (oldMax - oldMin);
|
|
13
|
+
return newMin + t * (newMax - newMin);
|
|
14
|
+
}
|
|
15
|
+
/** Remap a 0..1 value into a new range. */
|
|
16
|
+
export function fit01(value, newMin, newMax) {
|
|
17
|
+
return newMin + value * (newMax - newMin);
|
|
18
|
+
}
|
|
19
|
+
export function clamp(value, min, max) {
|
|
20
|
+
return Math.max(min, Math.min(max, value));
|
|
21
|
+
}
|
|
22
|
+
export function lerp(a, b, t) {
|
|
23
|
+
return a + (b - a) * t;
|
|
24
|
+
}
|
|
25
|
+
/** Smooth hermite interpolation (smoothstep). */
|
|
26
|
+
export function smooth(value, min, max) {
|
|
27
|
+
if (value <= min)
|
|
28
|
+
return 0;
|
|
29
|
+
if (value >= max)
|
|
30
|
+
return 1;
|
|
31
|
+
const t = (value - min) / (max - min);
|
|
32
|
+
return t * t * (3 - 2 * t);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Perlin-like noise in -1..1. Not true Perlin — a deterministic sum of sines.
|
|
36
|
+
*/
|
|
37
|
+
export function noise(...coords) {
|
|
38
|
+
if (coords.length === 0)
|
|
39
|
+
return 0;
|
|
40
|
+
let result = 0;
|
|
41
|
+
const frequencies = [1, 2.3, 4.7, 8.1];
|
|
42
|
+
const amplitudes = [1, 0.5, 0.25, 0.125];
|
|
43
|
+
for (let i = 0; i < frequencies.length; i++) {
|
|
44
|
+
let sum = 0;
|
|
45
|
+
for (let j = 0; j < coords.length; j++) {
|
|
46
|
+
sum += Math.sin(coords[j] * frequencies[i] * (j + 1) * 1.7 + j * 3.14159);
|
|
47
|
+
}
|
|
48
|
+
result += sum * amplitudes[i];
|
|
49
|
+
}
|
|
50
|
+
return Math.sin(result * 0.5);
|
|
51
|
+
}
|
|
52
|
+
/** Deterministic random in 0..1 from a seed. */
|
|
53
|
+
export function random(seed) {
|
|
54
|
+
const x = Math.sin(seed * 12.9898) * 43758.5453;
|
|
55
|
+
return x - Math.floor(x);
|
|
56
|
+
}
|
|
57
|
+
/** Zero-pad a number to a given number of digits. */
|
|
58
|
+
export function padzero(digits, value) {
|
|
59
|
+
return String(Math.floor(value)).padStart(digits, "0");
|
|
60
|
+
}
|
|
61
|
+
// ============ Bare maths, as Houdini exposes it ============
|
|
62
|
+
//
|
|
63
|
+
// An expression language whose users write `sin($T)` and get "sin is not
|
|
64
|
+
// defined" is one they stop trusting. Houdini exposes the whole maths library
|
|
65
|
+
// bare, and so do we.
|
|
66
|
+
//
|
|
67
|
+
// Angles are RADIANS, unlike Houdini's degrees. Two reasons, and the second is
|
|
68
|
+
// the deciding one. `$T` in radians oscillates over 2pi seconds, which is a
|
|
69
|
+
// usable animation period, where in degrees `sin($T)` would take six minutes to
|
|
70
|
+
// come round. And `Math` is also in scope, so a degree-based `sin()` would
|
|
71
|
+
// disagree with `Math.sin()` inside the same expression — a trap far worse than
|
|
72
|
+
// having to type `radians()`. The `sind`/`cosd`/`tand` trio is there for anyone
|
|
73
|
+
// carrying a formula over from Houdini.
|
|
74
|
+
/** Degrees to radians. */
|
|
75
|
+
export function radians(degrees) {
|
|
76
|
+
return (degrees * Math.PI) / 180;
|
|
77
|
+
}
|
|
78
|
+
/** Radians to degrees. */
|
|
79
|
+
export function degrees(radians) {
|
|
80
|
+
return (radians * 180) / Math.PI;
|
|
81
|
+
}
|
|
82
|
+
/** Sine of an angle in degrees — Houdini's `sin()`. */
|
|
83
|
+
export function sind(degrees) {
|
|
84
|
+
return Math.sin(radians(degrees));
|
|
85
|
+
}
|
|
86
|
+
/** Cosine of an angle in degrees — Houdini's `cos()`. */
|
|
87
|
+
export function cosd(degrees) {
|
|
88
|
+
return Math.cos(radians(degrees));
|
|
89
|
+
}
|
|
90
|
+
/** Tangent of an angle in degrees — Houdini's `tan()`. */
|
|
91
|
+
export function tand(degrees) {
|
|
92
|
+
return Math.tan(radians(degrees));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The bare maths names available to every expression. Spread into the
|
|
96
|
+
* evaluation scope; kept as one object so adding a function is a one-line
|
|
97
|
+
* change here rather than a change in two files.
|
|
98
|
+
*/
|
|
99
|
+
export const MATH_SCOPE = {
|
|
100
|
+
// Trigonometry, in radians
|
|
101
|
+
sin: Math.sin,
|
|
102
|
+
cos: Math.cos,
|
|
103
|
+
tan: Math.tan,
|
|
104
|
+
asin: Math.asin,
|
|
105
|
+
acos: Math.acos,
|
|
106
|
+
atan: Math.atan,
|
|
107
|
+
atan2: Math.atan2,
|
|
108
|
+
sinh: Math.sinh,
|
|
109
|
+
cosh: Math.cosh,
|
|
110
|
+
tanh: Math.tanh,
|
|
111
|
+
// Trigonometry, in degrees, for formulae carried over from Houdini
|
|
112
|
+
sind,
|
|
113
|
+
cosd,
|
|
114
|
+
tand,
|
|
115
|
+
radians,
|
|
116
|
+
degrees,
|
|
117
|
+
// Powers and logs
|
|
118
|
+
sqrt: Math.sqrt,
|
|
119
|
+
cbrt: Math.cbrt,
|
|
120
|
+
pow: Math.pow,
|
|
121
|
+
exp: Math.exp,
|
|
122
|
+
log: Math.log,
|
|
123
|
+
log2: Math.log2,
|
|
124
|
+
log10: Math.log10,
|
|
125
|
+
hypot: Math.hypot,
|
|
126
|
+
// Rounding and sign
|
|
127
|
+
abs: Math.abs,
|
|
128
|
+
sign: Math.sign,
|
|
129
|
+
floor: Math.floor,
|
|
130
|
+
ceil: Math.ceil,
|
|
131
|
+
round: Math.round,
|
|
132
|
+
trunc: Math.trunc,
|
|
133
|
+
min: Math.min,
|
|
134
|
+
max: Math.max,
|
|
135
|
+
// Constants
|
|
136
|
+
PI: Math.PI,
|
|
137
|
+
TAU: Math.PI * 2,
|
|
138
|
+
E: Math.E
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=math.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expression preprocessing: Houdini-style `$` time variables.
|
|
3
|
+
*
|
|
4
|
+
* Expressions compile to raw JS (`return (<expr>)`) evaluated against a context
|
|
5
|
+
* object, so `$F` is not valid input. This pass rewrites the `$` spellings to
|
|
6
|
+
* the plain identifiers the context carries, before compilation. The bare
|
|
7
|
+
* identifiers remain valid aliases — `time`, `frame`, `fframe`, `fps` — so
|
|
8
|
+
* nothing already authored breaks.
|
|
9
|
+
*
|
|
10
|
+
* $F -> frame integer frame
|
|
11
|
+
* $FF -> fframe fractional frame
|
|
12
|
+
* $T -> time seconds
|
|
13
|
+
* $FPS -> fps rate
|
|
14
|
+
*
|
|
15
|
+
* `$` is rewritten only in code position: occurrences inside string or template
|
|
16
|
+
* literals are left alone, so `chs("$F")` stays a string.
|
|
17
|
+
*/
|
|
18
|
+
/** The `$` time tokens, longest first so `$FPS` wins over `$F`. */
|
|
19
|
+
export declare const TIME_TOKENS: ReadonlyArray<readonly [token: string, identifier: string]>;
|
|
20
|
+
/** Bare identifiers that carry time, kept as aliases for the `$` spellings. */
|
|
21
|
+
export declare const TIME_IDENTIFIERS: readonly string[];
|
|
22
|
+
/**
|
|
23
|
+
* Rewrite `$` time variables to their plain identifiers.
|
|
24
|
+
* Returns the source unchanged when it contains no `$`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function preprocessExpression(source: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* True if an expression references any time variable, in either spelling.
|
|
29
|
+
* This is what sets `isTimeDependent`, which is what lets a per-frame cook
|
|
30
|
+
* recompute only the time-dependent subgraph.
|
|
31
|
+
*/
|
|
32
|
+
export declare function hasTimeReference(source: string): boolean;
|
|
33
|
+
//# sourceMappingURL=preprocess.d.ts.map
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expression preprocessing: Houdini-style `$` time variables.
|
|
3
|
+
*
|
|
4
|
+
* Expressions compile to raw JS (`return (<expr>)`) evaluated against a context
|
|
5
|
+
* object, so `$F` is not valid input. This pass rewrites the `$` spellings to
|
|
6
|
+
* the plain identifiers the context carries, before compilation. The bare
|
|
7
|
+
* identifiers remain valid aliases — `time`, `frame`, `fframe`, `fps` — so
|
|
8
|
+
* nothing already authored breaks.
|
|
9
|
+
*
|
|
10
|
+
* $F -> frame integer frame
|
|
11
|
+
* $FF -> fframe fractional frame
|
|
12
|
+
* $T -> time seconds
|
|
13
|
+
* $FPS -> fps rate
|
|
14
|
+
*
|
|
15
|
+
* `$` is rewritten only in code position: occurrences inside string or template
|
|
16
|
+
* literals are left alone, so `chs("$F")` stays a string.
|
|
17
|
+
*/
|
|
18
|
+
/** The `$` time tokens, longest first so `$FPS` wins over `$F`. */
|
|
19
|
+
export const TIME_TOKENS = [
|
|
20
|
+
["$FPS", "fps"],
|
|
21
|
+
["$FF", "fframe"],
|
|
22
|
+
["$F", "frame"],
|
|
23
|
+
["$T", "time"]
|
|
24
|
+
];
|
|
25
|
+
/** Bare identifiers that carry time, kept as aliases for the `$` spellings. */
|
|
26
|
+
export const TIME_IDENTIFIERS = ["time", "frame", "fframe", "fps"];
|
|
27
|
+
const DOLLAR_TIME_PATTERN = /\$(FPS|FF|F|T)\b/g;
|
|
28
|
+
const BARE_TIME_PATTERN = /\b(?:time|frame|fframe|fps)\b/;
|
|
29
|
+
const DOLLAR_TO_IDENTIFIER = {
|
|
30
|
+
FPS: "fps",
|
|
31
|
+
FF: "fframe",
|
|
32
|
+
F: "frame",
|
|
33
|
+
T: "time"
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Split an expression into code and literal spans, so a rewrite can skip
|
|
37
|
+
* string and template literals. Deliberately small: it handles quotes and
|
|
38
|
+
* escapes, which is all an expression field contains.
|
|
39
|
+
*/
|
|
40
|
+
function codeSpans(source) {
|
|
41
|
+
const spans = [];
|
|
42
|
+
let spanStart = 0;
|
|
43
|
+
let index = 0;
|
|
44
|
+
while (index < source.length) {
|
|
45
|
+
const char = source[index];
|
|
46
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
47
|
+
spans.push({ start: spanStart, end: index });
|
|
48
|
+
const quote = char;
|
|
49
|
+
index += 1;
|
|
50
|
+
while (index < source.length) {
|
|
51
|
+
if (source[index] === "\\") {
|
|
52
|
+
index += 2;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (source[index] === quote) {
|
|
56
|
+
index += 1;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
index += 1;
|
|
60
|
+
}
|
|
61
|
+
spanStart = index;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
index += 1;
|
|
65
|
+
}
|
|
66
|
+
spans.push({ start: spanStart, end: source.length });
|
|
67
|
+
return spans;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Rewrite `$` time variables to their plain identifiers.
|
|
71
|
+
* Returns the source unchanged when it contains no `$`.
|
|
72
|
+
*/
|
|
73
|
+
export function preprocessExpression(source) {
|
|
74
|
+
if (!source.includes("$"))
|
|
75
|
+
return source;
|
|
76
|
+
let out = "";
|
|
77
|
+
let cursor = 0;
|
|
78
|
+
for (const span of codeSpans(source)) {
|
|
79
|
+
// Literal text between spans is copied verbatim.
|
|
80
|
+
if (span.start > cursor)
|
|
81
|
+
out += source.slice(cursor, span.start);
|
|
82
|
+
out += source
|
|
83
|
+
.slice(span.start, span.end)
|
|
84
|
+
.replace(DOLLAR_TIME_PATTERN, (_match, key) => DOLLAR_TO_IDENTIFIER[key]);
|
|
85
|
+
cursor = span.end;
|
|
86
|
+
}
|
|
87
|
+
if (cursor < source.length)
|
|
88
|
+
out += source.slice(cursor);
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* True if an expression references any time variable, in either spelling.
|
|
93
|
+
* This is what sets `isTimeDependent`, which is what lets a per-frame cook
|
|
94
|
+
* recompute only the time-dependent subgraph.
|
|
95
|
+
*/
|
|
96
|
+
export function hasTimeReference(source) {
|
|
97
|
+
if (BARE_TIME_PATTERN.test(source))
|
|
98
|
+
return true;
|
|
99
|
+
DOLLAR_TIME_PATTERN.lastIndex = 0;
|
|
100
|
+
return DOLLAR_TIME_PATTERN.test(source);
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=preprocess.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host binding for expression evaluation.
|
|
3
|
+
*
|
|
4
|
+
* The expression engine needs to read parameters off neighbouring nodes and to
|
|
5
|
+
* follow inputs, but it must not know what a node *is* — that is what kept it
|
|
6
|
+
* pinned to Studio's compatibility `Graph`/`Node`. A host supplies a scope; the
|
|
7
|
+
* engine stays neutral and works unchanged in a headless cook.
|
|
8
|
+
*/
|
|
9
|
+
/** The minimum a node must offer to be addressable from an expression. */
|
|
10
|
+
export interface Node {
|
|
11
|
+
id: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ExpressionScope<TNode = Node> {
|
|
14
|
+
/**
|
|
15
|
+
* Resolve a channel path relative to a node, e.g. `./radius`,
|
|
16
|
+
* `../blur1/amount`, `/root/node/value`. Return null when it does not
|
|
17
|
+
* resolve — the engine turns that into 0 / '' / [] per accessor.
|
|
18
|
+
*/
|
|
19
|
+
resolveParam(from: TNode, path: string): {
|
|
20
|
+
value: unknown;
|
|
21
|
+
} | null;
|
|
22
|
+
/** True if a node exists at the path, relative to `from`. */
|
|
23
|
+
nodeExists(from: TNode, path: string): boolean;
|
|
24
|
+
/** The node connected to `from`'s input at `index`, if any. */
|
|
25
|
+
inputNode(from: TNode, index: number): TNode | null;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host binding for expression evaluation.
|
|
3
|
+
*
|
|
4
|
+
* The expression engine needs to read parameters off neighbouring nodes and to
|
|
5
|
+
* follow inputs, but it must not know what a node *is* — that is what kept it
|
|
6
|
+
* pinned to Studio's compatibility `Graph`/`Node`. A host supplies a scope; the
|
|
7
|
+
* engine stays neutral and works unchanged in a headless cook.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time state for expression evaluation.
|
|
3
|
+
*
|
|
4
|
+
* Frames are stored as a real number so sub-frame time exists. `frame` is the
|
|
5
|
+
* integer frame ($F), `frameFraction` is the exact fractional frame ($FF), and
|
|
6
|
+
* `time` is seconds ($T). Nothing here reads a clock: time is set by the caller
|
|
7
|
+
* (a cook request, a frame-range loop, a transport) and the engine only ever
|
|
8
|
+
* reports what it was told. That is what keeps a cook deterministic.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_FPS = 30;
|
|
11
|
+
export declare const MIN_FRAME = 1;
|
|
12
|
+
export declare class TimeState {
|
|
13
|
+
/** Exact, possibly fractional frame. Never below MIN_FRAME. */
|
|
14
|
+
private _frame;
|
|
15
|
+
private _fps;
|
|
16
|
+
/**
|
|
17
|
+
* Set the current frame. Fractional values are preserved; only the lower
|
|
18
|
+
* bound is enforced. Non-finite input is ignored.
|
|
19
|
+
*/
|
|
20
|
+
setFrame(frame: number): void;
|
|
21
|
+
/** Set the current time in seconds, keeping the sub-frame remainder. */
|
|
22
|
+
setTime(seconds: number): void;
|
|
23
|
+
setFps(fps: number): void;
|
|
24
|
+
/** Integer frame — $F. */
|
|
25
|
+
get frame(): number;
|
|
26
|
+
/** Fractional frame — $FF. */
|
|
27
|
+
get frameFraction(): number;
|
|
28
|
+
/**
|
|
29
|
+
* Seconds — $T. Derived from the fractional frame, so it round-trips.
|
|
30
|
+
*
|
|
31
|
+
* Zero at the first frame, which is Houdini's convention: $T = ($FF - 1)/$FPS.
|
|
32
|
+
* The previous definition was frame/fps, making $T equal 1/fps at frame 1 —
|
|
33
|
+
* so `sin($T)` started part-way through its cycle and an animation's first
|
|
34
|
+
* frame was never t=0. Changed 2026-09-07 because Marcus named Houdini as the
|
|
35
|
+
* reference for these variables, and because "time starts at zero" is the
|
|
36
|
+
* thing anybody writing an expression will assume.
|
|
37
|
+
*/
|
|
38
|
+
get time(): number;
|
|
39
|
+
/** Frame rate — $FPS. */
|
|
40
|
+
get fps(): number;
|
|
41
|
+
/** Immutable snapshot of the four time variables. */
|
|
42
|
+
snapshot(): TimeVariables;
|
|
43
|
+
}
|
|
44
|
+
export interface TimeVariables {
|
|
45
|
+
/** Integer frame — $F */
|
|
46
|
+
frame: number;
|
|
47
|
+
/** Fractional frame — $FF */
|
|
48
|
+
frameFraction: number;
|
|
49
|
+
/** Seconds — $T */
|
|
50
|
+
time: number;
|
|
51
|
+
/** Frame rate — $FPS */
|
|
52
|
+
fps: number;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=time.d.ts.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time state for expression evaluation.
|
|
3
|
+
*
|
|
4
|
+
* Frames are stored as a real number so sub-frame time exists. `frame` is the
|
|
5
|
+
* integer frame ($F), `frameFraction` is the exact fractional frame ($FF), and
|
|
6
|
+
* `time` is seconds ($T). Nothing here reads a clock: time is set by the caller
|
|
7
|
+
* (a cook request, a frame-range loop, a transport) and the engine only ever
|
|
8
|
+
* reports what it was told. That is what keeps a cook deterministic.
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_FPS = 30;
|
|
11
|
+
export const MIN_FRAME = 1;
|
|
12
|
+
export class TimeState {
|
|
13
|
+
/** Exact, possibly fractional frame. Never below MIN_FRAME. */
|
|
14
|
+
_frame = MIN_FRAME;
|
|
15
|
+
_fps = DEFAULT_FPS;
|
|
16
|
+
/**
|
|
17
|
+
* Set the current frame. Fractional values are preserved; only the lower
|
|
18
|
+
* bound is enforced. Non-finite input is ignored.
|
|
19
|
+
*/
|
|
20
|
+
setFrame(frame) {
|
|
21
|
+
if (!Number.isFinite(frame))
|
|
22
|
+
return;
|
|
23
|
+
this._frame = Math.max(MIN_FRAME, frame);
|
|
24
|
+
}
|
|
25
|
+
/** Set the current time in seconds, keeping the sub-frame remainder. */
|
|
26
|
+
setTime(seconds) {
|
|
27
|
+
if (!Number.isFinite(seconds))
|
|
28
|
+
return;
|
|
29
|
+
this.setFrame(seconds * this._fps + MIN_FRAME);
|
|
30
|
+
}
|
|
31
|
+
setFps(fps) {
|
|
32
|
+
if (!Number.isFinite(fps))
|
|
33
|
+
return;
|
|
34
|
+
this._fps = Math.max(1, fps);
|
|
35
|
+
}
|
|
36
|
+
/** Integer frame — $F. */
|
|
37
|
+
get frame() {
|
|
38
|
+
return Math.floor(this._frame);
|
|
39
|
+
}
|
|
40
|
+
/** Fractional frame — $FF. */
|
|
41
|
+
get frameFraction() {
|
|
42
|
+
return this._frame;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Seconds — $T. Derived from the fractional frame, so it round-trips.
|
|
46
|
+
*
|
|
47
|
+
* Zero at the first frame, which is Houdini's convention: $T = ($FF - 1)/$FPS.
|
|
48
|
+
* The previous definition was frame/fps, making $T equal 1/fps at frame 1 —
|
|
49
|
+
* so `sin($T)` started part-way through its cycle and an animation's first
|
|
50
|
+
* frame was never t=0. Changed 2026-09-07 because Marcus named Houdini as the
|
|
51
|
+
* reference for these variables, and because "time starts at zero" is the
|
|
52
|
+
* thing anybody writing an expression will assume.
|
|
53
|
+
*/
|
|
54
|
+
get time() {
|
|
55
|
+
return (this._frame - MIN_FRAME) / this._fps;
|
|
56
|
+
}
|
|
57
|
+
/** Frame rate — $FPS. */
|
|
58
|
+
get fps() {
|
|
59
|
+
return this._fps;
|
|
60
|
+
}
|
|
61
|
+
/** Immutable snapshot of the four time variables. */
|
|
62
|
+
snapshot() {
|
|
63
|
+
return {
|
|
64
|
+
frame: this.frame,
|
|
65
|
+
frameFraction: this.frameFraction,
|
|
66
|
+
time: this.time,
|
|
67
|
+
fps: this.fps
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=time.js.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expression types.
|
|
3
|
+
*
|
|
4
|
+
* These live in the runtime rather than in contracts because a compiled
|
|
5
|
+
* expression carries a function, so it is runtime machinery rather than a
|
|
6
|
+
* serializable DTO. Contracts stays dependency-free and data-only.
|
|
7
|
+
*/
|
|
8
|
+
import type { Node as NodeShape } from "./scope.js";
|
|
9
|
+
/**
|
|
10
|
+
* The context an expression is evaluated against. Everything an expression can
|
|
11
|
+
* see is on this object — there is no ambient global, and in particular no
|
|
12
|
+
* clock: the time variables are values placed here by the caller.
|
|
13
|
+
*/
|
|
14
|
+
export interface ExpressionContext<TNode = NodeShape> {
|
|
15
|
+
/** seconds — $T */
|
|
16
|
+
time: number;
|
|
17
|
+
/** integer frame — $F */
|
|
18
|
+
frame: number;
|
|
19
|
+
/** fractional frame — $FF */
|
|
20
|
+
fframe: number;
|
|
21
|
+
/** rate — $FPS */
|
|
22
|
+
fps: number;
|
|
23
|
+
/** The node whose parameter is being evaluated. */
|
|
24
|
+
self: TNode;
|
|
25
|
+
ch: (path: string) => number;
|
|
26
|
+
chs: (path: string) => string;
|
|
27
|
+
chv: (path: string) => number[];
|
|
28
|
+
opexist: (path: string) => 0 | 1;
|
|
29
|
+
opinput: (index: number) => TNode | null;
|
|
30
|
+
fit: (value: number, oldMin: number, oldMax: number, newMin: number, newMax: number) => number;
|
|
31
|
+
fit01: (value: number, newMin: number, newMax: number) => number;
|
|
32
|
+
clamp: (value: number, min: number, max: number) => number;
|
|
33
|
+
lerp: (a: number, b: number, t: number) => number;
|
|
34
|
+
smooth: (value: number, min: number, max: number) => number;
|
|
35
|
+
noise: (...coords: number[]) => number;
|
|
36
|
+
random: (seed: number) => number;
|
|
37
|
+
padzero: (digits: number, value: number) => string;
|
|
38
|
+
Math: typeof Math;
|
|
39
|
+
}
|
|
40
|
+
/** A compiled, cached expression ready to evaluate against a context. */
|
|
41
|
+
export interface CompiledExpression<TNode = NodeShape> {
|
|
42
|
+
/** The expression as authored, `$` spellings intact. */
|
|
43
|
+
source: string;
|
|
44
|
+
/** The expression after `$` preprocessing — what was actually compiled. */
|
|
45
|
+
compiledSource: string;
|
|
46
|
+
evaluate: (context: ExpressionContext<TNode>) => unknown;
|
|
47
|
+
/** Parameter paths referenced through ch/chs/chv, for dirty tracking. */
|
|
48
|
+
dependencies: string[];
|
|
49
|
+
/** True if the expression references any time variable, in either spelling. */
|
|
50
|
+
isTimeDependent: boolean;
|
|
51
|
+
error?: string;
|
|
52
|
+
}
|
|
53
|
+
/** Result of evaluating one expression. */
|
|
54
|
+
export interface ExpressionResult {
|
|
55
|
+
value: unknown;
|
|
56
|
+
error?: string;
|
|
57
|
+
}
|
|
58
|
+
/** A referenced path that does not resolve. */
|
|
59
|
+
export interface PathWarning {
|
|
60
|
+
nodeId: string;
|
|
61
|
+
nodePath: string;
|
|
62
|
+
propName: string;
|
|
63
|
+
expression: string;
|
|
64
|
+
brokenPath: string;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expression types.
|
|
3
|
+
*
|
|
4
|
+
* These live in the runtime rather than in contracts because a compiled
|
|
5
|
+
* expression carries a function, so it is runtime machinery rather than a
|
|
6
|
+
* serializable DTO. Contracts stays dependency-free and data-only.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AnyAttribute, type Attribute, type AttributeLevel, type AttributeSet, type AttributeStorage, type DetailValue, type ElementLevel, type Geometry, type StringAttribute } from "cascade/contracts";
|
|
1
|
+
import { type AnyAttribute, type Attribute, type AttributeLevel, type AttributeSet, type AttributeStorage, type DetailValue, type ElementLevel, type Geometry, type StringAttribute } from "@field/cascade/contracts";
|
|
2
2
|
/**
|
|
3
3
|
* Attribute reads and writes. Every write returns a new `Geometry` and shares
|
|
4
4
|
* the arrays it did not touch, which is the whole reason the format is
|
|
@@ -61,5 +61,5 @@ export interface AttributeCreateOptions {
|
|
|
61
61
|
*/
|
|
62
62
|
export declare function attributeCreate(geometry: Geometry, options: AttributeCreateOptions): Geometry;
|
|
63
63
|
/** A same-storage copy of an attribute's array, for a write-in-place pass. */
|
|
64
|
-
export declare function copyAttributeArray(attribute: Attribute): import("cascade/contracts").AttributeArray;
|
|
64
|
+
export declare function copyAttributeArray(attribute: Attribute): import("@field/cascade/contracts").AttributeArray;
|
|
65
65
|
//# sourceMappingURL=attributes.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { attributeArray, attributeArrayFrom, createGeometry, isStringAttribute, levelCount, POSITION_ATTRIBUTE, } from "cascade/contracts";
|
|
1
|
+
import { attributeArray, attributeArrayFrom, createGeometry, isStringAttribute, levelCount, POSITION_ATTRIBUTE, } from "@field/cascade/contracts";
|
|
2
2
|
/**
|
|
3
3
|
* Attribute reads and writes. Every write returns a new `Geometry` and shares
|
|
4
4
|
* the arrays it did not touch, which is the whole reason the format is
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { emptyGeometry, type AnyAttribute, type AttributeStorage, type DetailValue, type ElementLevel, type Geometry, type PrimitiveKind } from "cascade/contracts";
|
|
1
|
+
import { emptyGeometry, type AnyAttribute, type AttributeStorage, type DetailValue, type ElementLevel, type Geometry, type PrimitiveKind } from "@field/cascade/contracts";
|
|
2
2
|
export { emptyGeometry };
|
|
3
3
|
export interface GeometryBuilderOptions {
|
|
4
4
|
/** 2 by default: the reference workloads are two-component. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { attributeArrayFrom, createGeometry, emptyGeometry, POSITION_ATTRIBUTE, PRIMITIVE_KINDS, } from "cascade/contracts";
|
|
1
|
+
import { attributeArrayFrom, createGeometry, emptyGeometry, POSITION_ATTRIBUTE, PRIMITIVE_KINDS, } from "@field/cascade/contracts";
|
|
2
2
|
import { createStringAttribute, geometryError } from "./attributes.js";
|
|
3
3
|
export { emptyGeometry };
|
|
4
4
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { emptyGeometry, isStringAttribute, POSITION_ATTRIBUTE, } from "cascade/contracts";
|
|
1
|
+
import { emptyGeometry, isStringAttribute, POSITION_ATTRIBUTE, } from "@field/cascade/contracts";
|
|
2
2
|
import { createAttribute, createStringAttribute, geometryError, getPosition, numericAttribute, positionSize, readComponent, readElement, readString, setAttribute, } from "./attributes.js";
|
|
3
3
|
import { groupIndices, groupMask } from "./groups.js";
|
|
4
4
|
import { transformMatrix } from "./matrix.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Geometry } from "cascade/contracts";
|
|
1
|
+
import { type Geometry } from "@field/cascade/contracts";
|
|
2
2
|
/**
|
|
3
3
|
* Groups are named subsets, stored as one byte per element. A mask is the right
|
|
4
4
|
* shape because membership is tested far more often than it is enumerated, and
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { attributeArray, createGeometry, emptyGeometry, isStringAttribute, levelCount, } from "cascade/contracts";
|
|
1
|
+
import { attributeArray, createGeometry, emptyGeometry, isStringAttribute, levelCount, } from "@field/cascade/contracts";
|
|
2
2
|
import { createStringAttribute, geometryError, readString } from "./attributes.js";
|
|
3
3
|
/**
|
|
4
4
|
* Merge concatenates geometries and renumbers points, vertices and primitives.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Geometry, PrimitiveKind } from "cascade/contracts";
|
|
1
|
+
import type { Geometry, PrimitiveKind } from "@field/cascade/contracts";
|
|
2
2
|
/** Topology and measurement reads that the operations share. */
|
|
3
3
|
export declare function primitiveKind(geometry: Geometry, primitive: number): PrimitiveKind;
|
|
4
4
|
export declare function isClosed(geometry: Geometry, primitive: number): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BEZIER_STRIDE, PRIMITIVE_KINDS } from "cascade/contracts";
|
|
1
|
+
import { BEZIER_STRIDE, PRIMITIVE_KINDS } from "@field/cascade/contracts";
|
|
2
2
|
import { geometryError, positionAttribute, positionSize, } from "./attributes.js";
|
|
3
3
|
/** Topology and measurement reads that the operations share. */
|
|
4
4
|
export function primitiveKind(geometry, primitive) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AttributeLevel, type ElementLevel, type Geometry } from "cascade/contracts";
|
|
1
|
+
import { type AttributeLevel, type ElementLevel, type Geometry } from "@field/cascade/contracts";
|
|
2
2
|
/**
|
|
3
3
|
* Moving an attribute between levels, and copying one between geometries.
|
|
4
4
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { attributeArray, isStringAttribute, levelCount, POSITION_ATTRIBUTE, } from "cascade/contracts";
|
|
1
|
+
import { attributeArray, isStringAttribute, levelCount, POSITION_ATTRIBUTE, } from "@field/cascade/contracts";
|
|
2
2
|
import { createStringAttribute, geometryError, readString, removeAttribute, removeDetail, setAttribute, setDetail, } from "./attributes.js";
|
|
3
3
|
/**
|
|
4
4
|
* Which source elements feed each target element. This one table is the whole
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { attributeArray, createGeometry, isStringAttribute, } from "cascade/contracts";
|
|
1
|
+
import { attributeArray, createGeometry, isStringAttribute, } from "@field/cascade/contracts";
|
|
2
2
|
import { createStringAttribute, geometryError, readString, } from "./attributes.js";
|
|
3
3
|
import { groupMask } from "./groups.js";
|
|
4
4
|
import { arcLengths, isBezier, isClosed, loosePointMask, primitivePoints, } from "./primitives.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Color, type Geometry } from "cascade/contracts";
|
|
1
|
+
import { Color, type Geometry } from "@field/cascade/contracts";
|
|
2
2
|
/**
|
|
3
3
|
* Geometry to an SVG document. The node that makes the library provably useful,
|
|
4
4
|
* because it produces a file to print or plot rather than an assertion.
|