@viewscript/renderer 0.1.0-202605140639

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.
Files changed (89) hide show
  1. package/dist/ast/types.d.ts +403 -0
  2. package/dist/ast/types.js +33 -0
  3. package/dist/compiler/chunk-splitter.d.ts +98 -0
  4. package/dist/compiler/chunk-splitter.js +361 -0
  5. package/dist/index.d.ts +55 -0
  6. package/dist/index.js +17 -0
  7. package/dist/rasterizer/__tests__/error-distribution.test.d.ts +7 -0
  8. package/dist/rasterizer/__tests__/error-distribution.test.js +322 -0
  9. package/dist/rasterizer/canvas-mapper.d.ts +280 -0
  10. package/dist/rasterizer/canvas-mapper.js +414 -0
  11. package/dist/rasterizer/error-distribution.d.ts +143 -0
  12. package/dist/rasterizer/error-distribution.js +231 -0
  13. package/dist/rasterizer/gradient-mapper.d.ts +223 -0
  14. package/dist/rasterizer/gradient-mapper.js +352 -0
  15. package/dist/rasterizer/topology-rounding.d.ts +151 -0
  16. package/dist/rasterizer/topology-rounding.js +347 -0
  17. package/dist/runtime/__tests__/event-backpressure.test.d.ts +10 -0
  18. package/dist/runtime/__tests__/event-backpressure.test.js +190 -0
  19. package/dist/runtime/event-backpressure.d.ts +393 -0
  20. package/dist/runtime/event-backpressure.js +458 -0
  21. package/dist/runtime/render-loop.d.ts +277 -0
  22. package/dist/runtime/render-loop.js +435 -0
  23. package/dist/runtime/wasm-resource-manager.d.ts +122 -0
  24. package/dist/runtime/wasm-resource-manager.js +253 -0
  25. package/dist/runtime/wgpu-renderer-adapter.d.ts +168 -0
  26. package/dist/runtime/wgpu-renderer-adapter.js +230 -0
  27. package/dist/semantic/__tests__/semantic-translator.test.d.ts +4 -0
  28. package/dist/semantic/__tests__/semantic-translator.test.js +203 -0
  29. package/dist/semantic/semantic-translator.d.ts +229 -0
  30. package/dist/semantic/semantic-translator.js +398 -0
  31. package/package.json +28 -0
  32. package/playwright-report/data/0bafe4e0863f0e244bba68a838f73241f8f2efaa.md +226 -0
  33. package/playwright-report/data/9281aca8abfb06c6cecb35d5ddd13d61f8c752d8.md +226 -0
  34. package/playwright-report/index.html +90 -0
  35. package/playwright.config.ts +160 -0
  36. package/screenshot-chrome.png +0 -0
  37. package/screenshots/visual-demo-verification.png +0 -0
  38. package/screenshots/visual-demo.png +0 -0
  39. package/src/ast/types.ts +473 -0
  40. package/src/compiler/chunk-splitter.ts +534 -0
  41. package/src/index.ts +62 -0
  42. package/src/rasterizer/__tests__/error-distribution.test.ts +382 -0
  43. package/src/rasterizer/canvas-mapper.ts +677 -0
  44. package/src/rasterizer/error-distribution.ts +344 -0
  45. package/src/rasterizer/gradient-mapper.ts +563 -0
  46. package/src/rasterizer/topology-rounding.ts +499 -0
  47. package/src/runtime/__tests__/event-backpressure.test.ts +254 -0
  48. package/src/runtime/event-backpressure.ts +622 -0
  49. package/src/runtime/render-loop.ts +660 -0
  50. package/src/runtime/wasm-resource-manager.ts +349 -0
  51. package/src/runtime/wgpu-renderer-adapter.ts +318 -0
  52. package/src/semantic/__tests__/semantic-translator.test.ts +263 -0
  53. package/src/semantic/semantic-translator.ts +637 -0
  54. package/test-results/.last-run.json +4 -0
  55. package/tests/e2e/async-race.spec.ts +612 -0
  56. package/tests/e2e/bilayer-sync.spec.ts +405 -0
  57. package/tests/e2e/failures/.gitkeep +0 -0
  58. package/tests/e2e/fullstack.spec.ts +681 -0
  59. package/tests/e2e/g1-continuity.spec.ts +703 -0
  60. package/tests/e2e/golden/.gitkeep +0 -0
  61. package/tests/e2e/golden/conic-color-wheel.raw +0 -0
  62. package/tests/e2e/golden/conic-color-wheel.sha256 +1 -0
  63. package/tests/e2e/golden/conic-rotated.raw +0 -0
  64. package/tests/e2e/golden/conic-rotated.sha256 +1 -0
  65. package/tests/e2e/golden/linear-45deg.raw +0 -0
  66. package/tests/e2e/golden/linear-45deg.sha256 +1 -0
  67. package/tests/e2e/golden/linear-horizontal.raw +0 -0
  68. package/tests/e2e/golden/linear-horizontal.sha256 +1 -0
  69. package/tests/e2e/golden/linear-multi-stop.raw +0 -0
  70. package/tests/e2e/golden/linear-multi-stop.sha256 +1 -0
  71. package/tests/e2e/golden/radial-circle-center.raw +0 -0
  72. package/tests/e2e/golden/radial-circle-center.sha256 +1 -0
  73. package/tests/e2e/golden/radial-offset.raw +0 -0
  74. package/tests/e2e/golden/radial-offset.sha256 +1 -0
  75. package/tests/e2e/golden/tile-mirror.raw +0 -0
  76. package/tests/e2e/golden/tile-mirror.sha256 +1 -0
  77. package/tests/e2e/golden/tile-repeat.raw +0 -0
  78. package/tests/e2e/golden/tile-repeat.sha256 +1 -0
  79. package/tests/e2e/gradient-animation.spec.ts +606 -0
  80. package/tests/e2e/memory-stability.spec.ts +396 -0
  81. package/tests/e2e/path-topology.spec.ts +674 -0
  82. package/tests/e2e/performance-profile.spec.ts +501 -0
  83. package/tests/e2e/screenshot.spec.ts +60 -0
  84. package/tests/e2e/test-harness.html +1005 -0
  85. package/tests/e2e/text-layout.spec.ts +451 -0
  86. package/tests/e2e/visual-demo.html +340 -0
  87. package/tests/e2e/visual-regression.spec.ts +335 -0
  88. package/tsconfig.json +12 -0
  89. package/vitest.config.ts +8 -0
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Subpixel Error Distribution Algorithm
3
+ *
4
+ * This module implements the Largest Remainder Method (LRM) for distributing
5
+ * subpixel rounding errors across child elements within a parent container.
6
+ *
7
+ * ## The Problem (Architect's Decision #2: Spatial Closure)
8
+ *
9
+ * Given a 100px container with 3 children of equal width (33.333...px each):
10
+ *
11
+ * ```
12
+ * Naive rounding:
13
+ * floor(33.333) = 33
14
+ * 33 + 33 + 33 = 99px ← 1px HOLE!
15
+ * ```
16
+ *
17
+ * This violates VS axiom: "Constraint holes cannot be hidden in theoretical blind spots"
18
+ *
19
+ * ## Solution: Largest Remainder Method
20
+ *
21
+ * 1. Compute integer quotients: floor(33.333) = 33 for each
22
+ * 2. Compute remainders: 0.333... for each
23
+ * 3. Total shortfall: 100 - 99 = 1px
24
+ * 4. Distribute 1px to elements with largest remainders
25
+ *
26
+ * Result: [34, 33, 33] or [33, 34, 33] or [33, 33, 34]
27
+ * Sum: 100px exactly ✓
28
+ *
29
+ * ## Mathematical Guarantee
30
+ *
31
+ * For any set of positive rationals r₁, r₂, ..., rₙ where Σrᵢ = T (integer):
32
+ *
33
+ * Σ⌊rᵢ⌋ ≤ T ≤ Σ⌈rᵢ⌉
34
+ *
35
+ * LRM distributes exactly (T - Σ⌊rᵢ⌋) extra pixels to achieve Σ = T.
36
+ */
37
+ // =============================================================================
38
+ // Largest Remainder Method
39
+ // =============================================================================
40
+ /**
41
+ * Distribute subpixel errors using the Largest Remainder Method.
42
+ *
43
+ * ## Algorithm
44
+ *
45
+ * ```
46
+ * INPUT: childDimensions = [33.333, 33.333, 33.333], parentDimension = 100
47
+ *
48
+ * Step 1: Compute floors
49
+ * floors = [33, 33, 33]
50
+ * sum(floors) = 99
51
+ *
52
+ * Step 2: Compute remainders
53
+ * remainders = [0.333, 0.333, 0.333]
54
+ *
55
+ * Step 3: Compute shortfall
56
+ * shortfall = 100 - 99 = 1
57
+ *
58
+ * Step 4: Sort by remainder (descending), distribute shortfall
59
+ * Give 1px to first element (arbitrary tie-break: leftmost)
60
+ *
61
+ * OUTPUT: [34, 33, 33]
62
+ * ```
63
+ *
64
+ * ## Tie-Breaking Strategy
65
+ *
66
+ * When remainders are equal (common for equal-width elements):
67
+ * - Distribute extra pixels left-to-right (reading order)
68
+ * - This is visually predictable and matches user expectation
69
+ */
70
+ export function distributeWithLargestRemainder(group) {
71
+ const { childIds, parentDimension, childDimensions } = group;
72
+ // Edge case: no children
73
+ if (childIds.length === 0) {
74
+ return {
75
+ dimensions: [],
76
+ totalPixels: 0,
77
+ isExact: parentDimension === 0,
78
+ method: 'largest-remainder',
79
+ };
80
+ }
81
+ const items = childIds.map((id, index) => {
82
+ const original = childDimensions.get(id) ?? 0;
83
+ const floor = Math.floor(original);
84
+ return {
85
+ entityId: id,
86
+ original,
87
+ floor,
88
+ remainder: original - floor,
89
+ index,
90
+ };
91
+ });
92
+ // Step 2: Compute shortfall
93
+ const sumOfFloors = items.reduce((sum, item) => sum + item.floor, 0);
94
+ const shortfall = parentDimension - sumOfFloors;
95
+ // Sanity check: shortfall should be non-negative and <= childCount
96
+ if (shortfall < 0 || shortfall > items.length) {
97
+ // This indicates a constraint violation (children sum > parent)
98
+ // Fall back to proportional scaling
99
+ return distributeProportionally(group);
100
+ }
101
+ // Step 3: Sort by remainder (descending), then by index (ascending) for tie-break
102
+ const sorted = [...items].sort((a, b) => {
103
+ const remainderDiff = b.remainder - a.remainder;
104
+ if (Math.abs(remainderDiff) > 1e-10) {
105
+ return remainderDiff;
106
+ }
107
+ // Tie-break: leftmost first
108
+ return a.index - b.index;
109
+ });
110
+ // Step 4: Distribute shortfall to top N elements
111
+ const extraPixels = new Set();
112
+ for (let i = 0; i < shortfall; i++) {
113
+ extraPixels.add(sorted[i].entityId);
114
+ }
115
+ // Step 5: Build result
116
+ const dimensions = items.map(item => {
117
+ const pixels = item.floor + (extraPixels.has(item.entityId) ? 1 : 0);
118
+ return {
119
+ entityId: item.entityId,
120
+ pixels,
121
+ original: item.original,
122
+ error: pixels - item.original,
123
+ };
124
+ });
125
+ const totalPixels = dimensions.reduce((sum, d) => sum + d.pixels, 0);
126
+ return {
127
+ dimensions,
128
+ totalPixels,
129
+ isExact: totalPixels === parentDimension,
130
+ method: 'largest-remainder',
131
+ };
132
+ }
133
+ /**
134
+ * Fallback: Proportional scaling when LRM fails.
135
+ *
136
+ * Used when child sum exceeds parent (constraint violation).
137
+ */
138
+ function distributeProportionally(group) {
139
+ const { childIds, parentDimension, childDimensions } = group;
140
+ const totalOriginal = childIds.reduce((sum, id) => sum + (childDimensions.get(id) ?? 0), 0);
141
+ if (totalOriginal === 0) {
142
+ return {
143
+ dimensions: childIds.map(id => ({
144
+ entityId: id,
145
+ pixels: 0,
146
+ original: 0,
147
+ error: 0,
148
+ })),
149
+ totalPixels: 0,
150
+ isExact: parentDimension === 0,
151
+ method: 'first-fit',
152
+ };
153
+ }
154
+ const scale = parentDimension / totalOriginal;
155
+ const scaled = childIds.map(id => {
156
+ const original = childDimensions.get(id) ?? 0;
157
+ return {
158
+ entityId: id,
159
+ original,
160
+ scaled: original * scale,
161
+ };
162
+ });
163
+ // Apply LRM to scaled values
164
+ const scaledGroup = {
165
+ ...group,
166
+ childDimensions: new Map(scaled.map(s => [s.entityId, s.scaled])),
167
+ };
168
+ const result = distributeWithLargestRemainder(scaledGroup);
169
+ result.method = 'first-fit';
170
+ return result;
171
+ }
172
+ /**
173
+ * Apply error distribution to a set of sibling groups.
174
+ *
175
+ * This is called AFTER basic topology-preserving rounding,
176
+ * to ensure parent boundaries are exactly satisfied.
177
+ */
178
+ export function applyErrorDistribution(roundedBounds, containments) {
179
+ const result = new Map(roundedBounds);
180
+ for (const constraint of containments) {
181
+ const parentBounds = result.get(constraint.parentId);
182
+ if (!parentBounds)
183
+ continue;
184
+ const parentDimension = constraint.axis === 'horizontal'
185
+ ? parentBounds.width
186
+ : parentBounds.height;
187
+ // Build sibling group
188
+ const childDimensions = new Map();
189
+ for (const childId of constraint.childIds) {
190
+ const childBounds = result.get(childId);
191
+ if (childBounds) {
192
+ const dim = constraint.axis === 'horizontal'
193
+ ? childBounds.width
194
+ : childBounds.height;
195
+ childDimensions.set(childId, dim);
196
+ }
197
+ }
198
+ const group = {
199
+ parentId: constraint.parentId,
200
+ childIds: constraint.childIds,
201
+ axis: constraint.axis,
202
+ parentDimension,
203
+ childDimensions,
204
+ };
205
+ // Distribute
206
+ const distribution = distributeWithLargestRemainder(group);
207
+ // Apply distributed dimensions
208
+ let offset = constraint.axis === 'horizontal' ? parentBounds.x : parentBounds.y;
209
+ for (const dist of distribution.dimensions) {
210
+ const childBounds = result.get(dist.entityId);
211
+ if (childBounds) {
212
+ if (constraint.axis === 'horizontal') {
213
+ childBounds.x = offset;
214
+ childBounds.width = dist.pixels;
215
+ }
216
+ else {
217
+ childBounds.y = offset;
218
+ childBounds.height = dist.pixels;
219
+ }
220
+ offset += dist.pixels;
221
+ }
222
+ }
223
+ }
224
+ return result;
225
+ }
226
+ // =============================================================================
227
+ // Exports for Testing
228
+ // =============================================================================
229
+ export const _internals = {
230
+ distributeProportionally,
231
+ };
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Gradient Shader Mapper: P-Dimension to GPU Shaders
3
+ *
4
+ * This module maps P-dimension gradient entities to GPU shader objects.
5
+ * It handles the critical transition from exact rational arithmetic to GPU-compatible
6
+ * floating-point representation while preserving visual fidelity.
7
+ *
8
+ * ## Architecture
9
+ *
10
+ * ```
11
+ * P-Dimension (Exact) GPU (Float)
12
+ * ─────────────────────────────────────────────────────────────
13
+ *
14
+ * LinearGradient { GpuShaderBackend.Shader
15
+ * start: Rational(1, 3) ────────────▶ MakeLinearGradient(
16
+ * end: Rational(2, 3) [0.333..., 0.666...],
17
+ * stops: [ colors: Float32Array,
18
+ * ColorStop(r=255, ...) positions: Float32Array
19
+ * ] )
20
+ * }
21
+ *
22
+ * ┌─────────────────────────────────────────────────────────────┐
23
+ * │ CRITICAL: Topology-preserving rounding at this boundary │
24
+ * │ │
25
+ * │ - Color channels [0, 255] → [0.0, 1.0] with clamping │
26
+ * │ - Position values [0, 1] stay exact, no interpolation │
27
+ * │ - Control points use same rounding as other coordinates │
28
+ * └─────────────────────────────────────────────────────────────┘
29
+ * ```
30
+ *
31
+ * ## Usage
32
+ *
33
+ * ```typescript
34
+ * const shader = mapLinearGradientToShader(ck, gradient, bounds, dpr);
35
+ * paint.setShader(shader);
36
+ * canvas.drawRect(bounds, paint);
37
+ * ```
38
+ */
39
+ import type { Rational, RasterBounds } from '../ast/types';
40
+ /** GPU shader backend interface (minimal subset needed for gradients) */
41
+ export interface GpuShaderBackend {
42
+ Shader: {
43
+ MakeLinearGradient(start: Float32Array, end: Float32Array, colors: Float32Array, positions: Float32Array | null, mode: number, localMatrix?: Float32Array): ShaderInstance;
44
+ MakeTwoPointConicalGradient(start: Float32Array, startRadius: number, end: Float32Array, endRadius: number, colors: Float32Array, positions: Float32Array | null, mode: number, localMatrix?: Float32Array): ShaderInstance;
45
+ MakeSweepGradient(cx: number, cy: number, colors: Float32Array, positions: Float32Array | null, mode: number, startAngle: number, endAngle: number, localMatrix?: Float32Array): ShaderInstance;
46
+ };
47
+ TileMode: {
48
+ Clamp: number;
49
+ Repeat: number;
50
+ Mirror: number;
51
+ Decal: number;
52
+ };
53
+ }
54
+ export interface ShaderInstance {
55
+ delete(): void;
56
+ }
57
+ /**
58
+ * P-dimension color stop with exact rational values.
59
+ */
60
+ export interface PColorStop {
61
+ /** Entity ID */
62
+ id: number;
63
+ /** Red channel [0, 255] (rational) */
64
+ r: Rational;
65
+ /** Green channel [0, 255] (rational) */
66
+ g: Rational;
67
+ /** Blue channel [0, 255] (rational) */
68
+ b: Rational;
69
+ /** Alpha channel [0, 1] (rational) */
70
+ a: Rational;
71
+ /** Position along gradient [0, 1] (rational) */
72
+ position: Rational;
73
+ }
74
+ /**
75
+ * P-dimension control point with exact coordinates.
76
+ */
77
+ export interface PControlPoint {
78
+ id: number;
79
+ x: Rational;
80
+ y: Rational;
81
+ }
82
+ /**
83
+ * P-dimension linear gradient definition.
84
+ */
85
+ export interface PLinearGradient {
86
+ id: number;
87
+ start: PControlPoint;
88
+ end: PControlPoint;
89
+ stops: PColorStop[];
90
+ tileMode: 'clamp' | 'repeat' | 'mirror' | 'decal';
91
+ }
92
+ /**
93
+ * P-dimension radial gradient definition.
94
+ */
95
+ export interface PRadialGradient {
96
+ id: number;
97
+ center: PControlPoint;
98
+ radiusX: Rational;
99
+ radiusY: Rational;
100
+ focalPoint?: PControlPoint;
101
+ focalRadius?: Rational;
102
+ stops: PColorStop[];
103
+ tileMode: 'clamp' | 'repeat' | 'mirror' | 'decal';
104
+ }
105
+ /**
106
+ * P-dimension conic (sweep) gradient definition.
107
+ */
108
+ export interface PConicGradient {
109
+ id: number;
110
+ center: PControlPoint;
111
+ /** Rotation offset in degrees (rational) */
112
+ rotation: Rational;
113
+ /** Start angle in degrees (rational) */
114
+ startAngle: Rational;
115
+ /** End angle in degrees (rational) */
116
+ endAngle: Rational;
117
+ stops: PColorStop[];
118
+ }
119
+ /**
120
+ * Map a P-dimension linear gradient to a GPU shader.
121
+ *
122
+ * @param ck - GPU shader backend instance
123
+ * @param gradient - P-dimension linear gradient definition
124
+ * @param bounds - Rasterized bounds for coordinate transformation
125
+ * @param devicePixelRatio - Device pixel ratio for coordinate scaling
126
+ * @returns GPU shader instance (caller must call delete() when done)
127
+ */
128
+ export declare function mapLinearGradientToShader(ck: GpuShaderBackend, gradient: PLinearGradient, bounds: RasterBounds, devicePixelRatio: number): ShaderInstance;
129
+ /**
130
+ * Map a P-dimension radial gradient to a GPU shader.
131
+ *
132
+ * The GPU backend uses two-point conical gradients which can express:
133
+ * - Circle gradients (same center, different radii)
134
+ * - Focal gradients (different centers)
135
+ *
136
+ * @param ck - GPU shader backend instance
137
+ * @param gradient - P-dimension radial gradient definition
138
+ * @param bounds - Rasterized bounds for coordinate transformation
139
+ * @param devicePixelRatio - Device pixel ratio for coordinate scaling
140
+ * @returns GPU shader instance
141
+ */
142
+ export declare function mapRadialGradientToShader(ck: GpuShaderBackend, gradient: PRadialGradient, bounds: RasterBounds, devicePixelRatio: number): ShaderInstance;
143
+ /**
144
+ * Map a P-dimension conic (sweep) gradient to a GPU shader.
145
+ *
146
+ * @param ck - GPU shader backend instance
147
+ * @param gradient - P-dimension conic gradient definition
148
+ * @param bounds - Rasterized bounds for coordinate transformation
149
+ * @param devicePixelRatio - Device pixel ratio for coordinate scaling
150
+ * @returns GPU shader instance
151
+ */
152
+ export declare function mapConicGradientToShader(ck: GpuShaderBackend, gradient: PConicGradient, bounds: RasterBounds, devicePixelRatio: number): ShaderInstance;
153
+ /**
154
+ * Convert a rational number to a floating-point number.
155
+ *
156
+ * This is the critical boundary where exact arithmetic meets GPU floats.
157
+ * The conversion is straightforward division, but precision loss is
158
+ * unavoidable and acceptable at this layer.
159
+ */
160
+ export declare function rationalToFloat(r: Rational): number;
161
+ /**
162
+ * Convert P-dimension color stops to a Float32Array of RGBA values.
163
+ *
164
+ * GPU shader expects colors in RGBA order, with each channel in [0, 1].
165
+ * P-dimension stores RGB in [0, 255] and Alpha in [0, 1].
166
+ *
167
+ * ## Topology-Preserving Rounding (Clamping)
168
+ *
169
+ * Color values are clamped to [0, 1] to ensure GPU-valid input.
170
+ * This preserves the topological ordering of colors even if the
171
+ * original rational values were slightly out of range.
172
+ */
173
+ export declare function colorStopsToFloat32Array(stops: PColorStop[]): Float32Array;
174
+ /**
175
+ * Convert P-dimension color stop positions to a Float32Array.
176
+ *
177
+ * Positions are kept as-is (already in [0, 1] in P-dimension),
178
+ * with clamping for safety.
179
+ */
180
+ export declare function positionsToFloat32Array(stops: PColorStop[]): Float32Array;
181
+ /**
182
+ * Clamp a value to [0, 1] range.
183
+ *
184
+ * This is the "topology-preserving rounding" for color values:
185
+ * it ensures the value is valid for GPU while preserving ordering.
186
+ */
187
+ declare function clamp01(value: number): number;
188
+ /**
189
+ * Map P-dimension tile mode to GPU tile mode constant.
190
+ */
191
+ declare function mapTileMode(ck: GpuShaderBackend, mode: 'clamp' | 'repeat' | 'mirror' | 'decal'): number;
192
+ /**
193
+ * Create a GPU shader from a FillStyle gradient definition.
194
+ *
195
+ * This is a higher-level factory that integrates with the existing
196
+ * FillStyle type from the AST.
197
+ */
198
+ export declare function createGradientShader(ck: GpuShaderBackend, fillType: 'linear-gradient' | 'radial-gradient', stops: Array<{
199
+ offset: Rational;
200
+ color: string;
201
+ }>, bounds: RasterBounds, devicePixelRatio: number): ShaderInstance | null;
202
+ /**
203
+ * Parse a CSS color string to RGBA values.
204
+ *
205
+ * Supports:
206
+ * - Hex: #RGB, #RGBA, #RRGGBB, #RRGGBBAA
207
+ * - Named colors (basic set)
208
+ */
209
+ declare function parseColorString(color: string): {
210
+ r: number;
211
+ g: number;
212
+ b: number;
213
+ a: number;
214
+ };
215
+ export declare const _internals: {
216
+ rationalToFloat: typeof rationalToFloat;
217
+ clamp01: typeof clamp01;
218
+ colorStopsToFloat32Array: typeof colorStopsToFloat32Array;
219
+ positionsToFloat32Array: typeof positionsToFloat32Array;
220
+ mapTileMode: typeof mapTileMode;
221
+ parseColorString: typeof parseColorString;
222
+ };
223
+ export {};