Create monorepo from known-good production state
This commit is contained in:
commit
c034824338
651 changed files with 120469 additions and 0 deletions
|
|
@ -0,0 +1,88 @@
|
|||
"use client";
|
||||
|
||||
import { useMemo, useState } from "react";
|
||||
import ToolShell from "@/components/toolkit/ToolShell";
|
||||
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
function num(v: string) {
|
||||
const n = parseFloat(v);
|
||||
return Number.isFinite(n) ? n : 0;
|
||||
}
|
||||
|
||||
// Spot diameter (µm) ≈ 1.27 * M² * λ(µm) * f(mm) / D(mm)
|
||||
export default function Page() {
|
||||
const [lambdaNm, setLambdaNm] = useState("1064"); // nm (default fiber)
|
||||
const [focalMm, setFocalMm] = useState("160"); // mm
|
||||
const [beamDm, setBeamDm] = useState("6"); // mm (input beam diameter at lens)
|
||||
const [m2, setM2] = useState("1.3");
|
||||
|
||||
const dUm = useMemo(() => {
|
||||
const lamUm = num(lambdaNm) / 1000; // convert nm -> µm
|
||||
const f = num(focalMm);
|
||||
const D = num(beamDm);
|
||||
const M2 = Math.max(1, num(m2));
|
||||
if (lamUm <= 0 || f <= 0 || D <= 0) return 0;
|
||||
return 1.27 * M2 * lamUm * (f / D);
|
||||
}, [lambdaNm, focalMm, beamDm, m2]);
|
||||
|
||||
const dMm = dUm / 1000;
|
||||
|
||||
return (
|
||||
<ToolShell title="Beam Spot Size">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">Inputs</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="grid gap-3 sm:grid-cols-4">
|
||||
<label className="text-[11px] sm:text-xs">
|
||||
<div className="mb-1 text-muted-foreground">Wavelength (nm)</div>
|
||||
<Input value={lambdaNm} onChange={(e) => setLambdaNm(e.target.value)} />
|
||||
<div className="mt-1 text-[11px] text-muted-foreground space-x-2">
|
||||
<button type="button" className="underline" onClick={() => setLambdaNm("1064")}>
|
||||
Fiber (1064 nm)
|
||||
</button>
|
||||
<button type="button" className="underline" onClick={() => setLambdaNm("10600")}>
|
||||
CO₂ (10600 nm)
|
||||
</button>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label className="text-[11px] sm:text-xs">
|
||||
<div className="mb-1 text-muted-foreground">Focal length (mm)</div>
|
||||
<Input value={focalMm} onChange={(e) => setFocalMm(e.target.value)} />
|
||||
</label>
|
||||
|
||||
<label className="text-[11px] sm:text-xs">
|
||||
<div className="mb-1 text-muted-foreground">Beam Ø @ lens (mm)</div>
|
||||
<Input value={beamDm} onChange={(e) => setBeamDm(e.target.value)} />
|
||||
</label>
|
||||
|
||||
<label className="text-[11px] sm:text-xs">
|
||||
<div className="mb-1 text-muted-foreground">M²</div>
|
||||
<Input value={m2} onChange={(e) => setM2(e.target.value)} />
|
||||
</label>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="mt-4">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">Result</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="grid gap-3 sm:grid-cols-2">
|
||||
<div>
|
||||
<div className="text-sm text-muted-foreground">Spot diameter</div>
|
||||
<div className="text-lg">{dMm.toFixed(4)} mm</div>
|
||||
<div className="text-xs text-muted-foreground">{dUm.toFixed(2)} µm</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm text-muted-foreground">Spot radius</div>
|
||||
<div className="text-lg">{(dMm / 2).toFixed(4)} mm</div>
|
||||
<div className="text-xs text-muted-foreground">{(dUm / 2).toFixed(2)} µm</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</ToolShell>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue