makearmy-app/lib/laser-finder.ts
2025-09-22 18:51:12 -04:00

187 lines
7.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// lib/laser-finder.ts
export type LaserType = "fiber" | "co2_gantry" | "co2_galvo" | "uv";
export const LASER_LABEL: Record<LaserType, string> = {
fiber: "Fiber (MOPA/QR)",
co2_gantry: "CO₂ Gantry",
co2_galvo: "CO₂ Galvo",
uv: "UV (355 nm)",
};
export const TYPE_INFO: Record<
LaserType,
{
summary: string;
bestFor: string[]; // show as tags
materials: string[]; // show as tags
cautions: string[]; // negatives / limits
learnLink: string; // link to your settings pages
}
> = {
fiber: {
summary:
"Best for marking/engraving bare metals, color marking on stainless (MOPA), and high-throughput galvo jobs.",
bestFor: [
"Bare metal marking",
"Deep engraving on metals",
"Color marking stainless",
"Serials/QR/codes on parts",
],
materials: ["Steel", "Stainless", "Aluminum", "Brass", "Titanium"],
cautions: [
"Not for cutting wood/acrylic",
"Limited on organics/plastics (unless additives/coatings)",
],
learnLink: "/fiber-settings",
},
co2_gantry: {
summary:
"Large work area; best for cutting & engraving non-metals (wood, acrylic, leather, textiles).",
bestFor: ["Thick acrylic cuts", "Wood cutting/engraving", "Signage", "Textiles"],
materials: ["Wood", "Acrylic", "Leather", "Paper", "Textiles", "Rubber"],
cautions: [
"Poor on bare metals without coatings",
"Slower for fine micro-engraving",
],
learnLink: "/co2-gantry-settings",
},
co2_galvo: {
summary:
"High-speed CO₂ marking/engraving on organics/non-metals with small scan fields.",
bestFor: ["Fast marking on organics", "Photo engraving on wood/leather", "High throughput"],
materials: ["Wood", "Leather", "Paper/Card", "Anodized/painted items"],
cautions: [
"Small scan field vs gantry",
"Not for cutting thick sheets",
"Poor on bare metals",
],
learnLink: "/co2-galvo-settings",
},
uv: {
summary:
"Ultra-fine marking/engraving on plastics, glass, ceramics; low heat-affected zone for micro features.",
bestFor: ["Micro text/logos", "Fine plastic marking", "Glass/ceramic marking"],
materials: ["Plastics", "Glass", "Ceramics", "PCB/silicon (marking)"],
cautions: [
"Typically lower power; not for thick cutting",
"Higher $/W, smaller working areas",
],
learnLink: "/uv-settings",
},
};
export type Answers = {
materials: Array<
| "metals_bare"
| "metals_coated"
| "plastics"
| "wood_paper_leather"
| "glass_ceramic"
| "stone"
| "textiles"
>;
operations: Array<
| "deep_mark_metal"
| "color_mark_stainless"
| "fine_engraving"
| "photo_engrave"
| "cut_nonmetals_thick"
| "cut_nonmetals_thin"
| "mark_coated"
>;
part_size: "small" | "medium" | "large"; // ~ scan field or bed
detail: "low" | "medium" | "high" | "micro";
throughput: "low" | "medium" | "high";
budget: "low" | "mid" | "high";
};
type Score = Record<LaserType, number>;
const bump = (s: Score, k: LaserType, n: number) => (s[k] += n);
export function scoreAnswers(a: Answers): {
score: Score;
ranked: LaserType[];
why: Record<LaserType, string[]>;
} {
const s: Score = { fiber: 0, co2_gantry: 0, co2_galvo: 0, uv: 0 };
const why: Record<LaserType, string[]> = {
fiber: [],
co2_gantry: [],
co2_galvo: [],
uv: [],
};
// Materials
if (a.materials.includes("metals_bare")) {
bump(s, "fiber", 6); why.fiber.push("Bare metals benefit from fiber.");
bump(s, "uv", 2); why.uv.push("UV can mark some metals with fine detail.");
bump(s, "co2_gantry", -3);
bump(s, "co2_galvo", -3);
}
if (a.materials.includes("metals_coated")) {
bump(s, "fiber", 3); why.fiber.push("Coated metals are fiber-friendly.");
bump(s, "uv", 2); why.uv.push("UV works well on coatings and labels.");
bump(s, "co2_galvo", 1); why.co2_galvo.push("CO₂ galvo can mark coated items quickly.");
}
if (a.materials.includes("plastics") || a.materials.includes("wood_paper_leather")) {
bump(s, "co2_gantry", 3); why.co2_gantry.push("Organics & plastics suit CO₂ gantry cutting/engraving.");
bump(s, "co2_galvo", 3); why.co2_galvo.push("CO₂ galvo is fast for organic marking.");
bump(s, "uv", 1); why.uv.push("UV excels at fine marking plastics.");
}
if (a.materials.includes("glass_ceramic")) {
bump(s, "uv", 4); why.uv.push("Glass/ceramic: UV has low HAZ for crisp marks.");
bump(s, "co2_galvo", 1);
}
if (a.materials.includes("textiles")) {
bump(s, "co2_gantry", 3); why.co2_gantry.push("Textiles: CO₂ gantry handles larger panels.");
}
if (a.materials.includes("stone")) {
bump(s, "co2_gantry", 1); bump(s, "co2_galvo", 1);
}
// Operations
if (a.operations.includes("deep_mark_metal")) { bump(s, "fiber", 5); why.fiber.push("Deep metal marking favors fiber."); }
if (a.operations.includes("color_mark_stainless")) { bump(s, "fiber", 5); why.fiber.push("Color marking stainless = MOPA fiber."); }
if (a.operations.includes("fine_engraving")) {
bump(s, "uv", 4); why.uv.push("Micro features need UVs small spot.");
bump(s, "fiber", 2); why.fiber.push("Fiber can achieve fine detail on metals.");
bump(s, "co2_galvo", 2);
}
if (a.operations.includes("photo_engrave")) {
bump(s, "uv", 3); why.uv.push("UV gives clean dithers on many materials.");
bump(s, "co2_galvo", 2); why.co2_galvo.push("CO₂ galvo is common for photo engraving organics.");
}
if (a.operations.includes("cut_nonmetals_thick")) { bump(s, "co2_gantry", 6); why.co2_gantry.push("Thick cutting needs gantry CO₂."); }
if (a.operations.includes("cut_nonmetals_thin")) {
bump(s, "co2_gantry", 3); why.co2_gantry.push("Thin cutting works well on gantry CO₂.");
bump(s, "co2_galvo", 2);
}
if (a.operations.includes("mark_coated")) {
bump(s, "fiber", 2); why.fiber.push("Coated marks are straightforward on fiber.");
bump(s, "uv", 2); why.uv.push("UV marks coatings with low HAZ.");
bump(s, "co2_galvo", 1);
}
// Part size & throughput
if (a.part_size === "large") { bump(s, "co2_gantry", 5); why.co2_gantry.push("Large work area points to gantry CO₂."); }
if (a.part_size === "small") { bump(s, "co2_galvo", 2); }
if (a.throughput === "high") {
bump(s, "co2_galvo", 3); why.co2_galvo.push("High throughput favors galvo systems.");
bump(s, "fiber", 2); why.fiber.push("Fiber galvos are fast on metals.");
}
// Detail requirement
if (a.detail === "micro") {
bump(s, "uv", 5); why.uv.push("Micro detail → UVs spot and short wavelength.");
bump(s, "fiber", 2);
} else if (a.detail === "high") {
bump(s, "uv", 3); bump(s, "fiber", 2); bump(s, "co2_galvo", 1);
}
// Budget (very soft tie-breaker)
if (a.budget === "low") bump(s, "co2_gantry", 1);
if (a.budget === "high") { bump(s, "fiber", 1); bump(s, "uv", 1); }
const ranked = (Object.keys(s) as LaserType[]).sort((x, y) => s[y] - s[x]);
return { score: s, ranked, why };
}