@photivra/engine 0.2.0 → 0.5.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/CHANGELOG.md +79 -0
- package/CITATION.cff +1 -1
- package/README.md +59 -10
- package/dist/camera/equivalent-focal-length.d.ts +34 -0
- package/dist/camera/equivalent-focal-length.d.ts.map +1 -0
- package/dist/camera/equivalent-focal-length.js +33 -0
- package/dist/camera/equivalent-focal-length.js.map +1 -0
- package/dist/camera/field-of-view.d.ts +40 -3
- package/dist/camera/field-of-view.d.ts.map +1 -1
- package/dist/camera/field-of-view.js +66 -24
- package/dist/camera/field-of-view.js.map +1 -1
- package/dist/core/calculation-result.d.ts.map +1 -1
- package/dist/core/calculation-result.js +14 -2
- package/dist/core/calculation-result.js.map +1 -1
- package/dist/core/configuration-error.d.ts +9 -0
- package/dist/core/configuration-error.d.ts.map +1 -0
- package/dist/core/configuration-error.js +13 -0
- package/dist/core/configuration-error.js.map +1 -0
- package/dist/core/evidence-provenance.d.ts +40 -0
- package/dist/core/evidence-provenance.d.ts.map +1 -0
- package/dist/core/evidence-provenance.js +79 -0
- package/dist/core/evidence-provenance.js.map +1 -0
- package/dist/core/image-formation.d.ts +70 -0
- package/dist/core/image-formation.d.ts.map +1 -0
- package/dist/core/image-formation.js +335 -0
- package/dist/core/image-formation.js.map +1 -0
- package/dist/index.d.ts +15 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -3
- package/dist/index.js.map +1 -1
- package/dist/motion/camera-rotation.d.ts +91 -0
- package/dist/motion/camera-rotation.d.ts.map +1 -0
- package/dist/motion/camera-rotation.js +157 -0
- package/dist/motion/camera-rotation.js.map +1 -0
- package/dist/optics/focus-breathing.d.ts +73 -0
- package/dist/optics/focus-breathing.d.ts.map +1 -0
- package/dist/optics/focus-breathing.js +77 -0
- package/dist/optics/focus-breathing.js.map +1 -0
- package/dist/optics/illumination-vignetting.d.ts +59 -0
- package/dist/optics/illumination-vignetting.d.ts.map +1 -0
- package/dist/optics/illumination-vignetting.js +107 -0
- package/dist/optics/illumination-vignetting.js.map +1 -0
- package/dist/optics/lateral-chromatic-aberration.d.ts +117 -0
- package/dist/optics/lateral-chromatic-aberration.d.ts.map +1 -0
- package/dist/optics/lateral-chromatic-aberration.js +228 -0
- package/dist/optics/lateral-chromatic-aberration.js.map +1 -0
- package/dist/optics/psf-foundation.d.ts +102 -0
- package/dist/optics/psf-foundation.d.ts.map +1 -0
- package/dist/optics/psf-foundation.js +164 -0
- package/dist/optics/psf-foundation.js.map +1 -0
- package/dist/optics/radial-distortion.d.ts +131 -0
- package/dist/optics/radial-distortion.d.ts.map +1 -0
- package/dist/optics/radial-distortion.js +227 -0
- package/dist/optics/radial-distortion.js.map +1 -0
- package/dist/output/capture-geometry.d.ts +278 -0
- package/dist/output/capture-geometry.d.ts.map +1 -0
- package/dist/output/capture-geometry.js +562 -0
- package/dist/output/capture-geometry.js.map +1 -0
- package/dist/schema/validation.d.ts +1 -8
- package/dist/schema/validation.d.ts.map +1 -1
- package/dist/schema/validation.js +2 -11
- package/dist/schema/validation.js.map +1 -1
- package/dist/sensor/architecture.d.ts +40 -0
- package/dist/sensor/architecture.d.ts.map +1 -0
- package/dist/sensor/architecture.js +98 -0
- package/dist/sensor/architecture.js.map +1 -0
- package/dist/sensor/radiometry-readiness.d.ts +111 -0
- package/dist/sensor/radiometry-readiness.d.ts.map +1 -0
- package/dist/sensor/radiometry-readiness.js +294 -0
- package/dist/sensor/radiometry-readiness.js.map +1 -0
- package/dist/sensor/sensor-geometry.d.ts +99 -0
- package/dist/sensor/sensor-geometry.d.ts.map +1 -0
- package/dist/sensor/sensor-geometry.js +71 -0
- package/dist/sensor/sensor-geometry.js.map +1 -0
- package/dist/simulation/poc-simulation.d.ts +93 -1
- package/dist/simulation/poc-simulation.d.ts.map +1 -1
- package/dist/simulation/poc-simulation.js +308 -24
- package/dist/simulation/poc-simulation.js.map +1 -1
- package/docs/API_STYLE.md +36 -2
- package/docs/ARCHITECTURE.md +179 -1
- package/docs/IMAGE_FORMATION.md +151 -0
- package/docs/MOTION_AND_SIGNAL.md +52 -1
- package/docs/PHYSICS_FOUNDATION.md +190 -3
- package/docs/POC_API.md +73 -7
- package/docs/PROVENANCE.md +24 -0
- package/docs/PSF_FOUNDATION.md +133 -0
- package/docs/STABILIZATION.md +17 -4
- package/docs/USAGE.md +714 -3
- package/package.json +3 -2
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { calculateFieldOfViewBounds } from "../camera/field-of-view.js";
|
|
3
|
+
import { calculatedResult } from "../core/calculation-result.js";
|
|
4
|
+
import { InvalidScientificInputError, requirePositiveFinite, requirePositiveInteger } from "../core/validation.js";
|
|
5
|
+
import {} from "../sensor/sensor-geometry.js";
|
|
6
|
+
const CAPTURE_ORIENTATIONS = new Set([
|
|
7
|
+
"landscape",
|
|
8
|
+
"portrait-clockwise",
|
|
9
|
+
"landscape-inverted",
|
|
10
|
+
"portrait-counter-clockwise"
|
|
11
|
+
]);
|
|
12
|
+
function requireCaptureOrientation(value) {
|
|
13
|
+
if (typeof value !== "string" ||
|
|
14
|
+
!CAPTURE_ORIENTATIONS.has(value)) {
|
|
15
|
+
throw new InvalidScientificInputError("orientation is invalid.");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function requireRasterDimensions(name, raster) {
|
|
19
|
+
requirePositiveInteger(`${name}.pixelWidth`, raster.pixelWidth);
|
|
20
|
+
requirePositiveInteger(`${name}.pixelHeight`, raster.pixelHeight);
|
|
21
|
+
}
|
|
22
|
+
function requireNonNegativeInteger(name, value) {
|
|
23
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
24
|
+
throw new InvalidScientificInputError(`${name} must be a non-negative safe integer.`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function validateRasterRect(name, rect, bounds) {
|
|
28
|
+
requireNonNegativeInteger(`${name}.x`, rect.x);
|
|
29
|
+
requireNonNegativeInteger(`${name}.y`, rect.y);
|
|
30
|
+
requirePositiveInteger(`${name}.width`, rect.width);
|
|
31
|
+
requirePositiveInteger(`${name}.height`, rect.height);
|
|
32
|
+
if (rect.x + rect.width > bounds.pixelWidth ||
|
|
33
|
+
rect.y + rect.height > bounds.pixelHeight) {
|
|
34
|
+
throw new InvalidScientificInputError(`${name} must fit entirely within its raster bounds.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function validateRasterPoint(name, point, bounds) {
|
|
38
|
+
if (!Number.isFinite(point.x) || !Number.isFinite(point.y)) {
|
|
39
|
+
throw new InvalidScientificInputError(`${name} coordinates must be finite.`);
|
|
40
|
+
}
|
|
41
|
+
if (point.x < 0 ||
|
|
42
|
+
point.y < 0 ||
|
|
43
|
+
point.x > bounds.pixelWidth ||
|
|
44
|
+
point.y > bounds.pixelHeight) {
|
|
45
|
+
throw new InvalidScientificInputError(`${name} must lie within the raster edge-coordinate bounds.`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function validateRasterVector(name, vector) {
|
|
49
|
+
if (!Number.isFinite(vector.x) || !Number.isFinite(vector.y)) {
|
|
50
|
+
throw new InvalidScientificInputError(`${name} coordinates must be finite.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const NORMALIZED_UV_EDGE_TOLERANCE = 1e-12;
|
|
54
|
+
function validatePhysicalBounds(name, bounds) {
|
|
55
|
+
for (const key of ["left", "right", "top", "bottom"]) {
|
|
56
|
+
if (!Number.isFinite(bounds[key])) {
|
|
57
|
+
throw new InvalidScientificInputError(`${name}.${key} must be finite.`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (bounds.right <= bounds.left) {
|
|
61
|
+
throw new InvalidScientificInputError(`${name} must have right greater than left.`);
|
|
62
|
+
}
|
|
63
|
+
if (bounds.bottom <= bounds.top) {
|
|
64
|
+
throw new InvalidScientificInputError(`${name} must have bottom greater than top.`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function validateNormalizedUv(name, uv) {
|
|
68
|
+
if (!Number.isFinite(uv.u) || !Number.isFinite(uv.v)) {
|
|
69
|
+
throw new InvalidScientificInputError(`${name} coordinates must be finite.`);
|
|
70
|
+
}
|
|
71
|
+
if (uv.u < 0 || uv.u > 1 || uv.v < 0 || uv.v > 1) {
|
|
72
|
+
throw new InvalidScientificInputError(`${name} coordinates must lie within [0, 1].`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function normalizeUvEdge(name, value) {
|
|
76
|
+
if (!Number.isFinite(value)) {
|
|
77
|
+
throw new InvalidScientificInputError(`${name} must be finite.`);
|
|
78
|
+
}
|
|
79
|
+
if (value < -NORMALIZED_UV_EDGE_TOLERANCE ||
|
|
80
|
+
value > 1 + NORMALIZED_UV_EDGE_TOLERANCE) {
|
|
81
|
+
throw new InvalidScientificInputError(`${name} must lie within the supplied oriented physical bounds.`);
|
|
82
|
+
}
|
|
83
|
+
return Math.max(0, Math.min(1, value));
|
|
84
|
+
}
|
|
85
|
+
function fullRect(raster) {
|
|
86
|
+
return {
|
|
87
|
+
x: 0,
|
|
88
|
+
y: 0,
|
|
89
|
+
width: raster.pixelWidth,
|
|
90
|
+
height: raster.pixelHeight
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function orientRaster(raster, orientation) {
|
|
94
|
+
return orientation === "portrait-clockwise" ||
|
|
95
|
+
orientation === "portrait-counter-clockwise"
|
|
96
|
+
? {
|
|
97
|
+
pixelWidth: raster.pixelHeight,
|
|
98
|
+
pixelHeight: raster.pixelWidth
|
|
99
|
+
}
|
|
100
|
+
: {
|
|
101
|
+
pixelWidth: raster.pixelWidth,
|
|
102
|
+
pixelHeight: raster.pixelHeight
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function rotateVector(vector, orientation) {
|
|
106
|
+
switch (orientation) {
|
|
107
|
+
case "landscape":
|
|
108
|
+
return { x: vector.x, y: vector.y };
|
|
109
|
+
case "portrait-clockwise":
|
|
110
|
+
return { x: -vector.y, y: vector.x };
|
|
111
|
+
case "landscape-inverted":
|
|
112
|
+
return { x: -vector.x, y: -vector.y };
|
|
113
|
+
case "portrait-counter-clockwise":
|
|
114
|
+
return { x: vector.y, y: -vector.x };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function inverseRotateVector(vector, orientation) {
|
|
118
|
+
switch (orientation) {
|
|
119
|
+
case "landscape":
|
|
120
|
+
return { x: vector.x, y: vector.y };
|
|
121
|
+
case "portrait-clockwise":
|
|
122
|
+
return { x: vector.y, y: -vector.x };
|
|
123
|
+
case "landscape-inverted":
|
|
124
|
+
return { x: -vector.x, y: -vector.y };
|
|
125
|
+
case "portrait-counter-clockwise":
|
|
126
|
+
return { x: -vector.y, y: vector.x };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Transforms a continuous native raster edge-coordinate point into oriented
|
|
131
|
+
* capture coordinates. Pixel centers can be represented with +0.5 offsets.
|
|
132
|
+
*/
|
|
133
|
+
export function transformNativeRasterPointToOriented(input) {
|
|
134
|
+
requireCaptureOrientation(input.orientation);
|
|
135
|
+
requireRasterDimensions("nativeRaster", input.nativeRaster);
|
|
136
|
+
validateRasterPoint("point", input.point, input.nativeRaster);
|
|
137
|
+
const { pixelWidth: width, pixelHeight: height } = input.nativeRaster;
|
|
138
|
+
switch (input.orientation) {
|
|
139
|
+
case "landscape":
|
|
140
|
+
return { ...input.point };
|
|
141
|
+
case "portrait-clockwise":
|
|
142
|
+
return { x: height - input.point.y, y: input.point.x };
|
|
143
|
+
case "landscape-inverted":
|
|
144
|
+
return { x: width - input.point.x, y: height - input.point.y };
|
|
145
|
+
case "portrait-counter-clockwise":
|
|
146
|
+
return { x: input.point.y, y: width - input.point.x };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** Transforms an oriented raster edge-coordinate point back to native coordinates. */
|
|
150
|
+
export function transformOrientedRasterPointToNative(input) {
|
|
151
|
+
requireCaptureOrientation(input.orientation);
|
|
152
|
+
requireRasterDimensions("nativeRaster", input.nativeRaster);
|
|
153
|
+
const orientedRaster = orientRaster(input.nativeRaster, input.orientation);
|
|
154
|
+
validateRasterPoint("point", input.point, orientedRaster);
|
|
155
|
+
const { pixelWidth: width, pixelHeight: height } = input.nativeRaster;
|
|
156
|
+
switch (input.orientation) {
|
|
157
|
+
case "landscape":
|
|
158
|
+
return { ...input.point };
|
|
159
|
+
case "portrait-clockwise":
|
|
160
|
+
return { x: input.point.y, y: height - input.point.x };
|
|
161
|
+
case "landscape-inverted":
|
|
162
|
+
return { x: width - input.point.x, y: height - input.point.y };
|
|
163
|
+
case "portrait-counter-clockwise":
|
|
164
|
+
return { x: width - input.point.y, y: input.point.x };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/** Rotates a native raster vector into oriented coordinates. */
|
|
168
|
+
export function transformNativeRasterVectorToOriented(input) {
|
|
169
|
+
requireCaptureOrientation(input.orientation);
|
|
170
|
+
validateRasterVector("vector", input.vector);
|
|
171
|
+
return rotateVector(input.vector, input.orientation);
|
|
172
|
+
}
|
|
173
|
+
/** Rotates an oriented raster vector back into native coordinates. */
|
|
174
|
+
export function transformOrientedRasterVectorToNative(input) {
|
|
175
|
+
requireCaptureOrientation(input.orientation);
|
|
176
|
+
validateRasterVector("vector", input.vector);
|
|
177
|
+
return inverseRotateVector(input.vector, input.orientation);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Maps normalized coordinates in an oriented physical raster region into the
|
|
181
|
+
* pre-orientation optical image plane used by lens-field and camera-mapping
|
|
182
|
+
* APIs.
|
|
183
|
+
*
|
|
184
|
+
* The supplied physical bounds use the capture contract's +Y-down basis after
|
|
185
|
+
* physical camera orientation. The returned image-plane point uses optical-axis
|
|
186
|
+
* origin, +X right and +Y up. No lens or projection equation is applied.
|
|
187
|
+
*/
|
|
188
|
+
export function mapOrientedPhysicalUvToImagePlanePoint(input) {
|
|
189
|
+
requireCaptureOrientation(input.orientation);
|
|
190
|
+
validateNormalizedUv("uv", input.uv);
|
|
191
|
+
validatePhysicalBounds("orientedPhysicalBoundsFromOpticalAxisMm", input.orientedPhysicalBoundsFromOpticalAxisMm);
|
|
192
|
+
const bounds = input.orientedPhysicalBoundsFromOpticalAxisMm;
|
|
193
|
+
const orientedPhysicalPoint = {
|
|
194
|
+
x: bounds.left + input.uv.u * (bounds.right - bounds.left),
|
|
195
|
+
y: bounds.top + input.uv.v * (bounds.bottom - bounds.top)
|
|
196
|
+
};
|
|
197
|
+
const nativePhysicalPoint = inverseRotateVector(orientedPhysicalPoint, input.orientation);
|
|
198
|
+
return {
|
|
199
|
+
x: nativePhysicalPoint.x,
|
|
200
|
+
y: -nativePhysicalPoint.y
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Maps a pre-orientation optical image-plane point into normalized coordinates
|
|
205
|
+
* of an oriented physical raster region.
|
|
206
|
+
*
|
|
207
|
+
* This is the exact coordinate inverse of
|
|
208
|
+
* mapOrientedPhysicalUvToImagePlanePoint(). Points outside the supplied region
|
|
209
|
+
* fail closed; a tiny tolerance only absorbs floating-point round-trip noise at
|
|
210
|
+
* an edge.
|
|
211
|
+
*/
|
|
212
|
+
export function mapImagePlanePointToOrientedPhysicalUv(input) {
|
|
213
|
+
requireCaptureOrientation(input.orientation);
|
|
214
|
+
validateRasterVector("imagePlanePointMm", input.imagePlanePointMm);
|
|
215
|
+
validatePhysicalBounds("orientedPhysicalBoundsFromOpticalAxisMm", input.orientedPhysicalBoundsFromOpticalAxisMm);
|
|
216
|
+
const bounds = input.orientedPhysicalBoundsFromOpticalAxisMm;
|
|
217
|
+
const nativePhysicalPoint = {
|
|
218
|
+
x: input.imagePlanePointMm.x,
|
|
219
|
+
y: -input.imagePlanePointMm.y
|
|
220
|
+
};
|
|
221
|
+
const orientedPhysicalPoint = rotateVector(nativePhysicalPoint, input.orientation);
|
|
222
|
+
const u = (orientedPhysicalPoint.x - bounds.left) /
|
|
223
|
+
(bounds.right - bounds.left);
|
|
224
|
+
const v = (orientedPhysicalPoint.y - bounds.top) /
|
|
225
|
+
(bounds.bottom - bounds.top);
|
|
226
|
+
return {
|
|
227
|
+
u: normalizeUvEdge("imagePlanePointMm.u", u),
|
|
228
|
+
v: normalizeUvEdge("imagePlanePointMm.v", v)
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/** Transforms an integer half-open native raster rectangle into oriented coordinates. */
|
|
232
|
+
export function transformNativeRasterRectToOriented(input) {
|
|
233
|
+
requireCaptureOrientation(input.orientation);
|
|
234
|
+
requireRasterDimensions("nativeRaster", input.nativeRaster);
|
|
235
|
+
validateRasterRect("rect", input.rect, input.nativeRaster);
|
|
236
|
+
const { pixelWidth: width, pixelHeight: height } = input.nativeRaster;
|
|
237
|
+
const { x, y, width: rectWidth, height: rectHeight } = input.rect;
|
|
238
|
+
switch (input.orientation) {
|
|
239
|
+
case "landscape":
|
|
240
|
+
return { ...input.rect };
|
|
241
|
+
case "portrait-clockwise":
|
|
242
|
+
return {
|
|
243
|
+
x: height - (y + rectHeight),
|
|
244
|
+
y: x,
|
|
245
|
+
width: rectHeight,
|
|
246
|
+
height: rectWidth
|
|
247
|
+
};
|
|
248
|
+
case "landscape-inverted":
|
|
249
|
+
return {
|
|
250
|
+
x: width - (x + rectWidth),
|
|
251
|
+
y: height - (y + rectHeight),
|
|
252
|
+
width: rectWidth,
|
|
253
|
+
height: rectHeight
|
|
254
|
+
};
|
|
255
|
+
case "portrait-counter-clockwise":
|
|
256
|
+
return {
|
|
257
|
+
x: y,
|
|
258
|
+
y: width - (x + rectWidth),
|
|
259
|
+
width: rectHeight,
|
|
260
|
+
height: rectWidth
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/** Transforms an oriented integer half-open rectangle back to native coordinates. */
|
|
265
|
+
export function transformOrientedRasterRectToNative(input) {
|
|
266
|
+
requireCaptureOrientation(input.orientation);
|
|
267
|
+
requireRasterDimensions("nativeRaster", input.nativeRaster);
|
|
268
|
+
const orientedRaster = orientRaster(input.nativeRaster, input.orientation);
|
|
269
|
+
validateRasterRect("rect", input.rect, orientedRaster);
|
|
270
|
+
const { pixelWidth: width, pixelHeight: height } = input.nativeRaster;
|
|
271
|
+
const { x, y, width: rectWidth, height: rectHeight } = input.rect;
|
|
272
|
+
switch (input.orientation) {
|
|
273
|
+
case "landscape":
|
|
274
|
+
return { ...input.rect };
|
|
275
|
+
case "portrait-clockwise":
|
|
276
|
+
return {
|
|
277
|
+
x: y,
|
|
278
|
+
y: height - (x + rectWidth),
|
|
279
|
+
width: rectHeight,
|
|
280
|
+
height: rectWidth
|
|
281
|
+
};
|
|
282
|
+
case "landscape-inverted":
|
|
283
|
+
return {
|
|
284
|
+
x: width - (x + rectWidth),
|
|
285
|
+
y: height - (y + rectHeight),
|
|
286
|
+
width: rectWidth,
|
|
287
|
+
height: rectHeight
|
|
288
|
+
};
|
|
289
|
+
case "portrait-counter-clockwise":
|
|
290
|
+
return {
|
|
291
|
+
x: width - (y + rectHeight),
|
|
292
|
+
y: x,
|
|
293
|
+
width: rectHeight,
|
|
294
|
+
height: rectWidth
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
function nativePhysicalBoundsFromRect(imagingArea, nativeRaster, rect) {
|
|
299
|
+
const pitchX = imagingArea.widthMm / nativeRaster.pixelWidth;
|
|
300
|
+
const pitchY = imagingArea.heightMm / nativeRaster.pixelHeight;
|
|
301
|
+
return {
|
|
302
|
+
left: rect.x * pitchX - imagingArea.widthMm / 2,
|
|
303
|
+
right: (rect.x + rect.width) * pitchX - imagingArea.widthMm / 2,
|
|
304
|
+
top: rect.y * pitchY - imagingArea.heightMm / 2,
|
|
305
|
+
bottom: (rect.y + rect.height) * pitchY - imagingArea.heightMm / 2
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function orientPhysicalBounds(bounds, orientation) {
|
|
309
|
+
const corners = [
|
|
310
|
+
{ x: bounds.left, y: bounds.top },
|
|
311
|
+
{ x: bounds.right, y: bounds.top },
|
|
312
|
+
{ x: bounds.right, y: bounds.bottom },
|
|
313
|
+
{ x: bounds.left, y: bounds.bottom }
|
|
314
|
+
].map((corner) => rotateVector(corner, orientation));
|
|
315
|
+
return {
|
|
316
|
+
left: Math.min(...corners.map((corner) => corner.x)),
|
|
317
|
+
right: Math.max(...corners.map((corner) => corner.x)),
|
|
318
|
+
top: Math.min(...corners.map((corner) => corner.y)),
|
|
319
|
+
bottom: Math.max(...corners.map((corner) => corner.y))
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
function physicalBoundsFromRectWithinBounds(sourceBounds, sourceRaster, rect) {
|
|
323
|
+
const pitchX = (sourceBounds.right - sourceBounds.left) / sourceRaster.pixelWidth;
|
|
324
|
+
const pitchY = (sourceBounds.bottom - sourceBounds.top) / sourceRaster.pixelHeight;
|
|
325
|
+
return {
|
|
326
|
+
left: sourceBounds.left + rect.x * pitchX,
|
|
327
|
+
right: sourceBounds.left + (rect.x + rect.width) * pitchX,
|
|
328
|
+
top: sourceBounds.top + rect.y * pitchY,
|
|
329
|
+
bottom: sourceBounds.top + (rect.y + rect.height) * pitchY
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function validateOutputAspectRatio(cropRect, outputRaster) {
|
|
333
|
+
// Preserve one isotropic output scale while allowing only the sub-pixel
|
|
334
|
+
// disagreement introduced when an ideal scaled dimension is rounded to an
|
|
335
|
+
// integer raster size. A fixed percentage tolerance can admit visible
|
|
336
|
+
// anisotropic stretching at large output dimensions.
|
|
337
|
+
const widthScaleMinimum = (outputRaster.pixelWidth - 0.5) / cropRect.width;
|
|
338
|
+
const widthScaleMaximum = (outputRaster.pixelWidth + 0.5) / cropRect.width;
|
|
339
|
+
const heightScaleMinimum = (outputRaster.pixelHeight - 0.5) / cropRect.height;
|
|
340
|
+
const heightScaleMaximum = (outputRaster.pixelHeight + 0.5) / cropRect.height;
|
|
341
|
+
const minimumCommonScale = Math.max(widthScaleMinimum, heightScaleMinimum);
|
|
342
|
+
const maximumCommonScale = Math.min(widthScaleMaximum, heightScaleMaximum);
|
|
343
|
+
if (minimumCommonScale > maximumCommonScale) {
|
|
344
|
+
throw new InvalidScientificInputError("outputRaster must preserve outputCropRect aspect ratio within nearest-integer raster rounding; implicit geometric stretching is not supported.");
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
function angleBetweenSensorRaysDegrees(first, second, projectionDistanceMm) {
|
|
348
|
+
const firstLength = Math.hypot(first.x, first.y, projectionDistanceMm);
|
|
349
|
+
const secondLength = Math.hypot(second.x, second.y, projectionDistanceMm);
|
|
350
|
+
const dot = first.x * second.x +
|
|
351
|
+
first.y * second.y +
|
|
352
|
+
projectionDistanceMm * projectionDistanceMm;
|
|
353
|
+
const cosine = Math.max(-1, Math.min(1, dot / (firstLength * secondLength)));
|
|
354
|
+
return (Math.acos(cosine) * 180) / Math.PI;
|
|
355
|
+
}
|
|
356
|
+
function calculateBoundsFieldOfView(bounds, focalLengthMm, focusDistanceM) {
|
|
357
|
+
const fovInput = {
|
|
358
|
+
focalLengthMm,
|
|
359
|
+
...(focusDistanceM === undefined ? {} : { focusDistanceM })
|
|
360
|
+
};
|
|
361
|
+
const horizontal = calculateFieldOfViewBounds({
|
|
362
|
+
...fovInput,
|
|
363
|
+
minimumSensorCoordinateMm: bounds.left,
|
|
364
|
+
maximumSensorCoordinateMm: bounds.right
|
|
365
|
+
});
|
|
366
|
+
const vertical = calculateFieldOfViewBounds({
|
|
367
|
+
...fovInput,
|
|
368
|
+
minimumSensorCoordinateMm: bounds.top,
|
|
369
|
+
maximumSensorCoordinateMm: bounds.bottom
|
|
370
|
+
});
|
|
371
|
+
const projectionDistanceMm = horizontal.value.projectionDistanceMm;
|
|
372
|
+
const topLeft = { x: bounds.left, y: bounds.top };
|
|
373
|
+
const topRight = { x: bounds.right, y: bounds.top };
|
|
374
|
+
const bottomRight = { x: bounds.right, y: bounds.bottom };
|
|
375
|
+
const bottomLeft = { x: bounds.left, y: bounds.bottom };
|
|
376
|
+
const topLeftToBottomRight = angleBetweenSensorRaysDegrees(topLeft, bottomRight, projectionDistanceMm);
|
|
377
|
+
const topRightToBottomLeft = angleBetweenSensorRaysDegrees(topRight, bottomLeft, projectionDistanceMm);
|
|
378
|
+
return {
|
|
379
|
+
horizontalDegrees: horizontal.value.degrees,
|
|
380
|
+
verticalDegrees: vertical.value.degrees,
|
|
381
|
+
diagonalDegrees: Math.max(topLeftToBottomRight, topRightToBottomLeft),
|
|
382
|
+
horizontalBoundsDegrees: {
|
|
383
|
+
minimum: horizontal.value.minimumDegrees,
|
|
384
|
+
maximum: horizontal.value.maximumDegrees
|
|
385
|
+
},
|
|
386
|
+
verticalBoundsDegrees: {
|
|
387
|
+
minimum: vertical.value.minimumDegrees,
|
|
388
|
+
maximum: vertical.value.maximumDegrees
|
|
389
|
+
},
|
|
390
|
+
diagonalDegreesByCornerPair: {
|
|
391
|
+
topLeftToBottomRight,
|
|
392
|
+
topRightToBottomLeft
|
|
393
|
+
},
|
|
394
|
+
projection: {
|
|
395
|
+
projectionDistanceMm,
|
|
396
|
+
provenance: horizontal.provenance
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Resolves native sensor geometry, active capture, physical camera orientation,
|
|
402
|
+
* and final digital/output geometry without conflating their identities.
|
|
403
|
+
*/
|
|
404
|
+
export function resolveCaptureGeometry(input) {
|
|
405
|
+
requireCaptureOrientation(input.orientation);
|
|
406
|
+
requirePositiveFinite("imagingArea.widthMm", input.imagingArea.widthMm);
|
|
407
|
+
requirePositiveFinite("imagingArea.heightMm", input.imagingArea.heightMm);
|
|
408
|
+
requireRasterDimensions("nativeRaster", input.nativeRaster);
|
|
409
|
+
const activeCaptureRect = input.activeCaptureRect ?? fullRect(input.nativeRaster);
|
|
410
|
+
validateRasterRect("activeCaptureRect", activeCaptureRect, input.nativeRaster);
|
|
411
|
+
const nativeBounds = nativePhysicalBoundsFromRect(input.imagingArea, input.nativeRaster, activeCaptureRect);
|
|
412
|
+
const activeImagingArea = {
|
|
413
|
+
widthMm: nativeBounds.right - nativeBounds.left,
|
|
414
|
+
heightMm: nativeBounds.bottom - nativeBounds.top
|
|
415
|
+
};
|
|
416
|
+
const activeRaster = {
|
|
417
|
+
pixelWidth: activeCaptureRect.width,
|
|
418
|
+
pixelHeight: activeCaptureRect.height
|
|
419
|
+
};
|
|
420
|
+
const orientedBounds = orientPhysicalBounds(nativeBounds, input.orientation);
|
|
421
|
+
const orientedRaster = orientRaster(activeRaster, input.orientation);
|
|
422
|
+
const orientedImagingArea = {
|
|
423
|
+
widthMm: orientedBounds.right - orientedBounds.left,
|
|
424
|
+
heightMm: orientedBounds.bottom - orientedBounds.top
|
|
425
|
+
};
|
|
426
|
+
const outputCropRect = input.outputCropRect ?? fullRect(orientedRaster);
|
|
427
|
+
validateRasterRect("outputCropRect", outputCropRect, orientedRaster);
|
|
428
|
+
const outputRaster = input.outputRaster ?? {
|
|
429
|
+
pixelWidth: outputCropRect.width,
|
|
430
|
+
pixelHeight: outputCropRect.height
|
|
431
|
+
};
|
|
432
|
+
requireRasterDimensions("outputRaster", outputRaster);
|
|
433
|
+
validateOutputAspectRatio(outputCropRect, outputRaster);
|
|
434
|
+
const outputBounds = physicalBoundsFromRectWithinBounds(orientedBounds, orientedRaster, outputCropRect);
|
|
435
|
+
const outputImagingArea = {
|
|
436
|
+
widthMm: outputBounds.right - outputBounds.left,
|
|
437
|
+
heightMm: outputBounds.bottom - outputBounds.top
|
|
438
|
+
};
|
|
439
|
+
const outputScaleX = outputRaster.pixelWidth / outputCropRect.width;
|
|
440
|
+
const outputScaleY = outputRaster.pixelHeight / outputCropRect.height;
|
|
441
|
+
const outputScaleAxisRelativeDifference = Math.abs(outputScaleX - outputScaleY) /
|
|
442
|
+
((outputScaleX + outputScaleY) / 2);
|
|
443
|
+
return calculatedResult({
|
|
444
|
+
native: {
|
|
445
|
+
imagingArea: { ...input.imagingArea },
|
|
446
|
+
raster: { ...input.nativeRaster }
|
|
447
|
+
},
|
|
448
|
+
activeCapture: {
|
|
449
|
+
nativeRect: { ...activeCaptureRect },
|
|
450
|
+
imagingArea: activeImagingArea,
|
|
451
|
+
physicalOffsetMm: {
|
|
452
|
+
x: nativeBounds.left + input.imagingArea.widthMm / 2,
|
|
453
|
+
y: nativeBounds.top + input.imagingArea.heightMm / 2
|
|
454
|
+
},
|
|
455
|
+
centerOffsetFromOpticalAxisMm: {
|
|
456
|
+
x: (nativeBounds.left + nativeBounds.right) / 2,
|
|
457
|
+
y: (nativeBounds.top + nativeBounds.bottom) / 2
|
|
458
|
+
},
|
|
459
|
+
physicalBoundsFromOpticalAxisMm: nativeBounds,
|
|
460
|
+
imagingAreaDerivation: "uniform-native-raster",
|
|
461
|
+
raster: activeRaster
|
|
462
|
+
},
|
|
463
|
+
orientedCapture: {
|
|
464
|
+
orientation: input.orientation,
|
|
465
|
+
imagingArea: orientedImagingArea,
|
|
466
|
+
physicalBoundsFromOpticalAxisMm: orientedBounds,
|
|
467
|
+
raster: orientedRaster
|
|
468
|
+
},
|
|
469
|
+
output: {
|
|
470
|
+
cropRect: { ...outputCropRect },
|
|
471
|
+
raster: { ...outputRaster },
|
|
472
|
+
imagingArea: outputImagingArea,
|
|
473
|
+
physicalBoundsFromOpticalAxisMm: outputBounds,
|
|
474
|
+
centerOffsetFromOpticalAxisMm: {
|
|
475
|
+
x: (outputBounds.left + outputBounds.right) / 2,
|
|
476
|
+
y: (outputBounds.top + outputBounds.bottom) / 2
|
|
477
|
+
},
|
|
478
|
+
sourceRetainedAreaFraction: (outputCropRect.width * outputCropRect.height) /
|
|
479
|
+
(orientedRaster.pixelWidth * orientedRaster.pixelHeight),
|
|
480
|
+
orientedCaptureToOutputScale: {
|
|
481
|
+
x: outputScaleX,
|
|
482
|
+
y: outputScaleY,
|
|
483
|
+
axisRelativeDifference: outputScaleAxisRelativeDifference
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}, "capture-geometry-pipeline", "1.2.0", [
|
|
487
|
+
"Native sensor raster coordinates use a top-left origin with +X right and +Y down.",
|
|
488
|
+
"Raster rectangles are integer half-open extents.",
|
|
489
|
+
"Physical camera orientation does not rotate or redefine the native sensor coordinate system.",
|
|
490
|
+
"The generic active physical area is derived by assuming native image samples uniformly span the declared physical imaging area.",
|
|
491
|
+
"Output crop/resampling is digital geometry and does not mutate physical sensor or active-capture identity.",
|
|
492
|
+
"The physical image region retained by output crop is tracked explicitly for final framing and equivalent-viewing calculations.",
|
|
493
|
+
"Output raster aspect ratio must remain consistent with the output crop; implicit geometric stretching is rejected."
|
|
494
|
+
]);
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Calculates asymmetric horizontal/vertical FOV plus opposite-corner diagonal
|
|
498
|
+
* spans for the active physical capture area after physical camera orientation.
|
|
499
|
+
*
|
|
500
|
+
* Final digital/output crop is intentionally excluded.
|
|
501
|
+
*/
|
|
502
|
+
export function calculateActiveCaptureFieldOfView(input) {
|
|
503
|
+
requirePositiveFinite("focalLengthMm", input.focalLengthMm);
|
|
504
|
+
const geometry = resolveCaptureGeometry({
|
|
505
|
+
imagingArea: input.imagingArea,
|
|
506
|
+
nativeRaster: input.nativeRaster,
|
|
507
|
+
orientation: input.orientation,
|
|
508
|
+
...(input.activeCaptureRect === undefined
|
|
509
|
+
? {}
|
|
510
|
+
: { activeCaptureRect: input.activeCaptureRect })
|
|
511
|
+
}).value;
|
|
512
|
+
const bounds = geometry.orientedCapture.physicalBoundsFromOpticalAxisMm;
|
|
513
|
+
const fieldOfView = calculateBoundsFieldOfView(bounds, input.focalLengthMm, input.focusDistanceM);
|
|
514
|
+
return calculatedResult({
|
|
515
|
+
orientation: input.orientation,
|
|
516
|
+
...fieldOfView,
|
|
517
|
+
activeImagingArea: {
|
|
518
|
+
...geometry.orientedCapture.imagingArea
|
|
519
|
+
},
|
|
520
|
+
centerOffsetFromOpticalAxisMm: rotateVector(geometry.activeCapture.centerOffsetFromOpticalAxisMm, input.orientation)
|
|
521
|
+
}, "oriented-active-capture-field-of-view", "1.1.0", [
|
|
522
|
+
"Rectilinear projection is evaluated from signed active-area bounds relative to the optical axis.",
|
|
523
|
+
"Off-center active crops preserve asymmetric angular bounds rather than being treated as centered.",
|
|
524
|
+
"Camera orientation rotates physical bounds while leaving the native sensor coordinate system unchanged.",
|
|
525
|
+
"For off-center rectangles the two opposite-corner diagonal spans may differ; diagonalDegrees reports the larger span.",
|
|
526
|
+
"Final digital/output crop is excluded from active-capture FOV."
|
|
527
|
+
]);
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Calculates final visible field of view after physical active capture,
|
|
531
|
+
* orientation, and digital/output crop. Output raster resolution does not
|
|
532
|
+
* affect this optical/framing result.
|
|
533
|
+
*/
|
|
534
|
+
export function calculateOutputFieldOfView(input) {
|
|
535
|
+
requirePositiveFinite("focalLengthMm", input.focalLengthMm);
|
|
536
|
+
const geometry = resolveCaptureGeometry({
|
|
537
|
+
imagingArea: input.imagingArea,
|
|
538
|
+
nativeRaster: input.nativeRaster,
|
|
539
|
+
orientation: input.orientation,
|
|
540
|
+
...(input.activeCaptureRect === undefined
|
|
541
|
+
? {}
|
|
542
|
+
: { activeCaptureRect: input.activeCaptureRect }),
|
|
543
|
+
...(input.outputCropRect === undefined
|
|
544
|
+
? {}
|
|
545
|
+
: { outputCropRect: input.outputCropRect })
|
|
546
|
+
}).value;
|
|
547
|
+
const fieldOfView = calculateBoundsFieldOfView(geometry.output.physicalBoundsFromOpticalAxisMm, input.focalLengthMm, input.focusDistanceM);
|
|
548
|
+
return calculatedResult({
|
|
549
|
+
orientation: input.orientation,
|
|
550
|
+
...fieldOfView,
|
|
551
|
+
outputImagingArea: { ...geometry.output.imagingArea },
|
|
552
|
+
centerOffsetFromOpticalAxisMm: {
|
|
553
|
+
...geometry.output.centerOffsetFromOpticalAxisMm
|
|
554
|
+
}
|
|
555
|
+
}, "oriented-output-field-of-view", "1.0.0", [
|
|
556
|
+
"Final visible FOV is derived from the physical image region retained by active capture and digital/output crop.",
|
|
557
|
+
"Output raster resolution does not change field of view.",
|
|
558
|
+
"Off-center output crops preserve asymmetric angular bounds.",
|
|
559
|
+
"Physical sensor identity and active-capture 35 mm-equivalent focal length are unchanged by final digital crop."
|
|
560
|
+
]);
|
|
561
|
+
}
|
|
562
|
+
//# sourceMappingURL=capture-geometry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-geometry.js","sourceRoot":"","sources":["../../src/output/capture-geometry.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,EACL,0BAA0B,EAC3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,gBAAgB,EAGjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAIN,MAAM,8BAA8B,CAAC;AAQtC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAqB;IACvD,WAAW;IACX,oBAAoB;IACpB,oBAAoB;IACpB,4BAA4B;CAC7B,CAAC,CAAC;AAgPH,SAAS,yBAAyB,CAChC,KAAc;IAEd,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,oBAAoB,CAAC,GAAG,CAAC,KAA2B,CAAC,EACtD,CAAC;QACD,MAAM,IAAI,2BAA2B,CAAC,yBAAyB,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAC9B,IAAY,EACZ,MAAwB;IAExB,sBAAsB,CAAC,GAAG,IAAI,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAChE,sBAAsB,CAAC,GAAG,IAAI,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,yBAAyB,CAAC,IAAY,EAAE,KAAa;IAC5D,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,2BAA2B,CACnC,GAAG,IAAI,uCAAuC,CAC/C,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CACzB,IAAY,EACZ,IAAgB,EAChB,MAAwB;IAExB,yBAAyB,CAAC,GAAG,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/C,yBAAyB,CAAC,GAAG,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/C,sBAAsB,CAAC,GAAG,IAAI,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACpD,sBAAsB,CAAC,GAAG,IAAI,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAEtD,IACE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,UAAU;QACvC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,WAAW,EACzC,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,GAAG,IAAI,8CAA8C,CACtD,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAC1B,IAAY,EACZ,KAAkB,EAClB,MAAwB;IAExB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,2BAA2B,CACnC,GAAG,IAAI,8BAA8B,CACtC,CAAC;IACJ,CAAC;IACD,IACE,KAAK,CAAC,CAAC,GAAG,CAAC;QACX,KAAK,CAAC,CAAC,GAAG,CAAC;QACX,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU;QAC3B,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,WAAW,EAC5B,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,GAAG,IAAI,qDAAqD,CAC7D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY,EAAE,MAAoB;IAC9D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,2BAA2B,CACnC,GAAG,IAAI,8BAA8B,CACtC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,4BAA4B,GAAG,KAAK,CAAC;AAE3C,SAAS,sBAAsB,CAC7B,IAAY,EACZ,MAAuC;IAEvC,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAU,EAAE,CAAC;QAC9D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,2BAA2B,CACnC,GAAG,IAAI,IAAI,GAAG,kBAAkB,CACjC,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,IAAI,2BAA2B,CACnC,GAAG,IAAI,qCAAqC,CAC7C,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,IAAI,2BAA2B,CACnC,GAAG,IAAI,qCAAqC,CAC7C,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY,EAAE,EAAsB;IAChE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,2BAA2B,CACnC,GAAG,IAAI,8BAA8B,CACtC,CAAC;IACJ,CAAC;IACD,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,2BAA2B,CACnC,GAAG,IAAI,sCAAsC,CAC9C,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAY,EAAE,KAAa;IAClD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,2BAA2B,CAAC,GAAG,IAAI,kBAAkB,CAAC,CAAC;IACnE,CAAC;IACD,IACE,KAAK,GAAG,CAAC,4BAA4B;QACrC,KAAK,GAAG,CAAC,GAAG,4BAA4B,EACxC,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,GAAG,IAAI,yDAAyD,CACjE,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,QAAQ,CAAC,MAAwB;IACxC,OAAO;QACL,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,CAAC;QACJ,KAAK,EAAE,MAAM,CAAC,UAAU;QACxB,MAAM,EAAE,MAAM,CAAC,WAAW;KAC3B,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CACnB,MAAwB,EACxB,WAA+B;IAE/B,OAAO,WAAW,KAAK,oBAAoB;QACzC,WAAW,KAAK,4BAA4B;QAC5C,CAAC,CAAC;YACE,UAAU,EAAE,MAAM,CAAC,WAAW;YAC9B,WAAW,EAAE,MAAM,CAAC,UAAU;SAC/B;QACH,CAAC,CAAC;YACE,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC,CAAC;AACR,CAAC;AAED,SAAS,YAAY,CACnB,MAAoB,EACpB,WAA+B;IAE/B,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,WAAW;YACd,OAAO,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;QACtC,KAAK,oBAAoB;YACvB,OAAO,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;QACvC,KAAK,oBAAoB;YACvB,OAAO,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACxC,KAAK,4BAA4B;YAC/B,OAAO,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;IACzC,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAC1B,MAAoB,EACpB,WAA+B;IAE/B,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,WAAW;YACd,OAAO,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;QACtC,KAAK,oBAAoB;YACvB,OAAO,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACvC,KAAK,oBAAoB;YACvB,OAAO,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACxC,KAAK,4BAA4B;YAC/B,OAAO,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;IACzC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oCAAoC,CAClD,KAAgC;IAEhC,yBAAyB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,uBAAuB,CAAC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAC5D,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAE9D,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC;IACtE,QAAQ,KAAK,CAAC,WAAW,EAAE,CAAC;QAC1B,KAAK,WAAW;YACd,OAAO,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QAC5B,KAAK,oBAAoB;YACvB,OAAO,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACzD,KAAK,oBAAoB;YACvB,OAAO,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACjE,KAAK,4BAA4B;YAC/B,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,oCAAoC,CAClD,KAAgC;IAEhC,yBAAyB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,uBAAuB,CAAC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAC5D,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAC3E,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAE1D,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC;IACtE,QAAQ,KAAK,CAAC,WAAW,EAAE,CAAC;QAC1B,KAAK,WAAW;YACd,OAAO,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QAC5B,KAAK,oBAAoB;YACvB,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACzD,KAAK,oBAAoB;YACvB,OAAO,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACjE,KAAK,4BAA4B;YAC/B,OAAO,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,qCAAqC,CACnD,KAAiC;IAEjC,yBAAyB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,oBAAoB,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,OAAO,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;AACvD,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,qCAAqC,CACnD,KAAiC;IAEjC,yBAAyB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,oBAAoB,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,OAAO,mBAAmB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sCAAsC,CACpD,KAA6C;IAE7C,yBAAyB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IACrC,sBAAsB,CACpB,yCAAyC,EACzC,KAAK,CAAC,uCAAuC,CAC9C,CAAC;IAEF,MAAM,MAAM,GAAG,KAAK,CAAC,uCAAuC,CAAC;IAC7D,MAAM,qBAAqB,GAAG;QAC5B,CAAC,EAAE,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;QAC1D,CAAC,EAAE,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC;KAC1D,CAAC;IACF,MAAM,mBAAmB,GAAG,mBAAmB,CAC7C,qBAAqB,EACrB,KAAK,CAAC,WAAW,CAClB,CAAC;IAEF,OAAO;QACL,CAAC,EAAE,mBAAmB,CAAC,CAAC;QACxB,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sCAAsC,CACpD,KAAkD;IAElD,yBAAyB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,oBAAoB,CAAC,mBAAmB,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACnE,sBAAsB,CACpB,yCAAyC,EACzC,KAAK,CAAC,uCAAuC,CAC9C,CAAC;IAEF,MAAM,MAAM,GAAG,KAAK,CAAC,uCAAuC,CAAC;IAC7D,MAAM,mBAAmB,GAAG;QAC1B,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC5B,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;KAC9B,CAAC;IACF,MAAM,qBAAqB,GAAG,YAAY,CACxC,mBAAmB,EACnB,KAAK,CAAC,WAAW,CAClB,CAAC;IACF,MAAM,CAAC,GACL,CAAC,qBAAqB,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;QACvC,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,CAAC,GACL,CAAC,qBAAqB,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC;QACtC,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAE/B,OAAO;QACL,CAAC,EAAE,eAAe,CAAC,qBAAqB,EAAE,CAAC,CAAC;QAC5C,CAAC,EAAE,eAAe,CAAC,qBAAqB,EAAE,CAAC,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,mCAAmC,CACjD,KAA+B;IAE/B,yBAAyB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,uBAAuB,CAAC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAC5D,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAE3D,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC;IACtE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;IAClE,QAAQ,KAAK,CAAC,WAAW,EAAE,CAAC;QAC1B,KAAK,WAAW;YACd,OAAO,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC3B,KAAK,oBAAoB;YACvB,OAAO;gBACL,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC;gBAC5B,CAAC,EAAE,CAAC;gBACJ,KAAK,EAAE,UAAU;gBACjB,MAAM,EAAE,SAAS;aAClB,CAAC;QACJ,KAAK,oBAAoB;YACvB,OAAO;gBACL,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;gBAC1B,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC;gBAC5B,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,UAAU;aACnB,CAAC;QACJ,KAAK,4BAA4B;YAC/B,OAAO;gBACL,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;gBAC1B,KAAK,EAAE,UAAU;gBACjB,MAAM,EAAE,SAAS;aAClB,CAAC;IACN,CAAC;AACH,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,mCAAmC,CACjD,KAA+B;IAE/B,yBAAyB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,uBAAuB,CAAC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAC5D,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAC3E,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAEvD,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC;IACtE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;IAClE,QAAQ,KAAK,CAAC,WAAW,EAAE,CAAC;QAC1B,KAAK,WAAW;YACd,OAAO,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC3B,KAAK,oBAAoB;YACvB,OAAO;gBACL,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;gBAC3B,KAAK,EAAE,UAAU;gBACjB,MAAM,EAAE,SAAS;aAClB,CAAC;QACJ,KAAK,oBAAoB;YACvB,OAAO;gBACL,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;gBAC1B,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC;gBAC5B,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,UAAU;aACnB,CAAC;QACJ,KAAK,4BAA4B;YAC/B,OAAO;gBACL,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC;gBAC3B,CAAC,EAAE,CAAC;gBACJ,KAAK,EAAE,UAAU;gBACjB,MAAM,EAAE,SAAS;aAClB,CAAC;IACN,CAAC;AACH,CAAC;AAED,SAAS,4BAA4B,CACnC,WAA8B,EAC9B,YAA+B,EAC/B,IAAgB;IAEhB,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC;IAC7D,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,GAAG,YAAY,CAAC,WAAW,CAAC;IAE/D,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC,OAAO,GAAG,CAAC;QAC/C,KAAK,EACH,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC,OAAO,GAAG,CAAC;QAC1D,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC,QAAQ,GAAG,CAAC;QAC/C,MAAM,EACJ,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC,QAAQ,GAAG,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,MAAuC,EACvC,WAA+B;IAE/B,MAAM,OAAO,GAAG;QACd,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE;QACjC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE;QAClC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QACrC,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;KACrC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAErD,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACpD,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACrD,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;KACvD,CAAC;AACJ,CAAC;AAED,SAAS,kCAAkC,CACzC,YAA6C,EAC7C,YAA8B,EAC9B,IAAgB;IAEhB,MAAM,MAAM,GACV,CAAC,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC;IACrE,MAAM,MAAM,GACV,CAAC,YAAY,CAAC,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,WAAW,CAAC;IAEtE,OAAO;QACL,IAAI,EAAE,YAAY,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM;QACzC,KAAK,EAAE,YAAY,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM;QACzD,GAAG,EAAE,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM;QACvC,MAAM,EAAE,YAAY,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM;KAC3D,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAChC,QAAoB,EACpB,YAA8B;IAE9B,wEAAwE;IACxE,0EAA0E;IAC1E,sEAAsE;IACtE,qDAAqD;IACrD,MAAM,iBAAiB,GACrB,CAAC,YAAY,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IACnD,MAAM,iBAAiB,GACrB,CAAC,YAAY,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IACnD,MAAM,kBAAkB,GACtB,CAAC,YAAY,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;IACrD,MAAM,kBAAkB,GACtB,CAAC,YAAY,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;IAErD,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CACjC,iBAAiB,EACjB,kBAAkB,CACnB,CAAC;IACF,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CACjC,iBAAiB,EACjB,kBAAkB,CACnB,CAAC;IAEF,IAAI,kBAAkB,GAAG,kBAAkB,EAAE,CAAC;QAC5C,MAAM,IAAI,2BAA2B,CACnC,gJAAgJ,CACjJ,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,6BAA6B,CACpC,KAAmB,EACnB,MAAoB,EACpB,oBAA4B;IAE5B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,KAAK,CAAC,CAAC,EACP,KAAK,CAAC,CAAC,EACP,oBAAoB,CACrB,CAAC;IACF,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAC7B,MAAM,CAAC,CAAC,EACR,MAAM,CAAC,CAAC,EACR,oBAAoB,CACrB,CAAC;IACF,MAAM,GAAG,GACP,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QAClB,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QAClB,oBAAoB,GAAG,oBAAoB,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CACrB,CAAC,CAAC,EACF,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,CAAC,CAChD,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;AAC7C,CAAC;AAED,SAAS,0BAA0B,CACjC,MAAuC,EACvC,aAAqB,EACrB,cAAkC;IAgBlC,MAAM,QAAQ,GAAG;QACf,aAAa;QACb,GAAG,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC;KAC5D,CAAC;IACF,MAAM,UAAU,GAAG,0BAA0B,CAAC;QAC5C,GAAG,QAAQ;QACX,yBAAyB,EAAE,MAAM,CAAC,IAAI;QACtC,yBAAyB,EAAE,MAAM,CAAC,KAAK;KACxC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,0BAA0B,CAAC;QAC1C,GAAG,QAAQ;QACX,yBAAyB,EAAE,MAAM,CAAC,GAAG;QACrC,yBAAyB,EAAE,MAAM,CAAC,MAAM;KACzC,CAAC,CAAC;IACH,MAAM,oBAAoB,GAAG,UAAU,CAAC,KAAK,CAAC,oBAAoB,CAAC;IACnE,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;IAClD,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;IACpD,MAAM,WAAW,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IAC1D,MAAM,UAAU,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IACxD,MAAM,oBAAoB,GAAG,6BAA6B,CACxD,OAAO,EACP,WAAW,EACX,oBAAoB,CACrB,CAAC;IACF,MAAM,oBAAoB,GAAG,6BAA6B,CACxD,QAAQ,EACR,UAAU,EACV,oBAAoB,CACrB,CAAC;IAEF,OAAO;QACL,iBAAiB,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO;QAC3C,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO;QACvC,eAAe,EAAE,IAAI,CAAC,GAAG,CACvB,oBAAoB,EACpB,oBAAoB,CACrB;QACD,uBAAuB,EAAE;YACvB,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,cAAc;YACxC,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,cAAc;SACzC;QACD,qBAAqB,EAAE;YACrB,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,cAAc;YACtC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,cAAc;SACvC;QACD,2BAA2B,EAAE;YAC3B,oBAAoB;YACpB,oBAAoB;SACrB;QACD,UAAU,EAAE;YACV,oBAAoB;YACpB,UAAU,EAAE,UAAU,CAAC,UAAU;SAClC;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAAkC;IAElC,yBAAyB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,qBAAqB,CAAC,qBAAqB,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACxE,qBAAqB,CAAC,sBAAsB,EAAE,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC1E,uBAAuB,CAAC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAE5D,MAAM,iBAAiB,GACrB,KAAK,CAAC,iBAAiB,IAAI,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC1D,kBAAkB,CAChB,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,CAAC,YAAY,CACnB,CAAC;IAEF,MAAM,YAAY,GAAG,4BAA4B,CAC/C,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,iBAAiB,CAClB,CAAC;IACF,MAAM,iBAAiB,GAAsB;QAC3C,OAAO,EAAE,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC,IAAI;QAC/C,QAAQ,EAAE,YAAY,CAAC,MAAM,GAAG,YAAY,CAAC,GAAG;KACjD,CAAC;IACF,MAAM,YAAY,GAAqB;QACrC,UAAU,EAAE,iBAAiB,CAAC,KAAK;QACnC,WAAW,EAAE,iBAAiB,CAAC,MAAM;KACtC,CAAC;IACF,MAAM,cAAc,GAAG,oBAAoB,CACzC,YAAY,EACZ,KAAK,CAAC,WAAW,CAClB,CAAC;IACF,MAAM,cAAc,GAAG,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IACrE,MAAM,mBAAmB,GAAsB;QAC7C,OAAO,EAAE,cAAc,CAAC,KAAK,GAAG,cAAc,CAAC,IAAI;QACnD,QAAQ,EAAE,cAAc,CAAC,MAAM,GAAG,cAAc,CAAC,GAAG;KACrD,CAAC;IAEF,MAAM,cAAc,GAClB,KAAK,CAAC,cAAc,IAAI,QAAQ,CAAC,cAAc,CAAC,CAAC;IACnD,kBAAkB,CAChB,gBAAgB,EAChB,cAAc,EACd,cAAc,CACf,CAAC;IAEF,MAAM,YAAY,GAAqB,KAAK,CAAC,YAAY,IAAI;QAC3D,UAAU,EAAE,cAAc,CAAC,KAAK;QAChC,WAAW,EAAE,cAAc,CAAC,MAAM;KACnC,CAAC;IACF,uBAAuB,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IACtD,yBAAyB,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IAExD,MAAM,YAAY,GAAG,kCAAkC,CACrD,cAAc,EACd,cAAc,EACd,cAAc,CACf,CAAC;IACF,MAAM,iBAAiB,GAAsB;QAC3C,OAAO,EAAE,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC,IAAI;QAC/C,QAAQ,EAAE,YAAY,CAAC,MAAM,GAAG,YAAY,CAAC,GAAG;KACjD,CAAC;IACF,MAAM,YAAY,GAAG,YAAY,CAAC,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC;IACpE,MAAM,YAAY,GAAG,YAAY,CAAC,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC;IACtE,MAAM,iCAAiC,GACrC,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,YAAY,CAAC;QACrC,CAAC,CAAC,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;IAEtC,OAAO,gBAAgB,CACrB;QACE,MAAM,EAAE;YACN,WAAW,EAAE,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE;YACrC,MAAM,EAAE,EAAE,GAAG,KAAK,CAAC,YAAY,EAAE;SAClC;QACD,aAAa,EAAE;YACb,UAAU,EAAE,EAAE,GAAG,iBAAiB,EAAE;YACpC,WAAW,EAAE,iBAAiB;YAC9B,gBAAgB,EAAE;gBAChB,CAAC,EAAE,YAAY,CAAC,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,GAAG,CAAC;gBACpD,CAAC,EAAE,YAAY,CAAC,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,GAAG,CAAC;aACrD;YACD,6BAA6B,EAAE;gBAC7B,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC;gBAC/C,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC;aAChD;YACD,+BAA+B,EAAE,YAAY;YAC7C,qBAAqB,EAAE,uBAAuB;YAC9C,MAAM,EAAE,YAAY;SACrB;QACD,eAAe,EAAE;YACf,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,WAAW,EAAE,mBAAmB;YAChC,+BAA+B,EAAE,cAAc;YAC/C,MAAM,EAAE,cAAc;SACvB;QACD,MAAM,EAAE;YACN,QAAQ,EAAE,EAAE,GAAG,cAAc,EAAE;YAC/B,MAAM,EAAE,EAAE,GAAG,YAAY,EAAE;YAC3B,WAAW,EAAE,iBAAiB;YAC9B,+BAA+B,EAAE,YAAY;YAC7C,6BAA6B,EAAE;gBAC7B,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC;gBAC/C,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC;aAChD;YACD,0BAA0B,EACxB,CAAC,cAAc,CAAC,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC;gBAC9C,CAAC,cAAc,CAAC,UAAU,GAAG,cAAc,CAAC,WAAW,CAAC;YAC1D,4BAA4B,EAAE;gBAC5B,CAAC,EAAE,YAAY;gBACf,CAAC,EAAE,YAAY;gBACf,sBAAsB,EAAE,iCAAiC;aAC1D;SACF;KACF,EACD,2BAA2B,EAC3B,OAAO,EACP;QACE,mFAAmF;QACnF,kDAAkD;QAClD,8FAA8F;QAC9F,iIAAiI;QACjI,4GAA4G;QAC5G,gIAAgI;QAChI,oHAAoH;KACrH,CACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iCAAiC,CAC/C,KAA6C;IAE7C,qBAAqB,CAAC,eAAe,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAE5D,MAAM,QAAQ,GAAG,sBAAsB,CAAC;QACtC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,GAAG,CAAC,KAAK,CAAC,iBAAiB,KAAK,SAAS;YACvC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,EAAE,CAAC;KACpD,CAAC,CAAC,KAAK,CAAC;IAET,MAAM,MAAM,GACV,QAAQ,CAAC,eAAe,CAAC,+BAA+B,CAAC;IAC3D,MAAM,WAAW,GAAG,0BAA0B,CAC5C,MAAM,EACN,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,CACrB,CAAC;IAEF,OAAO,gBAAgB,CACrB;QACE,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,GAAG,WAAW;QACd,iBAAiB,EAAE;YACjB,GAAG,QAAQ,CAAC,eAAe,CAAC,WAAW;SACxC;QACD,6BAA6B,EAAE,YAAY,CACzC,QAAQ,CAAC,aAAa,CAAC,6BAA6B,EACpD,KAAK,CAAC,WAAW,CAClB;KACF,EACD,uCAAuC,EACvC,OAAO,EACP;QACE,kGAAkG;QAClG,mGAAmG;QACnG,yGAAyG;QACzG,uHAAuH;QACvH,gEAAgE;KACjE,CACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAsC;IAEtC,qBAAqB,CAAC,eAAe,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAE5D,MAAM,QAAQ,GAAG,sBAAsB,CAAC;QACtC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,GAAG,CAAC,KAAK,CAAC,iBAAiB,KAAK,SAAS;YACvC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,EAAE,CAAC;QACnD,GAAG,CAAC,KAAK,CAAC,cAAc,KAAK,SAAS;YACpC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC;KAC9C,CAAC,CAAC,KAAK,CAAC;IACT,MAAM,WAAW,GAAG,0BAA0B,CAC5C,QAAQ,CAAC,MAAM,CAAC,+BAA+B,EAC/C,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,CACrB,CAAC;IAEF,OAAO,gBAAgB,CACrB;QACE,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,GAAG,WAAW;QACd,iBAAiB,EAAE,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE;QACrD,6BAA6B,EAAE;YAC7B,GAAG,QAAQ,CAAC,MAAM,CAAC,6BAA6B;SACjD;KACF,EACD,+BAA+B,EAC/B,OAAO,EACP;QACE,iHAAiH;QACjH,yDAAyD;QACzD,6DAA6D;QAC7D,gHAAgH;KACjH,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
+
export { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
1
2
|
import type { CameraConfiguration } from "./camera.js";
|
|
2
3
|
import type { SceneDefinition } from "./scene.js";
|
|
3
|
-
/**
|
|
4
|
-
* Error thrown when external configuration data does not match a public
|
|
5
|
-
* runtime schema.
|
|
6
|
-
*/
|
|
7
|
-
export declare class InvalidConfigurationError extends TypeError {
|
|
8
|
-
readonly code = "INVALID_CONFIGURATION";
|
|
9
|
-
constructor(message: string);
|
|
10
|
-
}
|
|
11
4
|
/**
|
|
12
5
|
* Parses and validates an untrusted camera configuration.
|
|
13
6
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/schema/validation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/schema/validation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,OAAO,KAAK,EACV,mBAAmB,EAEpB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAEV,eAAe,EAChB,MAAM,YAAY,CAAC;AAsHpB;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,GACb,mBAAmB,CAwCrB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAuFpE"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
3
|
+
export { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
2
4
|
const CAMERA_SUPPORTS = new Set([
|
|
3
5
|
"handheld",
|
|
4
6
|
"braced",
|
|
@@ -15,17 +17,6 @@ const SCENE_CAPABILITIES = new Set([
|
|
|
15
17
|
"multi-resolution-layers",
|
|
16
18
|
"absolute-radiometry"
|
|
17
19
|
]);
|
|
18
|
-
/**
|
|
19
|
-
* Error thrown when external configuration data does not match a public
|
|
20
|
-
* runtime schema.
|
|
21
|
-
*/
|
|
22
|
-
export class InvalidConfigurationError extends TypeError {
|
|
23
|
-
code = "INVALID_CONFIGURATION";
|
|
24
|
-
constructor(message) {
|
|
25
|
-
super(message);
|
|
26
|
-
this.name = "InvalidConfigurationError";
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
20
|
function requireRecord(value, path) {
|
|
30
21
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
31
22
|
throw new InvalidConfigurationError(`${path} must be an object.`);
|