brepjs-verify 0.2.1
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 +24 -0
- package/LICENSE +191 -0
- package/README.md +85 -0
- package/dist/brepjs-verify.cjs +14 -0
- package/dist/brepjs-verify.js +2 -0
- package/dist/chunk-D6vf50IK.cjs +28 -0
- package/dist/cli/exportPart.d.ts +13 -0
- package/dist/cli/main.cjs +325 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +323 -0
- package/dist/cli/scaffold.d.ts +9 -0
- package/dist/cli/watch.d.ts +5 -0
- package/dist/diff-CZ4mLtrf.cjs +869 -0
- package/dist/diff-D7ZBNRJG.js +778 -0
- package/dist/disposeShape.d.ts +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/loader/brepjsResolve.mjs +57 -0
- package/dist/snapshot/registry.cjs +50 -0
- package/dist/snapshot/registry.d.ts +12 -0
- package/dist/snapshot/registry.js +48 -0
- package/dist/snapshot/serve.cjs +27 -0
- package/dist/snapshot/serve.d.ts +12 -0
- package/dist/snapshot/serve.js +26 -0
- package/dist/snapshot/shoot.cjs +64 -0
- package/dist/snapshot/shoot.d.ts +14 -0
- package/dist/snapshot/shoot.js +61 -0
- package/dist/snapshot/static.cjs +100 -0
- package/dist/snapshot/static.d.ts +16 -0
- package/dist/snapshot/static.js +98 -0
- package/dist/verify/brepjsRuntime.d.ts +4 -0
- package/dist/verify/checks.d.ts +4 -0
- package/dist/verify/diff.d.ts +2 -0
- package/dist/verify/expected.d.ts +26 -0
- package/dist/verify/measure.d.ts +6 -0
- package/dist/verify/report.d.ts +75 -0
- package/dist/verify/runPart.d.ts +23 -0
- package/dist/verify/typecheck.d.ts +17 -0
- package/package.json +78 -0
- package/viewer/dist/assets/brepjs-CDZqKweN.js +57 -0
- package/viewer/dist/assets/index-B8QUQDqM.js +4167 -0
- package/viewer/dist/assets/kernelWorker-C6s5i9JH.js +1 -0
- package/viewer/dist/index.html +22 -0
- package/viewer/dist/wasm/occt-wasm.js +2 -0
- package/viewer/dist/wasm/occt-wasm.wasm +0 -0
|
@@ -0,0 +1,869 @@
|
|
|
1
|
+
const require_chunk = require("./chunk-D6vf50IK.cjs");
|
|
2
|
+
let node_url = require("node:url");
|
|
3
|
+
let node_module = require("node:module");
|
|
4
|
+
let node_fs = require("node:fs");
|
|
5
|
+
let node_path = require("node:path");
|
|
6
|
+
let typescript = require("typescript");
|
|
7
|
+
typescript = require_chunk.__toESM(typescript, 1);
|
|
8
|
+
//#region src/verify/brepjsRuntime.ts
|
|
9
|
+
var cached;
|
|
10
|
+
var hookRegistered = false;
|
|
11
|
+
function toolDir() {
|
|
12
|
+
let dir = (0, node_path.dirname)((0, node_url.fileURLToPath)({}.url));
|
|
13
|
+
const root = (0, node_path.parse)(dir).root;
|
|
14
|
+
for (;;) {
|
|
15
|
+
const pkg = (0, node_path.resolve)(dir, "package.json");
|
|
16
|
+
if ((0, node_fs.existsSync)(pkg)) try {
|
|
17
|
+
if (JSON.parse((0, node_fs.readFileSync)(pkg, "utf8")).name === "brepjs-verify") return dir;
|
|
18
|
+
} catch {}
|
|
19
|
+
if (dir === root) return dir;
|
|
20
|
+
dir = (0, node_path.dirname)(dir);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function loaderUrl(dir) {
|
|
24
|
+
const built = (0, node_path.resolve)(dir, "dist", "loader", "brepjsResolve.mjs");
|
|
25
|
+
const source = (0, node_path.resolve)(dir, "src", "loader", "brepjsResolve.mjs");
|
|
26
|
+
return (0, node_url.pathToFileURL)((0, node_fs.existsSync)(built) ? built : source).href;
|
|
27
|
+
}
|
|
28
|
+
function registerHook() {
|
|
29
|
+
if (hookRegistered) return;
|
|
30
|
+
const dir = toolDir();
|
|
31
|
+
(0, node_module.register)(loaderUrl(dir), {
|
|
32
|
+
parentURL: {}.url,
|
|
33
|
+
data: { toolDir: dir }
|
|
34
|
+
});
|
|
35
|
+
hookRegistered = true;
|
|
36
|
+
}
|
|
37
|
+
function loadBrep() {
|
|
38
|
+
if (!cached) {
|
|
39
|
+
registerHook();
|
|
40
|
+
cached = import("brepjs");
|
|
41
|
+
}
|
|
42
|
+
return cached;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/verify/report.ts
|
|
46
|
+
function emptyReport() {
|
|
47
|
+
return {
|
|
48
|
+
shapeType: null,
|
|
49
|
+
checks: [],
|
|
50
|
+
measurements: {},
|
|
51
|
+
errors: [],
|
|
52
|
+
errorInfos: [],
|
|
53
|
+
hints: [],
|
|
54
|
+
assertions: []
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function pushError(r, info) {
|
|
58
|
+
r.errors.push(info.message);
|
|
59
|
+
r.errorInfos.push(info);
|
|
60
|
+
}
|
|
61
|
+
function reportOk(r) {
|
|
62
|
+
return r.errors.length === 0 && r.checks.every((c) => c.passed) && r.assertions.every((a) => a.passed);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Local, brepjs-cad-owned advice keyed on `BrepErrorCode` values (see `brepjs`'s public
|
|
66
|
+
* `BrepErrorCode`). Intentionally not importing the library's internal `getSuggestionForCode`:
|
|
67
|
+
* this table is the agent loop's own actionable `fix` + `nextStep` guidance, and the library's
|
|
68
|
+
* public `BrepError.suggestion` is still surfaced alongside it on each hint.
|
|
69
|
+
*/
|
|
70
|
+
var HINT_TABLE = {
|
|
71
|
+
FILLET_NO_EDGES: {
|
|
72
|
+
fix: "Select real edges before filleting — pass an edge query (e.g. find edges by direction/position) or a non-empty edge list, not the whole solid.",
|
|
73
|
+
nextStep: "List the solid’s edges, pick the ones to round, then call fillet(solid, radius, edges)."
|
|
74
|
+
},
|
|
75
|
+
CHAMFER_NO_EDGES: {
|
|
76
|
+
fix: "Select real edges before chamfering — pass a non-empty edge query/list rather than relying on a default that matched nothing.",
|
|
77
|
+
nextStep: "Enumerate the solid’s edges, choose the target edges, then call chamfer(solid, distance, edges)."
|
|
78
|
+
},
|
|
79
|
+
INVALID_FILLET_RADIUS: {
|
|
80
|
+
fix: "Use a fillet radius that is > 0 and small enough to fit the adjacent faces (well under half the thinnest wall).",
|
|
81
|
+
nextStep: "Reduce the radius (try a fraction of the smallest local feature size) and re-verify."
|
|
82
|
+
},
|
|
83
|
+
INVALID_CHAMFER_DISTANCE: {
|
|
84
|
+
fix: "Use a chamfer distance that is > 0 and smaller than the adjacent edge lengths.",
|
|
85
|
+
nextStep: "Lower the distance below the shortest adjacent edge and re-verify."
|
|
86
|
+
},
|
|
87
|
+
INVALID_THICKNESS: {
|
|
88
|
+
fix: "Use a shell/wall thickness that is > 0 and less than half the smallest cross-section.",
|
|
89
|
+
nextStep: "Reduce the thickness and re-verify, or remove the offending face from the removed-faces set."
|
|
90
|
+
},
|
|
91
|
+
ZERO_LENGTH_EXTRUSION: {
|
|
92
|
+
fix: "Extrude by a non-zero distance — a length of 0 produces no solid.",
|
|
93
|
+
nextStep: "Set a positive extrusion height (units: mm) and re-verify."
|
|
94
|
+
},
|
|
95
|
+
ZERO_OFFSET: {
|
|
96
|
+
fix: "Offset by a non-zero amount — an offset of 0 is a no-op the kernel rejects.",
|
|
97
|
+
nextStep: "Use a small non-zero offset (positive grows, negative shrinks) and re-verify."
|
|
98
|
+
},
|
|
99
|
+
FILLET_NOT_3D: {
|
|
100
|
+
fix: "fillet needs a 3D solid. Build the solid (extrude/revolve/box) before rounding edges.",
|
|
101
|
+
nextStep: "Move the fillet after the solid is created, then fillet the solid’s edges."
|
|
102
|
+
},
|
|
103
|
+
CHAMFER_NOT_3D: {
|
|
104
|
+
fix: "chamfer needs a 3D solid. Build the solid first, then chamfer its edges.",
|
|
105
|
+
nextStep: "Reorder so chamfer runs on the finished solid, not a sketch/wire/face."
|
|
106
|
+
},
|
|
107
|
+
FUSE_NOT_3D: {
|
|
108
|
+
fix: "fuse needs two 3D solids. Ensure both operands are solids before unioning.",
|
|
109
|
+
nextStep: "Extrude/loft each profile into a solid first, then fuse and unwrap the Result."
|
|
110
|
+
},
|
|
111
|
+
CUT_NOT_3D: {
|
|
112
|
+
fix: "cut needs 3D solids for both the base and the tool. Build both as solids first.",
|
|
113
|
+
nextStep: "Make the tool a solid (e.g. a box/cylinder), then cut(base, tool) and unwrap the Result."
|
|
114
|
+
},
|
|
115
|
+
INTERSECT_NOT_3D: {
|
|
116
|
+
fix: "intersect needs two 3D solids. Build both operands as solids first.",
|
|
117
|
+
nextStep: "Ensure both inputs are solids, then intersect(a, b) and unwrap the Result."
|
|
118
|
+
},
|
|
119
|
+
SHELL_NOT_3D: {
|
|
120
|
+
fix: "shell needs a 3D solid. Create the solid before hollowing it.",
|
|
121
|
+
nextStep: "Build the solid first, then shell it with a thickness and the faces to remove."
|
|
122
|
+
},
|
|
123
|
+
OFFSET_NOT_3D: {
|
|
124
|
+
fix: "This offset needs a 3D solid. Build the solid before offsetting.",
|
|
125
|
+
nextStep: "Reorder so offset runs on the solid, then re-verify."
|
|
126
|
+
},
|
|
127
|
+
SWEEP_NOT_3D: {
|
|
128
|
+
fix: "sweep needs a 3D result context — check the profile and path produce a solid sweep.",
|
|
129
|
+
nextStep: "Verify the profile is a closed wire/face and the path is a valid wire, then re-sweep."
|
|
130
|
+
},
|
|
131
|
+
LOFT_NOT_3D: {
|
|
132
|
+
fix: "loft needs 3D-capable sections. Use closed profiles that can form a solid.",
|
|
133
|
+
nextStep: "Provide at least two closed section wires/faces, then loft and unwrap the Result."
|
|
134
|
+
},
|
|
135
|
+
REVOLUTION_NOT_3D: {
|
|
136
|
+
fix: "revolve needs a 2D profile revolved about an axis. Pass a face/closed wire.",
|
|
137
|
+
nextStep: "Use a closed profile and a valid axis, then revolve and unwrap the Result."
|
|
138
|
+
},
|
|
139
|
+
LOFT_FAILED: {
|
|
140
|
+
fix: "The loft could not be built — usually mismatched, self-intersecting, or out-of-order sections.",
|
|
141
|
+
nextStep: "Make the sections consistent (same orientation, non-self-intersecting, ordered along the loft) and retry."
|
|
142
|
+
},
|
|
143
|
+
LOFT_EMPTY: {
|
|
144
|
+
fix: "loft received too few sections. Provide at least two profiles.",
|
|
145
|
+
nextStep: "Add the missing section wires/faces and loft again."
|
|
146
|
+
},
|
|
147
|
+
SWEEP_FAILED: {
|
|
148
|
+
fix: "The sweep failed — usually a path with sharp corners/self-intersection or a profile too large for the path curvature.",
|
|
149
|
+
nextStep: "Smooth or simplify the path, shrink the profile, then re-sweep."
|
|
150
|
+
},
|
|
151
|
+
FUSE_FAILED: {
|
|
152
|
+
fix: "The boolean union failed — often touching-but-not-overlapping solids or tolerance issues.",
|
|
153
|
+
nextStep: "Make the operands overlap slightly (or heal/translate one), then re-fuse."
|
|
154
|
+
},
|
|
155
|
+
CUT_FAILED: {
|
|
156
|
+
fix: "The boolean subtraction failed — often a tool that does not actually intersect the base, or tolerance issues.",
|
|
157
|
+
nextStep: "Confirm the tool overlaps the base, optionally heal the inputs, then re-cut."
|
|
158
|
+
},
|
|
159
|
+
BOOLEAN_HAS_ERRORS: {
|
|
160
|
+
fix: "The boolean ran but the kernel reported errors (often coincident faces or near-tangent contact).",
|
|
161
|
+
nextStep: "Perturb one operand slightly so contact is a clean overlap, or heal the inputs, then retry."
|
|
162
|
+
},
|
|
163
|
+
STEP_EXPORT_CRASHED: {
|
|
164
|
+
fix: "STEP export crashed in the kernel — frequently a disjoint/degenerate fuse or an invalid solid reaching the exporter.",
|
|
165
|
+
nextStep: "Run validity checks first, heal/simplify the shape (or avoid fusing disjoint solids), then re-export."
|
|
166
|
+
},
|
|
167
|
+
STEP_EXPORT_FAILED: {
|
|
168
|
+
fix: "STEP export failed. The shape is likely invalid or non-manifold.",
|
|
169
|
+
nextStep: "Fix validity errors (heal/sew) until the solid is valid, then re-export."
|
|
170
|
+
},
|
|
171
|
+
STL_EXPORT_CRASHED: {
|
|
172
|
+
fix: "STL export crashed — usually an invalid or non-manifold mesh source.",
|
|
173
|
+
nextStep: "Verify the solid is valid and watertight, then re-export."
|
|
174
|
+
},
|
|
175
|
+
STL_EXPORT_FAILED: {
|
|
176
|
+
fix: "STL export failed. The shape is likely invalid or empty.",
|
|
177
|
+
nextStep: "Fix validity errors first, then re-export."
|
|
178
|
+
},
|
|
179
|
+
NULL_SHAPE_INPUT: {
|
|
180
|
+
fix: "An operation received a null/empty shape. Ensure the previous step actually produced a shape.",
|
|
181
|
+
nextStep: "Check the upstream Result was unwrapped (not an Err) before passing it on."
|
|
182
|
+
},
|
|
183
|
+
NULL_SHAPE: {
|
|
184
|
+
fix: "An operation produced or received a null shape. A prior step likely failed silently.",
|
|
185
|
+
nextStep: "Verify each intermediate shape is non-null before chaining the next operation."
|
|
186
|
+
},
|
|
187
|
+
VALIDATION_FAILED: {
|
|
188
|
+
fix: "The shape failed validity (BRepCheck). It is non-manifold, self-intersecting, or has bad geometry.",
|
|
189
|
+
nextStep: "Heal/sew the shape, or revisit the operation that produced it, until validSolid passes."
|
|
190
|
+
},
|
|
191
|
+
TYPECHECK: {
|
|
192
|
+
fix: "Fix the TypeScript type error before running the part — the API call or value does not match brepjs’s types.",
|
|
193
|
+
nextStep: "Correct the flagged type (e.g. argument/return type or import), then re-verify."
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
/** Synthetic code attached to validity-check failures (validSolid returns a plain string error). */
|
|
197
|
+
var VALIDITY_FAILURE_CODE = "VALIDATION_FAILED";
|
|
198
|
+
function hintFor(info) {
|
|
199
|
+
if (!info.code) return null;
|
|
200
|
+
const entry = HINT_TABLE[info.code];
|
|
201
|
+
const fix = entry?.fix ?? info.suggestion ?? "No specific fix available; inspect the error and the operation that produced it.";
|
|
202
|
+
const nextStep = entry?.nextStep ?? "Adjust the failing operation per the message/suggestion, then re-verify.";
|
|
203
|
+
return {
|
|
204
|
+
code: info.code,
|
|
205
|
+
message: info.message,
|
|
206
|
+
fix,
|
|
207
|
+
nextStep
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function buildHints(r) {
|
|
211
|
+
const hints = [];
|
|
212
|
+
const seen = /* @__PURE__ */ new Set();
|
|
213
|
+
for (const info of r.errorInfos) {
|
|
214
|
+
const hint = hintFor(info);
|
|
215
|
+
if (!hint) continue;
|
|
216
|
+
const key = `${hint.code}${hint.message}`;
|
|
217
|
+
if (seen.has(key)) continue;
|
|
218
|
+
seen.add(key);
|
|
219
|
+
hints.push(hint);
|
|
220
|
+
}
|
|
221
|
+
return hints;
|
|
222
|
+
}
|
|
223
|
+
function serializeReport(r) {
|
|
224
|
+
return JSON.stringify({
|
|
225
|
+
ok: reportOk(r),
|
|
226
|
+
...r
|
|
227
|
+
}, null, 2);
|
|
228
|
+
}
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region src/verify/checks.ts
|
|
231
|
+
function shapeTypeOf(brep, s) {
|
|
232
|
+
const { isSolid, isFace, isShell, isWire, isEdge, isVertex, isCompound, isCompSolid } = brep;
|
|
233
|
+
if (isSolid(s)) return "Solid";
|
|
234
|
+
if (isCompSolid(s)) return "CompSolid";
|
|
235
|
+
if (isCompound(s)) return "Compound";
|
|
236
|
+
if (isShell(s)) return "Shell";
|
|
237
|
+
if (isFace(s)) return "Face";
|
|
238
|
+
if (isWire(s)) return "Wire";
|
|
239
|
+
if (isEdge(s)) return "Edge";
|
|
240
|
+
if (isVertex(s)) return "Vertex";
|
|
241
|
+
return "Unknown";
|
|
242
|
+
}
|
|
243
|
+
function runChecks(brep, shape) {
|
|
244
|
+
const { isSolid, isShape3D, isFace, measureVolume, measureArea, getBounds, validSolid, isOk } = brep;
|
|
245
|
+
const r = emptyReport();
|
|
246
|
+
r.shapeType = shapeTypeOf(brep, shape);
|
|
247
|
+
if (isSolid(shape)) {
|
|
248
|
+
const valid = validSolid(shape);
|
|
249
|
+
const validCheck = {
|
|
250
|
+
name: "isValidSolid",
|
|
251
|
+
passed: isOk(valid)
|
|
252
|
+
};
|
|
253
|
+
if (!isOk(valid)) {
|
|
254
|
+
validCheck.detail = valid.error;
|
|
255
|
+
r.errorInfos.push({
|
|
256
|
+
message: `isValidSolid: ${valid.error}`,
|
|
257
|
+
code: VALIDITY_FAILURE_CODE
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
r.checks.push(validCheck);
|
|
261
|
+
}
|
|
262
|
+
if (isShape3D(shape)) {
|
|
263
|
+
const vol = measureVolume(shape);
|
|
264
|
+
if (isOk(vol)) {
|
|
265
|
+
r.measurements.volume = vol.value;
|
|
266
|
+
r.checks.push({
|
|
267
|
+
name: "positiveVolume",
|
|
268
|
+
passed: vol.value > 0
|
|
269
|
+
});
|
|
270
|
+
} else pushError(r, {
|
|
271
|
+
message: `measureVolume: ${vol.error.message}`,
|
|
272
|
+
code: vol.error.code,
|
|
273
|
+
suggestion: vol.error.suggestion
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
if (isFace(shape) || isShape3D(shape)) {
|
|
277
|
+
const area = measureArea(shape);
|
|
278
|
+
if (isOk(area)) r.measurements.area = area.value;
|
|
279
|
+
}
|
|
280
|
+
try {
|
|
281
|
+
r.measurements.bounds = getBounds(shape);
|
|
282
|
+
} catch (e) {
|
|
283
|
+
pushError(r, { message: `getBounds: ${e.message}` });
|
|
284
|
+
}
|
|
285
|
+
r.hints = buildHints(r);
|
|
286
|
+
return r;
|
|
287
|
+
}
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region src/verify/expected.ts
|
|
290
|
+
var DEFAULT_TOLERANCE_PCT = .5;
|
|
291
|
+
/** Percent deviation of `actual` from `expected`; 0 expected matches only 0 actual. */
|
|
292
|
+
function pctDelta(actual, expected) {
|
|
293
|
+
if (expected === 0) return actual === 0 ? 0 : Infinity;
|
|
294
|
+
return Math.abs(actual - expected) / Math.abs(expected) * 100;
|
|
295
|
+
}
|
|
296
|
+
function withinTolerance(actual, expected, tolerancePct) {
|
|
297
|
+
return pctDelta(actual, expected) <= tolerancePct;
|
|
298
|
+
}
|
|
299
|
+
function isExpectedDims(v) {
|
|
300
|
+
if (typeof v !== "object" || v === null) return false;
|
|
301
|
+
const r = v;
|
|
302
|
+
const numOk = (k) => r[k] === void 0 || typeof r[k] === "number";
|
|
303
|
+
const boundsOk = r["bounds"] === void 0 || typeof r["bounds"] === "object" && r["bounds"] !== null;
|
|
304
|
+
return numOk("volume") && numOk("area") && numOk("tolerancePct") && boundsOk;
|
|
305
|
+
}
|
|
306
|
+
function pushAssertion(out, name, expected, actual, tolerancePct) {
|
|
307
|
+
if (actual === void 0) {
|
|
308
|
+
out.push({
|
|
309
|
+
name,
|
|
310
|
+
expected,
|
|
311
|
+
actual: null,
|
|
312
|
+
passed: false
|
|
313
|
+
});
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
out.push({
|
|
317
|
+
name,
|
|
318
|
+
expected,
|
|
319
|
+
actual,
|
|
320
|
+
passed: withinTolerance(actual, expected, tolerancePct)
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Compare measured dimensions against a part's `expected` export. Each declared field becomes one
|
|
325
|
+
* assertion; a missing measurement for a declared expectation is a failing assertion (`actual:null`).
|
|
326
|
+
*/
|
|
327
|
+
function evaluateExpected(expected, measurements) {
|
|
328
|
+
const tol = expected.tolerancePct ?? .5;
|
|
329
|
+
const assertions = [];
|
|
330
|
+
if (expected.volume !== void 0) pushAssertion(assertions, "volume", expected.volume, measurements.volume, tol);
|
|
331
|
+
if (expected.area !== void 0) pushAssertion(assertions, "area", expected.area, measurements.area, tol);
|
|
332
|
+
if (expected.bounds) {
|
|
333
|
+
const b = measurements.bounds;
|
|
334
|
+
for (const key of [
|
|
335
|
+
"xMin",
|
|
336
|
+
"xMax",
|
|
337
|
+
"yMin",
|
|
338
|
+
"yMax",
|
|
339
|
+
"zMin",
|
|
340
|
+
"zMax"
|
|
341
|
+
]) {
|
|
342
|
+
const want = expected.bounds[key];
|
|
343
|
+
if (want === void 0) continue;
|
|
344
|
+
pushAssertion(assertions, `bounds.${key}`, want, b?.[key], tol);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return assertions;
|
|
348
|
+
}
|
|
349
|
+
//#endregion
|
|
350
|
+
//#region src/verify/typecheck.ts
|
|
351
|
+
/** Code stamped on every type-check diagnostic so the report/hints can key on it. */
|
|
352
|
+
var TYPECHECK_CODE = "TYPECHECK";
|
|
353
|
+
/**
|
|
354
|
+
* Resolve the `brepjs` declaration entry the part should be checked against. Mirrors the
|
|
355
|
+
* runtime resolve hook's prefer-local-then-bundled policy: try to resolve `brepjs` from the
|
|
356
|
+
* part's own directory first (so authors in a real project type-check against THAT install),
|
|
357
|
+
* and fall back to the bundled copy via `toolDir`.
|
|
358
|
+
*/
|
|
359
|
+
function resolveBrepjsTypes(partPath, toolDir) {
|
|
360
|
+
const fromPart = brepjsTypesFor((0, node_url.pathToFileURL)(partPath).href);
|
|
361
|
+
if (fromPart) return fromPart;
|
|
362
|
+
if (toolDir) {
|
|
363
|
+
const fromTool = brepjsTypesFor((0, node_url.pathToFileURL)((0, node_path.resolve)(toolDir, "package.json")).href);
|
|
364
|
+
if (fromTool) return fromTool;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
function brepjsTypesFor(fromUrl) {
|
|
368
|
+
let jsEntry;
|
|
369
|
+
try {
|
|
370
|
+
jsEntry = (0, node_module.createRequire)(fromUrl).resolve("brepjs");
|
|
371
|
+
} catch {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const pkgDir = packageRootOf((0, node_path.dirname)(jsEntry), "brepjs");
|
|
375
|
+
if (!pkgDir) return void 0;
|
|
376
|
+
const pkgPath = (0, node_path.resolve)(pkgDir, "package.json");
|
|
377
|
+
let pkg;
|
|
378
|
+
try {
|
|
379
|
+
pkg = JSON.parse((0, node_fs.readFileSync)(pkgPath, "utf8"));
|
|
380
|
+
} catch {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
const rel = typesEntryOf(pkg);
|
|
384
|
+
if (!rel) return void 0;
|
|
385
|
+
const abs = (0, node_path.resolve)(pkgDir, rel);
|
|
386
|
+
return (0, node_fs.existsSync)(abs) ? abs : void 0;
|
|
387
|
+
}
|
|
388
|
+
function typesEntryOf(pkg) {
|
|
389
|
+
const exportsRoot = pkg.exports?.["."];
|
|
390
|
+
if (exportsRoot && typeof exportsRoot === "object") {
|
|
391
|
+
const imp = exportsRoot["import"];
|
|
392
|
+
if (imp && typeof imp === "object") {
|
|
393
|
+
const t = imp["types"];
|
|
394
|
+
if (typeof t === "string") return t;
|
|
395
|
+
}
|
|
396
|
+
const t = exportsRoot["types"];
|
|
397
|
+
if (typeof t === "string") return t;
|
|
398
|
+
}
|
|
399
|
+
return typeof pkg.types === "string" ? pkg.types : void 0;
|
|
400
|
+
}
|
|
401
|
+
function packageRootOf(startDir, name) {
|
|
402
|
+
let dir = startDir;
|
|
403
|
+
const root = (0, node_path.parse)(dir).root;
|
|
404
|
+
for (;;) {
|
|
405
|
+
const pkg = (0, node_path.resolve)(dir, "package.json");
|
|
406
|
+
if ((0, node_fs.existsSync)(pkg)) try {
|
|
407
|
+
if (JSON.parse((0, node_fs.readFileSync)(pkg, "utf8")).name === name) return dir;
|
|
408
|
+
} catch {}
|
|
409
|
+
if (dir === root) return void 0;
|
|
410
|
+
dir = (0, node_path.dirname)(dir);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
var COMPILER_OPTIONS = {
|
|
414
|
+
target: typescript.default.ScriptTarget.ES2022,
|
|
415
|
+
module: typescript.default.ModuleKind.ESNext,
|
|
416
|
+
moduleResolution: typescript.default.ModuleResolutionKind.Bundler,
|
|
417
|
+
strict: true,
|
|
418
|
+
noEmit: true,
|
|
419
|
+
skipLibCheck: true,
|
|
420
|
+
allowImportingTsExtensions: true
|
|
421
|
+
};
|
|
422
|
+
function diagnosticToErrorInfo(d) {
|
|
423
|
+
const text = typescript.default.flattenDiagnosticMessageText(d.messageText, "\n");
|
|
424
|
+
let where = "";
|
|
425
|
+
if (d.file && typeof d.start === "number") {
|
|
426
|
+
const { line, character } = d.file.getLineAndCharacterOfPosition(d.start);
|
|
427
|
+
where = `${d.file.fileName}:${line + 1}:${character + 1} `;
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
message: `typecheck: ${where}TS${d.code}: ${text}`,
|
|
431
|
+
code: TYPECHECK_CODE
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Type-check a single `.brep.ts` part against the bundled (or local) `brepjs` declarations.
|
|
436
|
+
*
|
|
437
|
+
* Uses a synthetic in-memory program: a `paths` mapping points the bare `brepjs` specifier at
|
|
438
|
+
* the resolved `.d.ts`, so the part can be checked without a real install or tsconfig. If the
|
|
439
|
+
* `brepjs` types cannot be resolved, the check is skipped (ok:true, no errors) rather than
|
|
440
|
+
* failing — `--check` should never be worse than not passing it.
|
|
441
|
+
*/
|
|
442
|
+
function typecheckPart(partPath, toolDir) {
|
|
443
|
+
const dts = resolveBrepjsTypes(partPath, toolDir);
|
|
444
|
+
const options = { ...COMPILER_OPTIONS };
|
|
445
|
+
if (dts) options.paths = { brepjs: [dts] };
|
|
446
|
+
const program = typescript.default.createProgram([partPath], options);
|
|
447
|
+
const errors = [
|
|
448
|
+
...program.getSemanticDiagnostics(),
|
|
449
|
+
...program.getSyntacticDiagnostics(),
|
|
450
|
+
...program.getGlobalDiagnostics()
|
|
451
|
+
].filter((d) => d.category === typescript.default.DiagnosticCategory.Error).map(diagnosticToErrorInfo);
|
|
452
|
+
return {
|
|
453
|
+
ok: errors.length === 0,
|
|
454
|
+
errors
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
//#endregion
|
|
458
|
+
//#region src/verify/runPart.ts
|
|
459
|
+
async function loadPart(modulePath) {
|
|
460
|
+
try {
|
|
461
|
+
return await import((0, node_url.pathToFileURL)(modulePath).href);
|
|
462
|
+
} catch (e) {
|
|
463
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
464
|
+
if (/\.[mc]?tsx?$/.test(modulePath) && /import statement|file extension/i.test(msg)) throw new Error(`cannot load TypeScript part "${modulePath}": author parts in an ESM project (set "type": "module" in package.json) or rename the file to .mts. (${msg})`, { cause: e });
|
|
465
|
+
throw e;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
function isResult(v) {
|
|
469
|
+
return typeof v === "object" && v !== null && "ok" in v && typeof v.ok === "boolean";
|
|
470
|
+
}
|
|
471
|
+
function isBrepError(v) {
|
|
472
|
+
if (typeof v !== "object" || v === null) return false;
|
|
473
|
+
const rec = v;
|
|
474
|
+
return typeof rec["code"] === "string" && typeof rec["message"] === "string";
|
|
475
|
+
}
|
|
476
|
+
function toErrorInfo(prefix, e) {
|
|
477
|
+
if (isBrepError(e)) return {
|
|
478
|
+
message: `${prefix}: ${e.message}`,
|
|
479
|
+
code: e.code,
|
|
480
|
+
suggestion: e.suggestion
|
|
481
|
+
};
|
|
482
|
+
if (e instanceof Error) return { message: `${prefix}: ${e.message}` };
|
|
483
|
+
return { message: `${prefix}: ${String(e)}` };
|
|
484
|
+
}
|
|
485
|
+
function finalize(result) {
|
|
486
|
+
result.report.hints = buildHints(result.report);
|
|
487
|
+
return result;
|
|
488
|
+
}
|
|
489
|
+
async function runPart(modulePath, opts = {}) {
|
|
490
|
+
const report = emptyReport();
|
|
491
|
+
if (opts.check) {
|
|
492
|
+
const tc = typecheckPart(modulePath, toolDir());
|
|
493
|
+
if (!tc.ok) {
|
|
494
|
+
for (const e of tc.errors) pushError(report, e);
|
|
495
|
+
return finalize({
|
|
496
|
+
shape: null,
|
|
497
|
+
report
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
let brep;
|
|
502
|
+
try {
|
|
503
|
+
brep = await loadBrep();
|
|
504
|
+
await brep.init();
|
|
505
|
+
} catch (e) {
|
|
506
|
+
pushError(report, toErrorInfo("kernel init failed", e));
|
|
507
|
+
return finalize({
|
|
508
|
+
shape: null,
|
|
509
|
+
report
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
const { isOk, mesh, exportGlb, exportSTEP } = brep;
|
|
513
|
+
let mod;
|
|
514
|
+
try {
|
|
515
|
+
mod = await loadPart(modulePath);
|
|
516
|
+
} catch (e) {
|
|
517
|
+
pushError(report, toErrorInfo("import failed", e));
|
|
518
|
+
return finalize({
|
|
519
|
+
shape: null,
|
|
520
|
+
report
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
if (typeof mod.default !== "function") {
|
|
524
|
+
pushError(report, { message: "module has no default-exported part function" });
|
|
525
|
+
return finalize({
|
|
526
|
+
shape: null,
|
|
527
|
+
report
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
let out;
|
|
531
|
+
try {
|
|
532
|
+
out = await mod.default();
|
|
533
|
+
} catch (e) {
|
|
534
|
+
pushError(report, toErrorInfo("part threw", e));
|
|
535
|
+
return finalize({
|
|
536
|
+
shape: null,
|
|
537
|
+
report
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
let shape;
|
|
541
|
+
if (isResult(out)) {
|
|
542
|
+
if (!isOk(out)) {
|
|
543
|
+
pushError(report, toErrorInfo("part returned Err", out.error));
|
|
544
|
+
return finalize({
|
|
545
|
+
shape: null,
|
|
546
|
+
report
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
shape = out.value;
|
|
550
|
+
} else shape = out;
|
|
551
|
+
if (!shape) {
|
|
552
|
+
pushError(report, { message: "part produced no shape" });
|
|
553
|
+
return finalize({
|
|
554
|
+
shape: null,
|
|
555
|
+
report
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
const result = runChecks(brep, shape);
|
|
559
|
+
if (isExpectedDims(mod.expected)) {
|
|
560
|
+
const expected = mod.expected;
|
|
561
|
+
result.assertions = evaluateExpected(expected, result.measurements);
|
|
562
|
+
}
|
|
563
|
+
let glb;
|
|
564
|
+
let step;
|
|
565
|
+
if (opts.glb) try {
|
|
566
|
+
glb = exportGlb(mesh(shape));
|
|
567
|
+
} catch (e) {
|
|
568
|
+
pushError(result, toErrorInfo("exportGlb", e));
|
|
569
|
+
}
|
|
570
|
+
if (opts.step) {
|
|
571
|
+
const r = exportSTEP(shape);
|
|
572
|
+
if (isOk(r)) step = await r.value.arrayBuffer();
|
|
573
|
+
else pushError(result, toErrorInfo("exportSTEP", r.error));
|
|
574
|
+
}
|
|
575
|
+
return finalize({
|
|
576
|
+
shape,
|
|
577
|
+
report: result,
|
|
578
|
+
step,
|
|
579
|
+
glb
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
//#endregion
|
|
583
|
+
//#region \0@oxc-project+runtime@0.132.0/helpers/usingCtx.js
|
|
584
|
+
function _usingCtx() {
|
|
585
|
+
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
586
|
+
var n = Error();
|
|
587
|
+
return n.name = "SuppressedError", n.error = r, n.suppressed = e, n;
|
|
588
|
+
}, e = {}, n = [];
|
|
589
|
+
function using(r, e) {
|
|
590
|
+
if (null != e) {
|
|
591
|
+
if (Object(e) !== e) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
592
|
+
if (r) var o = e[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
593
|
+
if (void 0 === o && (o = e[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r)) var t = o;
|
|
594
|
+
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
595
|
+
t && (o = function o() {
|
|
596
|
+
try {
|
|
597
|
+
t.call(e);
|
|
598
|
+
} catch (r) {
|
|
599
|
+
return Promise.reject(r);
|
|
600
|
+
}
|
|
601
|
+
}), n.push({
|
|
602
|
+
v: e,
|
|
603
|
+
d: o,
|
|
604
|
+
a: r
|
|
605
|
+
});
|
|
606
|
+
} else r && n.push({
|
|
607
|
+
d: e,
|
|
608
|
+
a: r
|
|
609
|
+
});
|
|
610
|
+
return e;
|
|
611
|
+
}
|
|
612
|
+
return {
|
|
613
|
+
e,
|
|
614
|
+
u: using.bind(null, !1),
|
|
615
|
+
a: using.bind(null, !0),
|
|
616
|
+
d: function d() {
|
|
617
|
+
var o, t = this.e, s = 0;
|
|
618
|
+
function next() {
|
|
619
|
+
for (; o = n.pop();) try {
|
|
620
|
+
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
621
|
+
if (o.d) {
|
|
622
|
+
var r = o.d.call(o.v);
|
|
623
|
+
if (o.a) return s |= 2, Promise.resolve(r).then(next, err);
|
|
624
|
+
} else s |= 1;
|
|
625
|
+
} catch (r) {
|
|
626
|
+
return err(r);
|
|
627
|
+
}
|
|
628
|
+
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
629
|
+
if (t !== e) throw t;
|
|
630
|
+
}
|
|
631
|
+
function err(n) {
|
|
632
|
+
return t = t !== e ? new r(n, t) : n, next();
|
|
633
|
+
}
|
|
634
|
+
return next();
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
//#endregion
|
|
639
|
+
//#region src/verify/measure.ts
|
|
640
|
+
async function runMeasure(aPath, bPath) {
|
|
641
|
+
try {
|
|
642
|
+
var _usingCtx$2 = _usingCtx();
|
|
643
|
+
const { measureDistance, measureLength, isOk } = await loadBrep();
|
|
644
|
+
const errors = [];
|
|
645
|
+
const a = await runPart(aPath);
|
|
646
|
+
errors.push(...a.report.errors);
|
|
647
|
+
if (!a.shape) return { errors };
|
|
648
|
+
const sa = _usingCtx$2.u(a.shape);
|
|
649
|
+
if (bPath === void 0) {
|
|
650
|
+
const len = measureLength(sa);
|
|
651
|
+
if (isOk(len)) return {
|
|
652
|
+
length: len.value,
|
|
653
|
+
errors
|
|
654
|
+
};
|
|
655
|
+
errors.push(`measureLength: ${len.error.message}`);
|
|
656
|
+
return { errors };
|
|
657
|
+
}
|
|
658
|
+
const b = await runPart(bPath);
|
|
659
|
+
errors.push(...b.report.errors);
|
|
660
|
+
if (!b.shape) return { errors };
|
|
661
|
+
const dist = measureDistance(sa, _usingCtx$2.u(b.shape));
|
|
662
|
+
if (isOk(dist)) return {
|
|
663
|
+
distance: dist.value,
|
|
664
|
+
errors
|
|
665
|
+
};
|
|
666
|
+
errors.push(`measureDistance: ${dist.error.message}`);
|
|
667
|
+
return { errors };
|
|
668
|
+
} catch (_) {
|
|
669
|
+
_usingCtx$2.e = _;
|
|
670
|
+
} finally {
|
|
671
|
+
_usingCtx$2.d();
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
//#endregion
|
|
675
|
+
//#region src/verify/diff.ts
|
|
676
|
+
function emptyDiff(errors) {
|
|
677
|
+
return {
|
|
678
|
+
volumeDelta: 0,
|
|
679
|
+
areaDelta: 0,
|
|
680
|
+
bboxDelta: {
|
|
681
|
+
xMin: 0,
|
|
682
|
+
xMax: 0,
|
|
683
|
+
yMin: 0,
|
|
684
|
+
yMax: 0,
|
|
685
|
+
zMin: 0,
|
|
686
|
+
zMax: 0
|
|
687
|
+
},
|
|
688
|
+
symmetricDifferenceVolume: 0,
|
|
689
|
+
errors
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
function volumeOf(brep, shape, errors) {
|
|
693
|
+
const v = brep.measureVolume(shape);
|
|
694
|
+
if (brep.isOk(v)) return v.value;
|
|
695
|
+
errors.push(`measureVolume: ${v.error.message}`);
|
|
696
|
+
return 0;
|
|
697
|
+
}
|
|
698
|
+
function areaOf(brep, shape, errors) {
|
|
699
|
+
if (!brep.isShape3D(shape)) return 0;
|
|
700
|
+
const a = brep.measureArea(shape);
|
|
701
|
+
if (brep.isOk(a)) return a.value;
|
|
702
|
+
errors.push(`measureArea: ${a.error.message}`);
|
|
703
|
+
return 0;
|
|
704
|
+
}
|
|
705
|
+
function boundsDelta(brep, a, b, errors) {
|
|
706
|
+
try {
|
|
707
|
+
const ba = brep.getBounds(a);
|
|
708
|
+
const bb = brep.getBounds(b);
|
|
709
|
+
return {
|
|
710
|
+
xMin: bb.xMin - ba.xMin,
|
|
711
|
+
xMax: bb.xMax - ba.xMax,
|
|
712
|
+
yMin: bb.yMin - ba.yMin,
|
|
713
|
+
yMax: bb.yMax - ba.yMax,
|
|
714
|
+
zMin: bb.zMin - ba.zMin,
|
|
715
|
+
zMax: bb.zMax - ba.zMax
|
|
716
|
+
};
|
|
717
|
+
} catch (e) {
|
|
718
|
+
errors.push(`getBounds: ${e.message}`);
|
|
719
|
+
return {
|
|
720
|
+
xMin: 0,
|
|
721
|
+
xMax: 0,
|
|
722
|
+
yMin: 0,
|
|
723
|
+
yMax: 0,
|
|
724
|
+
zMin: 0,
|
|
725
|
+
zMax: 0
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
function cutVolume(brep, x, y, errors) {
|
|
730
|
+
try {
|
|
731
|
+
var _usingCtx$1 = _usingCtx();
|
|
732
|
+
const r = brep.cut(x, y);
|
|
733
|
+
if (!brep.isOk(r)) {
|
|
734
|
+
errors.push(`cut: ${r.error.message}`);
|
|
735
|
+
return 0;
|
|
736
|
+
}
|
|
737
|
+
return volumeOf(brep, _usingCtx$1.u(r.value), errors);
|
|
738
|
+
} catch (_) {
|
|
739
|
+
_usingCtx$1.e = _;
|
|
740
|
+
} finally {
|
|
741
|
+
_usingCtx$1.d();
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
async function runDiff(aPath, bPath) {
|
|
745
|
+
try {
|
|
746
|
+
var _usingCtx3 = _usingCtx();
|
|
747
|
+
const brep = await loadBrep();
|
|
748
|
+
const { isShape3D } = brep;
|
|
749
|
+
const errors = [];
|
|
750
|
+
const a = await runPart(aPath);
|
|
751
|
+
errors.push(...a.report.errors);
|
|
752
|
+
if (!a.shape) return emptyDiff(errors);
|
|
753
|
+
const sa = _usingCtx3.u(a.shape);
|
|
754
|
+
const b = await runPart(bPath);
|
|
755
|
+
errors.push(...b.report.errors);
|
|
756
|
+
if (!b.shape) return emptyDiff(errors);
|
|
757
|
+
const sb = _usingCtx3.u(b.shape);
|
|
758
|
+
const bboxDelta = boundsDelta(brep, sa, sb, errors);
|
|
759
|
+
const areaDelta = areaOf(brep, sb, errors) - areaOf(brep, sa, errors);
|
|
760
|
+
let volumeDelta = 0;
|
|
761
|
+
let symmetricDifferenceVolume = 0;
|
|
762
|
+
if (isShape3D(sa) && isShape3D(sb)) {
|
|
763
|
+
volumeDelta = volumeOf(brep, sb, errors) - volumeOf(brep, sa, errors);
|
|
764
|
+
symmetricDifferenceVolume = cutVolume(brep, sa, sb, errors) + cutVolume(brep, sb, sa, errors);
|
|
765
|
+
}
|
|
766
|
+
return {
|
|
767
|
+
volumeDelta,
|
|
768
|
+
areaDelta,
|
|
769
|
+
bboxDelta,
|
|
770
|
+
symmetricDifferenceVolume,
|
|
771
|
+
errors
|
|
772
|
+
};
|
|
773
|
+
} catch (_) {
|
|
774
|
+
_usingCtx3.e = _;
|
|
775
|
+
} finally {
|
|
776
|
+
_usingCtx3.d();
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
//#endregion
|
|
780
|
+
Object.defineProperty(exports, "DEFAULT_TOLERANCE_PCT", {
|
|
781
|
+
enumerable: true,
|
|
782
|
+
get: function() {
|
|
783
|
+
return DEFAULT_TOLERANCE_PCT;
|
|
784
|
+
}
|
|
785
|
+
});
|
|
786
|
+
Object.defineProperty(exports, "TYPECHECK_CODE", {
|
|
787
|
+
enumerable: true,
|
|
788
|
+
get: function() {
|
|
789
|
+
return TYPECHECK_CODE;
|
|
790
|
+
}
|
|
791
|
+
});
|
|
792
|
+
Object.defineProperty(exports, "emptyReport", {
|
|
793
|
+
enumerable: true,
|
|
794
|
+
get: function() {
|
|
795
|
+
return emptyReport;
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
Object.defineProperty(exports, "evaluateExpected", {
|
|
799
|
+
enumerable: true,
|
|
800
|
+
get: function() {
|
|
801
|
+
return evaluateExpected;
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
Object.defineProperty(exports, "isExpectedDims", {
|
|
805
|
+
enumerable: true,
|
|
806
|
+
get: function() {
|
|
807
|
+
return isExpectedDims;
|
|
808
|
+
}
|
|
809
|
+
});
|
|
810
|
+
Object.defineProperty(exports, "loadBrep", {
|
|
811
|
+
enumerable: true,
|
|
812
|
+
get: function() {
|
|
813
|
+
return loadBrep;
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
Object.defineProperty(exports, "pctDelta", {
|
|
817
|
+
enumerable: true,
|
|
818
|
+
get: function() {
|
|
819
|
+
return pctDelta;
|
|
820
|
+
}
|
|
821
|
+
});
|
|
822
|
+
Object.defineProperty(exports, "pushError", {
|
|
823
|
+
enumerable: true,
|
|
824
|
+
get: function() {
|
|
825
|
+
return pushError;
|
|
826
|
+
}
|
|
827
|
+
});
|
|
828
|
+
Object.defineProperty(exports, "reportOk", {
|
|
829
|
+
enumerable: true,
|
|
830
|
+
get: function() {
|
|
831
|
+
return reportOk;
|
|
832
|
+
}
|
|
833
|
+
});
|
|
834
|
+
Object.defineProperty(exports, "runChecks", {
|
|
835
|
+
enumerable: true,
|
|
836
|
+
get: function() {
|
|
837
|
+
return runChecks;
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
Object.defineProperty(exports, "runDiff", {
|
|
841
|
+
enumerable: true,
|
|
842
|
+
get: function() {
|
|
843
|
+
return runDiff;
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
Object.defineProperty(exports, "runMeasure", {
|
|
847
|
+
enumerable: true,
|
|
848
|
+
get: function() {
|
|
849
|
+
return runMeasure;
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
Object.defineProperty(exports, "runPart", {
|
|
853
|
+
enumerable: true,
|
|
854
|
+
get: function() {
|
|
855
|
+
return runPart;
|
|
856
|
+
}
|
|
857
|
+
});
|
|
858
|
+
Object.defineProperty(exports, "serializeReport", {
|
|
859
|
+
enumerable: true,
|
|
860
|
+
get: function() {
|
|
861
|
+
return serializeReport;
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
Object.defineProperty(exports, "typecheckPart", {
|
|
865
|
+
enumerable: true,
|
|
866
|
+
get: function() {
|
|
867
|
+
return typecheckPart;
|
|
868
|
+
}
|
|
869
|
+
});
|