{"id":24969,"date":"2026-10-23T05:59:34","date_gmt":"2026-10-23T05:59:34","guid":{"rendered":"https:\/\/www.mechstream.com\/?p=24969"},"modified":"2026-10-23T05:59:36","modified_gmt":"2026-10-23T05:59:36","slug":"material-failure-mode-prediction-calculator","status":"publish","type":"post","link":"https:\/\/www.mechstream.com\/fr\/material-failure-mode-prediction-calculator\/","title":{"rendered":"Material Failure Mode Prediction Calculator"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The Material Failure Mode Prediction Calculator is a practical engineering tool designed to assess potential material failure mechanisms under different loading and operating conditions. Using established mechanical engineering formulas, this calculator helps engineers evaluate ductile yielding, brittle fracture, fatigue failure, elastic buckling, and creep-related failure. By entering material properties, stress conditions, and geometric parameters, users can calculate safety factors, utilization ratios, and preliminary failure risk levels. Ideal for mechanical engineers, material scientists, and structural designers, the Material Failure Mode Prediction Calculator supports material selection, structural integrity assessment, and mechanical component design optimization. Improve engineering efficiency, identify potential failure risks, and enhance product reliability with formula-based material failure analysis.<\/p>\n\n\n\n<div id=\"fmp-calculator\" class=\"fmp-root\" data-fmp-widget=\"material-failure-mode-prediction\">\n<style>\n#fmp-calculator,#fmp-calculator *,#fmp-calculator *::before,#fmp-calculator *::after{box-sizing:border-box}\n#fmp-calculator{\n  --fmp-bg:#ffffff;--fmp-card:#ffffff;--fmp-navy:#16202e;--fmp-text:#2b3442;--fmp-muted:#5b6675;--fmp-soft:#808b99;\n  --fmp-line:#d5dbe3;--fmp-line-soft:#e6eaf0;--fmp-panel:#f6f8fb;--fmp-accent:#1d64c8;--fmp-accent-dark:#154c9a;--fmp-accent-soft:#e8f0fb;\n  --fmp-err:#b42318;--fmp-err-soft:#fdecea;--fmp-warn:#7a5200;--fmp-warn-soft:#fff6e0;--fmp-ok:#17643f;--fmp-ok-soft:#e7f5ee;\n  display:block;width:100%;max-width:1180px;margin:24px auto;padding:28px;background:var(--fmp-bg);color:var(--fmp-text);\n  border:1px solid var(--fmp-line-soft);border-radius:20px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif;\n  font-size:16px;line-height:1.55;font-weight:400;letter-spacing:normal;text-transform:none;text-indent:0;word-spacing:normal;-webkit-font-smoothing:antialiased;text-align:left;position:relative\n}\n#fmp-calculator .fmp-wrap{container-type:inline-size;container-name:fmp;width:100%}\n#fmp-calculator h1,#fmp-calculator h2,#fmp-calculator h3,#fmp-calculator h4,#fmp-calculator p,#fmp-calculator ul,#fmp-calculator ol,#fmp-calculator li,#fmp-calculator dl,#fmp-calculator dt,#fmp-calculator dd,#fmp-calculator figure,#fmp-calculator figcaption,#fmp-calculator details,#fmp-calculator summary,#fmp-calculator fieldset,#fmp-calculator legend,#fmp-calculator label,#fmp-calculator header,#fmp-calculator section,#fmp-calculator article,#fmp-calculator aside{\n  margin:0;padding:0;border:0;background:none;color:inherit;font-family:inherit;font-size:inherit;font-weight:inherit;font-style:normal;line-height:inherit;text-indent:0;text-transform:none;letter-spacing:normal;text-shadow:none;box-shadow:none;float:none;width:auto;max-width:none;min-width:0\n}\n#fmp-calculator ul,#fmp-calculator ol{list-style:none}\n#fmp-calculator a{color:var(--fmp-accent);text-decoration:underline}\n#fmp-calculator sub,#fmp-calculator sup{font-size:.72em;line-height:0;position:relative;vertical-align:baseline}\n#fmp-calculator sub{bottom:-.25em}\n#fmp-calculator sup{top:-.5em}\n#fmp-calculator [hidden]{display:none!important}\n#fmp-calculator .fmp-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:18px;align-items:start}\n#fmp-calculator .fmp-left{container-type:inline-size;container-name:fmpl;min-width:0}\n#fmp-calculator .fmp-right{min-width:0}\n#fmp-calculator .fmp-card{background:var(--fmp-card);border:1px solid var(--fmp-line-soft);border-radius:16px;padding:20px;box-shadow:0 1px 2px rgba(22,32,46,.04),0 4px 14px rgba(22,32,46,.05);min-width:0}\n#fmp-calculator .fmp-card+.fmp-card{margin-top:14px}\n#fmp-calculator .fmp-card-title{margin:0 0 4px;color:var(--fmp-navy);font-size:17.5px;font-weight:650;line-height:1.3;display:flex;align-items:center;gap:10px}\n#fmp-calculator .fmp-step{display:inline-flex;align-items:center;justify-content:center;flex:0 0 24px;width:24px;height:24px;border-radius:50%;background:var(--fmp-accent-soft);color:var(--fmp-accent);font-size:12.8px;font-weight:700}\n#fmp-calculator .fmp-card-note{color:var(--fmp-muted);font-size:14px;margin:0 0 14px}\n#fmp-calculator .fmp-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:14px 16px}\n#fmp-calculator .fmp-field{min-width:0}\n#fmp-calculator .fmp-span{grid-column:1\/-1}\n#fmp-calculator .fmp-label{display:block;font-size:14px;font-weight:600;color:var(--fmp-navy);margin:0 0 6px;line-height:1.3}\n#fmp-calculator .fmp-opt{color:var(--fmp-soft);font-weight:400;font-size:12.8px;margin-left:4px}\n#fmp-calculator .fmp-hint{display:block;color:var(--fmp-soft);font-size:12.7px;margin-top:5px;line-height:1.45}\n#fmp-calculator .fmp-error{display:block;color:var(--fmp-err);font-size:13px;margin-top:4px;line-height:1.4}\n#fmp-calculator .fmp-error:empty{display:none}\n#fmp-calculator .fmp-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:stretch}\n#fmp-calculator .fmp-unit{display:inline-flex;align-items:center;justify-content:center;min-width:64px;min-height:46px;padding:0 12px;border-radius:11px;background:#eef2f7;color:var(--fmp-muted);font-size:14px;font-weight:600;white-space:nowrap}\n#fmp-calculator input[type=number],#fmp-calculator input[type=text],#fmp-calculator select{\n  -webkit-appearance:none;appearance:none;display:block;width:100%;min-height:46px;height:auto;margin:0;padding:10px 13px;font:inherit;font-size:16px;line-height:1.3;\n  color:var(--fmp-text);background-color:#fff;border:1px solid var(--fmp-line);border-radius:11px;box-shadow:none;outline:none;max-width:none;transition:border-color .15s ease,box-shadow .15s ease\n}\n#fmp-calculator select{padding-right:34px;background-image:linear-gradient(45deg,transparent 50%,#5b6675 50%),linear-gradient(135deg,#5b6675 50%,transparent 50%);background-position:calc(100% - 18px) 20px,calc(100% - 13px) 20px;background-size:5px 5px,5px 5px;background-repeat:no-repeat;cursor:pointer}\n#fmp-calculator select.fmp-usel{width:auto;min-width:96px;background-color:#eef2f7;font-weight:600;font-size:14.5px;color:var(--fmp-muted)}\n#fmp-calculator input:focus,#fmp-calculator select:focus{border-color:var(--fmp-accent);box-shadow:0 0 0 4px rgba(29,100,200,.17)}\n#fmp-calculator input::placeholder{color:#a7b1be;opacity:1}\n#fmp-calculator .fmp-invalid{border-color:var(--fmp-err)!important;box-shadow:0 0 0 3px rgba(180,35,24,.12)!important}\n#fmp-calculator .fmp-modes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;border:0;margin:0;padding:0;position:relative}\n#fmp-calculator .fmp-modes legend,#fmp-calculator .fmp-seg legend{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}\n#fmp-calculator .fmp-modes input,#fmp-calculator .fmp-seg input{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}\n#fmp-calculator .fmp-modes label{display:flex;flex-direction:column;justify-content:center;gap:2px;min-height:58px;padding:9px 12px;border:1px solid var(--fmp-line);border-radius:12px;cursor:pointer;background:#fff;transition:border-color .15s,background .15s,box-shadow .15s}\n#fmp-calculator .fmp-modes label b{font-weight:650;font-size:14.6px;color:var(--fmp-navy);line-height:1.25}\n#fmp-calculator .fmp-modes label small{font-size:12.2px;color:var(--fmp-soft);line-height:1.3}\n#fmp-calculator .fmp-modes input:checked+label{border-color:var(--fmp-accent);background:var(--fmp-accent-soft);box-shadow:inset 0 0 0 1px var(--fmp-accent)}\n#fmp-calculator .fmp-modes input:focus-visible+label,#fmp-calculator .fmp-seg input:focus-visible+label{outline:3px solid rgba(29,100,200,.4);outline-offset:1px}\n#fmp-calculator .fmp-seg{display:grid;grid-auto-columns:minmax(0,1fr);grid-auto-flow:column;min-width:0;width:100%;gap:4px;padding:4px;background:#eaeef3;border-radius:12px;border:0;margin:0;position:relative}\n#fmp-calculator .fmp-seg label{display:flex;align-items:center;justify-content:center;min-height:40px;padding:6px;border-radius:9px;font-size:13.8px;font-weight:600;color:var(--fmp-muted);cursor:pointer;text-align:center;line-height:1.2;transition:background .15s,color .15s,box-shadow .15s;margin:0}\n#fmp-calculator .fmp-seg input:checked+label{background:#fff;color:var(--fmp-navy);box-shadow:0 1px 3px rgba(22,32,46,.15)}\n#fmp-calculator .fmp-seg-label{display:block;font-size:14px;font-weight:600;color:var(--fmp-navy);margin:0 0 6px}\n#fmp-calculator .fmp-modedesc{margin-top:12px;font-size:13.6px;color:var(--fmp-muted)}\n#fmp-calculator .fmp-info{padding:12px 14px;border-radius:11px;background:var(--fmp-panel);border:1px solid var(--fmp-line-soft);font-size:13.5px;color:var(--fmp-muted);line-height:1.5}\n#fmp-calculator .fmp-info strong{color:var(--fmp-navy);font-weight:650}\n#fmp-calculator .fmp-check{display:flex;gap:10px;align-items:flex-start;font-size:14.2px;font-weight:600;color:var(--fmp-navy);cursor:pointer;line-height:1.4}\n#fmp-calculator .fmp-check input{flex:0 0 18px;width:18px;height:18px;margin:2px 0 0;accent-color:var(--fmp-accent);cursor:pointer}\n#fmp-calculator .fmp-check span small{display:block;font-weight:400;color:var(--fmp-soft);font-size:12.6px;margin-top:2px}\n#fmp-calculator .fmp-actions{display:flex;justify-content:center;margin-top:16px}\n#fmp-calculator .fmp-btn{-webkit-appearance:none;appearance:none;display:inline-flex;align-items:center;justify-content:center;min-height:48px;margin:0;padding:10px 16px;border-radius:999px;border:1px solid var(--fmp-line);background:#fff;color:var(--fmp-navy);font:inherit;font-size:15px;font-weight:600;line-height:1.2;cursor:pointer;text-decoration:none;text-transform:none;letter-spacing:normal;box-shadow:none;width:auto;min-width:180px;height:auto;transition:background .15s,border-color .15s,color .15s}\n#fmp-calculator .fmp-btn:hover{border-color:var(--fmp-accent);color:var(--fmp-accent-dark)}\n#fmp-calculator .fmp-btn-primary{background:var(--fmp-accent);border-color:var(--fmp-accent);color:#fff}\n#fmp-calculator .fmp-btn-primary:hover{background:var(--fmp-accent-dark);border-color:var(--fmp-accent-dark);color:#fff}\n#fmp-calculator .fmp-btn-secondary{background:var(--fmp-accent-soft);border-color:#c6d8f2;color:var(--fmp-accent-dark)}\n#fmp-calculator .fmp-btn:focus-visible{outline:3px solid rgba(29,100,200,.4);outline-offset:2px}\n#fmp-calculator .fmp-form-msg{text-align:center;color:var(--fmp-err);font-size:13.8px;margin-top:10px;min-height:1.3em}\n#fmp-calculator .fmp-form-msg.fmp-good{color:var(--fmp-ok)}\n#fmp-calculator .fmp-results{scroll-margin-top:16px}\n#fmp-calculator .fmp-placeholder{color:var(--fmp-muted);font-size:14.5px;padding:18px;border:1px dashed var(--fmp-line);border-radius:12px;background:var(--fmp-panel);margin-top:12px}\n#fmp-calculator .fmp-res-head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:8px 12px;margin:10px 0 14px}\n#fmp-calculator .fmp-eyebrow{display:block;font-size:12.2px;font-weight:650;letter-spacing:.04em;text-transform:uppercase;color:var(--fmp-soft)}\n#fmp-calculator .fmp-res-title{display:block;font-size:20px;font-weight:700;color:var(--fmp-navy);line-height:1.25}\n#fmp-calculator .fmp-badge{display:inline-block;padding:3px 11px;border-radius:999px;font-size:12.6px;font-weight:700;line-height:1.5;white-space:nowrap}\n#fmp-calculator .fmp-c-low{background:var(--fmp-ok-soft);color:var(--fmp-ok)}\n#fmp-calculator .fmp-c-mod{background:var(--fmp-accent-soft);color:var(--fmp-accent-dark)}\n#fmp-calculator .fmp-c-near{background:var(--fmp-warn-soft);color:var(--fmp-warn)}\n#fmp-calculator .fmp-c-exc{background:var(--fmp-err-soft);color:var(--fmp-err)}\n#fmp-calculator .fmp-c-ne{background:#eef1f5;color:#4d5866}\n#fmp-calculator .fmp-hero{display:grid;grid-template-columns:minmax(0,1fr);gap:10px}\n#fmp-calculator .fmp-hero-card{border-radius:13px;padding:14px 16px;border:1px solid var(--fmp-line-soft);background:var(--fmp-panel);min-width:0}\n#fmp-calculator .fmp-hero-card.fmp-primary{background:var(--fmp-accent-soft);border-color:#c9dbf3}\n#fmp-calculator .fmp-hero-label{font-size:13px;font-weight:600;color:var(--fmp-muted);line-height:1.35}\n#fmp-calculator .fmp-hero-value{font-size:clamp(22px,2.6vw,28px);font-weight:700;color:var(--fmp-navy);letter-spacing:-.01em;line-height:1.2;margin-top:4px;overflow-wrap:anywhere}\n#fmp-calculator .fmp-hero-sub{font-size:12.8px;color:var(--fmp-muted);margin-top:4px;line-height:1.45;overflow-wrap:anywhere}\n#fmp-calculator .fmp-kpis{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:10px}\n#fmp-calculator .fmp-kpi{background:var(--fmp-panel);border:1px solid var(--fmp-line-soft);border-radius:12px;padding:11px 13px;min-width:0}\n#fmp-calculator .fmp-kpi-label{font-size:12.6px;font-weight:600;color:var(--fmp-muted);line-height:1.3}\n#fmp-calculator .fmp-kpi-value{font-size:clamp(17px,2vw,21px);font-weight:700;color:var(--fmp-navy);letter-spacing:-.01em;margin-top:3px;line-height:1.25;overflow-wrap:anywhere}\n#fmp-calculator .fmp-kpi-value.fmp-na{color:var(--fmp-soft);font-size:15.5px}\n#fmp-calculator .fmp-kpi-sub{font-size:12.2px;color:var(--fmp-muted);margin-top:3px;line-height:1.4;overflow-wrap:anywhere}\n#fmp-calculator .fmp-meter{margin-top:14px}\n#fmp-calculator .fmp-meter-track{position:relative;height:14px;border-radius:999px;background:linear-gradient(90deg,#d9efe3 0,#d9efe3 var(--fmp-b1),#dbe7f8 var(--fmp-b1),#dbe7f8 var(--fmp-b2),#fbebc4 var(--fmp-b2),#fbebc4 var(--fmp-b3),#f8d4cf var(--fmp-b3),#f8d4cf 100%)}\n#fmp-calculator .fmp-meter-fill{position:absolute;top:3px;left:0;height:8px;border-radius:999px;background:var(--fmp-navy)}\n#fmp-calculator .fmp-meter-mark{position:absolute;top:-3px;width:2px;height:20px;background:#fff;border-left:1px solid rgba(22,32,46,.35)}\n#fmp-calculator .fmp-meter-scale{position:relative;height:18px;font-size:11.5px;color:var(--fmp-soft);margin-top:4px}\n#fmp-calculator .fmp-meter-scale span{position:absolute;transform:translateX(-50%);white-space:nowrap}\n#fmp-calculator .fmp-sec{color:var(--fmp-navy);font-size:15.2px;font-weight:650;margin:20px 0 8px}\n#fmp-calculator .fmp-interp{font-size:14.6px;color:var(--fmp-text);line-height:1.6}\n#fmp-calculator .fmp-params{display:grid;grid-template-columns:minmax(0,1fr);gap:0;border:1px solid var(--fmp-line-soft);border-radius:12px;overflow:hidden}\n#fmp-calculator .fmp-params div{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:10px;padding:8px 12px;font-size:13.6px;border-top:1px solid var(--fmp-line-soft)}\n#fmp-calculator .fmp-params div:first-child{border-top:0}\n#fmp-calculator .fmp-params dt{color:var(--fmp-muted)}\n#fmp-calculator .fmp-params dd{color:var(--fmp-navy);font-weight:600;text-align:right;overflow-wrap:anywhere}\n#fmp-calculator .fmp-steps{counter-reset:fmpstep;display:grid;gap:6px}\n#fmp-calculator .fmp-steps li{position:relative;padding:8px 12px 8px 38px;background:var(--fmp-panel);border:1px dashed var(--fmp-line);border-radius:10px;font-size:13.6px;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}\n#fmp-calculator .fmp-steps li::before{counter-increment:fmpstep;content:counter(fmpstep);position:absolute;left:11px;top:8px;width:19px;height:19px;border-radius:50%;background:#e1e8f1;color:var(--fmp-muted);font-size:11.5px;font-weight:700;display:flex;align-items:center;justify-content:center}\n#fmp-calculator .fmp-steps li.fmp-step-h{background:none;border:0;padding:6px 0 0;font-weight:650;color:var(--fmp-navy)}\n#fmp-calculator .fmp-steps li.fmp-step-h::before{display:none}\n#fmp-calculator .fmp-notes{display:grid;gap:7px}\n#fmp-calculator .fmp-notes li{padding:9px 12px 9px 14px;border-radius:10px;font-size:13.4px;line-height:1.5;border-left:4px solid #b7c3d2;background:var(--fmp-panel)}\n#fmp-calculator .fmp-notes li.fmp-n-e{border-left-color:var(--fmp-err);background:var(--fmp-err-soft);color:#6e1a12}\n#fmp-calculator .fmp-notes li.fmp-n-w{border-left-color:#d49b16;background:var(--fmp-warn-soft);color:#5c4300}\n#fmp-calculator .fmp-notes li strong{font-weight:650}\n#fmp-calculator .fmp-ne-box{padding:14px 16px;border-radius:12px;background:#f3f5f8;border:1px solid var(--fmp-line-soft);font-size:14px}\n#fmp-calculator .fmp-ne-box p+p{margin-top:6px}\n#fmp-calculator .fmp-ne-box strong{color:var(--fmp-navy)}\n#fmp-calculator .fmp-crit-note{margin-top:14px;font-size:12.6px;color:var(--fmp-soft);line-height:1.5}\n#fmp-calculator .fmp-cmp{display:grid;gap:8px}\n#fmp-calculator .fmp-cmp-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 12px;padding:11px 13px;border:1px solid var(--fmp-line-soft);border-radius:12px;background:#fff}\n#fmp-calculator .fmp-cmp-row.fmp-gov{border-color:var(--fmp-accent);box-shadow:inset 0 0 0 1px var(--fmp-accent)}\n#fmp-calculator .fmp-cmp-name{font-weight:650;color:var(--fmp-navy);font-size:14.6px}\n#fmp-calculator .fmp-cmp-meta{grid-column:1\/-1;font-size:12.8px;color:var(--fmp-muted);line-height:1.45}\n#fmp-calculator .fmp-cmp-nums{grid-column:1\/-1;display:flex;flex-wrap:wrap;gap:4px 16px;font-size:13.4px;color:var(--fmp-text)}\n#fmp-calculator .fmp-cmp-nums b{font-weight:700;color:var(--fmp-navy)}\n@container fmpl (min-width:520px){\n  #fmp-calculator .fmp-grid{grid-template-columns:repeat(2,minmax(0,1fr))}\n}\n@container fmpl (min-width:640px){\n  #fmp-calculator .fmp-modes{grid-template-columns:repeat(5,minmax(0,1fr))}\n  #fmp-calculator .fmp-modes label{min-height:66px}\n}\n@container fmp (min-width:600px){\n  #fmp-calculator .fmp-hero{grid-template-columns:repeat(2,minmax(0,1fr))}\n  #fmp-calculator .fmp-kpis{grid-template-columns:repeat(4,minmax(0,1fr))}\n}\n@media (max-width:700px){\n  #fmp-calculator{padding:18px 14px;border-radius:16px;margin:12px auto}\n  #fmp-calculator .fmp-card{padding:16px 14px;border-radius:14px}\n  #fmp-calculator .fmp-modes label{padding:8px 10px}\n  #fmp-calculator .fmp-params div{grid-template-columns:minmax(0,1fr)}\n  #fmp-calculator .fmp-params dd{text-align:left}\n}\n@media (prefers-reduced-motion:reduce){#fmp-calculator *{transition:none!important}}\n@media print{#fmp-calculator .fmp-actions,#fmp-calculator .fmp-form-msg{display:none!important}}\n<\/style>\n<div class=\"fmp-wrap\">\n<div class=\"fmp-layout\">\n<form class=\"fmp-left\" id=\"fmp-form\" novalidate onsubmit=\"return false;\">\n<section class=\"fmp-card\" aria-labelledby=\"fmp-h-mode\">\n<h2 class=\"fmp-card-title\" id=\"fmp-h-mode\"><span class=\"fmp-step\" aria-hidden=\"true\">1<\/span>Calculation mode<\/h2>\n<p class=\"fmp-card-note\">Choose the failure criterion to calculate.<\/p>\n<fieldset class=\"fmp-modes\">\n<legend>Failure mode<\/legend>\n<input type=\"radio\" id=\"fmp-m-yield\" name=\"fmp-mode\" value=\"yield\" checked><label for=\"fmp-m-yield\"><b>Yielding<\/b><small>Von Mises<\/small><\/label>\n<input type=\"radio\" id=\"fmp-m-brittle\" name=\"fmp-mode\" value=\"brittle\"><label for=\"fmp-m-brittle\"><b>Brittle Fracture<\/b><small>Strength or K<sub>I<\/sub><\/small><\/label>\n<input type=\"radio\" id=\"fmp-m-fatigue\" name=\"fmp-mode\" value=\"fatigue\"><label for=\"fmp-m-fatigue\"><b>Fatigue<\/b><small>Modified Goodman<\/small><\/label>\n<input type=\"radio\" id=\"fmp-m-buckling\" name=\"fmp-mode\" value=\"buckling\"><label for=\"fmp-m-buckling\"><b>Buckling<\/b><small>Euler elastic<\/small><\/label>\n<input type=\"radio\" id=\"fmp-m-creep\" name=\"fmp-mode\" value=\"creep\"><label for=\"fmp-m-creep\"><b>Creep<\/b><small>Rupture-life ratio<\/small><\/label>\n<\/fieldset>\n<p class=\"fmp-modedesc\" id=\"fmp-modedesc\" aria-live=\"polite\"><\/p>\n<div class=\"fmp-field\" id=\"fmp-f-appr\" data-modes=\"brittle\" style=\"margin-top:14px\">\n<span class=\"fmp-seg-label\" aria-hidden=\"true\">Brittle fracture approach<\/span>\n<fieldset class=\"fmp-seg\">\n<legend>Brittle fracture approach<\/legend>\n<input type=\"radio\" id=\"fmp-ap-s\" name=\"fmp-appr\" value=\"strength\"><label for=\"fmp-ap-s\">Strength screening<\/label>\n<input type=\"radio\" id=\"fmp-ap-f\" name=\"fmp-appr\" value=\"fracture\"><label for=\"fmp-ap-f\">Fracture mechanics<\/label>\n<input type=\"radio\" id=\"fmp-ap-b\" name=\"fmp-appr\" value=\"both\" checked><label for=\"fmp-ap-b\">Both<\/label>\n<\/fieldset>\n<span class=\"fmp-hint\">Strength screening compares principal stresses with S<sub>ut<\/sub> and S<sub>uc<\/sub> (brittle materials only). Fracture mechanics compares K<sub>I<\/sub> with K<sub>IC<\/sub> for a known or assumed crack.<\/span>\n<\/div>\n<div style=\"margin-top:14px\">\n<label class=\"fmp-check\" for=\"fmp-showall\"><input type=\"checkbox\" id=\"fmp-showall\"><span>Show inputs for all failure modes<small>Shows every input field regardless of the selected mode.<\/small><\/span><\/label>\n<\/div>\n<\/section>\n<section class=\"fmp-card\" aria-labelledby=\"fmp-h-mat\">\n<h2 class=\"fmp-card-title\" id=\"fmp-h-mat\"><span class=\"fmp-step\" aria-hidden=\"true\">2<\/span>Material and units<\/h2>\n<p class=\"fmp-card-note\">Selecting a material never fills in property values. Enter validated data for your exact grade, condition and temperature.<\/p>\n<div class=\"fmp-grid\">\n<div class=\"fmp-field\" data-modes=\"all\">\n<label class=\"fmp-label\" for=\"fmp-material\">Material<\/label>\n<select id=\"fmp-material\">\n<option value=\"carbon\" selected>Carbon Steel<\/option>\n<option value=\"alloy\">Alloy Steel<\/option>\n<option value=\"stainless\">Stainless Steel<\/option>\n<option value=\"aluminum\">Aluminum Alloy<\/option>\n<option value=\"castiron\">Cast Iron<\/option>\n<option value=\"titanium\">Titanium Alloy<\/option>\n<option value=\"custom\">Custom Material<\/option>\n<\/select>\n<\/div>\n<div class=\"fmp-field\" data-modes=\"all\">\n<label class=\"fmp-label\" for=\"fmp-behavior\">Material behavior for criterion selection<\/label>\n<select id=\"fmp-behavior\" aria-describedby=\"fmp-behavior-hint\">\n<option value=\"ductile\" selected>Ductile<\/option>\n<option value=\"brittle\">Brittle<\/option>\n<\/select>\n<span class=\"fmp-hint\" id=\"fmp-behavior-hint\">Ductile enables von Mises yielding; Brittle enables principal stress screening.<\/span>\n<\/div>\n<div class=\"fmp-field fmp-span\" data-modes=\"all\">\n<label class=\"fmp-label\" for=\"fmp-matname\">Material name or grade <span class=\"fmp-opt\">(required for creep)<\/span><\/label>\n<input type=\"text\" id=\"fmp-matname\" maxlength=\"80\" autocomplete=\"off\" placeholder=\"e.g. ASTM A36 plate, as-rolled\" aria-describedby=\"fmp-matname-hint fmp-matname-err\">\n<span class=\"fmp-hint\" id=\"fmp-matname-hint\">Identifies the material the entered data belong to.<\/span>\n<span class=\"fmp-error\" id=\"fmp-matname-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-info fmp-span\" id=\"fmp-matinfo\" aria-live=\"polite\"><\/div>\n<div class=\"fmp-field\" data-modes=\"all\">\n<label class=\"fmp-label\" for=\"fmp-ustress\">Stress and strength unit<\/label>\n<select id=\"fmp-ustress\" data-prev=\"MPa\" aria-describedby=\"fmp-ustress-hint\">\n<option value=\"MPa\" selected>MPa (N\/mm\u00b2)<\/option>\n<option value=\"ksi\">ksi<\/option>\n<option value=\"psi\">psi<\/option>\n<\/select>\n<span class=\"fmp-hint\" id=\"fmp-ustress-hint\">Entered stresses are converted when you switch. 1 ksi = 6.894757 MPa.<\/span>\n<\/div>\n<div class=\"fmp-field\" data-modes=\"all\">\n<label class=\"fmp-label\" for=\"fmp-nreq\">Required design safety factor <span class=\"fmp-opt\">(optional)<\/span><\/label>\n<input id=\"fmp-nreq\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"1\" placeholder=\"e.g. 1.5\" title=\"Minimum safety factor required by your design code or specification\" aria-describedby=\"fmp-nreq-hint fmp-nreq-err\">\n<span class=\"fmp-hint\" id=\"fmp-nreq-hint\">If entered, each evaluated criterion is checked for n \u2265 n<sub>req<\/sub>.<\/span>\n<span class=\"fmp-error\" id=\"fmp-nreq-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<\/div>\n<\/section>\n<section class=\"fmp-card fmp-incard\" aria-labelledby=\"fmp-h-prop\">\n<h2 class=\"fmp-card-title\" id=\"fmp-h-prop\"><span class=\"fmp-step\" aria-hidden=\"true\">3<\/span>Material properties<\/h2>\n<p class=\"fmp-card-note\">Only the properties needed by the selected mode are shown. Values must apply at the operating temperature.<\/p>\n<div class=\"fmp-grid\">\n<div class=\"fmp-field\" id=\"fmp-f-sy\" data-modes=\"yield fatigue brittleF buckling\">\n<label class=\"fmp-label\" for=\"fmp-sy\">Yield Strength (S<sub>y<\/sub>)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-sy\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"0.2% offset yield strength\" aria-describedby=\"fmp-sy-hint fmp-sy-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-hint\" id=\"fmp-sy-hint\">Required for yielding. Optional elsewhere: enables the first-cycle yield, LEFM validity and inelastic buckling checks.<\/span>\n<span class=\"fmp-error\" id=\"fmp-sy-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-sut\" data-modes=\"brittleS fatigue\">\n<label class=\"fmp-label\" for=\"fmp-sut\">Ultimate Tensile Strength (S<sub>ut<\/sub>)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-sut\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Ultimate tensile strength\" aria-describedby=\"fmp-sut-hint fmp-sut-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-hint\" id=\"fmp-sut-hint\">Used by brittle strength screening and the Goodman line. Never used as a substitute for fracture toughness.<\/span>\n<span class=\"fmp-error\" id=\"fmp-sut-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-suc\" data-modes=\"brittleS\">\n<label class=\"fmp-label\" for=\"fmp-suc\">Ultimate Compressive Strength (S<sub>uc<\/sub>)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-suc\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Ultimate compressive strength, entered as a positive magnitude\" aria-describedby=\"fmp-suc-hint fmp-suc-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-hint\" id=\"fmp-suc-hint\">Enter as a positive magnitude.<\/span>\n<span class=\"fmp-error\" id=\"fmp-suc-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-E\" data-modes=\"buckling\">\n<label class=\"fmp-label\" for=\"fmp-E\">Young&#8217;s Modulus (E)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-E\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Elastic modulus at the operating temperature\" aria-describedby=\"fmp-E-hint fmp-E-err\"><select class=\"fmp-usel\" id=\"fmp-uE\" data-prev=\"GPa\" aria-label=\"Modulus unit\"><option value=\"GPa\" selected>GPa<\/option><option value=\"MPa\">MPa<\/option><option value=\"Msi\">Msi<\/option><option value=\"ksi\">ksi<\/option><\/select><\/div>\n<span class=\"fmp-hint\" id=\"fmp-E-hint\">Elastic modulus at the operating temperature. 1 Msi = 10\u2076 psi.<\/span>\n<span class=\"fmp-error\" id=\"fmp-E-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-kic\" data-modes=\"brittleF\">\n<label class=\"fmp-label\" for=\"fmp-kic\">Fracture Toughness (K<sub>IC<\/sub>)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-kic\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Plane-strain fracture toughness\" aria-describedby=\"fmp-kic-hint fmp-kic-err\"><select class=\"fmp-usel\" id=\"fmp-uK\" data-prev=\"MPam\" aria-label=\"Fracture toughness unit\"><option value=\"MPam\" selected>MPa\u221am<\/option><option value=\"ksiin\">ksi\u221ain<\/option><\/select><\/div>\n<span class=\"fmp-hint\" id=\"fmp-kic-hint\">Valid plane-strain toughness (e.g. ASTM E399 or E1820) at the service temperature, thickness and loading rate.<\/span>\n<span class=\"fmp-error\" id=\"fmp-kic-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field fmp-span\" id=\"fmp-f-fbasis\" data-modes=\"fatigue\">\n<label class=\"fmp-label\" for=\"fmp-fbasis\">Fatigue strength basis<\/label>\n<select id=\"fmp-fbasis\" aria-describedby=\"fmp-fbasis-hint\">\n<option value=\"limit\" selected>Corrected endurance limit Se (infinite-life basis)<\/option>\n<option value=\"life\">Fatigue strength Sf at a specified design life N<\/option>\n<\/select>\n<span class=\"fmp-hint\" id=\"fmp-fbasis-hint\">Not every material has a true endurance limit. Aluminum alloys require a fatigue strength at a stated life.<\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-se\" data-modes=\"fatigue\">\n<label class=\"fmp-label\" for=\"fmp-se\" id=\"fmp-se-label\">Corrected Endurance Limit (S<sub>e<\/sub>)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-se\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Fully reversed fatigue strength already corrected for surface, size, loading, temperature and reliability\" aria-describedby=\"fmp-se-hint fmp-se-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-hint\" id=\"fmp-se-hint\">Fully reversed value already corrected for surface, size, loading type, temperature and reliability. Not estimated automatically.<\/span>\n<span class=\"fmp-error\" id=\"fmp-se-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-ncyc\" data-modes=\"fatigue\">\n<label class=\"fmp-label\" for=\"fmp-ncyc\">Design life N<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-ncyc\" type=\"number\" inputmode=\"decimal\" step=\"any\" placeholder=\"e.g. 500000000\" title=\"Number of cycles at which the fatigue strength applies\" aria-describedby=\"fmp-ncyc-hint fmp-ncyc-err\"><span class=\"fmp-unit\" aria-hidden=\"true\">cycles<\/span><\/div>\n<span class=\"fmp-hint\" id=\"fmp-ncyc-hint\">Cycle count at which the entered fatigue strength applies.<\/span>\n<span class=\"fmp-error\" id=\"fmp-ncyc-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field fmp-span\" id=\"fmp-f-notchincl\" data-modes=\"fatigue\">\n<label class=\"fmp-check\" for=\"fmp-notchincl\"><input type=\"checkbox\" id=\"fmp-notchincl\"><span>The fatigue strength above already includes the notch effect<small>When ticked, K<sub>f<\/sub> is not applied again, which prevents double-counting the stress concentration.<\/small><\/span><\/label>\n<\/div>\n<div class=\"fmp-field fmp-span\" id=\"fmp-f-cmethod\" data-modes=\"creep\">\n<label class=\"fmp-label\" for=\"fmp-cmethod\">Creep rupture data source<\/label>\n<select id=\"fmp-cmethod\" aria-describedby=\"fmp-cmethod-hint\">\n<option value=\"none\" selected>No validated creep data available<\/option>\n<option value=\"direct\">Creep rupture life at the operating temperature and stress<\/option>\n<option value=\"lmp\">Larson\u2013Miller parameter from a validated master curve<\/option>\n<\/select>\n<span class=\"fmp-hint\" id=\"fmp-cmethod-hint\">Rupture life is never estimated from temperature and stress alone.<\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-tr\" data-modes=\"creep\">\n<label class=\"fmp-label\" for=\"fmp-tr\">Creep Rupture Life (t<sub>r<\/sub>)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-tr\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Time to creep rupture at the operating temperature and applied stress\" aria-describedby=\"fmp-tr-hint fmp-tr-err\"><select class=\"fmp-usel\" id=\"fmp-utr\" data-prev=\"h\" aria-label=\"Rupture life unit\"><option value=\"h\" selected>hours<\/option><option value=\"yr\">years<\/option><\/select><\/div>\n<span class=\"fmp-hint\" id=\"fmp-tr-hint\">From validated rupture data (for example a minimum or design rupture curve) for this temperature and stress.<\/span>\n<span class=\"fmp-error\" id=\"fmp-tr-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-confirm\" data-modes=\"creep\">\n<label class=\"fmp-check\" for=\"fmp-confirm\" style=\"margin-top:6px\"><input type=\"checkbox\" id=\"fmp-confirm\"><span>I confirm this rupture life is for the entered temperature and stress<small>Required for a quantitative creep result.<\/small><\/span><\/label>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-lmp\" data-modes=\"creep\">\n<label class=\"fmp-label\" for=\"fmp-lmp\">Larson\u2013Miller Parameter (P)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-lmp\" type=\"number\" inputmode=\"decimal\" step=\"any\" placeholder=\"e.g. 18500\" title=\"P = T(C + log10 tr), T in kelvin, tr in hours\" aria-describedby=\"fmp-lmp-hint fmp-lmp-err\"><span class=\"fmp-unit\" aria-hidden=\"true\">K\u00b7(C + log h)<\/span><\/div>\n<span class=\"fmp-hint\" id=\"fmp-lmp-hint\">P = T(C + log<sub>10<\/sub> t<sub>r<\/sub>) with T in kelvin and t<sub>r<\/sub> in hours, read from the master curve at the applied stress.<\/span>\n<span class=\"fmp-error\" id=\"fmp-lmp-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-lmpc\" data-modes=\"creep\">\n<label class=\"fmp-label\" for=\"fmp-lmpc\">Larson\u2013Miller Constant (C)<\/label>\n<input id=\"fmp-lmpc\" type=\"number\" inputmode=\"decimal\" step=\"any\" placeholder=\"from the same data source\" title=\"Constant used to construct the master curve\" aria-describedby=\"fmp-lmpc-hint fmp-lmpc-err\">\n<span class=\"fmp-hint\" id=\"fmp-lmpc-hint\">Use the constant from the same data set (often near 20 for steels, but take it from the source).<\/span>\n<span class=\"fmp-error\" id=\"fmp-lmpc-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<\/div>\n<\/section>\n<section class=\"fmp-card fmp-incard\" aria-labelledby=\"fmp-h-load\">\n<h2 class=\"fmp-card-title\" id=\"fmp-h-load\"><span class=\"fmp-step\" aria-hidden=\"true\">4<\/span>Loading parameters<\/h2>\n<p class=\"fmp-card-note\">Tension is positive and compression is negative. Use local stresses at the critical location unless a field says otherwise. Section properties are entered directly; they are not derived from assumed shapes.<\/p>\n<div class=\"fmp-grid\">\n<div class=\"fmp-field\" id=\"fmp-f-s1\" data-modes=\"yield brittleS\">\n<label class=\"fmp-label\" for=\"fmp-s1\">Principal Stress \u03c3<sub>1<\/sub><\/label>\n<div class=\"fmp-row\"><input id=\"fmp-s1\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"First principal stress (any order is accepted)\" aria-describedby=\"fmp-s1-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-error\" id=\"fmp-s1-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-s2\" data-modes=\"yield brittleS\">\n<label class=\"fmp-label\" for=\"fmp-s2\">Principal Stress \u03c3<sub>2<\/sub><\/label>\n<div class=\"fmp-row\"><input id=\"fmp-s2\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Second principal stress\" aria-describedby=\"fmp-s2-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-error\" id=\"fmp-s2-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-s3\" data-modes=\"yield brittleS\">\n<label class=\"fmp-label\" for=\"fmp-s3\">Principal Stress \u03c3<sub>3<\/sub><\/label>\n<div class=\"fmp-row\"><input id=\"fmp-s3\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Third principal stress; enter 0 for plane stress\" aria-describedby=\"fmp-s3-hint fmp-s3-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-hint\" id=\"fmp-s3-hint\">Enter 0 for a plane stress state. Principal stresses may be entered in any order.<\/span>\n<span class=\"fmp-error\" id=\"fmp-s3-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-scrack\" data-modes=\"brittleF\">\n<label class=\"fmp-label\" for=\"fmp-scrack\">Tensile Stress Normal to Crack (\u03c3)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-scrack\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Nominal stress acting normal to the crack plane, as defined for the chosen Y\" aria-describedby=\"fmp-scrack-hint fmp-scrack-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-hint\" id=\"fmp-scrack-hint\">The stress used in the definition of your geometry factor Y (usually the remote or nominal stress across the crack plane).<\/span>\n<span class=\"fmp-error\" id=\"fmp-scrack-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field fmp-span\" id=\"fmp-f-cyc\" data-modes=\"fatigue\">\n<span class=\"fmp-seg-label\" aria-hidden=\"true\">Cyclic stress input<\/span>\n<fieldset class=\"fmp-seg\">\n<legend>Cyclic stress input<\/legend>\n<input type=\"radio\" id=\"fmp-cy-mm\" name=\"fmp-cyc\" value=\"maxmin\" checked><label for=\"fmp-cy-mm\">Max \/ min stress<\/label>\n<input type=\"radio\" id=\"fmp-cy-am\" name=\"fmp-cyc\" value=\"amp\"><label for=\"fmp-cy-am\">Amplitude \/ mean<\/label>\n<\/fieldset>\n<span class=\"fmp-hint\">Nominal stresses at the critical section for constant-amplitude, uniaxial cycling.<\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-smax\" data-modes=\"fatigue\">\n<label class=\"fmp-label\" for=\"fmp-smax\">Maximum Cyclic Stress (\u03c3<sub>max<\/sub>)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-smax\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Algebraically largest stress in the cycle\" aria-describedby=\"fmp-smax-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-error\" id=\"fmp-smax-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-smin\" data-modes=\"fatigue\">\n<label class=\"fmp-label\" for=\"fmp-smin\">Minimum Cyclic Stress (\u03c3<sub>min<\/sub>)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-smin\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Algebraically smallest stress in the cycle\" aria-describedby=\"fmp-smin-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-error\" id=\"fmp-smin-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-sa\" data-modes=\"fatigue\">\n<label class=\"fmp-label\" for=\"fmp-sa\">Alternating Stress Amplitude (\u03c3<sub>a<\/sub>)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-sa\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Half the stress range\" aria-describedby=\"fmp-sa-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-error\" id=\"fmp-sa-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-sm\" data-modes=\"fatigue\">\n<label class=\"fmp-label\" for=\"fmp-sm\">Mean Stress (\u03c3<sub>m<\/sub>)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-sm\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Average of maximum and minimum stress\" aria-describedby=\"fmp-sm-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-error\" id=\"fmp-sm-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-kf\" data-modes=\"fatigue\">\n<label class=\"fmp-label\" for=\"fmp-kf\">Fatigue Stress Concentration Factor (K<sub>f<\/sub>) <span class=\"fmp-opt\">(optional)<\/span><\/label>\n<input id=\"fmp-kf\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"1\" placeholder=\"1.0 if blank\" title=\"Fatigue notch factor applied to the nominal alternating stress\" aria-describedby=\"fmp-kf-hint fmp-kf-err\">\n<span class=\"fmp-hint\" id=\"fmp-kf-hint\">Applied to the nominal alternating stress. Leave blank (1.0) if the stresses are already local values.<\/span>\n<span class=\"fmp-error\" id=\"fmp-kf-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-kfmean\" data-modes=\"fatigue\">\n<label class=\"fmp-check\" for=\"fmp-kfmean\" style=\"margin-top:6px\"><input type=\"checkbox\" id=\"fmp-kfmean\"><span>Also apply K<sub>f<\/sub> to the mean stress<small>Conservative convention for notched parts without significant notch yielding.<\/small><\/span><\/label>\n<\/div>\n<div class=\"fmp-field fmp-span\" id=\"fmp-f-cmean\" data-modes=\"fatigue\">\n<label class=\"fmp-label\" for=\"fmp-cmean\">Compressive mean stress treatment<\/label>\n<select id=\"fmp-cmean\" aria-describedby=\"fmp-cmean-hint\">\n<option value=\"cons\" selected>Conservative: ignore the beneficial effect (\u03c3m treated as 0)<\/option>\n<option value=\"lin\">Extend the Goodman line into compression (needs supporting data)<\/option>\n<\/select>\n<span class=\"fmp-hint\" id=\"fmp-cmean-hint\">Applies only when the mean stress is compressive.<\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-P\" data-modes=\"buckling\">\n<label class=\"fmp-label\" for=\"fmp-P\">Applied Compressive Load (P)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-P\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" title=\"Axial compressive load as a positive magnitude\" aria-describedby=\"fmp-P-hint fmp-P-err\"><select class=\"fmp-usel\" id=\"fmp-uforce\" data-prev=\"kN\" aria-label=\"Force unit\"><option value=\"N\">N<\/option><option value=\"kN\" selected>kN<\/option><option value=\"lbf\">lbf<\/option><option value=\"kip\">kip<\/option><\/select><\/div>\n<span class=\"fmp-hint\" id=\"fmp-P-hint\">Concentric axial load, entered as a positive magnitude.<\/span>\n<span class=\"fmp-error\" id=\"fmp-P-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-cs\" data-modes=\"creep\">\n<label class=\"fmp-label\" for=\"fmp-cs\">Applied Stress for Creep<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-cs\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Sustained stress at which the rupture data were taken\" aria-describedby=\"fmp-cs-hint fmp-cs-err\"><span class=\"fmp-unit fmp-ul-stress\" aria-hidden=\"true\">MPa<\/span><\/div>\n<span class=\"fmp-hint\" id=\"fmp-cs-hint\">Sustained stress magnitude that the rupture data correspond to.<\/span>\n<span class=\"fmp-error\" id=\"fmp-cs-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-T\" data-modes=\"creep\">\n<label class=\"fmp-label\" for=\"fmp-T\">Operating Temperature<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-T\" type=\"number\" inputmode=\"decimal\" step=\"any\" title=\"Metal temperature during sustained loading\" aria-describedby=\"fmp-T-err\"><select class=\"fmp-usel\" id=\"fmp-utemp\" data-prev=\"C\" aria-label=\"Temperature unit\"><option value=\"C\" selected>\u00b0C<\/option><option value=\"F\">\u00b0F<\/option><option value=\"K\">K<\/option><\/select><\/div>\n<span class=\"fmp-error\" id=\"fmp-T-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-ts\" data-modes=\"creep\">\n<label class=\"fmp-label\" for=\"fmp-ts\">Service Duration (t<sub>service<\/sub>)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-ts\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" title=\"Intended time at the operating temperature and stress\" aria-describedby=\"fmp-ts-err\"><select class=\"fmp-usel\" id=\"fmp-uts\" data-prev=\"h\" aria-label=\"Service duration unit\"><option value=\"h\" selected>hours<\/option><option value=\"yr\">years<\/option><\/select><\/div>\n<span class=\"fmp-error\" id=\"fmp-ts-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-a\" data-modes=\"brittleF\">\n<label class=\"fmp-label\" for=\"fmp-a\">Crack Size (a)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-a\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" title=\"Crack depth or half-length, as defined by the chosen Y\" aria-describedby=\"fmp-a-hint fmp-a-err\"><select class=\"fmp-usel\" id=\"fmp-ucrack\" data-prev=\"mm\" aria-label=\"Crack size unit\"><option value=\"mm\" selected>mm<\/option><option value=\"m\">m<\/option><option value=\"in\">in<\/option><\/select><\/div>\n<span class=\"fmp-hint\" id=\"fmp-a-hint\">Defined consistently with Y: e.g. depth of an edge crack, or half-length of a through centre crack.<\/span>\n<span class=\"fmp-error\" id=\"fmp-a-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-Y\" data-modes=\"brittleF\">\n<label class=\"fmp-label\" for=\"fmp-Y\">Crack Geometry Factor (Y)<\/label>\n<input id=\"fmp-Y\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" title=\"Dimensionless geometry factor\" aria-describedby=\"fmp-Y-hint fmp-Y-err\">\n<span class=\"fmp-hint\" id=\"fmp-Y-hint\">Dimensionless. About 1.0 for a centre crack in a wide plate and about 1.12 for a shallow edge crack; take Y from a handbook solution for your geometry.<\/span>\n<span class=\"fmp-error\" id=\"fmp-Y-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field fmp-span\" id=\"fmp-f-ulen\" data-modes=\"buckling\">\n<label class=\"fmp-label\" for=\"fmp-ulen\">Length unit for member geometry<\/label>\n<select id=\"fmp-ulen\" data-prev=\"mm\" aria-describedby=\"fmp-ulen-hint\">\n<option value=\"mm\" selected>mm (area mm\u00b2, I mm\u2074)<\/option>\n<option value=\"m\">m (area m\u00b2, I m\u2074)<\/option>\n<option value=\"in\">in (area in\u00b2, I in\u2074)<\/option>\n<option value=\"ft\">ft (area ft\u00b2, I ft\u2074)<\/option>\n<\/select>\n<span class=\"fmp-hint\" id=\"fmp-ulen-hint\">Length, area and second moment of area all use this unit. Entered values are converted when you switch.<\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-L\" data-modes=\"buckling\">\n<label class=\"fmp-label\" for=\"fmp-L\">Unsupported Member Length (L)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-L\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" title=\"Unbraced length for the buckling axis considered\" aria-describedby=\"fmp-L-err\"><span class=\"fmp-unit fmp-ul-len\" aria-hidden=\"true\">mm<\/span><\/div>\n<span class=\"fmp-error\" id=\"fmp-L-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-endc\" data-modes=\"buckling\">\n<label class=\"fmp-label\" for=\"fmp-endc\">End Condition (effective length factor K)<\/label>\n<select id=\"fmp-endc\" aria-describedby=\"fmp-endc-hint\">\n<option value=\"pp\" selected>Pinned\u2013Pinned (K = 1.0)<\/option>\n<option value=\"ff\">Fixed\u2013Fixed (K = 0.5)<\/option>\n<option value=\"fp\">Fixed\u2013Pinned (K = 0.7)<\/option>\n<option value=\"fr\">Fixed\u2013Free (K = 2.0)<\/option>\n<option value=\"custom\">Custom K<\/option>\n<\/select>\n<span class=\"fmp-hint\" id=\"fmp-endc-hint\">Theoretical values for ideal supports. Real connections are rarely perfectly fixed.<\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-kc\" data-modes=\"buckling\">\n<label class=\"fmp-label\" for=\"fmp-kc\">Custom Effective Length Factor (K)<\/label>\n<input id=\"fmp-kc\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" title=\"Effective length factor from your design code or analysis\" aria-describedby=\"fmp-kc-err\">\n<span class=\"fmp-error\" id=\"fmp-kc-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-A\" data-modes=\"buckling\">\n<label class=\"fmp-label\" for=\"fmp-A\">Cross-Sectional Area (A) <span class=\"fmp-opt\">(optional)<\/span><\/label>\n<div class=\"fmp-row\"><input id=\"fmp-A\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" title=\"Gross cross-sectional area\" aria-describedby=\"fmp-A-hint fmp-A-err\"><span class=\"fmp-unit fmp-ul-len2\" aria-hidden=\"true\">mm\u00b2<\/span><\/div>\n<span class=\"fmp-hint\" id=\"fmp-A-hint\">Enables the slenderness ratio and the elastic-range check.<\/span>\n<span class=\"fmp-error\" id=\"fmp-A-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"fmp-field\" id=\"fmp-f-I\" data-modes=\"buckling\">\n<label class=\"fmp-label\" for=\"fmp-I\">Second Moment of Area (I)<\/label>\n<div class=\"fmp-row\"><input id=\"fmp-I\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" title=\"Second moment of area about the critical (usually weakest) buckling axis\" aria-describedby=\"fmp-I-hint fmp-I-err\"><span class=\"fmp-unit fmp-ul-len4\" aria-hidden=\"true\">mm\u2074<\/span><\/div>\n<span class=\"fmp-hint\" id=\"fmp-I-hint\">About the critical buckling axis, normally the axis with the smallest I for the same unbraced length.<\/span>\n<span class=\"fmp-error\" id=\"fmp-I-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<\/div>\n<\/section>\n<div class=\"fmp-actions\">\n<button type=\"button\" class=\"fmp-btn fmp-btn-primary\" id=\"fmp-calc\">Calculate<\/button>\n<\/div>\n<p class=\"fmp-form-msg\" id=\"fmp-msg\" role=\"status\" aria-live=\"polite\"><\/p>\n<\/form>\n<div class=\"fmp-right\">\n<section class=\"fmp-card fmp-results\" id=\"fmp-results\" aria-labelledby=\"fmp-h-res\" tabindex=\"-1\" hidden>\n<h2 class=\"fmp-card-title\" id=\"fmp-h-res\"><span class=\"fmp-step\" aria-hidden=\"true\">5<\/span>Calculation results<\/h2>\n<div id=\"fmp-res-body\" aria-live=\"polite\">\n<p class=\"fmp-placeholder\">Enter the inputs for the selected mode and press <strong>Calculate<\/strong>.<\/p>\n<\/div>\n<\/section>\n<\/div>\n<\/div>\n<\/div>\n<script>\n(function () {\n  \"use strict\";\n  \/* =====================================================================\n     CONSTANTS AND UNIT CONVERSION\n     Internal base units: stress and modulus in MPa (N\/mm\u00b2), stress intensity\n     in MPa\u00b7\u221am, lengths in mm, force in N, time in hours, temperature in \u00b0C.\n     ===================================================================== *\/\n  var UNITS = {\n    stress: { MPa: 1, ksi: 6.894757, psi: 0.006894757 },\n    E: { GPa: 1000, MPa: 1, ksi: 6.894757, Msi: 6894.757 },\n    K: { MPam: 1, ksiin: 1.098843 },\n    crack: { mm: 1, m: 1000, \"in\": 25.4 },\n    len: { mm: 1, m: 1000, \"in\": 25.4, ft: 304.8 },\n    force: { N: 1, kN: 1000, lbf: 4.4482216, kip: 4448.2216 },\n    time: { h: 1, yr: 8760 }\n  };\n  var ULAB = { MPa: \"MPa\", ksi: \"ksi\", psi: \"psi\", GPa: \"GPa\", Msi: \"Msi\", MPam: \"MPa\u221am\", ksiin: \"ksi\u221ain\", mm: \"mm\", m: \"m\", \"in\": \"in\", ft: \"ft\", N: \"N\", kN: \"kN\", lbf: \"lbf\", kip: \"kip\", h: \"h\", yr: \"years\", C: \"\u00b0C\", F: \"\u00b0F\", K: \"K\" };\n  \/* Field definitions: type selects the unit family, sel the unit selector, rule the validation *\/\n  var F = {\n    sy: { type: \"stress\", sel: \"fmp-ustress\", rule: \"pos\", label: \"Yield strength Sy\", sym: \"Sy\" },\n    sut: { type: \"stress\", sel: \"fmp-ustress\", rule: \"pos\", label: \"Ultimate tensile strength Sut\", sym: \"Sut\" },\n    suc: { type: \"stress\", sel: \"fmp-ustress\", rule: \"pos\", label: \"Ultimate compressive strength Suc\", sym: \"Suc\" },\n    E: { type: \"E\", sel: \"fmp-uE\", rule: \"pos\", label: \"Young's modulus E\", sym: \"E\" },\n    kic: { type: \"K\", sel: \"fmp-uK\", rule: \"pos\", label: \"Fracture toughness KIC\", sym: \"KIC\" },\n    se: { type: \"stress\", sel: \"fmp-ustress\", rule: \"pos\", label: \"Fatigue strength Se\", sym: \"Se\" },\n    ncyc: { type: \"num\", rule: \"cycles\", label: \"Design life N\", sym: \"N\" },\n    tr: { type: \"time\", sel: \"fmp-utr\", rule: \"pos\", label: \"Creep rupture life tr\", sym: \"tr\" },\n    lmp: { type: \"num\", rule: \"pos\", label: \"Larson\u2013Miller parameter P\", sym: \"P(LM)\" },\n    lmpc: { type: \"num\", rule: \"lmpc\", label: \"Larson\u2013Miller constant C\", sym: \"C\" },\n    s1: { type: \"stress\", sel: \"fmp-ustress\", rule: \"any\", label: \"Principal stress \u03c31\", sym: \"\u03c31\" },\n    s2: { type: \"stress\", sel: \"fmp-ustress\", rule: \"any\", label: \"Principal stress \u03c32\", sym: \"\u03c32\" },\n    s3: { type: \"stress\", sel: \"fmp-ustress\", rule: \"any\", label: \"Principal stress \u03c33\", sym: \"\u03c33\" },\n    scrack: { type: \"stress\", sel: \"fmp-ustress\", rule: \"any\", label: \"Stress normal to crack \u03c3\", sym: \"\u03c3 (crack)\" },\n    smax: { type: \"stress\", sel: \"fmp-ustress\", rule: \"any\", label: \"Maximum cyclic stress \u03c3max\", sym: \"\u03c3max\" },\n    smin: { type: \"stress\", sel: \"fmp-ustress\", rule: \"any\", label: \"Minimum cyclic stress \u03c3min\", sym: \"\u03c3min\" },\n    sa: { type: \"stress\", sel: \"fmp-ustress\", rule: \"nonneg\", label: \"Alternating stress \u03c3a\", sym: \"\u03c3a\" },\n    sm: { type: \"stress\", sel: \"fmp-ustress\", rule: \"any\", label: \"Mean stress \u03c3m\", sym: \"\u03c3m\" },\n    kf: { type: \"num\", rule: \"kf\", label: \"Fatigue stress concentration factor Kf\", sym: \"Kf\" },\n    P: { type: \"force\", sel: \"fmp-uforce\", rule: \"nonneg\", neg: \"Enter the compressive load as a positive magnitude.\", label: \"Applied compressive load P\", sym: \"P\" },\n    cs: { type: \"stress\", sel: \"fmp-ustress\", rule: \"pos\", label: \"Applied stress for creep\", sym: \"creep stress\" },\n    T: { type: \"temp\", sel: \"fmp-utemp\", rule: \"temp\", label: \"Operating temperature\", sym: \"T\" },\n    ts: { type: \"time\", sel: \"fmp-uts\", rule: \"nonneg\", label: \"Service duration\", sym: \"tservice\" },\n    a: { type: \"crack\", sel: \"fmp-ucrack\", rule: \"pos\", label: \"Crack size a\", sym: \"a\" },\n    Y: { type: \"num\", rule: \"Y\", label: \"Geometry factor Y\", sym: \"Y\" },\n    L: { type: \"len\", sel: \"fmp-ulen\", rule: \"pos\", label: \"Unsupported length L\", sym: \"L\" },\n    kc: { type: \"num\", rule: \"kc\", label: \"Custom effective length factor K\", sym: \"K\" },\n    A: { type: \"len2\", sel: \"fmp-ulen\", rule: \"pos\", label: \"Cross-sectional area A\", sym: \"A\" },\n    I: { type: \"len4\", sel: \"fmp-ulen\", rule: \"pos\", label: \"Second moment of area I\", sym: \"I\" },\n    nreq: { type: \"num\", rule: \"nreq\", label: \"Required design safety factor\", sym: \"nreq\" }\n  };\n  var ORDER = [\"yield\", \"brittle\", \"fatigue\", \"buckling\", \"creep\"];\n  var MODE_NAME = { yield: \"Ductile Yielding\", brittle: \"Brittle Fracture\", fatigue: \"Fatigue Failure\", buckling: \"Elastic Buckling\", creep: \"Creep-Related Failure\" };\n  var MODE_DESC = {\n    yield: \"Von Mises (distortion-energy) criterion for isotropic ductile materials under a multiaxial stress state.\",\n    brittle: \"Principal stress screening against Sut and Suc for brittle materials, and Mode I fracture mechanics (KI vs KIC) when a crack is known or assumed.\",\n    fatigue: \"Modified Goodman screening of constant-amplitude cyclic stress against a corrected endurance limit or a design-life fatigue strength.\",\n    buckling: \"Euler elastic critical load of a slender, straight, concentrically loaded compression member with idealized end supports.\",\n    creep: \"Rupture-life ratio from user-supplied creep rupture data or a validated Larson\u2013Miller parameter. Temperature and service time are always recorded.\"\n  };\n  var KEND = { pp: 1.0, ff: 0.5, fp: 0.7, fr: 2.0 };\n  var KEND_NAME = { pp: \"Pinned\u2013Pinned\", ff: \"Fixed\u2013Fixed\", fp: \"Fixed\u2013Pinned\", fr: \"Fixed\u2013Free\", custom: \"Custom\" };\n  var MAT = {\n    carbon: { name: \"Carbon Steel\", beh: \"ductile\", info: \"Usually ductile at room temperature. Ferritic steels can become brittle below their ductile-to-brittle transition temperature, so check toughness for low-temperature service.\" },\n    alloy: { name: \"Alloy Steel\", beh: \"ductile\", info: \"Usually ductile. High-strength and through-hardened grades can have limited toughness and high notch sensitivity, so fracture mechanics checks are often important.\" },\n    stainless: { name: \"Stainless Steel\", beh: \"ductile\", info: \"Austenitic grades are ductile with no ductile-to-brittle transition; martensitic and duplex grades behave differently. Fatigue limits are often less distinct than for carbon steels, so prefer test data.\" },\n    aluminum: { name: \"Aluminum Alloy\", beh: \"ductile\", info: \"Aluminum alloys have no well-defined endurance limit, so fatigue requires a fatigue strength at a stated design life. Strength and creep resistance fall at comparatively modest elevated temperatures.\" },\n    castiron: { name: \"Cast Iron\", beh: \"brittle\", info: \"Gray cast iron is brittle, with a compressive strength several times its tensile strength, so the default behavior is Brittle. Ductile (nodular) iron may be set to Ductile if supported by data.\" },\n    titanium: { name: \"Titanium Alloy\", beh: \"ductile\", info: \"Usually ductile with a high strength-to-weight ratio. Fatigue performance is sensitive to microstructure, surface condition and dwell loading; use design-life fatigue data where no endurance limit is established.\" },\n    custom: { name: \"Custom Material\", beh: \"ductile\", info: \"Choose the material behavior and enter every property from a validated source. No assumptions are applied to custom materials.\" }\n  };\n  var CLS = {\n    low: { t: \"Low Utilization\", c: \"fmp-c-low\" },\n    mod: { t: \"Moderate Utilization\", c: \"fmp-c-mod\" },\n    near: { t: \"Near Criterion\", c: \"fmp-c-near\" },\n    exc: { t: \"Criterion Reached or Exceeded\", c: \"fmp-c-exc\" }\n  };\n  var CLS_SENT = {\n    low: \"Utilization is in the low band (below 0.50) for this criterion.\",\n    mod: \"Utilization is in the moderate band (0.50 to 0.80) for this criterion.\",\n    near: \"The result is near the criterion (0.80 to 1.00): small changes in load, properties or geometry could reach it.\",\n    exc: \"The selected criterion is reached or exceeded (U \u2265 1.00) with the entered data.\"\n  };\n  function grp(type) { return type === \"len2\" ? \"len\" : (type === \"len4\" ? \"len\" : type); }\n  function fac(type, unit) {\n    var g = UNITS[grp(type)][unit];\n    if (type === \"len2\") { return g * g; }\n    if (type === \"len4\") { return g * g * g * g; }\n    return g;\n  }\n  function toBaseU(type, v, unit) {\n    if (type === \"temp\") { return unit === \"F\" ? (v - 32) \/ 1.8 : (unit === \"K\" ? v - 273.15 : v); }\n    return v * fac(type, unit);\n  }\n  function fromBaseU(type, b, unit) {\n    if (type === \"temp\") { return unit === \"F\" ? b * 1.8 + 32 : (unit === \"K\" ? b + 273.15 : b); }\n    return b \/ fac(type, unit);\n  }\n  function unitText(type, unit) {\n    var t = ULAB[unit] || unit;\n    if (type === \"len2\") { return t + \"\u00b2\"; }\n    if (type === \"len4\") { return t + \"\u2074\"; }\n    return t;\n  }\n  \/* =====================================================================\n     NUMBER FORMATTING (never shows NaN or Infinity)\n     ===================================================================== *\/\n  function isNum(v) { return typeof v === \"number\" ? isFinite(v) : false; }\n  var SUPD = { \"0\": \"\u2070\", \"1\": \"\u00b9\", \"2\": \"\u00b2\", \"3\": \"\u00b3\", \"4\": \"\u2074\", \"5\": \"\u2075\", \"6\": \"\u2076\", \"7\": \"\u2077\", \"8\": \"\u2078\", \"9\": \"\u2079\", \"-\": \"\u207b\" };\n  function supStr(n) { return String(n).split(\"\").map(function (ch) { return SUPD[ch] || ch; }).join(\"\"); }\n  function fmtExp(v, sig) {\n    var e = Math.floor(Math.log(Math.abs(v)) \/ Math.LN10);\n    var ms = (v \/ Math.pow(10, e)).toFixed(sig - 1);\n    if (Math.abs(Number(ms)) >= 10) { e += 1; ms = (v \/ Math.pow(10, e)).toFixed(sig - 1); }\n    return ms.replace(\"-\", \"\u2212\") + \"\u00d710\" + supStr(e);\n  }\n  function fmtD(v, d) {\n    if (!isNum(v)) { return \"\u2014\"; }\n    var r = Number(v.toFixed(d));\n    if (r === 0) { r = 0; }\n    return (r < 0 ? \"\u2212\" : \"\") + Math.abs(r).toLocaleString(\"en-US\", { minimumFractionDigits: d, maximumFractionDigits: d });\n  }\n  function fmtA(v) {\n    if (!isNum(v)) { return \"\u2014\"; }\n    var a = Math.abs(v);\n    if (a === 0) { return \"0\"; }\n    if (a >= 1e7 ? true : a < 1e-3) { return fmtExp(v, 3); }\n    if (a >= 10000) { return fmtD(v, 0); }\n    if (a >= 1000) { return fmtD(v, 1); }\n    if (a >= 0.1) { return fmtD(v, 2); }\n    return fmtD(v, 4);\n  }\n  function fmtT(v) {\n    if (!isNum(v)) { return \"\u2014\"; }\n    var a = Math.abs(v);\n    if (a === 0) { return \"0\"; }\n    if (a >= 1e7 ? true : a < 1e-3) { return fmtExp(v, 4); }\n    var r = Number(v.toPrecision(6));\n    return (r < 0 ? \"\u2212\" : \"\") + Math.abs(r).toLocaleString(\"en-US\", { maximumFractionDigits: 4 });\n  }\n  function pct(U) { return isNum(U) ? fmtD(U * 100, 1) + \"%\" : \"\u2014\"; }\n  function sq(x) { return x * x; }\n  function makeFmt(u) {\n    function q(type, b, unit) { return fmtA(fromBaseU(type, b, unit)) + \" \" + unitText(type, unit); }\n    return {\n      S: function (b) { return q(\"stress\", b, u.stress); },\n      s: function (b) { return fmtT(fromBaseU(\"stress\", b, u.stress)); },\n      sp: function (b) { var t = fmtT(fromBaseU(\"stress\", b, u.stress)); return b < 0 ? \"(\" + t + \")\" : t; },\n      E: function (b) { return q(\"E\", b, u.E); },\n      K: function (b) { return q(\"K\", b, u.K); },\n      C: function (b) { return q(\"crack\", b, u.crack); },\n      L: function (b) { return q(\"len\", b, u.len); },\n      A: function (b) { return q(\"len2\", b, u.len); },\n      I: function (b) { return q(\"len4\", b, u.len); },\n      P: function (b) { return q(\"force\", b, u.force); },\n      T: function (b) { return fmtT(fromBaseU(\"temp\", b, u.temp)) + \" \" + ULAB[u.temp]; },\n      t: function (h) { return fmtA(h) + \" h\" + (h >= 8760 ? \" (\" + fmtA(h \/ 8760) + \" years)\" : \"\"); },\n      su: ULAB[u.stress]\n    };\n  }\n  function classify(U) {\n    if (U < 0.5) { return \"low\"; }\n    if (U < 0.8) { return \"mod\"; }\n    if (U < 1) { return \"near\"; }\n    return \"exc\";\n  }\n  \/* =====================================================================\n     VALIDATION RULES (applied to each non-empty field in base units)\n     ===================================================================== *\/\n  function checkRule(spec, b) {\n    switch (spec.rule) {\n      case \"pos\": if (!(b > 0)) { return \"Enter a value greater than zero.\"; } break;\n      case \"nonneg\": if (b < 0) { return spec.neg || \"Negative values are not allowed.\"; } break;\n      case \"cycles\": if (b < 1) { return \"Enter at least 1 cycle.\"; } if (b > 1e12) { return \"Enter at most 10\u00b9\u00b2 cycles.\"; } break;\n      case \"lmpc\": if (!(b > 0)) { return \"C must be greater than zero.\"; } if (b > 100) { return \"C must not exceed 100.\"; } break;\n      case \"kf\": if (b < 1) { return \"Kf must be at least 1.0 (1.0 means no stress concentration).\"; } if (b > 20) { return \"Kf must not exceed 20.\"; } break;\n      case \"Y\": if (!(b > 0)) { return \"Y must be greater than zero.\"; } if (b > 10) { return \"Y above 10 is outside the range of common geometry factors. Check the value.\"; } break;\n      case \"kc\": if (!(b > 0)) { return \"K must be greater than zero.\"; } if (b > 10) { return \"K must not exceed 10.\"; } break;\n      case \"nreq\": if (b < 1) { return \"The required safety factor must be at least 1.0.\"; } if (b > 100) { return \"Enter a factor of at most 100.\"; } break;\n      case \"temp\": if (b < -273.15) { return \"Temperature cannot be below absolute zero.\"; } if (b > 5000) { return \"Temperature must not exceed 5,000 \u00b0C.\"; } break;\n      default: break;\n    }\n    if (spec.type === \"stress\" ? Math.abs(b) > 1e5 : false) { return \"Magnitude exceeds 100,000 MPa. Check the value and unit.\"; }\n    if (spec.type === \"E\" ? b > 2e6 : false) { return \"A modulus above 2,000 GPa is not physically plausible. Check the unit.\"; }\n    if (spec.type === \"K\" ? b > 1000 : false) { return \"Fracture toughness above 1,000 MPa\u221am is not plausible. Check the unit.\"; }\n    return \"\";\n  }\n  \/* =====================================================================\n     ENGINE HELPERS\n     ===================================================================== *\/\n  function base(mode) {\n    return { mode: mode, status: \"ok\", reasons: [], missing: [], invalid: [], U: null, n: null, noDemand: false, noDemandText: \"\", primary: null, secondary: null, params: [], steps: [], warn: [], lead: \"\", scope: \"\", short: \"\", nName: \"n\", subName: \"\" };\n  }\n  function need(c, req, opt) {\n    var miss = [], inv = [];\n    req.forEach(function (k) { if (c.bad[k]) { inv.push(k); } else if (c.v[k] === null) { miss.push(k); } });\n    (opt || []).forEach(function (k) { if (c.bad[k]) { inv.push(k); } });\n    return { miss: miss, inv: inv };\n  }\n  function symList(keys) { return keys.map(function (k) { return F[k].sym; }).join(\", \"); }\n  function labelList(keys) { return keys.map(function (k) { return F[k].label; }).join(\", \"); }\n  function failed(c, r, chk) {\n    if (chk.inv.length) {\n      r.status = \"invalid\"; r.invalid = chk.inv; r.missing = chk.miss;\n      r.reasons.push(\"Invalid input: \" + chk.inv.map(function (k) { return F[k].label + \" (\" + c.bad[k] + \")\"; }).join(\"; \"));\n      if (chk.miss.length) { r.reasons.push(\"Missing required data: \" + labelList(chk.miss) + \".\"); }\n      r.short = \"invalid \" + symList(chk.inv);\n      return true;\n    }\n    if (chk.miss.length) {\n      r.status = \"missing\"; r.missing = chk.miss;\n      r.reasons.push(\"Missing required data: \" + labelList(chk.miss) + \".\");\n      r.short = \"missing \" + symList(chk.miss.slice(0, 4)) + (chk.miss.length > 4 ? \"\u2026\" : \"\");\n      return true;\n    }\n    return false;\n  }\n  function W(r, lvl, text) { r.warn.push({ lvl: lvl, text: text }); }\n  \/* ---------------------------------------------------------------------\n     MODE A: DUCTILE YIELDING (von Mises)\n     --------------------------------------------------------------------- *\/\n  function evalYield(c) {\n    var r = base(\"yield\"), v = c.v, f = c.f;\n    if (c.o.behavior === \"brittle\") {\n      r.status = \"na\"; r.short = \"not applicable to brittle behavior\";\n      r.reasons.push(\"The von Mises yielding criterion applies to ductile materials. Material behavior is set to Brittle, so this criterion is not evaluated. Use Brittle Fracture, or change the behavior setting if the material is genuinely ductile (for example ductile iron).\");\n      return r;\n    }\n    if (failed(c, r, need(c, [\"sy\", \"s1\", \"s2\", \"s3\"]))) { return r; }\n    var s1 = v.s1, s2 = v.s2, s3 = v.s3, sy = v.sy;\n    var vm = Math.sqrt((sq(s1 - s2) + sq(s2 - s3) + sq(s3 - s1)) \/ 2);\n    if (vm <= 1e-12 * Math.max(Math.abs(s1), Math.abs(s2), Math.abs(s3), sy)) { vm = 0; }\n    r.nName = \"ny\";\n    r.primary = { label: \"Von Mises equivalent stress \u03c3vm\", value: f.S(vm), sub: \"Compared with yield strength Sy = \" + f.S(sy) };\n    r.secondary = { label: \"Yield strength Sy\", value: f.S(sy), sub: \"Isotropic ductile material assumed\" };\n    if (vm === 0) { r.noDemand = true; r.U = 0; r.noDemandText = \"No yielding demand under the entered stress state\"; }\n    else { r.U = vm \/ sy; r.n = sy \/ vm; }\n    r.params = [[\"Principal stress \u03c31\", f.S(s1)], [\"Principal stress \u03c32\", f.S(s2)], [\"Principal stress \u03c33\", f.S(s3)], [\"Yield strength Sy\", f.S(sy)], [\"Material behavior\", \"Ductile\"]];\n    r.steps = [\n      \"\u03c3vm = \u221a{[(\u03c31 \u2212 \u03c32)\u00b2 + (\u03c32 \u2212 \u03c33)\u00b2 + (\u03c33 \u2212 \u03c31)\u00b2] \/ 2}\",\n      \"\u03c3vm = \u221a{[(\" + f.s(s1) + \" \u2212 \" + f.sp(s2) + \")\u00b2 + (\" + f.s(s2) + \" \u2212 \" + f.sp(s3) + \")\u00b2 + (\" + f.s(s3) + \" \u2212 \" + f.sp(s1) + \")\u00b2] \/ 2} = \" + f.S(vm),\n      r.noDemand ? \"\u03c3vm = 0, so no yielding safety factor is defined: no yielding demand under the entered stress state.\" : \"ny = Sy \/ \u03c3vm = \" + f.s(sy) + \" \/ \" + f.s(vm) + \" = \" + fmtD(r.n, 2),\n      \"Uy = \u03c3vm \/ Sy = \" + fmtD(r.U, 3) + \" (\" + pct(r.U) + \")\"\n    ];\n    r.lead = r.noDemand ? \"The entered principal stresses give zero von Mises equivalent stress (an equal-triaxial, purely hydrostatic state), so there is no yielding demand under this criterion.\" : \"The von Mises equivalent stress is \" + f.S(vm) + \", which is \" + pct(r.U) + \" of the yield strength (ny = \" + fmtD(r.n, 2) + \").\";\n    r.scope = \"This evaluates only the onset of yielding at the analyzed stress point; it does not predict plastic collapse, fracture, fatigue or buckling.\";\n    W(r, \"i\", \"The von Mises criterion is primarily applicable to isotropic ductile materials. Anisotropic, textured or brittle materials need other criteria.\");\n    if (s1 === s2 ? (s2 === s3 ? s1 > 0 : false) : false) { W(r, \"w\", \"Equal triaxial tension produces zero von Mises stress but high constraint, which can promote brittle (cleavage) fracture. Check fracture separately.\"); }\n    if (r.U >= 1) { W(r, \"w\", \"Yielding is predicted at this point. Whether local yielding is acceptable depends on the governing code (for example, local peak stresses may be allowed to yield while membrane stresses may not) and on the ductility of the material.\"); }\n    W(r, \"i\", \"Use stresses consistent with the question being asked: local peak stresses (including stress concentrations) for onset of local yielding, or nominal and linearized stresses where a design code specifies them.\");\n    return r;\n  }\n  \/* ---------------------------------------------------------------------\n     MODE B1: BRITTLE STRENGTH SCREENING (maximum principal stress)\n     --------------------------------------------------------------------- *\/\n  function evalBrittleStrength(c) {\n    var r = base(\"brittle\"), v = c.v, f = c.f;\n    r.subName = \"Principal stress screening\";\n    if (c.o.behavior !== \"brittle\") {\n      r.status = \"na\"; r.short = \"not applicable to ductile behavior\";\n      r.reasons.push(\"Maximum principal stress screening is intended for brittle materials such as gray cast iron or ceramics. Material behavior is set to Ductile, so use the yielding criterion, or fracture mechanics if a crack is present.\");\n      return r;\n    }\n    if (failed(c, r, need(c, [\"sut\", \"suc\", \"s1\", \"s2\", \"s3\"]))) { return r; }\n    var st = Math.max(0, v.s1, v.s2, v.s3), sc = Math.max(0, -v.s1, -v.s2, -v.s3);\n    var Ut = st \/ v.sut, Uc = sc \/ v.suc, Ub = Math.max(Ut, Uc);\n    var gov = Ut >= Uc ? \"tension\" : \"compression\";\n    r.nName = \"nb\";\n    r.U = Ub;\n    if (Ub === 0) { r.noDemand = true; r.noDemandText = \"No principal stress demand under the entered stress state\"; }\n    else { r.n = 1 \/ Ub; }\n    r.primary = { label: gov === \"tension\" ? \"Maximum principal tensile stress\" : \"Maximum principal compressive stress (magnitude)\", value: f.S(gov === \"tension\" ? st : sc), sub: \"Governing: \" + gov + \" \u00b7 compared with \" + (gov === \"tension\" ? \"Sut = \" + f.S(v.sut) : \"Suc = \" + f.S(v.suc)) };\n    r.secondary = { label: \"Tensile and compressive utilization\", value: \"Ut \" + pct(Ut) + \" \u00b7 Uc \" + pct(Uc), sub: \"Ub = max(Ut, Uc)\" };\n    r.params = [[\"Principal stresses \u03c31, \u03c32, \u03c33\", f.s(v.s1) + \", \" + f.s(v.s2) + \", \" + f.s(v.s3) + \" \" + f.su], [\"Ultimate tensile strength Sut\", f.S(v.sut)], [\"Ultimate compressive strength Suc\", f.S(v.suc)], [\"Tensile utilization Ut\", fmtD(Ut, 3)], [\"Compressive utilization Uc\", fmtD(Uc, 3)], [\"Governing\", gov]];\n    r.steps = [\n      \"Ut = max(0, \u03c31, \u03c32, \u03c33) \/ Sut = \" + f.s(st) + \" \/ \" + f.s(v.sut) + \" = \" + fmtD(Ut, 3),\n      \"Uc = max(0, \u2212\u03c31, \u2212\u03c32, \u2212\u03c33) \/ Suc = \" + f.s(sc) + \" \/ \" + f.s(v.suc) + \" = \" + fmtD(Uc, 3),\n      \"Ub = max(Ut, Uc) = \" + fmtD(Ub, 3) + (r.noDemand ? \" (no demand)\" : \"; nb = 1 \/ Ub = \" + fmtD(r.n, 2))\n    ];\n    r.lead = r.noDemand ? \"All principal stresses are zero, so there is no demand under the principal stress screening.\" : \"The governing \" + gov + \" principal stress uses \" + pct(Ub) + \" of the corresponding strength (Ut = \" + fmtD(Ut, 3) + \", Uc = \" + fmtD(Uc, 3) + \", nb = \" + fmtD(r.n, 2) + \").\";\n    r.scope = \"This is a simplified brittle-strength screening model and does not replace material-specific multiaxial fracture criteria. Brittle materials are highly sensitive to flaws and stress concentrations.\";\n    if (Ub >= 1) { W(r, \"e\", \"The selected brittle strength criterion has been reached or exceeded (Ub \u2265 1).\"); }\n    if (st > 0 ? sc > 0 : false) {\n      var cm = st \/ v.sut + sc \/ v.suc;\n      W(r, \"w\", \"Mixed tension and compression: brittle materials can fail below both individual limits. For comparison, the Coulomb\u2013Mohr utilization \u03c3A\/Sut \u2212 \u03c3B\/Suc = \" + fmtD(cm, 3) + \" (n = \" + fmtD(1 \/ cm, 2) + \"). Consider Coulomb\u2013Mohr or modified Mohr criteria for mixed stress states.\");\n    }\n    W(r, \"i\", \"Use peak local stresses: brittle materials do not redistribute stress by local yielding, so stress concentrations act at full value.\");\n    return r;\n  }\n  \/* ---------------------------------------------------------------------\n     MODE B2: FRACTURE MECHANICS (LEFM, KI vs KIC)\n     --------------------------------------------------------------------- *\/\n  function evalFracture(c) {\n    var r = base(\"brittle\"), v = c.v, f = c.f;\n    r.subName = \"Fracture mechanics\";\n    if (failed(c, r, need(c, [\"kic\", \"a\", \"Y\", \"scrack\"], [\"sy\"]))) { return r; }\n    var aM = v.a \/ 1000, sig = v.scrack, Y = v.Y, kic = v.kic;\n    var KI = sig > 0 ? Y * sig * Math.sqrt(Math.PI * aM) : 0;\n    r.nName = \"nf\";\n    if (KI === 0) { r.noDemand = true; r.U = 0; r.noDemandText = \"No Mode I demand: the stress normal to the crack is not tensile\"; }\n    else { r.U = KI \/ kic; r.n = kic \/ KI; }\n    r.primary = { label: \"Mode I stress intensity factor KI\", value: f.K(KI), sub: \"Compared with KIC = \" + f.K(kic) };\n    var ac = null, scrit = null;\n    if (sig > 0) { ac = sq(kic \/ (Y * sig)) \/ Math.PI * 1000; scrit = kic \/ (Y * Math.sqrt(Math.PI * aM)); }\n    r.secondary = ac === null ? { label: \"Critical crack size\", value: \"Not defined\", sub: \"No tensile stress normal to the crack\" } : { label: \"Critical crack size ac (same Y and \u03c3)\", value: f.C(ac), sub: \"Critical stress at the entered crack size: \" + f.S(scrit) };\n    r.params = [[\"Stress normal to crack \u03c3\", f.S(sig)], [\"Crack size a\", f.C(v.a)], [\"Geometry factor Y\", fmtT(Y)], [\"Fracture toughness KIC\", f.K(kic)], [\"Critical crack size ac\", ac === null ? \"\u2014\" : f.C(ac)], [\"Critical stress at a\", scrit === null ? \"\u2014\" : f.S(scrit)]];\n    r.steps = [\n      \"KI = Y\u00b7\u03c3\u00b7\u221a(\u03c0\u00b7a), evaluated in MPa and metres to give MPa\u221am\",\n      sig > 0 ? \"KI = \" + fmtT(Y) + \" \u00d7 \" + fmtT(sig) + \" MPa \u00d7 \u221a(\u03c0 \u00d7 \" + fmtT(aM) + \" m) = \" + fmtA(KI) + \" MPa\u221am\" + (c.u.K === \"MPam\" ? \"\" : \" = \" + f.K(KI)) : \"\u03c3 \u2264 0: the crack faces are not opened, so KI = 0 (no Mode I demand).\",\n      r.noDemand ? \"No fracture safety factor is defined without Mode I demand.\" : \"nf = KIC \/ KI = \" + fmtA(kic) + \" \/ \" + fmtA(KI) + \" = \" + fmtD(r.n, 2) + \" (both in MPa\u221am)\",\n      \"Uf = KI \/ KIC = \" + fmtD(r.U, 3) + \" (\" + pct(r.U) + \")\"\n    ];\n    r.lead = r.noDemand ? \"The stress normal to the crack is zero or compressive, so there is no Mode I crack driving force under this model.\" : \"The Mode I stress intensity factor is KI = \" + f.K(KI) + \", which is \" + pct(r.U) + \" of KIC (nf = \" + fmtD(r.n, 2) + \"). With the same Y and stress, the critical crack size would be about \" + f.C(ac) + \".\";\n    r.scope = \"KI versus KIC is valid only when linear elastic fracture mechanics applies (small-scale yielding) and KIC is a valid plane-strain toughness for the service temperature, thickness and loading rate.\";\n    W(r, \"i\", \"Y must correspond to the actual crack shape, location and loading, and a must be defined the same way as in the Y solution (for example edge-crack depth or centre-crack half-length).\");\n    if (v.sy !== null) {\n      var lim = 2.5 * sq(kic \/ v.sy) * 1000;\n      if (v.a < lim) { W(r, \"w\", \"The crack size is smaller than 2.5(KIC\/Sy)\u00b2 = \" + f.C(lim) + \". Plasticity at the crack tip may not be small compared with the crack, so plane-strain LEFM conditions may not be satisfied and the KIC comparison may not be valid. Consider an elastic-plastic assessment such as a failure assessment diagram (for example BS 7910 or API 579-1\/ASME FFS-1).\"); }\n      if (sig > 0.5 * v.sy) { W(r, \"w\", \"The stress normal to the crack is \" + pct(sig \/ v.sy) + \" of Sy. At this level plasticity and net-section collapse may control; LEFM alone can be unconservative.\"); }\n    } else {\n      W(r, \"i\", \"Enter Sy to check basic LEFM size requirements and the stress level relative to yield.\");\n    }\n    if (c.o.behavior === \"ductile\") { W(r, \"i\", \"For tough, ductile materials, plastic collapse or ductile tearing can govern before KI reaches KIC. Two-criterion methods (failure assessment diagrams) are commonly used.\"); }\n    if (r.U >= 1) { W(r, \"e\", \"KI \u2265 KIC: the fracture mechanics criterion is reached or exceeded with the entered crack and stress.\"); }\n    return r;\n  }\n  function evalBrittle(c, appr) {\n    var subs = [];\n    if (appr !== \"fracture\") { subs.push(evalBrittleStrength(c)); }\n    if (appr !== \"strength\") { subs.push(evalFracture(c)); }\n    var ok = subs.filter(function (s) { return s.status === \"ok\"; });\n    var r;\n    if (!ok.length) {\n      r = base(\"brittle\");\n      var st = subs.map(function (s) { return s.status; });\n      r.status = st.indexOf(\"invalid\") >= 0 ? \"invalid\" : (st.every(function (x) { return x === \"na\"; }) ? \"na\" : \"missing\");\n      subs.forEach(function (s) {\n        s.reasons.forEach(function (t) { r.reasons.push((subs.length > 1 ? s.subName + \": \" : \"\") + t); });\n        r.missing = r.missing.concat(s.missing); r.invalid = r.invalid.concat(s.invalid);\n      });\n      r.short = subs.map(function (s) { return (subs.length > 1 ? s.subName.toLowerCase() + \" \" : \"\") + s.short; }).join(\"; \");\n      r.subs = subs;\n      return r;\n    }\n    var gov = ok[0];\n    ok.forEach(function (s) { if (s.U > gov.U) { gov = s; } });\n    r = gov;\n    r.subs = subs;\n    if (subs.length > 1) {\n      var steps = [], params = [], warn = [];\n      subs.forEach(function (s) {\n        if (s.status === \"ok\") {\n          steps.push({ head: s.subName + (s === gov ? \" (governing)\" : \"\") });\n          steps = steps.concat(s.steps);\n          if (s !== gov) { params.push([s.subName + \" utilization\", pct(s.U) + (s.noDemand ? \" (no demand)\" : \"\")]); }\n          if (s !== gov) { warn = warn.concat(s.warn); }\n        } else {\n          params.push([s.subName, \"Not evaluated\"]);\n          warn.push({ lvl: \"i\", text: s.subName + \" not evaluated: \" + s.reasons.join(\" \") });\n        }\n      });\n      r.steps = steps; r.params = gov.params.concat(params); r.warn = gov.warn.concat(warn);\n    }\n    return r;\n  }\n  \/* ---------------------------------------------------------------------\n     MODE C: FATIGUE (modified Goodman)\n     --------------------------------------------------------------------- *\/\n  function evalFatigue(c) {\n    var r = base(\"fatigue\"), v = c.v, f = c.f, o = c.o;\n    if (o.material === \"aluminum\" ? o.fbasis === \"limit\" : false) {\n      r.status = \"invalid\"; r.short = \"needs design-life fatigue strength\";\n      r.reasons.push(\"Aluminum alloys do not have a well-defined endurance limit. Select \u201cFatigue strength Sf at a specified design life N\u201d and enter the fatigue strength and its cycle count.\");\n      return r;\n    }\n    var keys = [\"se\", \"sut\"].concat(o.cyc === \"maxmin\" ? [\"smax\", \"smin\"] : [\"sa\", \"sm\"]);\n    if (o.fbasis === \"life\") { keys.push(\"ncyc\"); }\n    if (failed(c, r, need(c, keys, [\"kf\", \"sy\"]))) { return r; }\n    var saN, smN;\n    if (o.cyc === \"maxmin\") { saN = (v.smax - v.smin) \/ 2; smN = (v.smax + v.smin) \/ 2; }\n    else { saN = v.sa; smN = v.sm; }\n    var kfIn = v.kf === null ? 1 : v.kf;\n    var kfA = o.notchIncl ? 1 : kfIn;\n    var kfM = o.kfMean ? kfA : 1;\n    var sa = kfA * saN, sm = kfM * smN;\n    var smU = sm;\n    if (sm < 0) { smU = o.cmean === \"lin\" ? sm : 0; }\n    var se = v.se, sut = v.sut, U;\n    r.nName = \"nfatigue\";\n    if (sa === 0 ? smU <= 0 : false) { U = 0; r.noDemand = true; r.noDemandText = \"No fatigue demand: no alternating stress and no tensile mean stress\"; }\n    else {\n      U = sa \/ se + smU \/ sut;\n      if (U <= 0) { U = 0; r.noDemand = true; r.noDemandText = \"No fatigue demand on the extended Goodman line\"; }\n    }\n    r.U = U; r.n = r.noDemand ? null : 1 \/ U;\n    var lifeTxt = o.fbasis === \"life\" ? \"fatigue strength at N = \" + fmtT(v.ncyc) + \" cycles\" : \"corrected endurance limit\";\n    var saAllow = se * (1 - smU \/ sut);\n    r.primary = { label: \"Applied alternating stress \u03c3a\" + (kfA > 1 ? \" (with Kf)\" : \"\"), value: f.S(sa), sub: \"Mean stress \u03c3m = \" + f.S(sm) + (smU !== sm ? \" (taken as 0 in the Goodman check)\" : \"\") };\n    r.secondary = { label: \"Allowable \u03c3a on the Goodman line at this mean stress\", value: saAllow > 0 ? f.S(saAllow) : \"None\", sub: \"Se = \" + f.S(se) + \" (\" + lifeTxt + \"), Sut = \" + f.S(sut) };\n    r.params = [];\n    if (o.cyc === \"maxmin\") { r.params.push([\"Maximum and minimum stress\", f.s(v.smax) + \" \/ \" + f.s(v.smin) + \" \" + f.su]); }\n    r.params.push([\"Nominal \u03c3a and \u03c3m\", f.s(saN) + \" \/ \" + f.s(smN) + \" \" + f.su]);\n    r.params.push([\"Kf applied to \u03c3a\" + (o.kfMean ? \" and \u03c3m\" : \"\"), o.notchIncl ? \"Not applied (included in Se)\" : fmtT(kfA)]);\n    r.params.push([\"Fatigue strength\", f.S(se) + \" (\" + lifeTxt + \")\"]);\n    r.params.push([\"Ultimate tensile strength Sut\", f.S(sut)]);\n    r.params.push([\"Compressive mean treatment\", sm < 0 ? (o.cmean === \"lin\" ? \"Goodman line extended\" : \"Conservative, \u03c3m \u2192 0\") : \"Not applicable (\u03c3m \u2265 0)\"]);\n    r.steps = [];\n    if (o.cyc === \"maxmin\") {\n      r.steps.push(\"\u03c3a = (\u03c3max \u2212 \u03c3min) \/ 2 = (\" + f.s(v.smax) + \" \u2212 \" + f.sp(v.smin) + \") \/ 2 = \" + f.S(saN));\n      r.steps.push(\"\u03c3m = (\u03c3max + \u03c3min) \/ 2 = (\" + f.s(v.smax) + \" + \" + f.sp(v.smin) + \") \/ 2 = \" + f.S(smN));\n    }\n    if (kfA !== 1) { r.steps.push(\"Local \u03c3a = Kf \u00d7 \u03c3a = \" + fmtT(kfA) + \" \u00d7 \" + f.s(saN) + \" = \" + f.S(sa) + (o.kfMean ? \"; local \u03c3m = \" + fmtT(kfA) + \" \u00d7 \" + f.sp(smN) + \" = \" + f.S(sm) : \"\")); }\n    if (smU !== sm) { r.steps.push(\"Compressive mean stress ignored (conservative): \u03c3m used = 0\"); }\n    r.steps.push(\"Ufatigue = \u03c3a \/ Se + \u03c3m \/ Sut = \" + f.s(sa) + \" \/ \" + f.s(se) + \" + \" + f.sp(smU) + \" \/ \" + f.s(sut) + \" = \" + fmtD(U, 3) + \" (\" + pct(U) + \")\");\n    r.steps.push(r.noDemand ? \"No fatigue safety factor is defined without demand.\" : \"nfatigue = 1 \/ Ufatigue = \" + fmtD(r.n, 2));\n    r.gm = { se: se, sut: sut, sa: sa, sm: sm, smU: smU, U: U, cmean: o.cmean, n: r.n };\n    r.lead = r.noDemand ? \"There is no fatigue demand under the modified Goodman criterion for the entered cycle.\" : \"With \u03c3a = \" + f.S(sa) + \" and \u03c3m = \" + f.S(smU) + \" in the Goodman check, the modified Goodman utilization is \" + fmtD(U, 3) + \" (nfatigue = \" + fmtD(r.n, 2) + \").\";\n    r.scope = \"This is a constant-amplitude fatigue screening against the supplied \" + lifeTxt + \", not a complete fatigue life prediction. Variable-amplitude loading, multiaxial or non-proportional stresses, fretting and corrosion fatigue are not covered.\";\n    if (o.fbasis === \"life\") { W(r, \"i\", \"The result applies only at the stated design life of \" + fmtT(v.ncyc) + \" cycles. It does not establish unlimited life.\"); }\n    else if (o.material === \"titanium\" ? true : (o.material === \"custom\" ? true : o.material === \"stainless\")) { W(r, \"w\", \"Confirm that this material has a well-defined endurance limit. If not, use a fatigue strength at a stated design life.\"); }\n    W(r, \"i\", \"Se must already include surface, size, loading-type, temperature and reliability corrections. The calculator does not estimate or correct it.\");\n    if (o.notchIncl ? kfIn > 1 : false) { W(r, \"i\", \"Kf = \" + fmtT(kfIn) + \" was not applied because the fatigue strength already includes the notch effect, avoiding double counting.\"); }\n    else if (kfA > 1) { W(r, \"i\", \"Kf = \" + fmtT(kfA) + \" was applied to the nominal alternating stress\" + (o.kfMean ? \" and the mean stress\" : \"\") + \". Make sure the supplied fatigue strength does not already include this notch effect.\"); }\n    if (sm < 0) { W(r, o.cmean === \"lin\" ? \"w\" : \"i\", o.cmean === \"lin\" ? \"The Goodman line was extended into the compressive mean stress region, crediting compression. This is not conservative and needs supporting test data.\" : \"Compressive mean stress detected: its beneficial effect was ignored (\u03c3m treated as 0), which is conservative.\"); }\n    if (sa === 0 ? smU > 0 : false) { W(r, \"w\", \"There is no alternating stress, so this is effectively a static case. The Goodman check reduces to \u03c3m\/Sut; use the yielding assessment for static loading.\"); }\n    if (v.sy !== null) {\n      var peak = sa + Math.abs(sm);\n      if (peak > v.sy) { W(r, \"e\", \"The peak stress \u03c3a + |\u03c3m| = \" + f.S(peak) + \" exceeds Sy: yielding is expected on the first cycle (Langer line). The Goodman criterion does not check for yielding.\"); }\n      else { W(r, \"i\", \"First-cycle yield check (Langer): ny = Sy \/ (\u03c3a + |\u03c3m|) = \" + fmtD(v.sy \/ peak, 2) + \".\"); }\n    } else { W(r, \"i\", \"Enter Sy to check first-cycle yielding, which the Goodman criterion does not cover.\"); }\n    if (c.o.behavior === \"brittle\") { W(r, \"w\", \"Goodman may be unconservative for gray cast iron, whose fatigue data often fall below the Goodman line. Use material-specific data.\"); }\n    if (U >= 1) { W(r, \"e\", \"The modified Goodman criterion is reached or exceeded: fatigue failure is predicted before the stated life under this simplified model.\"); }\n    W(r, \"i\", \"Assumes proportional, uniaxial loading at constant amplitude. Combined loading needs von Mises equivalent alternating and mean stresses or a multiaxial fatigue method.\");\n    return r;\n  }\n  \/* ---------------------------------------------------------------------\n     MODE D: ELASTIC BUCKLING (Euler)\n     --------------------------------------------------------------------- *\/\n  function evalBuckling(c) {\n    var r = base(\"buckling\"), v = c.v, f = c.f, o = c.o;\n    var keys = [\"E\", \"L\", \"I\", \"P\"];\n    if (o.endc === \"custom\") { keys.push(\"kc\"); }\n    if (failed(c, r, need(c, keys, [\"A\", \"sy\"]))) { return r; }\n    var K = o.endc === \"custom\" ? v.kc : KEND[o.endc];\n    var KL = K * v.L;\n    var Pcr = Math.PI * Math.PI * v.E * v.I \/ sq(KL);\n    var P = v.P;\n    r.nName = \"nbuckling\";\n    if (P === 0) { r.U = 0; r.noDemand = true; r.noDemandText = \"No compressive demand: the applied load is zero\"; }\n    else { r.U = P \/ Pcr; r.n = Pcr \/ P; }\n    r.primary = { label: \"Euler critical buckling load Pcr\", value: f.P(Pcr), sub: \"Applied compressive load P = \" + f.P(P) };\n    var lam = null, rg = null, scr = null, sap = null;\n    if (v.A !== null) { rg = Math.sqrt(v.I \/ v.A); lam = KL \/ rg; scr = Pcr \/ v.A; sap = P \/ v.A; }\n    r.secondary = lam === null ? { label: \"Slenderness ratio \u03bb\", value: \"Not calculated\", sub: \"Enter A to calculate \u03bb = KL\/r\" } : { label: \"Slenderness ratio \u03bb = KL\/r\", value: fmtD(lam, 1), sub: \"r = \u221a(I\/A) = \" + f.L(rg) + \" \u00b7 Euler stress \u03c3cr = \" + f.S(scr) };\n    r.params = [[\"Young's modulus E\", f.E(v.E)], [\"Second moment of area I\", f.I(v.I)], [\"Unsupported length L\", f.L(v.L)], [\"End condition\", KEND_NAME[o.endc] + \", K = \" + fmtT(K)], [\"Effective length KL\", f.L(KL)], [\"Applied load P\", f.P(P)]];\n    if (v.A !== null) { r.params.push([\"Cross-sectional area A\", f.A(v.A)]); r.params.push([\"Applied axial stress P\/A\", f.S(sap)]); }\n    r.steps = [\n      \"Pcr = \u03c0\u00b2\u00b7E\u00b7I \/ (K\u00b7L)\u00b2, evaluated in N, mm and MPa\",\n      \"Pcr = \u03c0\u00b2 \u00d7 \" + fmtT(v.E) + \" MPa \u00d7 \" + fmtT(v.I) + \" mm\u2074 \/ (\" + fmtT(K) + \" \u00d7 \" + fmtT(v.L) + \" mm)\u00b2 = \" + fmtA(Pcr) + \" N\" + (c.u.force === \"N\" ? \"\" : \" = \" + f.P(Pcr)),\n      r.noDemand ? \"P = 0: no buckling safety factor is defined.\" : \"nbuckling = Pcr \/ P = \" + fmtA(Pcr) + \" \/ \" + fmtA(P) + \" = \" + fmtD(r.n, 2) + \" (both in N)\",\n      \"Ubuckling = P \/ Pcr = \" + fmtD(r.U, 3) + \" (\" + pct(r.U) + \")\"\n    ];\n    if (lam !== null) { r.steps.push(\"\u03bb = K\u00b7L \/ \u221a(I\/A) = \" + fmtT(KL) + \" mm \/ \u221a(\" + fmtT(v.I) + \" \/ \" + fmtT(v.A) + \") mm = \" + fmtD(lam, 1)); }\n    r.lead = r.noDemand ? \"With zero applied load there is no buckling demand. The Euler critical load is \" + f.P(Pcr) + \".\" : \"The Euler critical load is \" + f.P(Pcr) + \" against an applied load of \" + f.P(P) + \", a utilization of \" + pct(r.U) + \" (nbuckling = \" + fmtD(r.n, 2) + \").\";\n    r.scope = \"Euler theory assumes a perfectly straight, elastic, concentrically loaded member with idealized end supports. Real capacities are lower because of imperfections, eccentricity, residual stresses and inelastic behavior, and Euler results are not universally valid for every structural component.\";\n    W(r, \"i\", \"The K values represent idealized supports. Real connections are rarely fully fixed; design guidance (for example the AISC commentary) recommends larger values such as 0.65 for fixed\u2013fixed, 0.8 for fixed\u2013pinned and 2.1 for fixed\u2013free.\");\n    if (lam !== null ? v.sy !== null : false) {\n      var Cc = Math.PI * Math.sqrt(2 * v.E \/ v.sy);\n      r.params.push([\"Transition slenderness Cc = \u03c0\u221a(2E\/Sy)\", fmtD(Cc, 1)]);\n      if (lam < Cc) {\n        var Pj = v.A * v.sy * (1 - v.sy * lam * lam \/ (4 * Math.PI * Math.PI * v.E));\n        W(r, \"w\", \"\u03bb = \" + fmtD(lam, 1) + \" is below the transition slenderness Cc = \" + fmtD(Cc, 1) + \". The member may be too stocky for elastic Euler buckling to govern: inelastic buckling controls and Euler overestimates the capacity. For comparison, the Johnson parabola gives about \" + f.P(Pj) + (P > 0 ? \" (utilization \" + pct(P \/ Pj) + \")\" : \"\") + \". Use the column curve of the applicable design code.\");\n      }\n      if (sap >= v.sy) { W(r, \"e\", \"The applied axial stress P\/A reaches or exceeds Sy: the section yields in compression regardless of buckling.\"); }\n      else if (scr > v.sy) { W(r, \"w\", \"The Euler stress \u03c3cr exceeds Sy, which confirms that elastic buckling cannot govern; yielding or inelastic buckling occurs first.\"); }\n    } else if (lam !== null) {\n      W(r, \"i\", \"Enter Sy to check whether the member is slender enough for elastic Euler buckling to govern.\");\n    } else {\n      W(r, \"i\", \"Enter the cross-sectional area A to calculate the slenderness ratio and check the elastic range.\");\n    }\n    W(r, \"w\", \"Imperfections, load eccentricity, residual stresses and local buckling of thin-walled sections can reduce capacity well below Pcr. Check I about the weakest axis that is not braced.\");\n    if (r.U >= 1) { W(r, \"e\", \"The applied load reaches or exceeds the Euler critical load.\"); }\n    return r;\n  }\n  \/* ---------------------------------------------------------------------\n     MODE E: CREEP RUPTURE-LIFE RATIO\n     --------------------------------------------------------------------- *\/\n  function evalCreep(c) {\n    var r = base(\"creep\"), v = c.v, f = c.f, o = c.o;\n    r.record = [[\"Operating temperature\", v.T === null ? (c.bad.T ? \"Invalid\" : \"Not entered\") : f.T(v.T)], [\"Service duration\", v.ts === null ? (c.bad.ts ? \"Invalid\" : \"Not entered\") : f.t(v.ts)], [\"Material\", o.matname || \"Not entered\"], [\"Applied stress\", v.cs === null ? \"Not entered\" : f.S(v.cs)]];\n    if (o.cmethod === \"none\") {\n      var bad = need(c, [], [\"T\", \"ts\", \"cs\"]);\n      if (bad.inv.length) { failed(c, r, bad); return r; }\n      r.status = \"insufficient\"; r.short = \"insufficient creep data\";\n      r.reasons.push(\"Insufficient creep material data for quantitative assessment.\");\n      r.reasons.push(\"Creep rupture life is not estimated from temperature and stress alone. Provide validated rupture data or Larson\u2013Miller parameters for this material.\");\n      return r;\n    }\n    var keys = [\"T\", \"ts\", \"cs\"].concat(o.cmethod === \"direct\" ? [\"tr\"] : [\"lmp\", \"lmpc\"]);\n    var chk = need(c, keys);\n    if (failed(c, r, chk)) {\n      if (!o.matname) { r.reasons.push(\"Also enter the material name or grade that the creep data refer to.\"); r.missingName = true; }\n      return r;\n    }\n    if (!o.matname) { r.status = \"missing\"; r.missingName = true; r.short = \"missing material name\"; r.reasons.push(\"Enter the material name or grade that the creep data refer to.\"); return r; }\n    var tr;\n    r.steps = [];\n    if (o.cmethod === \"direct\") {\n      if (!o.confirm) { r.status = \"missing\"; r.short = \"rupture data not confirmed\"; r.reasons.push(\"Confirm that the creep rupture life corresponds to the entered operating temperature and applied stress.\"); return r; }\n      tr = v.tr;\n      r.steps.push(\"tr = \" + f.t(tr) + \" (user-supplied rupture life at \" + f.T(v.T) + \" and \" + f.S(v.cs) + \")\");\n    } else {\n      var TK = v.T + 273.15;\n      if (!(TK > 0)) { r.status = \"invalid\"; r.short = \"invalid temperature\"; r.reasons.push(\"The absolute temperature must be above 0 K for the Larson\u2013Miller relation.\"); return r; }\n      var ex = v.lmp \/ TK - v.lmpc;\n      if (ex > 12) { r.status = \"invalid\"; r.short = \"rupture life out of range\"; r.reasons.push(\"The Larson\u2013Miller inputs give a rupture life above 10\u00b9\u00b2 hours, far outside any test data. Check P, C and the temperature.\"); return r; }\n      tr = Math.pow(10, ex);\n      r.steps.push(\"T = \" + fmtT(TK) + \" K; log\u2081\u2080 tr = P \/ T \u2212 C = \" + fmtT(v.lmp) + \" \/ \" + fmtT(TK) + \" \u2212 \" + fmtT(v.lmpc) + \" = \" + fmtD(ex, 3));\n      r.steps.push(\"tr = 10^\" + fmtD(ex, 3) + \" = \" + f.t(tr));\n    }\n    if (!isNum(tr) ? true : tr <= 0) { r.status = \"invalid\"; r.short = \"invalid rupture life\"; r.reasons.push(\"The rupture life is not a valid positive number.\"); return r; }\n    var ts = v.ts;\n    r.nName = \"n = tr\/tservice\";\n    if (ts === 0) { r.U = 0; r.noDemand = true; r.noDemandText = \"No creep demand: service duration is zero\"; }\n    else { r.U = ts \/ tr; r.n = tr \/ ts; }\n    r.primary = { label: \"Creep rupture life tr\", value: f.t(tr), sub: o.cmethod === \"direct\" ? \"User-supplied for \" + f.T(v.T) + \" and \" + f.S(v.cs) : \"From Larson\u2013Miller P = \" + fmtT(v.lmp) + \", C = \" + fmtT(v.lmpc) };\n    r.secondary = { label: \"Intended service duration\", value: f.t(ts), sub: \"Operating temperature \" + f.T(v.T) };\n    r.params = [[\"Material\", o.matname], [\"Operating temperature\", f.T(v.T)], [\"Applied stress\", f.S(v.cs)], [\"Service duration\", f.t(ts)], [\"Rupture data source\", o.cmethod === \"direct\" ? \"Direct rupture life (confirmed)\" : \"Larson\u2013Miller master curve\"], [\"Creep rupture life tr\", f.t(tr)]];\n    r.steps.push(\"Ucreep = tservice \/ trupture = \" + fmtA(ts) + \" h \/ \" + fmtA(tr) + \" h = \" + fmtD(r.U, 3) + \" (\" + pct(r.U) + \")\");\n    if (!r.noDemand) { r.steps.push(\"Life ratio tr \/ tservice = \" + fmtD(r.n, 2)); }\n    r.lead = r.noDemand ? \"With zero service duration there is no creep demand.\" : \"The intended service duration uses \" + pct(r.U) + \" of the creep rupture life at the entered conditions (tr\/tservice = \" + fmtD(r.n, 2) + \").\";\n    r.scope = \"This ratio is a simplified single-condition rupture-life utilization indicator, not a complete creep damage model.\";\n    W(r, \"w\", \"Creep deformation (strain) limits, varying temperature or stress (life-fraction summation), creep\u2013fatigue interaction, oxidation and environmental damage are not evaluated.\");\n    W(r, \"i\", \"Rupture data scatter widely. Design assessments normally use minimum or design rupture curves together with code-specified margins on stress or life.\");\n    if (o.cmethod === \"lmp\") { W(r, \"w\", \"Larson\u2013Miller results are reliable only within the stress and temperature range of the underlying data. Extrapolation to long lives can be unconservative.\"); }\n    if (r.U >= 1) { W(r, \"e\", \"The service duration reaches or exceeds the supplied creep rupture life.\"); }\n    return r;\n  }\n  \/* ---------------------------------------------------------------------\n     DISPATCH AND SAFETY GUARD\n     --------------------------------------------------------------------- *\/\n  function guard(r) {\n    if (r.status !== \"ok\") { return r; }\n    if (!isNum(r.U) ? true : (r.n !== null ? !isNum(r.n) : false)) {\n      var g = base(r.mode); g.status = \"invalid\"; g.short = \"non-finite result\";\n      g.reasons.push(\"The inputs produce a non-finite result. Check the values and units.\");\n      return g;\n    }\n    return r;\n  }\n  function evaluateMode(c, mode, appr) {\n    if (mode === \"yield\") { return guard(evalYield(c)); }\n    if (mode === \"brittle\") { return guard(evalBrittle(c, appr || c.o.appr)); }\n    if (mode === \"fatigue\") { return guard(evalFatigue(c)); }\n    if (mode === \"buckling\") { return guard(evalBuckling(c)); }\n    return guard(evalCreep(c));\n  }\n  function evaluateAll(c) {\n    var all = {};\n    ORDER.forEach(function (m) { all[m] = evaluateMode(c, m, \"both\"); });\n    return all;\n  }\n  \/* =====================================================================\n     USER INTERFACE\n     ===================================================================== *\/\n  function init() {\n    var root = document.getElementById(\"fmp-calculator\");\n    if (!root) { return; }\n    if (root.getAttribute(\"data-fmp-init\") === \"1\") { return; }\n    root.setAttribute(\"data-fmp-init\", \"1\");\n    function q(id) { return root.querySelector(\"#\" + id); }\n    function val(id) { var e = q(id); return e ? e.value : \"\"; }\n    function radio(name) { var e = root.querySelector('input[name=\"' + name + '\"]:checked'); return e ? e.value : \"\"; }\n    function setRadio(name, value) { var e = root.querySelector('input[name=\"' + name + '\"][value=\"' + value + '\"]'); if (e) { e.checked = true; } }\n    function h(tag, a, kids) {\n      var n = document.createElement(tag);\n      if (a) { Object.keys(a).forEach(function (k) { if (k === \"class\") { n.className = a[k]; } else if (k === \"text\") { n.textContent = a[k]; } else if (k === \"html\") { n.innerHTML = a[k]; } else { n.setAttribute(k, a[k]); } }); }\n      add(n, kids);\n      return n;\n    }\n    function add(n, kids) {\n      if (kids === undefined ? true : kids === null) { return; }\n      if (Array.isArray(kids)) { kids.forEach(function (k) { add(n, k); }); return; }\n      if (typeof kids === \"string\" ? true : typeof kids === \"number\") { n.appendChild(document.createTextNode(String(kids))); return; }\n      n.appendChild(kids);\n    }\n    function clear(n) { while (n.firstChild) { n.removeChild(n.firstChild); } }\n    var state = { last: null, live: false, view: \"single\", timer: null, rz: null, prevW: 0 };\n    var SELS = [\"fmp-ustress\", \"fmp-uE\", \"fmp-uK\", \"fmp-ucrack\", \"fmp-ulen\", \"fmp-uforce\", \"fmp-utemp\", \"fmp-uts\", \"fmp-utr\"];\n    \/* ---------- reading inputs ---------- *\/\n    function readOpts() {\n      return {\n        mode: radio(\"fmp-mode\") || \"yield\", material: val(\"fmp-material\"), behavior: val(\"fmp-behavior\"), matname: String(q(\"fmp-matname\").value).trim(),\n        fbasis: val(\"fmp-fbasis\"), notchIncl: q(\"fmp-notchincl\").checked, cyc: radio(\"fmp-cyc\") || \"maxmin\", kfMean: q(\"fmp-kfmean\").checked,\n        cmean: val(\"fmp-cmean\"), appr: radio(\"fmp-appr\") || \"both\", endc: val(\"fmp-endc\"), cmethod: val(\"fmp-cmethod\"), confirm: q(\"fmp-confirm\").checked, showAll: q(\"fmp-showall\").checked\n      };\n    }\n    function readUnits() {\n      return { stress: val(\"fmp-ustress\"), E: val(\"fmp-uE\"), K: val(\"fmp-uK\"), crack: val(\"fmp-ucrack\"), len: val(\"fmp-ulen\"), force: val(\"fmp-uforce\"), temp: val(\"fmp-utemp\"), ts: val(\"fmp-uts\"), tr: val(\"fmp-utr\") };\n    }\n    function readAll() {\n      var o = readOpts(), uu = {}, v = {}, bad = {}, disp = {};\n      SELS.forEach(function (id) { uu[id] = val(id); });\n      Object.keys(F).forEach(function (k) {\n        var spec = F[k], el = q(\"fmp-\" + k), s = String(el.value).trim();\n        v[k] = null;\n        if (s === \"\") { if (el.validity ? el.validity.badInput : false) { bad[k] = \"Enter a valid number.\"; } return; }\n        var n = Number(s);\n        if (!isFinite(n)) { bad[k] = \"Enter a valid number.\"; return; }\n        disp[k] = n;\n        var b = spec.sel ? toBaseU(spec.type, n, uu[spec.sel]) : n;\n        var msg = checkRule(spec, b);\n        if (msg) { bad[k] = msg; return; }\n        v[k] = b;\n      });\n      \/* cross-field checks *\/\n      if (v.sy !== null ? v.sut !== null : false) { if (v.sy > v.sut) { bad.sy = \"Yield strength cannot exceed the ultimate tensile strength.\"; v.sy = null; } }\n      if (v.se !== null ? v.sut !== null : false) { if (v.se >= v.sut) { bad.se = \"The fatigue strength must be lower than Sut.\"; v.se = null; } }\n      if (o.cyc === \"maxmin\" ? (v.smax !== null ? v.smin !== null : false) : false) { if (v.smin > v.smax) { bad.smin = \"The minimum stress cannot be greater than the maximum stress.\"; v.smin = null; } }\n      var u = readUnits();\n      return { v: v, bad: bad, disp: disp, o: o, u: u, f: makeFmt(u) };\n    }\n    \/* ---------- field errors ---------- *\/\n    function setErr(k, msg) {\n      var input = q(\"fmp-\" + k), e = q(\"fmp-\" + k + \"-err\");\n      if (e) { e.textContent = msg || \"\"; }\n      if (!input) { return; }\n      if (msg) { input.classList.add(\"fmp-invalid\"); input.setAttribute(\"aria-invalid\", \"true\"); }\n      else { input.classList.remove(\"fmp-invalid\"); input.removeAttribute(\"aria-invalid\"); }\n    }\n    function clearErrors() { Object.keys(F).forEach(function (k) { setErr(k, \"\"); }); setErr(\"matname\", \"\"); }\n    function showBad(bad) { Object.keys(bad).forEach(function (k) { setErr(k, bad[k]); }); }\n    function msg(text, good) { var m = q(\"fmp-msg\"); m.textContent = text || \"\"; m.className = \"fmp-form-msg\" + (good ? \" fmp-good\" : \"\"); }\n    \/* ---------- dependent visibility ---------- *\/\n    var COND = {\n      \"fmp-f-ncyc\": function (o) { return o.fbasis === \"life\"; },\n      \"fmp-f-smax\": function (o) { return o.cyc === \"maxmin\"; },\n      \"fmp-f-smin\": function (o) { return o.cyc === \"maxmin\"; },\n      \"fmp-f-sa\": function (o) { return o.cyc === \"amp\"; },\n      \"fmp-f-sm\": function (o) { return o.cyc === \"amp\"; },\n      \"fmp-f-kfmean\": function (o) { return !o.notchIncl; },\n      \"fmp-f-kc\": function (o) { return o.endc === \"custom\"; },\n      \"fmp-f-tr\": function (o) { return o.cmethod === \"direct\"; },\n      \"fmp-f-confirm\": function (o) { return o.cmethod === \"direct\"; },\n      \"fmp-f-lmp\": function (o) { return o.cmethod === \"lmp\"; },\n      \"fmp-f-lmpc\": function (o) { return o.cmethod === \"lmp\"; }\n    };\n    function activeTokens(o) {\n      if (o.showAll) { return [\"yield\", \"brittle\", \"brittleS\", \"brittleF\", \"fatigue\", \"buckling\", \"creep\"]; }\n      if (o.mode === \"brittle\") { return [\"brittle\"].concat(o.appr === \"strength\" ? [\"brittleS\"] : (o.appr === \"fracture\" ? [\"brittleF\"] : [\"brittleS\", \"brittleF\"])); }\n      return [o.mode];\n    }\n    function updateVisibility() {\n      var o = readOpts(), act = activeTokens(o);\n      var nodes = root.querySelectorAll(\"[data-modes]\"), i;\n      for (i = 0; i < nodes.length; i++) {\n        var nd = nodes[i], toks = nd.getAttribute(\"data-modes\").split(\" \");\n        var vis = toks.some(function (t) { return t === \"all\" ? true : act.indexOf(t) >= 0; });\n        var cond = COND[nd.id];\n        if (cond ? !cond(o) : false) { vis = false; }\n        nd.hidden = !vis;\n      }\n      var cards = root.querySelectorAll(\".fmp-incard\");\n      for (i = 0; i < cards.length; i++) {\n        var fs = cards[i].querySelectorAll(\"[data-modes]\"), any = false, j;\n        for (j = 0; j < fs.length; j++) { if (!fs[j].hidden) { any = true; } }\n        cards[i].hidden = !any;\n      }\n      q(\"fmp-modedesc\").textContent = MODE_DESC[o.mode];\n      var life = o.fbasis === \"life\";\n      q(\"fmp-se-label\").innerHTML = life ? \"Fatigue Strength at Design Life (S<sub>f<\/sub>)\" : \"Corrected Endurance Limit (S<sub>e<\/sub>)\";\n      q(\"fmp-kf\").disabled = o.notchIncl;\n      q(\"fmp-kf-hint\").textContent = o.notchIncl ? \"Not applied: the fatigue strength already includes the notch effect.\" : \"Applied to the nominal alternating stress. Leave blank (1.0) if the stresses are already local values.\";\n    }\n    function updateMaterialInfo() {\n      var o = readOpts(), m = MAT[o.material], box = q(\"fmp-matinfo\");\n      clear(box);\n      box.appendChild(h(\"strong\", { text: m.name + \". \" }));\n      box.appendChild(document.createTextNode(m.info + \" No property values are filled in automatically.\"));\n      if (o.behavior !== m.beh) { box.appendChild(document.createTextNode(\" Behavior has been changed from the default (\" + m.beh + \") for this material; make sure your data support this.\")); }\n      var lim = q(\"fmp-fbasis\").querySelector('option[value=\"limit\"]');\n      lim.disabled = o.material === \"aluminum\";\n      q(\"fmp-fbasis-hint\").textContent = o.material === \"aluminum\" ? \"Aluminum alloys have no well-defined endurance limit, so a fatigue strength at a stated design life is required.\" : \"Not every material has a true endurance limit. Aluminum alloys require a fatigue strength at a stated life.\";\n    }\n    function updateUnitLabels() {\n      var u = readUnits(), i, a;\n      a = root.querySelectorAll(\".fmp-ul-stress\"); for (i = 0; i < a.length; i++) { a[i].textContent = ULAB[u.stress]; }\n      a = root.querySelectorAll(\".fmp-ul-len\"); for (i = 0; i < a.length; i++) { a[i].textContent = unitText(\"len\", u.len); }\n      a = root.querySelectorAll(\".fmp-ul-len2\"); for (i = 0; i < a.length; i++) { a[i].textContent = unitText(\"len2\", u.len); }\n      a = root.querySelectorAll(\".fmp-ul-len4\"); for (i = 0; i < a.length; i++) { a[i].textContent = unitText(\"len4\", u.len); }\n    }\n    \/* converts already-entered values when a unit selector changes *\/\n    function onUnitChange(sel) {\n      var prev = sel.getAttribute(\"data-prev\"), now = sel.value;\n      if (!prev ? true : prev === now) { sel.setAttribute(\"data-prev\", now); return; }\n      Object.keys(F).forEach(function (k) {\n        if (F[k].sel !== sel.id) { return; }\n        var el = q(\"fmp-\" + k), s = String(el.value).trim();\n        if (s === \"\") { return; }\n        var n = Number(s);\n        if (!isFinite(n)) { return; }\n        var b = toBaseU(F[k].type, n, prev);\n        el.value = String(Number(fromBaseU(F[k].type, b, now).toPrecision(6)));\n      });\n      sel.setAttribute(\"data-prev\", now);\n      updateUnitLabels();\n    }\n    \/* =====================================================================\n       RESULTS RENDERING (DOM built with createElement)\n       ===================================================================== *\/\n    function badge(r) {\n      if (r.status !== \"ok\") { return h(\"span\", { class: \"fmp-badge fmp-c-ne\", text: r.status === \"na\" ? \"Not Evaluated (not applicable)\" : (r.status === \"insufficient\" ? \"Not Evaluated (insufficient data)\" : \"Not Evaluated\") }); }\n      var k = classify(r.U);\n      return h(\"span\", { class: \"fmp-badge \" + CLS[k].c, text: CLS[k].t });\n    }\n    function kpi(label, value, sub, na) {\n      return h(\"div\", { class: \"fmp-kpi\" }, [h(\"div\", { class: \"fmp-kpi-label\", text: label }), h(\"div\", { class: \"fmp-kpi-value\" + (na ? \" fmp-na\" : \"\"), text: value }), sub ? h(\"div\", { class: \"fmp-kpi-sub\", text: sub }) : null]);\n    }\n    function heroCard(o, primary) {\n      return h(\"div\", { class: \"fmp-hero-card\" + (primary ? \" fmp-primary\" : \"\") }, [h(\"div\", { class: \"fmp-hero-label\", text: o.label }), h(\"div\", { class: \"fmp-hero-value\", text: o.value }), o.sub ? h(\"div\", { class: \"fmp-hero-sub\", text: o.sub }) : null]);\n    }\n    function meter(U) {\n      var maxV = Math.max(1.25, Math.min(2, U * 1.08));\n      var p = function (x) { return (Math.min(x, maxV) \/ maxV * 100).toFixed(2) + \"%\"; };\n      var track = h(\"div\", { class: \"fmp-meter-track\", role: \"img\", \"aria-label\": \"Utilization \" + pct(U) + \" on a scale with bands at 0.5, 0.8 and 1.0\" });\n      track.style.setProperty(\"--fmp-b1\", p(0.5)); track.style.setProperty(\"--fmp-b2\", p(0.8)); track.style.setProperty(\"--fmp-b3\", p(1));\n      var fill = h(\"span\", { class: \"fmp-meter-fill\" }); fill.style.width = p(U); track.appendChild(fill);\n      [0.5, 0.8, 1].forEach(function (x) { var m = h(\"span\", { class: \"fmp-meter-mark\" }); m.style.left = p(x); track.appendChild(m); });\n      var scale = h(\"div\", { class: \"fmp-meter-scale\", \"aria-hidden\": \"true\" });\n      [0, 0.5, 0.8, 1].forEach(function (x) { var s = h(\"span\", { text: x === 0 ? \"0\" : String(x) }); s.style.left = p(x); if (x === 0) { s.style.transform = \"none\"; } scale.appendChild(s); });\n      var end = h(\"span\", { text: U > maxV ? \"> \" + fmtD(maxV, 2) : fmtD(maxV, 2) }); end.style.left = \"100%\"; end.style.transform = \"translateX(-100%)\"; scale.appendChild(end);\n      return h(\"div\", { class: \"fmp-meter\" }, [track, scale]);\n    }\n    function notesList(warn) {\n      var ul = h(\"ul\", { class: \"fmp-notes\" });\n      warn.forEach(function (w) {\n        var tag = w.lvl === \"e\" ? \"Critical: \" : (w.lvl === \"w\" ? \"Warning: \" : \"Note: \");\n        ul.appendChild(h(\"li\", { class: w.lvl === \"e\" ? \"fmp-n-e\" : (w.lvl === \"w\" ? \"fmp-n-w\" : \"\") }, [h(\"strong\", { text: tag }), w.text]));\n      });\n      return ul;\n    }\n    function paramsList(rows) {\n      var dl = h(\"dl\", { class: \"fmp-params\" });\n      rows.forEach(function (p) { dl.appendChild(h(\"div\", {}, [h(\"dt\", { text: p[0] }), h(\"dd\", { text: p[1] })])); });\n      return dl;\n    }\n    function stepsList(steps) {\n      var ol = h(\"ol\", { class: \"fmp-steps\" });\n      steps.forEach(function (s) { ol.appendChild(typeof s === \"string\" ? h(\"li\", { text: s }) : h(\"li\", { class: \"fmp-step-h\", text: s.head })); });\n      return ol;\n    }\n    function nreqText(r, nreq) {\n      if (nreq === null) { return { v: \"Not specified\", s: \"Optional design requirement\", na: true }; }\n      if (r.noDemand) { return { v: \"Met\", s: \"No demand for this criterion (nreq = \" + fmtT(nreq) + \")\" }; }\n      return r.n >= nreq ? { v: \"Met\", s: \"n = \" + fmtD(r.n, 2) + \" \u2265 nreq = \" + fmtT(nreq) } : { v: \"Not met\", s: \"n = \" + fmtD(r.n, 2) + \" < nreq = \" + fmtT(nreq) };\n    }\n    function interpretation(r, nreq) {\n      var parts = [r.lead];\n      if (!r.noDemand) { parts.push(CLS_SENT[classify(r.U)]); }\n      if (nreq !== null) {\n        if (r.noDemand) { parts.push(\"With no demand, the required design factor of \" + fmtT(nreq) + \" is not challenged by this criterion.\"); }\n        else { parts.push(r.n >= nreq ? \"The calculated factor \" + fmtD(r.n, 2) + \" meets the required design factor of \" + fmtT(nreq) + \" for this criterion.\" : \"The calculated factor \" + fmtD(r.n, 2) + \" is below the required design factor of \" + fmtT(nreq) + \".\"); }\n      }\n      if (r.U < 1) { parts.push(\"A utilization below 1 does not by itself mean the component is safe.\"); }\n      parts.push(r.scope);\n      return parts.join(\" \");\n    }\n    function renderSingle(r, c, body) {\n      var ok = r.status === \"ok\";\n      body.appendChild(h(\"div\", { class: \"fmp-res-head\" }, [h(\"div\", {}, [h(\"span\", { class: \"fmp-eyebrow\", text: \"Selected failure mode\" }), h(\"strong\", { class: \"fmp-res-title\", text: MODE_NAME[r.mode] + (r.subName ? \" \u00b7 \" + r.subName : \"\") })]), badge(r)]));\n      if (!ok) {\n        var box = h(\"div\", { class: \"fmp-ne-box\" });\n        box.appendChild(h(\"p\", {}, [h(\"strong\", { text: \"Not Evaluated. \" }), \"This criterion was not calculated, and it is not treated as safe.\"]));\n        r.reasons.forEach(function (t) { box.appendChild(h(\"p\", { text: t })); });\n        body.appendChild(box);\n        if (r.record) { body.appendChild(h(\"h3\", { class: \"fmp-sec\", text: \"Recorded operating conditions\" })); body.appendChild(paramsList(r.record)); }\n        return;\n      }\n      body.appendChild(h(\"div\", { class: \"fmp-hero\" }, [heroCard(r.primary, true), r.secondary ? heroCard(r.secondary, false) : null]));\n      var nr = nreqText(r, c.v.nreq);\n      body.appendChild(h(\"div\", { class: \"fmp-kpis\" }, [\n        kpi(\"Safety factor \" + r.nName, r.noDemand ? \"No demand\" : fmtD(r.n, 2), r.noDemand ? r.noDemandText : \"Capacity \u00f7 demand\", r.noDemand),\n        kpi(\"Utilization ratio U\", pct(r.U), \"U = \" + fmtD(r.U, 3)),\n        kpi(\"Preliminary assessment\", CLS[classify(r.U)].t, \"Illustrative band, not a code limit\"),\n        kpi(\"Required design factor\", nr.v, nr.s, nr.na)\n      ]));\n      body.appendChild(meter(r.U));\n      body.appendChild(h(\"h3\", { class: \"fmp-sec\", text: \"Engineering interpretation\" }));\n      body.appendChild(h(\"p\", { class: \"fmp-interp\", text: interpretation(r, c.v.nreq) }));\n      body.appendChild(h(\"h3\", { class: \"fmp-sec\", text: \"Governing input parameters\" }));\n      body.appendChild(paramsList(r.params));\n      body.appendChild(h(\"h3\", { class: \"fmp-sec\", text: \"Calculation steps\" }));\n      body.appendChild(stepsList(r.steps));\n      body.appendChild(h(\"h3\", { class: \"fmp-sec\", text: \"Assumptions, warnings and limitations\" }));\n      body.appendChild(notesList(r.warn));\n      body.appendChild(h(\"p\", { class: \"fmp-crit-note\", text: \"This is a numerical failure criterion result for preliminary screening. It is not a prediction of actual physical failure.\" }));\n    }\n    function renderResults() {\n      var L = state.last, body = q(\"fmp-res-body\");\n      clear(body);\n      if (!L) { body.appendChild(h(\"p\", { class: \"fmp-placeholder\", html: \"Enter the inputs for the selected mode and press <strong>Calculate<\/strong>.\" })); return; }\n      renderSingle(L.sel, L.c, body);\n    }\n    \/* =====================================================================\n       RUN\n       ===================================================================== *\/\n    function focusFirstError() {\n      var first = root.querySelector(\".fmp-invalid\");\n      if (first) { try { first.focus({ preventScroll: false }); } catch (e) { first.focus(); } }\n    }\n    function scrollToResults() {\n      var el = q(\"fmp-results\");\n      try { el.focus({ preventScroll: true }); } catch (e) { \/* ignore *\/ }\n      var rect = el.getBoundingClientRect(), vh = window.innerHeight || document.documentElement.clientHeight;\n      if (rect.top < 0 ? true : rect.top > vh * 0.6) { if (el.scrollIntoView) { el.scrollIntoView({ behavior: \"smooth\", block: \"start\" }); } }\n    }\n    function run(view, fromButton) {\n      var c = readAll();\n      clearErrors(); showBad(c.bad);\n      msg(\"\");\n      if (c.bad.nreq) { if (fromButton) { msg(\"Correct the required design safety factor.\"); focusFirstError(); } return; }\n      var sel = evaluateMode(c, c.o.mode);\n      if (view === \"single\") {\n        if (fromButton ? sel.status !== \"ok\" : false) {\n          sel.missing.forEach(function (k) { if (!c.bad[k]) { setErr(k, \"Required for this assessment.\"); } });\n          if (sel.missingName) { setErr(\"matname\", \"Required for a quantitative creep assessment.\"); }\n          msg(sel.status === \"na\" ? \"This criterion is not applicable to the selected material behavior.\" : (sel.status === \"insufficient\" ? \"Insufficient creep material data for quantitative assessment.\" : \"Some required inputs are missing or invalid. See the highlighted fields.\"));\n          focusFirstError();\n        }\n      }\n      state.last = { view: view, c: c, sel: sel };\n      state.live = true; state.view = view;\n      q(\"fmp-results\").hidden = false;\n      renderResults();\n      if (fromButton) { if (!root.querySelector(\".fmp-invalid\")) { scrollToResults(); } }\n    }\n    \/* =====================================================================\n       EXAMPLE AND RESET\n       ===================================================================== *\/\n    function setUnitsDefault() {\n      var D = { \"fmp-ustress\": \"MPa\", \"fmp-uE\": \"GPa\", \"fmp-uK\": \"MPam\", \"fmp-ucrack\": \"mm\", \"fmp-ulen\": \"mm\", \"fmp-uforce\": \"kN\", \"fmp-utemp\": \"C\", \"fmp-uts\": \"h\", \"fmp-utr\": \"h\" };\n      Object.keys(D).forEach(function (id) { q(id).value = D[id]; q(id).setAttribute(\"data-prev\", D[id]); });\n    }\n    function resetAll(keepMessage) {\n      Object.keys(F).forEach(function (k) { q(\"fmp-\" + k).value = \"\"; });\n      q(\"fmp-matname\").value = \"\";\n      setUnitsDefault();\n      q(\"fmp-material\").value = \"carbon\"; q(\"fmp-behavior\").value = \"ductile\";\n      q(\"fmp-fbasis\").value = \"limit\"; q(\"fmp-cmean\").value = \"cons\"; q(\"fmp-endc\").value = \"pp\"; q(\"fmp-cmethod\").value = \"none\";\n      q(\"fmp-notchincl\").checked = false; q(\"fmp-kfmean\").checked = false; q(\"fmp-confirm\").checked = false; q(\"fmp-showall\").checked = false;\n      setRadio(\"fmp-mode\", \"yield\"); setRadio(\"fmp-appr\", \"both\"); setRadio(\"fmp-cyc\", \"maxmin\");\n      clearErrors();\n      if (!keepMessage) { msg(\"\"); }\n      state.last = null; state.live = false; state.view = \"single\";\n      updateUnitLabels(); updateMaterialInfo(); updateVisibility(); renderResults(); q(\"fmp-results\").hidden = true;\n    }\n    \/* =====================================================================\n       EVENTS (bound once)\n       ===================================================================== *\/\n    var form = q(\"fmp-form\");\n    function onChange(e) {\n      var t = e.target;\n      if (!t) { return; }\n      if (SELS.indexOf(t.id) >= 0) { onUnitChange(t); }\n      if (t.id === \"fmp-material\") { q(\"fmp-behavior\").value = MAT[t.value].beh; if (t.value === \"aluminum\") { q(\"fmp-fbasis\").value = \"life\"; } }\n      if (t.id === \"fmp-material\" ? true : t.id === \"fmp-behavior\") { updateMaterialInfo(); }\n      updateVisibility();\n    }\n    function isChoice(t) { return !t ? false : (t.tagName === \"SELECT\" ? true : (t.type === \"radio\" ? true : t.type === \"checkbox\")); }\n    form.addEventListener(\"change\", function (e) { if (isChoice(e.target)) { onChange(e); } });\n    form.addEventListener(\"keydown\", function (e) { if (e.key === \"Enter\" ? (e.target ? e.target.tagName === \"INPUT\" : false) : false) { e.preventDefault(); run(\"single\", true); } });\n    q(\"fmp-calc\").addEventListener(\"click\", function () { run(\"single\", true); });\n    root.fmpEngine = { evaluateMode: evaluateMode, evaluateAll: evaluateAll, readAll: readAll };\n    resetAll(false);\n  }\n  if (document.getElementById(\"fmp-calculator\")) { init(); }\n  else if (document.readyState === \"loading\") { document.addEventListener(\"DOMContentLoaded\", init); }\n  else { init(); }\n})();\n<\/script>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The Material Failure Mode Prediction Calculator is a practical engineering tool designed to assess potential material failure mechanisms under different loading and operating conditions. Using&#8230;<\/p>","protected":false},"author":2,"featured_media":24970,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"pmpro_default_level":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[8647],"tags":[8772,8770,8773,8769,8771],"class_list":["post-24969","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-materials-science-and-properties","tag-failure-mode-prediction","tag-material-failure-analysis","tag-material-strength-analysis","tag-mechanical-failure-calculator","tag-structural-integrity","pmpro-has-access"],"acf":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/www.mechstream.com\/wp-content\/uploads\/2026\/10\/Material-Failure-Mode-Prediction-Calculator.png","_links":{"self":[{"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/posts\/24969","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/comments?post=24969"}],"version-history":[{"count":1,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/posts\/24969\/revisions"}],"predecessor-version":[{"id":24971,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/posts\/24969\/revisions\/24971"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/media\/24970"}],"wp:attachment":[{"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/media?parent=24969"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/categories?post=24969"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/tags?post=24969"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}