@toolpath/dfm 0.3.1 → 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/README.md +47 -5
- package/dist/{chunk-5MPHT7BC.js → chunk-4IRNLDE6.js} +548 -142
- package/dist/{feature-record-BUoFFjN6.d.ts → feature-record-CfjgDCJU.d.ts} +195 -99
- package/dist/index.d.ts +18 -2
- package/dist/index.js +97 -76
- package/dist/model/index.d.ts +61 -15
- package/dist/model/index.js +575 -166
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
MILLING_RULES,
|
|
3
3
|
OPS,
|
|
4
4
|
PRESENCE_METRIC,
|
|
5
|
-
QUICK_METRICS,
|
|
6
|
-
QUICK_SUBJECTS,
|
|
7
5
|
RANGE_HIGHS,
|
|
8
6
|
RANGE_LOWS,
|
|
9
7
|
RULE_COLORS,
|
|
8
|
+
TURNING_RULES,
|
|
9
|
+
directionLabel,
|
|
10
10
|
featureRows,
|
|
11
11
|
featureTypeLabel,
|
|
12
12
|
formatMeasured,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
withMetric,
|
|
35
35
|
withOp,
|
|
36
36
|
withSubject
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-4IRNLDE6.js";
|
|
38
38
|
|
|
39
39
|
// src/rule-list/rule-list.tsx
|
|
40
40
|
import { useMemo as useMemo2, useState as useState8 } from "react";
|
|
@@ -73,17 +73,21 @@ var isField = (target) => target instanceof HTMLSelectElement || target instance
|
|
|
73
73
|
import { useState as useState2 } from "react";
|
|
74
74
|
|
|
75
75
|
// src/rule-list/options.ts
|
|
76
|
-
var subjectChoices = (current, all) => {
|
|
77
|
-
const
|
|
78
|
-
const
|
|
76
|
+
var subjectChoices = (current, all, vocabulary = MILLING_RULES) => {
|
|
77
|
+
const { quickSubjects } = vocabulary;
|
|
78
|
+
const quick = [...quickSubjects, ...quickSubjects.includes(current) ? [] : [current]];
|
|
79
|
+
const first = {
|
|
80
|
+
choices: quick.map((value) => ({ value, label: subjectLabel(value, vocabulary) }))
|
|
81
|
+
};
|
|
79
82
|
if (!all) return { groups: [first], more: "More feature types\u2026" };
|
|
80
|
-
const rest =
|
|
83
|
+
const rest = vocabulary.subjects.filter((each) => !quick.includes(each.value));
|
|
81
84
|
return { groups: [first, { heading: "More feature types", choices: rest }] };
|
|
82
85
|
};
|
|
83
|
-
var metricChoices = (subject, current, all) => {
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
quick.
|
|
86
|
+
var metricChoices = (subject, current, all, vocabulary = MILLING_RULES) => {
|
|
87
|
+
const { quickMetrics } = vocabulary;
|
|
88
|
+
const offered = metricsForSubject(subject, vocabulary);
|
|
89
|
+
const quick = offered.filter((each) => quickMetrics.includes(each.key) || each.key === current);
|
|
90
|
+
quick.sort((a, b) => rank(quickMetrics, a.key) - rank(quickMetrics, b.key));
|
|
87
91
|
const rest = offered.filter((each) => !quick.includes(each));
|
|
88
92
|
const first = { choices: quick.map(choice) };
|
|
89
93
|
if (!all) return { groups: [first], more: rest.length > 0 ? "More measures\u2026" : void 0 };
|
|
@@ -95,9 +99,9 @@ var metricChoices = (subject, current, all) => {
|
|
|
95
99
|
};
|
|
96
100
|
};
|
|
97
101
|
var choice = ({ key, label }) => ({ value: key, label });
|
|
98
|
-
var rank = (key) => {
|
|
99
|
-
const at =
|
|
100
|
-
return at === -1 ?
|
|
102
|
+
var rank = (quickMetrics, key) => {
|
|
103
|
+
const at = quickMetrics.indexOf(key);
|
|
104
|
+
return at === -1 ? quickMetrics.length : at;
|
|
101
105
|
};
|
|
102
106
|
var grouped = (items) => {
|
|
103
107
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -275,7 +279,10 @@ var keepKeys = (event) => {
|
|
|
275
279
|
|
|
276
280
|
// src/rule-list/new-rule.tsx
|
|
277
281
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
278
|
-
var NewRule = ({
|
|
282
|
+
var NewRule = ({
|
|
283
|
+
onAdd,
|
|
284
|
+
vocabulary
|
|
285
|
+
}) => {
|
|
279
286
|
const [all, setAll] = useState2(false);
|
|
280
287
|
return /* @__PURE__ */ jsxs2("li", { className: "flex items-start gap-1.5 py-1 pr-1.5", children: [
|
|
281
288
|
/* @__PURE__ */ jsx2("span", { "aria-hidden": true, className: "size-7 shrink-0" }),
|
|
@@ -292,7 +299,7 @@ var NewRule = ({ onAdd }) => {
|
|
|
292
299
|
label: "New rule",
|
|
293
300
|
placeholder: "+ New Rule",
|
|
294
301
|
value: "",
|
|
295
|
-
choices: subjectChoices("any", all),
|
|
302
|
+
choices: subjectChoices("any", all, vocabulary),
|
|
296
303
|
onChange: onAdd,
|
|
297
304
|
onMore: () => setAll(true),
|
|
298
305
|
className: "font-normal text-gray-400 dark:text-zinc-500"
|
|
@@ -309,23 +316,6 @@ import { IconButton, cn as cn7 } from "@toolpath/ui";
|
|
|
309
316
|
// src/rule-list/feature-rows.tsx
|
|
310
317
|
import { useMemo } from "react";
|
|
311
318
|
|
|
312
|
-
// src/rule-list/direction-label.ts
|
|
313
|
-
var EPSILON = 1e-6;
|
|
314
|
-
var trim = (value) => Number.parseFloat(value.toFixed(3)).toString();
|
|
315
|
-
var directionLabel = (direction) => {
|
|
316
|
-
const axes = [
|
|
317
|
-
["X", direction.x],
|
|
318
|
-
["Y", direction.y],
|
|
319
|
-
["Z", direction.z]
|
|
320
|
-
];
|
|
321
|
-
const nonZero = axes.filter(([, value]) => Math.abs(value) > EPSILON);
|
|
322
|
-
const [axis] = nonZero;
|
|
323
|
-
if (nonZero.length === 1 && axis && Math.abs(Math.abs(axis[1]) - 1) < EPSILON) {
|
|
324
|
-
return `${axis[1] > 0 ? "+" : "\u2212"}${axis[0]}`;
|
|
325
|
-
}
|
|
326
|
-
return axes.map(([, value]) => trim(value)).join(", ");
|
|
327
|
-
};
|
|
328
|
-
|
|
329
319
|
// src/rule-list/feature-button.tsx
|
|
330
320
|
import { cn as cn3 } from "@toolpath/ui";
|
|
331
321
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
@@ -347,6 +337,7 @@ var FeatureButton = ({
|
|
|
347
337
|
rule,
|
|
348
338
|
check,
|
|
349
339
|
units,
|
|
340
|
+
vocabulary,
|
|
350
341
|
selected,
|
|
351
342
|
selectedGroup,
|
|
352
343
|
onInspect,
|
|
@@ -354,6 +345,7 @@ var FeatureButton = ({
|
|
|
354
345
|
onBack
|
|
355
346
|
}) => {
|
|
356
347
|
const feature = featureOf.get(tag);
|
|
348
|
+
const { name, detail } = feature ? vocabulary.featureLabel(feature) : { name: "Feature", detail: "" };
|
|
357
349
|
return /* @__PURE__ */ jsxs3(
|
|
358
350
|
"button",
|
|
359
351
|
{
|
|
@@ -373,9 +365,9 @@ var FeatureButton = ({
|
|
|
373
365
|
className: FEATURE_ROW,
|
|
374
366
|
children: [
|
|
375
367
|
/* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1 truncate", children: [
|
|
376
|
-
|
|
368
|
+
name,
|
|
377
369
|
" ",
|
|
378
|
-
/* @__PURE__ */ jsx3("span", { className: "font-normal text-gray-300 dark:text-zinc-500", children:
|
|
370
|
+
/* @__PURE__ */ jsx3("span", { className: "font-normal text-gray-300 dark:text-zinc-500", children: detail })
|
|
379
371
|
] }),
|
|
380
372
|
/* @__PURE__ */ jsx3(HitFigure, { hit: ruleHit(check, rule, tag), units })
|
|
381
373
|
]
|
|
@@ -620,10 +612,11 @@ var RANGE_LOW = {
|
|
|
620
612
|
var RuleSentence = ({
|
|
621
613
|
rule,
|
|
622
614
|
units,
|
|
615
|
+
vocabulary,
|
|
623
616
|
onChange,
|
|
624
617
|
autoFocus
|
|
625
618
|
}) => {
|
|
626
|
-
const info = metricInfo(rule.metric);
|
|
619
|
+
const info = metricInfo(rule.metric, vocabulary);
|
|
627
620
|
const flag = info?.quantity === "flag" || info?.quantity === "presence";
|
|
628
621
|
const presence = info?.quantity === "presence";
|
|
629
622
|
const ranged = info !== void 0 && !flag && rule.op === "between";
|
|
@@ -637,8 +630,8 @@ var RuleSentence = ({
|
|
|
637
630
|
{
|
|
638
631
|
label: "Features",
|
|
639
632
|
value: rule.subject,
|
|
640
|
-
choices: subjectChoices(rule.subject, allSubjects),
|
|
641
|
-
onChange: (value) => onChange(withSubject(rule, value, units)),
|
|
633
|
+
choices: subjectChoices(rule.subject, allSubjects, vocabulary),
|
|
634
|
+
onChange: (value) => onChange(withSubject(rule, value, units, vocabulary)),
|
|
642
635
|
onMore: () => setAllSubjects(true)
|
|
643
636
|
}
|
|
644
637
|
),
|
|
@@ -677,8 +670,8 @@ var RuleSentence = ({
|
|
|
677
670
|
label: "Measure",
|
|
678
671
|
title: info?.hint,
|
|
679
672
|
value: rule.metric,
|
|
680
|
-
choices: metricChoices(rule.subject, rule.metric, allMetrics),
|
|
681
|
-
onChange: (value) => onChange(withMetric(rule, value, units)),
|
|
673
|
+
choices: metricChoices(rule.subject, rule.metric, allMetrics, vocabulary),
|
|
674
|
+
onChange: (value) => onChange(withMetric(rule, value, units, vocabulary)),
|
|
682
675
|
onMore: () => setAllMetrics(true),
|
|
683
676
|
autoFocus
|
|
684
677
|
}
|
|
@@ -775,6 +768,7 @@ var RuleRow = ({
|
|
|
775
768
|
features,
|
|
776
769
|
sheets,
|
|
777
770
|
units,
|
|
771
|
+
vocabulary,
|
|
778
772
|
...list
|
|
779
773
|
}) => {
|
|
780
774
|
const [picking, setPicking] = useState6(false);
|
|
@@ -846,7 +840,16 @@ var RuleRow = ({
|
|
|
846
840
|
className: "mt-1.5"
|
|
847
841
|
}
|
|
848
842
|
),
|
|
849
|
-
/* @__PURE__ */ jsx10(
|
|
843
|
+
/* @__PURE__ */ jsx10(
|
|
844
|
+
RuleSentence,
|
|
845
|
+
{
|
|
846
|
+
rule,
|
|
847
|
+
units,
|
|
848
|
+
vocabulary,
|
|
849
|
+
onChange,
|
|
850
|
+
autoFocus: focusOnMount
|
|
851
|
+
}
|
|
852
|
+
),
|
|
850
853
|
/* @__PURE__ */ jsxs7("div", { className: "relative mt-1 shrink-0", children: [
|
|
851
854
|
/* @__PURE__ */ jsx10(
|
|
852
855
|
IconButton,
|
|
@@ -900,6 +903,7 @@ var RuleRow = ({
|
|
|
900
903
|
features,
|
|
901
904
|
sheets,
|
|
902
905
|
units,
|
|
906
|
+
vocabulary,
|
|
903
907
|
onBack: () => swatchRef.current?.focus(),
|
|
904
908
|
...list
|
|
905
909
|
}
|
|
@@ -960,11 +964,7 @@ var useTimedValue = (ms) => {
|
|
|
960
964
|
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
961
965
|
var NOTE_MS = 4e3;
|
|
962
966
|
var COPIED_MS = 2e3;
|
|
963
|
-
var
|
|
964
|
-
var RuleSetActions = ({
|
|
965
|
-
rules,
|
|
966
|
-
actions
|
|
967
|
-
}) => {
|
|
967
|
+
var RuleSetActions = ({ rules, actions, vocabulary }) => {
|
|
968
968
|
const [note, setNote] = useTimedValue(NOTE_MS);
|
|
969
969
|
const [copied, setCopied] = useTimedValue(COPIED_MS);
|
|
970
970
|
const fileInput = useRef4(null);
|
|
@@ -977,7 +977,7 @@ var RuleSetActions = ({
|
|
|
977
977
|
setNote("Could not import: the file could not be read.");
|
|
978
978
|
return;
|
|
979
979
|
}
|
|
980
|
-
const read = parseRuleSetFile(text);
|
|
980
|
+
const read = parseRuleSetFile(text, vocabulary);
|
|
981
981
|
if ("error" in read) {
|
|
982
982
|
setNote(`Could not import: ${read.error}`);
|
|
983
983
|
return;
|
|
@@ -987,7 +987,7 @@ var RuleSetActions = ({
|
|
|
987
987
|
};
|
|
988
988
|
const copyPrompt = async () => {
|
|
989
989
|
try {
|
|
990
|
-
await navigator.clipboard.writeText(llmRulePrompt(rules.rules));
|
|
990
|
+
await navigator.clipboard.writeText(llmRulePrompt(rules.rules, vocabulary));
|
|
991
991
|
} catch {
|
|
992
992
|
setNote("Could not copy the prompt. Allow clipboard access and try again.");
|
|
993
993
|
return;
|
|
@@ -998,7 +998,7 @@ var RuleSetActions = ({
|
|
|
998
998
|
return /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2 px-4 pt-2 pb-3", children: [
|
|
999
999
|
/* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
1000
1000
|
/* @__PURE__ */ jsx11(Button, { variant: "secondary", onClick: () => fileInput.current?.click(), children: /* @__PURE__ */ jsx11(ActionLabel, { icon: /* @__PURE__ */ jsx11(UploadSimpleIcon, { weight: "bold" }), children: "Import\u2026" }) }),
|
|
1001
|
-
/* @__PURE__ */ jsx11(Button, { variant: "secondary", onClick: () => downloadRuleSet(rules), children: /* @__PURE__ */ jsx11(ActionLabel, { icon: /* @__PURE__ */ jsx11(DownloadSimpleIcon, { weight: "bold" }), children: "Export" }) }),
|
|
1001
|
+
/* @__PURE__ */ jsx11(Button, { variant: "secondary", onClick: () => downloadRuleSet(rules, vocabulary), children: /* @__PURE__ */ jsx11(ActionLabel, { icon: /* @__PURE__ */ jsx11(DownloadSimpleIcon, { weight: "bold" }), children: "Export" }) }),
|
|
1002
1002
|
/* @__PURE__ */ jsx11(
|
|
1003
1003
|
Button,
|
|
1004
1004
|
{
|
|
@@ -1041,13 +1041,13 @@ var ActionLabel = ({ icon, children, hidden = false }) => /* @__PURE__ */ jsxs8(
|
|
|
1041
1041
|
]
|
|
1042
1042
|
}
|
|
1043
1043
|
);
|
|
1044
|
-
var downloadRuleSet = (rules) => {
|
|
1044
|
+
var downloadRuleSet = (rules, vocabulary) => {
|
|
1045
1045
|
const url = URL.createObjectURL(
|
|
1046
|
-
new Blob([serializeRuleSet(rules.rules)], { type: "application/json" })
|
|
1046
|
+
new Blob([serializeRuleSet(rules.rules, {}, vocabulary)], { type: "application/json" })
|
|
1047
1047
|
);
|
|
1048
1048
|
const link = document.createElement("a");
|
|
1049
1049
|
link.href = url;
|
|
1050
|
-
link.download =
|
|
1050
|
+
link.download = vocabulary.fileName;
|
|
1051
1051
|
link.click();
|
|
1052
1052
|
URL.revokeObjectURL(url);
|
|
1053
1053
|
};
|
|
@@ -1068,6 +1068,7 @@ var RuleList = ({
|
|
|
1068
1068
|
sheets,
|
|
1069
1069
|
units,
|
|
1070
1070
|
actions,
|
|
1071
|
+
vocabulary = MILLING_RULES,
|
|
1071
1072
|
...list
|
|
1072
1073
|
}) => {
|
|
1073
1074
|
const [openIds, setOpenIds] = useState8(/* @__PURE__ */ new Set());
|
|
@@ -1102,6 +1103,7 @@ var RuleList = ({
|
|
|
1102
1103
|
features,
|
|
1103
1104
|
sheets,
|
|
1104
1105
|
units,
|
|
1106
|
+
vocabulary,
|
|
1105
1107
|
...list
|
|
1106
1108
|
},
|
|
1107
1109
|
rule.id
|
|
@@ -1115,15 +1117,16 @@ var RuleList = ({
|
|
|
1115
1117
|
/* @__PURE__ */ jsx12(
|
|
1116
1118
|
NewRule,
|
|
1117
1119
|
{
|
|
1120
|
+
vocabulary,
|
|
1118
1121
|
onAdd: (subject) => {
|
|
1119
|
-
const rule = makeRule(subject, PRESENCE_METRIC.key, units);
|
|
1122
|
+
const rule = makeRule(subject, PRESENCE_METRIC.key, units, void 0, vocabulary);
|
|
1120
1123
|
rules.add(rule);
|
|
1121
1124
|
setAdded(rule.id);
|
|
1122
1125
|
}
|
|
1123
1126
|
}
|
|
1124
1127
|
)
|
|
1125
1128
|
] }),
|
|
1126
|
-
/* @__PURE__ */ jsx12(RuleSetActions, { rules, actions })
|
|
1129
|
+
/* @__PURE__ */ jsx12(RuleSetActions, { rules, actions, vocabulary })
|
|
1127
1130
|
] })
|
|
1128
1131
|
);
|
|
1129
1132
|
};
|
|
@@ -1799,14 +1802,16 @@ var faintText = (look) => look.muted === "strong" ? "text-gray dark:text-zinc-30
|
|
|
1799
1802
|
|
|
1800
1803
|
// src/feature-panel/feature-name.tsx
|
|
1801
1804
|
import { Fragment as Fragment7, jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1802
|
-
var FeatureName = ({ feature, label, look }) =>
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
] })
|
|
1805
|
+
var FeatureName = ({ feature, label, look, vocabulary = MILLING_RULES }) => {
|
|
1806
|
+
const { name, detail } = vocabulary.featureLabel(feature);
|
|
1807
|
+
return /* @__PURE__ */ jsxs14(Fragment7, { children: [
|
|
1808
|
+
label ?? name,
|
|
1809
|
+
detail ? /* @__PURE__ */ jsxs14(Fragment7, { children: [
|
|
1810
|
+
" ",
|
|
1811
|
+
/* @__PURE__ */ jsx17("span", { className: cn9("font-normal", faintText(look)), children: detail })
|
|
1812
|
+
] }) : null
|
|
1813
|
+
] });
|
|
1814
|
+
};
|
|
1810
1815
|
var RequiredBadge = () => /* @__PURE__ */ jsx17("span", { className: "rounded-full bg-gray-100 px-1.5 text-2xs font-semibold text-gray-500 uppercase dark:bg-zinc-800 dark:text-zinc-300", children: "Required" });
|
|
1811
1816
|
|
|
1812
1817
|
// src/feature-panel/fold-section.tsx
|
|
@@ -2120,10 +2125,12 @@ var FeatureDetails = ({
|
|
|
2120
2125
|
record,
|
|
2121
2126
|
PopOut,
|
|
2122
2127
|
look: lookOption,
|
|
2123
|
-
folds
|
|
2128
|
+
folds,
|
|
2129
|
+
vocabulary = MILLING_RULES
|
|
2124
2130
|
}) => {
|
|
2125
2131
|
const look = resolveLook(lookOption);
|
|
2126
|
-
const name = /* @__PURE__ */ jsx22(FeatureName, { feature, label, look });
|
|
2132
|
+
const name = /* @__PURE__ */ jsx22(FeatureName, { feature, label, look, vocabulary });
|
|
2133
|
+
const { detail: cutFrom } = vocabulary.featureLabel(feature);
|
|
2127
2134
|
const [out, setOut] = useState13(/* @__PURE__ */ new Set());
|
|
2128
2135
|
const openOut = useCallback2((id) => setOut((was) => new Set(was).add(id)), []);
|
|
2129
2136
|
const closeOut = useCallback2(
|
|
@@ -2142,8 +2149,7 @@ var FeatureDetails = ({
|
|
|
2142
2149
|
/* @__PURE__ */ jsx22("h3", { className: "truncate text-sm font-semibold text-gray-600 dark:text-zinc-100", children: name }),
|
|
2143
2150
|
/* @__PURE__ */ jsxs19("p", { className: cn12("flex flex-wrap items-center gap-1.5 text-xs", secondaryText(look)), children: [
|
|
2144
2151
|
/* @__PURE__ */ jsx22(Swatch, { color: directionColor, className: "size-2.5" }),
|
|
2145
|
-
|
|
2146
|
-
directionLabel(feature.machiningDirection),
|
|
2152
|
+
cutFrom ? `Machined ${cutFrom}` : "Machined",
|
|
2147
2153
|
required ? /* @__PURE__ */ jsx22(RequiredBadge, {}) : null,
|
|
2148
2154
|
status
|
|
2149
2155
|
] })
|
|
@@ -2157,7 +2163,15 @@ var FeatureDetails = ({
|
|
|
2157
2163
|
children
|
|
2158
2164
|
] }),
|
|
2159
2165
|
/* @__PURE__ */ jsx22(FoldSection, { id: "rules", title: "Rules broken", folds, children: /* @__PURE__ */ jsx22(BrokenRuleList, { rules, look }) }),
|
|
2160
|
-
/* @__PURE__ */ jsx22(
|
|
2166
|
+
/* @__PURE__ */ jsx22(
|
|
2167
|
+
MeasurementSections,
|
|
2168
|
+
{
|
|
2169
|
+
measurements,
|
|
2170
|
+
considerationsTitle: vocabulary.considerationsTitle,
|
|
2171
|
+
look,
|
|
2172
|
+
folds
|
|
2173
|
+
}
|
|
2174
|
+
),
|
|
2161
2175
|
/* @__PURE__ */ jsx22(
|
|
2162
2176
|
ReachSection2,
|
|
2163
2177
|
{
|
|
@@ -2221,7 +2235,7 @@ var Explained = ({ note, children }) => note ? /* @__PURE__ */ jsx22(Tooltip, {
|
|
|
2221
2235
|
}
|
|
2222
2236
|
) }) : children;
|
|
2223
2237
|
var None = ({ look }) => /* @__PURE__ */ jsx22("p", { className: cn12("text-sm", secondaryText(look)), children: "None" });
|
|
2224
|
-
var MeasurementSections = ({ measurements, look, folds }) => {
|
|
2238
|
+
var MeasurementSections = ({ measurements, considerationsTitle, look, folds }) => {
|
|
2225
2239
|
if (measurements.status !== "ready") {
|
|
2226
2240
|
return /* @__PURE__ */ jsx22(Fragment10, { children: /* @__PURE__ */ jsx22(FoldSection, { id: "measurements", title: "Measurements", folds, children: measurements.status === "loading" ? /* @__PURE__ */ jsx22(Reading, { children: "Reading the feature\u2019s datasheet\u2026" }) : /* @__PURE__ */ jsx22(ReadFailure, { failure: measurements }) }) });
|
|
2227
2241
|
}
|
|
@@ -2229,7 +2243,7 @@ var MeasurementSections = ({ measurements, look, folds }) => {
|
|
|
2229
2243
|
const milling = measurements.value.filter((row) => row.milling);
|
|
2230
2244
|
return /* @__PURE__ */ jsxs19(Fragment10, { children: [
|
|
2231
2245
|
/* @__PURE__ */ jsx22(FoldSection, { id: "measurements", title: "Measurements", folds, children: /* @__PURE__ */ jsx22(MeasurementList, { rows: measured, look }) }),
|
|
2232
|
-
milling.length > 0 ? /* @__PURE__ */ jsx22(FoldSection, { id: "milling", title:
|
|
2246
|
+
milling.length > 0 ? /* @__PURE__ */ jsx22(FoldSection, { id: "milling", title: considerationsTitle, folds, children: /* @__PURE__ */ jsx22(MeasurementList, { rows: milling, look }) }) : null
|
|
2233
2247
|
] });
|
|
2234
2248
|
};
|
|
2235
2249
|
var MeasurementList = ({ rows, look }) => rows.length > 0 ? /* @__PURE__ */ jsx22("dl", { className: "grid grid-cols-[1fr_auto] items-center gap-x-3 gap-y-1 text-sm", children: rows.map((row) => /* @__PURE__ */ jsxs19("div", { className: "contents", children: [
|
|
@@ -2297,7 +2311,8 @@ var CandidateList = ({
|
|
|
2297
2311
|
onHover,
|
|
2298
2312
|
face,
|
|
2299
2313
|
look: lookOption,
|
|
2300
|
-
folds
|
|
2314
|
+
folds,
|
|
2315
|
+
vocabulary
|
|
2301
2316
|
}) => {
|
|
2302
2317
|
const look = resolveLook(lookOption);
|
|
2303
2318
|
const count = `Candidate features (${rows.length})`;
|
|
@@ -2328,14 +2343,15 @@ var CandidateList = ({
|
|
|
2328
2343
|
chosen: row.feature.tag === selected,
|
|
2329
2344
|
onSelect,
|
|
2330
2345
|
onHover,
|
|
2331
|
-
look
|
|
2346
|
+
look,
|
|
2347
|
+
vocabulary
|
|
2332
2348
|
},
|
|
2333
2349
|
row.feature.tag
|
|
2334
2350
|
)) })
|
|
2335
2351
|
}
|
|
2336
2352
|
) });
|
|
2337
2353
|
};
|
|
2338
|
-
var Row = ({ row, chosen, onSelect, onHover, look }) => {
|
|
2354
|
+
var Row = ({ row, chosen, onSelect, onHover, look, vocabulary }) => {
|
|
2339
2355
|
const { feature } = row;
|
|
2340
2356
|
const info = look.selected === "info";
|
|
2341
2357
|
return /* @__PURE__ */ jsxs20(
|
|
@@ -2367,7 +2383,7 @@ var Row = ({ row, chosen, onSelect, onHover, look }) => {
|
|
|
2367
2383
|
children: [
|
|
2368
2384
|
/* @__PURE__ */ jsxs20("span", { className: "flex w-full items-center gap-2", children: [
|
|
2369
2385
|
row.color ? /* @__PURE__ */ jsx23(Swatch, { color: row.color }) : /* @__PURE__ */ jsx23("span", { "aria-hidden": true, className: "size-4 shrink-0" }),
|
|
2370
|
-
/* @__PURE__ */ jsx23("span", { className: "min-w-0 flex-1 truncate", children: /* @__PURE__ */ jsx23(FeatureName, { feature, label: row.label, look }) }),
|
|
2386
|
+
/* @__PURE__ */ jsx23("span", { className: "min-w-0 flex-1 truncate", children: /* @__PURE__ */ jsx23(FeatureName, { feature, label: row.label, look, vocabulary }) }),
|
|
2371
2387
|
row.ruleCount ? /* @__PURE__ */ jsxs20("span", { className: cn13("text-2xs tabular-nums", secondaryText(look)), children: [
|
|
2372
2388
|
row.ruleCount,
|
|
2373
2389
|
" ",
|
|
@@ -2527,6 +2543,7 @@ var FeaturePanel = ({
|
|
|
2527
2543
|
className,
|
|
2528
2544
|
look: lookOption,
|
|
2529
2545
|
folds,
|
|
2546
|
+
vocabulary,
|
|
2530
2547
|
children
|
|
2531
2548
|
}) => {
|
|
2532
2549
|
const look = resolveLook(lookOption);
|
|
@@ -2579,7 +2596,8 @@ var FeaturePanel = ({
|
|
|
2579
2596
|
...onDropFace ? { onStop: () => onDropFace(index) } : {}
|
|
2580
2597
|
},
|
|
2581
2598
|
look: lookOption,
|
|
2582
|
-
folds
|
|
2599
|
+
folds,
|
|
2600
|
+
vocabulary
|
|
2583
2601
|
},
|
|
2584
2602
|
`${each.region ?? "list"}-${index}`
|
|
2585
2603
|
)),
|
|
@@ -2602,7 +2620,8 @@ var FeaturePanel = ({
|
|
|
2602
2620
|
onSelect: (tag) => onSelect(tag, active),
|
|
2603
2621
|
onHover,
|
|
2604
2622
|
look: lookOption,
|
|
2605
|
-
folds
|
|
2623
|
+
folds,
|
|
2624
|
+
vocabulary
|
|
2606
2625
|
}
|
|
2607
2626
|
) : null,
|
|
2608
2627
|
face?.selected ? children : /* @__PURE__ */ jsx25("p", { className: cn15("px-4 py-3 text-sm", secondaryText(look)), children: face && face.rows.length > 0 ? "Choose a feature to read its details." : "No feature owns this face." })
|
|
@@ -2616,10 +2635,12 @@ export {
|
|
|
2616
2635
|
ComparisonTable,
|
|
2617
2636
|
FeatureDetails,
|
|
2618
2637
|
FeaturePanel,
|
|
2638
|
+
MILLING_RULES,
|
|
2619
2639
|
ReachChart,
|
|
2620
2640
|
ReachDrawing,
|
|
2621
2641
|
RuleList,
|
|
2622
2642
|
Swatch,
|
|
2643
|
+
TURNING_RULES,
|
|
2623
2644
|
candidateListKeys,
|
|
2624
2645
|
isField,
|
|
2625
2646
|
listKeys,
|
package/dist/model/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { B as BrokenRule, C as CRITICAL_COLOR,
|
|
1
|
+
import { h as DfmHit, U as Units, i as FeaturePinch, j as FeatureSheet, g as RuleProcess, D as DfmRule, R as RuleVocabulary, b as DfmFeature, a as DfmCheck } from '../feature-record-CfjgDCJU.js';
|
|
2
|
+
export { B as BrokenRule, C as CRITICAL_COLOR, k as ClearanceFit, l as DfmMetric, m as DfmOp, n as DfmQuantity, o as DfmSources, p as DfmSubject, q as FactsKind, r as FeatureAcross, d as FeatureProfile, e as FeatureRecord, F as FeatureSheets, s as FeatureThreading, t as FeatureUndercut, f as MILLING_RULES, M as Measurement, P as PINCH_TOOL_MM, u as PinchDisc, v as RULE_COLORS, w as RangeHigh, x as RangeLow, c as ReachCurve, y as ReportFeature, z as RuleResult, S as SurfaceToolKind, T as TURNING_RULES, A as TurnedFactsKind, W as WARNING_COLOR, E as brokenRules, G as checkPart, H as compareColors, I as describeRule, J as dfmFeatures, K as featureColor, L as featureMeasurements, N as featureProfile, O as featureSheet, Q as featureTypeLabel, V as isNoReading, X as isSurfaceType, Y as makeRule, Z as maxBallDiameter, _ as parseRules, $ as peakHeight, a0 as readPinch, a1 as readReachCurve, a2 as runStart, a3 as trimmedCurve, a4 as turnedTypeLabel, a5 as withSurroundedFaces } from '../feature-record-CfjgDCJU.js';
|
|
3
3
|
|
|
4
4
|
/** The figure that broke a rule, bare: `7.5`, `0.05"`. Empty for a yes/no or "any size". */
|
|
5
5
|
declare const hitFigure: (hit: DfmHit, units: Units) => string;
|
|
@@ -87,6 +87,11 @@ interface RuleSetFile {
|
|
|
87
87
|
kind: typeof FILE_KIND;
|
|
88
88
|
/** The file format's version, for a later reader. */
|
|
89
89
|
version: 1;
|
|
90
|
+
/**
|
|
91
|
+
* Which rules these are: milled features' or turned ones'. Always written;
|
|
92
|
+
* a file without it was written before turning rules, so it is milling.
|
|
93
|
+
*/
|
|
94
|
+
process?: RuleProcess;
|
|
90
95
|
/** What the set is for: "Aluminium prototypes", "Acme Corp sheet work". */
|
|
91
96
|
name?: string;
|
|
92
97
|
description?: string;
|
|
@@ -95,21 +100,23 @@ interface RuleSetFile {
|
|
|
95
100
|
rules: DfmRule[];
|
|
96
101
|
}
|
|
97
102
|
declare const FILE_KIND = "toolpath-dfm-rules";
|
|
98
|
-
/** The rules as a file, pretty-printed. */
|
|
103
|
+
/** The rules as a file, pretty-printed, saying which process they are for. */
|
|
99
104
|
declare const serializeRuleSet: (rules: readonly DfmRule[], meta?: {
|
|
100
105
|
name?: string;
|
|
101
106
|
description?: string;
|
|
102
|
-
}) => string;
|
|
107
|
+
}, vocabulary?: RuleVocabulary) => string;
|
|
103
108
|
/**
|
|
104
109
|
* The rules in a file, or the reason it cannot be read. Lenient about the
|
|
105
110
|
* wrapper — a bare array of rules is accepted, and so is an object with a
|
|
106
111
|
* `rules` list and nothing else, since an LLM may well hand back either —
|
|
107
|
-
* strict about every rule, which `parseRules` checks field by field
|
|
108
|
-
* without an id, or whose ids collide, are given
|
|
109
|
-
* its lengths are in anything but millimetres is
|
|
110
|
-
* millimetres; one that does not say is read as
|
|
112
|
+
* strict about every rule, which `parseRules` checks field by field in the
|
|
113
|
+
* vocabulary given. Rules without an id, or whose ids collide, are given
|
|
114
|
+
* fresh ones. A file that says its lengths are in anything but millimetres is
|
|
115
|
+
* refused rather than read as millimetres; one that does not say is read as
|
|
116
|
+
* millimetres. A file of the other process's rules is refused, saying where it
|
|
117
|
+
* belongs, rather than read as rules it is not.
|
|
111
118
|
*/
|
|
112
|
-
declare const parseRuleSetFile: (text: string) => {
|
|
119
|
+
declare const parseRuleSetFile: (text: string, vocabulary?: RuleVocabulary) => {
|
|
113
120
|
rules: DfmRule[];
|
|
114
121
|
skipped: number;
|
|
115
122
|
name?: string;
|
|
@@ -118,11 +125,50 @@ declare const parseRuleSetFile: (text: string) => {
|
|
|
118
125
|
};
|
|
119
126
|
/**
|
|
120
127
|
* A prompt that lets any LLM interview a user and write a rule set this
|
|
121
|
-
* viewer reads. Built from the metric and
|
|
122
|
-
* never drifts from what the parser accepts:
|
|
123
|
-
* metric key with its unit and meaning and the
|
|
124
|
-
* it, every comparison, and the palette.
|
|
128
|
+
* viewer reads, for one process. Built from the vocabulary's metric and
|
|
129
|
+
* subject tables themselves, so it never drifts from what the parser accepts:
|
|
130
|
+
* every subject value, every metric key with its unit and meaning and the
|
|
131
|
+
* kinds of feature that report it, every comparison, and the palette.
|
|
132
|
+
*/
|
|
133
|
+
declare const llmRulePrompt: (current?: readonly DfmRule[], vocabulary?: RuleVocabulary) => string;
|
|
134
|
+
|
|
135
|
+
/** The end of the part a turned feature is cut from: the end the axis points toward, or the other. */
|
|
136
|
+
type TurnedApproach = 'PlusZ' | 'MinusZ';
|
|
137
|
+
/**
|
|
138
|
+
* A turned feature as the Engine's report gives it, cut down to what the
|
|
139
|
+
* rules read. `@toolpath/api`'s `TurnedFeature` is one, so the package takes
|
|
140
|
+
* no dependency on the SDK for a type.
|
|
141
|
+
*/
|
|
142
|
+
interface TurnedReportFeature {
|
|
143
|
+
readonly featureTag: string;
|
|
144
|
+
/** Snake case, open-ended: `od_groove`. */
|
|
145
|
+
readonly featureType: string;
|
|
146
|
+
/** The end it is cut from; null or absent on older reports, and for an `unknown` feature. */
|
|
147
|
+
readonly approach?: TurnedApproach | null;
|
|
148
|
+
readonly regionIdxs: readonly number[];
|
|
149
|
+
/** Its turning datasheet as the API sent it, or null where it was not measured. */
|
|
150
|
+
readonly datasheet: unknown;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* One stretch of a turned part: its per-end copies as one feature, named by
|
|
154
|
+
* the first copy's tag. Its machining direction is along the axis toward the
|
|
155
|
+
* end it is cut from — `+Z` or `−Z` — and zero where it is cut from both or
|
|
156
|
+
* neither; it is there to make a stretch a `DfmFeature`, not to be read.
|
|
157
|
+
*/
|
|
158
|
+
interface TurnedStretch extends DfmFeature {
|
|
159
|
+
/** The report's features it was merged from, in the report's order. */
|
|
160
|
+
readonly copies: readonly TurnedReportFeature[];
|
|
161
|
+
/** The ends it is cut from, in the order its copies give them. */
|
|
162
|
+
readonly approaches: readonly TurnedApproach[];
|
|
163
|
+
}
|
|
164
|
+
/** The report's turned features with each stretch's per-end copies merged, in the order each first comes. */
|
|
165
|
+
declare const turnedStretches: (features: readonly TurnedReportFeature[]) => TurnedStretch[];
|
|
166
|
+
/**
|
|
167
|
+
* Checks every stretch of a turned part against turning rules. Every stretch
|
|
168
|
+
* is required — a turned part has one reading of each face — so `otherTags`
|
|
169
|
+
* is always empty and nothing is painted whole; each broken stretch's faces
|
|
170
|
+
* are painted its worst rule's colour.
|
|
125
171
|
*/
|
|
126
|
-
declare const
|
|
172
|
+
declare const checkTurnedPart: (stretches: readonly TurnedStretch[], rules: readonly DfmRule[]) => DfmCheck;
|
|
127
173
|
|
|
128
|
-
export { DfmHit, DfmRule, FILE_KIND, type FaceTriangles, FeaturePinch, FeatureSheet, type PinchMark, type PlacedTool, type RuleSetFile, Units, type Vec3, hitFigure, llmRulePrompt, parseRuleSetFile, pinchLabel, pinchMark, placePinchTool, sameDepth, serializeRuleSet };
|
|
174
|
+
export { DfmCheck, DfmFeature, DfmHit, DfmRule, FILE_KIND, type FaceTriangles, FeaturePinch, FeatureSheet, type PinchMark, type PlacedTool, RuleProcess, type RuleSetFile, RuleVocabulary, type TurnedReportFeature, type TurnedStretch, Units, type Vec3, checkTurnedPart, hitFigure, llmRulePrompt, parseRuleSetFile, pinchLabel, pinchMark, placePinchTool, sameDepth, serializeRuleSet, turnedStretches };
|