{"id":10451,"date":"2026-08-06T08:37:19","date_gmt":"2026-08-06T08:37:19","guid":{"rendered":"https:\/\/voyawave.com\/%e7%b4%a2%e5%bc%95%e6%a2%af%e5%ba%a6%e9%a1%b5%e9%9d%a2\/"},"modified":"2026-08-11T07:59:23","modified_gmt":"2026-08-11T07:59:23","slug":"%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97","status":"publish","type":"page","link":"https:\/\/voyawave.com\/zh-hans\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\/","title":{"rendered":"\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"10451\" class=\"elementor elementor-10451 elementor-10448\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f52bd78 e-con-full wd-section-stretch-content e-flex e-con e-parent\" data-id=\"f52bd78\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ad28b6b elementor-widget elementor-widget-html\" data-id=\"ad28b6b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97\u5668<\/title>\n<style>\n:root{\n  --bg:#ffffff;\n  --panel:#ffffff;\n  --soft:#fff6f6;\n  --line:#ead6d8;\n  --grid:#f3e2e4;\n  --text:#141414;\n  --muted:#75686a;\n  --accent:#b31222;\n  --accent2:#e33342;\n  --accentDark:#720912;\n  --shadow:0 12px 30px rgba(0,0,0,.08);\n  --radius:16px;\n}\n*{box-sizing:border-box}\nbody{\n  margin:0;\n  font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"Microsoft YaHei\",Arial,sans-serif;\n  background:\n    linear-gradient(90deg, rgba(179,18,34,.035) 1px, transparent 1px),\n    linear-gradient(rgba(179,18,34,.035) 1px, transparent 1px),\n    #fff;\n  background-size:42px 42px;\n  color:var(--text);\n}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app > header{\n  height:64px;padding:0 24px;display:flex;align-items:center;justify-content:space-between;\n  border-bottom:1px solid #efdadd;background:rgba(255,255,255,.94);\n  backdrop-filter:saturate(160%) blur(8px);position:static;\n  z-index:auto;\n}\n.brand{display:flex;align-items:center;gap:12px;font-weight:950;font-size:22px;color:#111}\n.logo{width:34px;height:34px;border-radius:9px;background:linear-gradient(135deg,var(--accent),var(--accent2));display:flex;align-items:center;justify-content:center;color:#fff;font-weight:900;box-shadow:0 8px 18px rgba(179,18,34,.24)}\n.logo svg{width:23px;height:23px}\n.layout{display:grid;grid-template-columns:430px 1fr 330px;gap:24px;padding:24px;align-items:start}\n.side,.main,.right-panel{display:flex;flex-direction:column;gap:18px}\n.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);padding:18px}\n.card-title{display:flex;align-items:center;gap:9px;font-size:17px;font-weight:950;margin-bottom:16px;color:#111}\n.mark{width:6px;height:18px;border-radius:9px;background:var(--accent);display:inline-block}\nbutton,select,input,textarea{font:inherit}\ninput,select,textarea{width:100%;border:1px solid #e0c5c8;background:#fff;border-radius:10px;padding:10px 12px;outline:none;color:#111}\n\/* \u4f7f\u7528\u81ea\u7ed8\u4e0b\u62c9\u7bad\u5934\uff0c\u907f\u514d Hostinger \/ \u9875\u9762\u4e3b\u9898\u9690\u85cf\u6d4f\u89c8\u5668\u539f\u751f select \u7bad\u5934 *\/\n.app select{\n  -webkit-appearance:none !important;\n  -moz-appearance:none !important;\n  appearance:none !important;\n  padding-right:38px !important;\n  background-color:#fff !important;\n  background-image:url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1.5 1.5 7 7l5.5-5.5' fill='none' stroke='%23b31222' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'\/%3E%3C\/svg%3E\") !important;\n  background-repeat:no-repeat !important;\n  background-position:right 12px center !important;\n  background-size:14px 9px !important;\n  cursor:pointer;\n}\n.app select::-ms-expand{display:none}\ninput:focus,select:focus,textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(179,18,34,.1)}\n.field{display:flex;flex-direction:column;gap:7px}\n.field label{font-size:13px;color:#43383a;font-weight:800}\n.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px 12px}\n.btn{border:1px solid var(--accent);background:var(--accent);color:#fff;padding:10px 16px;border-radius:10px;cursor:pointer;font-weight:800;transition:.15s ease;white-space:nowrap}\n.btn:hover{background:var(--accentDark);transform:translateY(-1px)}\n.btn.secondary{background:#fff;color:var(--accent)}\n.btn.secondary:hover{background:#fff2f3}\n.btn.ghost{border-color:#ead6d8;background:#fff;color:#111}\n.btn.full{width:100%;font-size:16px;padding:13px 18px}\n.top-actions,.data-row,.footer-actions{display:grid;grid-template-columns:1fr 1fr;gap:10px}\n.top-actions{display:flex;align-items:center}\n.mini-row{display:grid;grid-template-columns:1fr 1fr;gap:10px}\n.data-row{margin-top:10px}\n.lists{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:14px}\n.list-title{font-size:13px;font-weight:950;color:#111;margin-bottom:7px;display:flex;justify-content:space-between;align-items:center}\n.pill{display:inline-flex;align-items:center;justify-content:center;padding:4px 9px;border-radius:999px;background:#fff2f3;color:var(--accent);font-weight:900;font-size:12px;border:1px solid #f0c9cd}\n.data-list{height:130px;overflow:auto;border:1px solid #ead6d8;border-radius:10px;background:#fff;padding:8px}\n.data-item{display:flex;justify-content:space-between;gap:8px;padding:6px 8px;border-radius:8px;font-size:13px;align-items:center}\n.data-item:nth-child(odd){background:#fff7f7}\n.data-item button{border:0;background:transparent;color:var(--accent);cursor:pointer;font-weight:950}\n.hint{font-size:12px;color:var(--muted);line-height:1.65;margin:12px 0 0}\n.result-head{display:grid;grid-template-columns:1.5fr 1.2fr 1fr 1fr;gap:14px;align-items:end}\n.metric{background:#fff;border:1px solid #ead6d8;border-radius:13px;padding:13px 14px;min-height:75px;box-shadow:0 4px 15px rgba(0,0,0,.035)}\n.metric .label{color:#7f6f71;font-size:12px;font-weight:900;margin-bottom:8px}.metric .value{color:var(--accent);font-size:22px;font-weight:950;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}\n.tabs{display:flex;gap:8px;margin:2px 0 12px}.tab{padding:10px 18px;border-radius:10px 10px 0 0;border:1px solid #ead6d8;background:#fff;color:#4a4042;cursor:pointer;font-weight:950}.tab.active{background:var(--accent);border-color:var(--accent);color:#fff}\n.chart-wrap{border:1px solid #ead6d8;border-radius:12px;padding:14px;background:#fff;position:relative}canvas{width:100%;height:auto;display:block}\n.context-menu{position:fixed;z-index:9999;display:none;min-width:140px;background:#fff;border:1px solid #e0c5c8;border-radius:10px;box-shadow:0 12px 28px rgba(0,0,0,.16);padding:6px}\n.context-menu button{width:100%;border:0;background:#fff;color:#111;text-align:left;padding:9px 12px;border-radius:8px;cursor:pointer;font-weight:800}\n.context-menu button:hover{background:#fff2f3;color:var(--accent)}\n.chart-wrap canvas{cursor:crosshair}\n\n.table-wrap{max-height:370px;overflow:auto;border:1px solid #ead6d8;border-radius:10px}table{border-collapse:collapse;width:100%;font-size:13px}th,td{padding:10px;border-bottom:1px solid #f0e2e3;text-align:right;white-space:nowrap}th{background:#fff4f5;color:#111;font-weight:950;position:sticky;top:0;z-index:2}td:first-child,th:first-child{text-align:left}\n\/* Prevent Hostinger\/theme CSS from forcing table headers to uppercase. *\/\n.app .table-wrap th{\n  text-transform:none !important;\n  font-variant-caps:normal !important;\n}\n.codebox{background:#141414;color:#fff;border-radius:12px;padding:14px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.55;white-space:pre-wrap;min-height:95px}.status{padding:10px 12px;border-radius:10px;background:#fff7f7;border:1px solid #f1cbcf;color:#4a3032;font-size:13px;line-height:1.55}.status.error{background:#fff0f0;border-color:#ef9aa2;color:#7d0d18}.status.ok{background:#fff8f8;border-color:#e7c7ca;color:#262020}\n.legend-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-size:12px;color:#6e6062;margin-top:12px}.dot{width:10px;height:10px;border-radius:50%;background:var(--accent);display:inline-block}\n@media(max-width:1280px){.layout{grid-template-columns:380px 1fr}.right-panel{grid-column:1\/-1;display:grid;grid-template-columns:1fr 1fr}.result-head{grid-template-columns:1fr 1fr}}\n@media(max-width:900px){.layout{grid-template-columns:1fr}.right-panel{display:flex}.form-grid,.lists,.result-head{grid-template-columns:1fr}}\n<\/style>\n<\/head>\n<body>\n<div class=\"app\">\n<header>\n  <div class=\"brand\"><span class=\"logo\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M3 4.5h18L12 20 3 4.5Z\" stroke=\"white\" stroke-width=\"1.8\"\/><path d=\"M7 7h10l-5 8.5L7 7Z\" stroke=\"white\" stroke-width=\"1.2\"\/><path d=\"M9.2 9.2h5.6L12 14 9.2 9.2Z\" fill=\"white\" opacity=\".85\"\/><\/svg><\/span>\u6298\u5c04\u7387\u5206\u5e03<\/div>\n  <div class=\"top-actions\"><button class=\"btn secondary\" id=\"btnLoadDemo\">\u8f7d\u5165\u793a\u4f8b<\/button><button class=\"btn\" id=\"btnCalcTop\">\u5f00\u59cb\u8ba1\u7b97<\/button><\/div>\n<\/header>\n<main class=\"layout\">\n<aside class=\"side\">\n<section class=\"card\"><div class=\"card-title\"><span class=\"mark\"><\/span>\u5165\u5c04\u4e0e\u8ba1\u7b97\u53c2\u6570<\/div><div class=\"form-grid\">\n  <div class=\"field\"><label>\u6ce2\u957f \u03bb (nm)<\/label><input id=\"wavelength\" type=\"number\" step=\"0.001\" value=\"1553\"><\/div>\n  <div class=\"field\"><label>\u6a21\u5f0f\u7c7b\u578b<\/label><select id=\"activePol\"><option>TE<\/option><option selected>TM<\/option><\/select><\/div>\n  <div class=\"field\"><label>\u57fa\u5e95\u6298\u5c04\u7387 ns<\/label><input id=\"substrate\" type=\"number\" step=\"0.00001\" value=\"2.02603\"><\/div>\n  <div class=\"field\"><label>\u62df\u5408\u70b9\u6570<\/label><input id=\"fitPoints\" type=\"number\" step=\"1\" min=\"20\" value=\"200\"><\/div>\n  <div class=\"field\"><label>\u819c\u9636\u8865\u507f<\/label><input id=\"modeOffset\" type=\"number\" step=\"1\" value=\"0\"><\/div>\n  <div class=\"field\"><label>\u6ce2\u5bfc\u7ebf\u5bbd\u5ea6 (\u03bcm)<\/label><input id=\"guideWidth\" type=\"number\" step=\"0.1\" value=\"10\"><\/div>\n<\/div><\/section>\n<section class=\"card\"><div class=\"card-title\"><span class=\"mark\"><\/span>\u6dfb\u52a0\u6570\u636e<\/div>\n  <div class=\"mini-row\"><div class=\"field\"><label>\u6709\u6548\u6298\u5c04\u7387 n_eff<\/label><input id=\"neffInput\" type=\"number\" step=\"0.00001\" placeholder=\"\u5982 2.15829\"><\/div><div class=\"field\"><label>\u5feb\u901f\u6dfb\u52a0<\/label><button class=\"btn full\" id=\"btnAddActive\">\u6dfb\u52a0\u5230\u5f53\u524d\u6a21\u5f0f<\/button><\/div><\/div>\n  <div class=\"data-row\"><button class=\"btn secondary\" id=\"btnAddTE\">\u6dfb\u52a0 TE<\/button><button class=\"btn secondary\" id=\"btnAddTM\">\u6dfb\u52a0 TM<\/button><button class=\"btn ghost\" id=\"btnRemoveLast\">\u5220\u9664\u6700\u540e<\/button><button class=\"btn ghost\" id=\"btnClear\">\u5168\u90e8\u5220\u9664<\/button><\/div>\n  <div class=\"lists\"><div><div class=\"list-title\">TE <span class=\"pill\" id=\"teCount\">0<\/span><\/div><div class=\"data-list\" id=\"teList\"><\/div><\/div><div><div class=\"list-title\">TM <span class=\"pill\" id=\"tmCount\">0<\/span><\/div><div class=\"data-list\" id=\"tmList\"><\/div><\/div><\/div>\n<\/section>\n<section class=\"card\"><div class=\"card-title\"><span class=\"mark\"><\/span>\u7b97\u6cd5\u4e0e\u62df\u5408<\/div>\n  <div class=\"field\" style=\"margin-bottom:12px\"><label>\u6df1\u5ea6\u8ba1\u7b97\u65b9\u5f0f<\/label><select id=\"method\"><option value=\"chiang1985\" selected>K. S. Chiang 1985\uff1a\u5355\u4e00TE\/TM\u5e73\u6ed1\u5256\u9762<\/option><option value=\"white1976\">White-Heidrich 1976\uff1a\u5206\u6bb5\u7ebf\u6027\u8fd1\u4f3c<\/option><option value=\"chiang1996\">Chiang 1996\uff1aTE\/TM\u8054\u5408\u6a21\u5f0f<\/option><\/select><\/div>\n  <div class=\"field\"><label>\u6700\u7ec8\u62df\u5408\u516c\u5f0f<\/label><select id=\"formula\"><option value=\"exponential\" selected>Exponential  n(x)=ns+\u0394n\u00b7exp(-x\/D)<\/option><option value=\"gaussian\">Gaussian  n(x)=ns+\u0394n\u00b7exp(-x\u00b2\/D\u00b2)<\/option><option value=\"fermi\">Fermi  n(x)=ns+\u0394n\/(1+exp((x-D)\/a))<\/option><option value=\"slowFermi\">Slow Fermi  n(x)=ns+\u0394n\/(1-exp(-D)+exp(x-D))<\/option><option value=\"erfc\">Erfc  n(x)=ns+\u0394n\u00b7erfc(x\/D)<\/option><\/select><\/div>\n  <p class=\"hint\">\u8bf4\u660e\uff1a\u0394n = peakIndex \u2212 ns\u3002Erfc \u6309\u7269\u7406\u8870\u51cf\u5f0f erfc(x\/D) \u5b9e\u73b0\uff1b\u82e5\u5199\u6210 exp(x\/D)\uff0c\u6298\u5c04\u7387\u4f1a\u968f\u6df1\u5ea6\u589e\u52a0\u3002<\/p><button class=\"btn full\" id=\"btnCalc\">\u5f00\u59cb\u8ba1\u7b97<\/button>\n<\/section>\n<\/aside>\n<section class=\"main\">\n<section class=\"card\"><div class=\"result-head\"><div class=\"field\"><label>\u6700\u7ec8\u62df\u5408\u516c\u5f0f<\/label><select id=\"formulaMirror\"><\/select><\/div><div class=\"metric\"><div class=\"label\">peakIndex n0<\/div><div class=\"value\" id=\"n0Metric\">--<\/div><\/div><div class=\"metric\"><div class=\"label\">\u0394n<\/div><div class=\"value\" id=\"dnMetric\">--<\/div><\/div><div class=\"metric\"><div class=\"label\">R\u00b2<\/div><div class=\"value\" id=\"r2Metric\">--<\/div><\/div><\/div><\/section>\n<section class=\"card\"><div class=\"tabs\"><button class=\"tab active\" data-tab=\"curve\">\u62df\u5408\u66f2\u7ebf<\/button><button class=\"tab\" data-tab=\"map2d\">2D\u5206\u5e03\u56fe<\/button><\/div><div class=\"chart-wrap\" id=\"curvePanel\"><canvas id=\"curveCanvas\" width=\"1050\" height=\"640\"><\/canvas><\/div><div class=\"chart-wrap\" id=\"mapPanel\" style=\"display:none\"><canvas id=\"mapCanvas\" width=\"1050\" height=\"640\"><\/canvas><\/div><div class=\"legend-row\"><span class=\"dot\"><\/span>\u6a21\u5f0f\u8f6c\u6298\u6df1\u5ea6\u70b9 <span class=\"dot\" style=\"background:#111\"><\/span>\u62df\u5408\u66f2\u7ebf\/\u7b49\u503c\u7ebf <span>\u5355\u4f4d\uff1a\u03bcm<\/span><\/div><\/section>\n<\/section>\n<aside class=\"right-panel\">\n<section class=\"card\"><div class=\"card-title\"><span class=\"mark\"><\/span>\u8ba1\u7b97\u7ed3\u679c<\/div><div class=\"table-wrap\"><table><thead><tr><th>\u6a21\u5f0f<\/th><th>Pol<\/th><th>n_eff<\/th><th>\u6df1\u5ea6(\u03bcm)<\/th><\/tr><\/thead><tbody id=\"resultBody\"><tr><td colspan=\"4\" style=\"text-align:center;color:#888\">\u6682\u65e0\u6570\u636e<\/td><\/tr><\/tbody><\/table><\/div><\/section>\n<section class=\"card\"><div class=\"card-title\"><span class=\"mark\"><\/span>\u516c\u5f0f\u4e0e\u53c2\u6570<\/div><div class=\"codebox\" id=\"formulaText\">\u70b9\u51fb\u201c\u5f00\u59cb\u8ba1\u7b97\u201d\u540e\u663e\u793a\u3002<\/div><div class=\"status\" id=\"statusBox\" style=\"margin-top:12px\">\u5efa\u8bae\u5148\u70b9\u51fb\u201c\u8f7d\u5165\u793a\u4f8b\u201d\uff0c\u518d\u8ba1\u7b97\u3002<\/div><\/section>\n<section class=\"card\"><div class=\"card-title\"><span class=\"mark\"><\/span>\u5bfc\u51fa<\/div><div class=\"footer-actions\"><button class=\"btn secondary\" id=\"btnPngCurve\">\u5bfc\u51fa\u66f2\u7ebfPNG<\/button><button class=\"btn secondary\" id=\"btnPngMap\">\u5bfc\u51fa2D PNG<\/button><button class=\"btn ghost\" id=\"btnCsv\">\u5bfc\u51faCSV<\/button><button class=\"btn ghost\" id=\"btnPrint\">\u6253\u5370<\/button><\/div><\/section>\n<\/aside>\n<\/main>\n<\/div>\n<script>\n(function(){\n'use strict';\nfunction id(name){ return document.getElementById(name); }\nvar state = { te: [], tm: [], last: null, activeTab: 'curve', curveView: null, curveHome: null, curveHover: null, curveDrag: null, curveData: null };\nfunction fmt(v, n){ if(n === undefined) n = 6; return isFinite(v) ? Number(v).toFixed(n) : '--'; }\nfunction clamp(v, a, b){ return Math.max(a, Math.min(b, v)); }\nfunction sqr(v){ return v*v; }\nfunction linspace(a,b,n){ var arr=[]; if(n<=1){ arr.push(a); return arr; } for(var i=0;i<n;i++) arr.push(a+(b-a)*i\/(n-1)); return arr; }\nfunction maxArray(arr, fallback){ var m = (fallback === undefined ? -Infinity : fallback); for(var i=0;i<arr.length;i++){ if(arr[i] > m) m = arr[i]; } return m; }\nfunction minArray(arr, fallback){ var m = (fallback === undefined ? Infinity : fallback); for(var i=0;i<arr.length;i++){ if(arr[i] < m) m = arr[i]; } return m; }\nfunction erfc(x){\n  var z=Math.abs(x), t=1\/(1+0.5*z);\n  var r=t*Math.exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+t*(-0.82215223+t*0.17087277)))))))));\n  return x>=0 ? r : 2-r;\n}\nfunction getCfg(){\n  return { wavelengthNm: parseFloat(id('wavelength').value), ns: parseFloat(id('substrate').value), activePol: id('activePol').value,\n    fitPoints: Math.max(20, parseInt(id('fitPoints').value || '200',10)), modeOffset: parseInt(id('modeOffset').value || '0',10),\n    guideWidth: Math.max(0.5, parseFloat(id('guideWidth').value || '10')), method: id('method').value, formula: id('formula').value, na: 1.0 };\n}\nfunction setStatus(text, type){ var box=id('statusBox'); box.textContent=text; box.className='status '+(type || 'ok'); }\nfunction syncFormulaSelects(source){ var src=id(source), dst=(source==='formula' ? id('formulaMirror') : id('formula')); dst.innerHTML=id('formula').innerHTML; dst.value=src.value; }\nfunction renderLists(){\n  var offset=parseInt(id('modeOffset').value || '0',10);\n  var groups=['te','tm'];\n  for(var g=0; g<groups.length; g++){\n    (function(pol){\n      var list=id(pol+'List'); list.innerHTML='';\n      for(var i=0;i<state[pol].length;i++){\n        (function(ii){\n          var row=document.createElement('div'); row.className='data-item';\n          row.innerHTML='<span>m='+(ii+offset)+'<\/span><b>'+fmt(state[pol][ii],6)+'<\/b><button title=\"\u5220\u9664\">\u00d7<\/button>';\n          row.getElementsByTagName('button')[0].onclick=function(){ state[pol].splice(ii,1); renderLists(); };\n          list.appendChild(row);\n        })(i);\n      }\n      id(pol+'Count').textContent=state[pol].length;\n    })(groups[g]);\n  }\n}\nfunction addData(pol){ var v=parseFloat(id('neffInput').value); if(!isFinite(v)){ setStatus('\u8bf7\u8f93\u5165\u6709\u6548\u6298\u5c04\u7387 n_eff\u3002','error'); return; } state[pol.toLowerCase()].push(v); id('neffInput').value=''; renderLists(); }\nfunction loadDemo(){ id('wavelength').value='1553'; id('activePol').value='TM'; id('substrate').value='2.02603'; id('fitPoints').value='200'; id('modeOffset').value='0'; id('guideWidth').value='10'; id('method').value='chiang1985'; id('formula').value='exponential'; syncFormulaSelects('formula'); state.te=[]; state.tm=[2.15829,2.14047,2.13292]; renderLists(); calculateAll(); }\nfunction solveLinear(A,b){\n  var n=b.length;\n  for(var col=0; col<n; col++){\n    var pivot=col, max=Math.abs(A[col][col]);\n    for(var r=col+1;r<n;r++){ var vv=Math.abs(A[r][col]); if(vv>max){ max=vv; pivot=r; } }\n    if(max<1e-14) throw new Error('\u591a\u9879\u5f0f\u62df\u5408\u77e9\u9635\u5947\u5f02\uff0c\u8bf7\u51cf\u5c11\u9636\u6570\u6216\u68c0\u67e5\u8f93\u5165\u6570\u636e\u3002');\n    if(pivot!==col){ var tmp=A[pivot]; A[pivot]=A[col]; A[col]=tmp; var tb=b[pivot]; b[pivot]=b[col]; b[col]=tb; }\n    var diag=A[col][col]; for(var c=col;c<n;c++) A[col][c]\/=diag; b[col]\/=diag;\n    for(var rr=0; rr<n; rr++) if(rr!==col){ var f=A[rr][col]; if(Math.abs(f)>1e-14){ for(var cc=col;cc<n;cc++) A[rr][cc]-=f*A[col][cc]; b[rr]-=f*b[col]; } }\n  }\n  return b;\n}\nfunction polyFit(xs,ys,degree){\n  var n=degree+1, A=[], b=[]; for(var i=0;i<n;i++){ A[i]=[]; b[i]=0; for(var j=0;j<n;j++) A[i][j]=0; }\n  for(var p=0;p<xs.length;p++){\n    var xp=[]; xp[0]=1; for(var k=1;k<=2*degree;k++) xp[k]=xp[k-1]*xs[p];\n    for(var r=0;r<n;r++){ for(var c=0;c<n;c++) A[r][c]+=xp[r+c]; b[r]+=ys[p]*xp[r]; }\n  }\n  return solveLinear(A,b);\n}\nfunction polyEval(coef,x){ var y=0,p=1; for(var i=0;i<coef.length;i++){ y+=coef[i]*p; p*=x; } return y; }\nfunction phase(pol,N,n0,na){ var denom=n0*n0-N*N; if(denom<=1e-14) return Math.PI\/2; var ratio=(N*N-na*na)\/denom; if(ratio<0) ratio=0; var r=(pol==='TM') ? sqr(n0\/na) : 1.0; return Math.atan(r*Math.sqrt(ratio)); }\nfunction chiang1985(cfg){\n  var arr=(cfg.activePol==='TE') ? state.te : state.tm;\n  if(arr.length<3) throw new Error('Chiang 1985 \u81f3\u5c11\u9700\u8981\u540c\u4e00\u6a21\u5f0f\u7c7b\u578b\u7684 3 \u4e2a n_eff\u3002');\n  var modes=[]; for(var i=0;i<arr.length;i++) modes.push(i+cfg.modeOffset);\n  var degree=Math.min(2, arr.length-1), coef=polyFit(modes, arr, degree), n0=polyEval(coef,-0.75), dn=n0-cfg.ns;\n  if(!(dn>0)) throw new Error('\u8ba1\u7b97\u5f97\u5230\u7684 peakIndex \u672a\u9ad8\u4e8e\u57fa\u5e95\u6298\u5c04\u7387\uff0c\u8bf7\u68c0\u67e5 n_eff \u6216\u57fa\u5e95\u6298\u5c04\u7387\u3002');\n  var wavelengthUm=cfg.wavelengthNm\/1000, k=2*Math.PI\/wavelengthUm, N=[n0], depths=[]; for(i=0;i<arr.length;i++) N.push(arr[i]);\n  for(i=1;i<N.length;i++){\n    var Ni=N[i], alpha=modes[i-1]*Math.PI + phase(cfg.activePol, Ni, n0, cfg.na) + 0.25*Math.PI, sum=0;\n    for(var j=1;j<=i-1;j++){ var a=0.5*(N[j-1]+N[j]), bb=0.5*(N[j]+N[j+1]); sum += depths[j-1]*(Math.sqrt(Math.max(0,sqr(a)-sqr(Ni))) - Math.sqrt(Math.max(0,sqr(bb)-sqr(Ni)))); }\n    var Nbar=0.5*(N[i-1]+N[i]), denom2=sqr(Nbar)-sqr(Ni); if(denom2<=1e-14) throw new Error('WKB \u5206\u6bcd\u8fc7\u5c0f\uff0c\u6a21\u5f0f\u53ef\u80fd\u8fc7\u8fd1\u6216\u6570\u636e\u4e0d\u7a33\u5b9a\u3002');\n    var xi=(alpha\/k - sum)\/Math.sqrt(denom2); if(!(xi>=0) || !isFinite(xi)) throw new Error('\u6df1\u5ea6\u8ba1\u7b97\u51fa\u73b0\u65e0\u6548\u503c\uff0c\u8bf7\u68c0\u67e5\u6a21\u5f0f\u987a\u5e8f\u3002'); depths.push(xi);\n  }\n  var pts=[]; for(i=0;i<arr.length;i++) pts.push({mode:modes[i], pol:cfg.activePol, neff:arr[i], depth:depths[i]});\n  return {method:'Chiang 1985', peakIndex:n0, deltaN:dn, polyCoef:coef, points:pts};\n}\nfunction whiteDepthsNorm(arr,n0){\n  var n=[n0], z=[0]; for(var i=0;i<arr.length;i++) n.push(arr[i]);\n  for(i=1;i<n.length;i++){\n    var rhs=(4*i-1)\/8;\n    if(i===1){ z[i]=(9\/16)\/Math.sqrt(0.5*(n[0]+3*n[1]))\/Math.sqrt(n[0]-n[1]); continue; }\n    var prev=0, ni=n[i];\n    for(var k=1;k<=i-1;k++){ var nL=n[k-1], nR=n[k], dz=z[k]-z[k-1], dn=nL-nR, A=0.5*(nL+nR)+ni; prev += (2\/3)*Math.sqrt(A)*dz\/dn*(Math.pow(Math.max(0,nL-ni),1.5)-Math.pow(Math.max(0,nR-ni),1.5)); }\n    var ALast=0.5*(n[i-1]+3*n[i]), dnLast=n[i-1]-n[i], dZ=(rhs-prev)\/((2\/3)*Math.sqrt(ALast)*Math.sqrt(dnLast)); if(!(dZ>0)) throw new Error('invalid'); z[i]=z[i-1]+dZ;\n  }\n  return z;\n}\nfunction curvature(n,z){ var sum=0; for(var k=0;k<n.length-2;k++){ var s1=(n[k+1]-n[k])\/(z[k+1]-z[k]), s2=(n[k+2]-n[k+1])\/(z[k+2]-z[k+1]), gap=0.5*(z[k+2]-z[k]); sum+=sqr((s2-s1)\/gap); } return sum; }\nfunction white1976(cfg){\n  var arr=(cfg.activePol==='TE') ? state.te : state.tm; if(arr.length<2) throw new Error('White-Heidrich \u65b9\u6cd5\u81f3\u5c11\u9700\u8981 2 \u4e2a n_eff\u3002');\n  var n1=arr[0], nLast=arr[arr.length-1], span=Math.max(1e-5,n1-nLast), bestN0=n1+span*0.1, bestObj=Infinity, low=n1+1e-7, high=n1+Math.max(0.05,6*span);\n  for(var s=0;s<600;s++){ var n0=low+(high-low)*s\/599; try{ var z=whiteDepthsNorm(arr,n0), obj=curvature([n0].concat(arr),z); if(obj<bestObj){ bestObj=obj; bestN0=n0; } }catch(e){} }\n  var zz=whiteDepthsNorm(arr,bestN0), wavelengthUm=cfg.wavelengthNm\/1000, modes=[], pts=[]; for(var i=0;i<arr.length;i++){ modes.push(i+cfg.modeOffset); pts.push({mode:modes[i], pol:cfg.activePol, neff:arr[i], depth:zz[i+1]*wavelengthUm}); }\n  return {method:'White-Heidrich 1976', peakIndex:bestN0, deltaN:bestN0-cfg.ns, polyCoef:[], points:pts};\n}\nfunction chiang1996(cfg){\n  if(state.te.length === 0 || state.tm.length === 0) throw new Error('Chiang 1996\uff1aTE\/TM\u8054\u5408\u6a21\u5f0f\u5fc5\u987b\u540c\u65f6\u8f93\u5165 TE \u548c TM \u6570\u636e\uff1b\u53ea\u6709\u5355\u4e00 TE \u6216\u5355\u4e00 TM \u6570\u636e\u65f6\uff0c\u8bf7\u9009\u62e9 Chiang 1985 \u6216 White-Heidrich\u3002');\n  if(state.te.length + state.tm.length < 3) throw new Error('Chiang 1996 \u81f3\u5c11\u9700\u8981 TE\/TM \u5408\u8ba1 3 \u4e2a\u6570\u636e\u70b9\u3002');\n  var raw=[], i; for(i=0;i<state.te.length;i++) raw.push({mode:i+cfg.modeOffset, pol:'TE', neff:state.te[i]}); for(i=0;i<state.tm.length;i++) raw.push({mode:i+cfg.modeOffset, pol:'TM', neff:state.tm[i]});\n  var neffs=[]; for(i=0;i<raw.length;i++) neffs.push(raw[i].neff); var maxN=maxArray(neffs), minN=minArray(neffs), n0=maxN+0.75*Math.max(1e-4,maxN-minN), coef=[], eff=[];\n  for(var iter=0; iter<80; iter++){\n    eff=[]; for(i=0;i<raw.length;i++){ var p=raw[i], phiActual=phase(p.pol,p.neff,n0,cfg.na), phiTM=phase('TM',p.neff,n0,cfg.na); eff.push({mode:p.mode, pol:p.pol, neff:p.neff, mbar:p.mode+(phiActual-phiTM)\/Math.PI}); }\n    var xs=[], ys=[]; for(i=0;i<eff.length;i++){ xs.push(eff[i].mbar); ys.push(eff[i].neff); } coef=polyFit(xs,ys,Math.min(2,eff.length-1)); var nn=polyEval(coef,-0.75); if(Math.abs(nn-n0)<1e-10){ n0=nn; break; } n0=nn;\n  }\n  eff=[]; for(i=0;i<raw.length;i++){ var pr=raw[i], pa=phase(pr.pol,pr.neff,n0,cfg.na), pt=phase('TM',pr.neff,n0,cfg.na); eff.push({mode:pr.mode, pol:pr.pol, neff:pr.neff, mbar:pr.mode+(pa-pt)\/Math.PI}); }\n  eff.sort(function(a,b){ return b.neff-a.neff; });\n  var wavelengthUm=cfg.wavelengthNm\/1000, k=2*Math.PI\/wavelengthUm, N=[n0], depths=[]; for(i=0;i<eff.length;i++) N.push(eff[i].neff);\n  for(i=1;i<N.length;i++){\n    var pp=eff[i-1], Ni=N[i], alpha=(pp.mbar+0.25)*Math.PI+phase('TM',Ni,n0,cfg.na), sum=0;\n    for(var j=1;j<=i-1;j++){ var a=0.5*(N[j-1]+N[j]), bb=0.5*(N[j]+N[j+1]); sum += depths[j-1]*(Math.sqrt(Math.max(0,sqr(a)-sqr(Ni)))-Math.sqrt(Math.max(0,sqr(bb)-sqr(Ni)))); }\n    var Nbar=0.5*(N[i-1]+N[i]), xi=(alpha\/k-sum)\/Math.sqrt(sqr(Nbar)-sqr(Ni)); if(!(xi>=0)||!isFinite(xi)) throw new Error('Chiang 1996 \u6df1\u5ea6\u8ba1\u7b97\u51fa\u73b0\u65e0\u6548\u503c\u3002'); depths.push(xi); pp.depth=xi;\n  }\n  eff.sort(function(a,b){ var pc=a.pol.localeCompare(b.pol); return pc!==0 ? pc : a.mode-b.mode; });\n  var pts=[]; for(i=0;i<eff.length;i++) pts.push({mode:eff[i].mode, pol:eff[i].pol, neff:eff[i].neff, depth:eff[i].depth, mbar:eff[i].mbar});\n  return {method:'Chiang 1996 TE\/TM Combined', peakIndex:n0, deltaN:n0-cfg.ns, polyCoef:coef, points:pts};\n}\nfunction modelValue(type,x,params,ns,dn){\n  var D=params.D, a=params.a;\n  if(type==='exponential') return ns + dn*Math.exp(-x\/D);\n  if(type==='gaussian') return ns + dn*Math.exp(-sqr(x)\/sqr(D));\n  if(type==='fermi') return ns + dn\/(1+Math.exp((x-D)\/a));\n  if(type==='slowFermi') return ns + dn\/(1-Math.exp(-D)+Math.exp(x-D));\n  if(type==='erfc') return ns + dn*erfc(x\/D);\n  return ns;\n}\nfunction sseFor(type,points,params,ns,dn){ var s=0; for(var i=0;i<points.length;i++){ var r=points[i].neff-modelValue(type,points[i].depth,params,ns,dn); s+=r*r; } return s; }\nfunction r2For(type,points,params,ns,dn){ var mean=0; for(var i=0;i<points.length;i++) mean+=points[i].neff; mean\/=points.length; var sst=0; for(i=0;i<points.length;i++) sst+=sqr(points[i].neff-mean); var sse=sseFor(type,points,params,ns,dn); return sst<=1e-15 ? (sse<=1e-15?1:0) : 1-sse\/sst; }\nfunction fitOneParam(type,points,ns,dn){\n  var depths=[]; for(var i=0;i<points.length;i++) depths.push(points[i].depth); var maxDepth=maxArray(depths, 1);\n  var minD=0.001, maxD=Math.max(10000, maxDepth*100), bestD=1, bestS=Infinity;\n  for(var g=0; g<1600; g++){ var t=g\/1599, D=Math.exp(Math.log(minD)+t*(Math.log(maxD)-Math.log(minD))), ss=sseFor(type,points,{D:D,a:1},ns,dn); if(ss<bestS){ bestS=ss; bestD=D; } }\n  var lo=Math.log(bestD)-0.02, hi=Math.log(bestD)+0.02, gr=(Math.sqrt(5)-1)\/2;\n  for(var it=0; it<80; it++){ var c=hi-gr*(hi-lo), d=lo+gr*(hi-lo), sc=sseFor(type,points,{D:Math.exp(c),a:1},ns,dn), sd=sseFor(type,points,{D:Math.exp(d),a:1},ns,dn); if(sc<sd) hi=d; else lo=c; }\n  bestD=Math.exp((lo+hi)\/2); return {params:{D:bestD,a:1}, sse:sseFor(type,points,{D:bestD,a:1},ns,dn), r2:r2For(type,points,{D:bestD,a:1},ns,dn)};\n}\nfunction fitFermi(points,ns,dn){\n  var depths=[]; for(var i=0;i<points.length;i++) depths.push(points[i].depth); var maxDepth=Math.max(1, maxArray(depths,1)); var best={D:maxDepth\/2,a:Math.max(0.1,maxDepth\/5),sse:Infinity};\n  for(var iD=0;iD<120;iD++){\n    var D=0.01 + maxDepth*2*iD\/119;\n    for(var ia=0;ia<80;ia++){\n      var a=0.02 + maxDepth*1.5*ia\/79;\n      var ss=sseFor('fermi',points,{D:D,a:a},ns,dn);\n      if(ss<best.sse) best={D:D,a:a,sse:ss};\n    }\n  }\n  return {params:{D:best.D,a:best.a}, sse:best.sse, r2:r2For('fermi',points,{D:best.D,a:best.a},ns,dn)};\n}\nfunction fitFormula(points,type,ns,dn){ if(type==='fermi') return fitFermi(points,ns,dn); return fitOneParam(type,points,ns,dn); }\nfunction formulaText(type,fit,ns,dn){ var D=fit.params.D, a=fit.params.a; if(type==='exponential') return 'n(x) = '+fmt(ns,6)+' + '+fmt(dn,8)+' exp(-x \/ '+fmt(D,5)+')'; if(type==='gaussian') return 'n(x) = '+fmt(ns,6)+' + '+fmt(dn,8)+' exp(-x\u00b2 \/ '+fmt(D,5)+'\u00b2)'; if(type==='fermi') return 'n(x) = '+fmt(ns,6)+' + '+fmt(dn,8)+' \/ (1 + exp((x - '+fmt(D,5)+') \/ '+fmt(a,5)+'))'; if(type==='slowFermi') return 'n(x) = '+fmt(ns,6)+' + '+fmt(dn,8)+' \/ (1 - exp(-'+fmt(D,5)+') + exp(x - '+fmt(D,5)+'))'; if(type==='erfc') return 'n(x) = '+fmt(ns,6)+' + '+fmt(dn,8)+' erfc(x \/ '+fmt(D,5)+')'; return ''; }\nfunction calculateAll(){\n  try{\n    var cfg=getCfg(), result;\n    if(cfg.method==='chiang1985') result=chiang1985(cfg);\n    else if(cfg.method==='white1976') result=white1976(cfg);\n    else result=chiang1996(cfg);\n    var fit=fitFormula(result.points,cfg.formula,cfg.ns,result.deltaN);\n    state.last={cfg:cfg,result:result,fit:fit};\n    state.curveView=null; state.curveHome=null; state.curveHover=null; state.curveDrag=null;\n    updateOutputs(); drawCurve(); drawMap2D();\n    setStatus('\u8ba1\u7b97\u5b8c\u6210\u3002\u56fe\u8868\u548c\u53f3\u4fa7\u7ed3\u679c\u5df2\u66f4\u65b0\u3002','ok');\n  }\n  catch(err){ setStatus(err.message || String(err), 'error'); }\n}\nfunction updateOutputs(){\n  var cfg=state.last.cfg, result=state.last.result, fit=state.last.fit; id('n0Metric').textContent=fmt(result.peakIndex,6); id('dnMetric').textContent=fmt(result.deltaN,6); id('r2Metric').textContent=fmt(fit.r2,4);\n  var body=id('resultBody'); body.innerHTML=''; for(var i=0;i<result.points.length;i++){ var p=result.points[i], tr=document.createElement('tr'); tr.innerHTML='<td>m='+p.mode+'<\/td><td>'+p.pol+'<\/td><td>'+fmt(p.neff,6)+'<\/td><td>'+fmt(p.depth,5)+'<\/td>'; body.appendChild(tr); }\n  var coefText=''; if(result.polyCoef && result.polyCoef.length){ var parts=[]; for(i=0;i<result.polyCoef.length;i++) parts.push(fmt(result.polyCoef[i],10)); coefText='N(m)\u7cfb\u6570(\u5347\u5e42): ['+parts.join(', ')+']\\n'; }\n  id('formulaText').textContent=result.method+'\\npeakIndex n0 = '+fmt(result.peakIndex,8)+'\\n\u0394n = n0 - ns = '+fmt(result.deltaN,8)+'\\n'+coefText+'\\n\u62df\u5408\u516c\u5f0f\uff1a\\n'+formulaText(cfg.formula,fit,cfg.ns,result.deltaN)+'\\nR\u00b2 = '+fmt(fit.r2,8)+'\\nSSE = '+fit.sse.toExponential(6);\n}\nfunction drawAxes(ctx,rect,xMin,xMax,yMin,yMax,xLabel,yLabel,title,yIncreasingDown){\n  ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); ctx.fillStyle='#fff'; ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height); ctx.strokeStyle='#ecd9db'; ctx.lineWidth=1; ctx.font='14px Arial'; ctx.fillStyle='#4b4042';\n  var xTicks=5,yTicks=5;\n  for(var i=0;i<=xTicks;i++){ var x=rect.x+rect.w*i\/xTicks; ctx.beginPath(); ctx.moveTo(x,rect.y); ctx.lineTo(x,rect.y+rect.h); ctx.stroke(); var vx=xMin+(xMax-xMin)*i\/xTicks; ctx.fillText(fmt(vx,0),x-8,rect.y+rect.h+25); }\n  for(i=0;i<=yTicks;i++){ var y=rect.y+rect.h*i\/yTicks; ctx.beginPath(); ctx.moveTo(rect.x,y); ctx.lineTo(rect.x+rect.w,y); ctx.stroke(); var vy=yIncreasingDown ? yMin+(yMax-yMin)*i\/yTicks : yMax-(yMax-yMin)*i\/yTicks; ctx.fillText(fmt(vy,3),rect.x-58,y+5); }\n  ctx.strokeStyle='#111'; ctx.lineWidth=1.8; ctx.strokeRect(rect.x,rect.y,rect.w,rect.h); ctx.fillStyle='#111'; ctx.font='18px Arial'; ctx.textAlign='center'; ctx.fillText(xLabel,rect.x+rect.w\/2,ctx.canvas.height-20); ctx.save(); ctx.translate(24,rect.y+rect.h\/2); ctx.rotate(-Math.PI\/2); ctx.fillText(yLabel,0,0); ctx.restore(); ctx.textAlign='left'; if(title){ ctx.font='bold 20px Arial'; ctx.textAlign='center'; ctx.fillText(title,ctx.canvas.width\/2,30); ctx.textAlign='left'; }\n}\nfunction niceFloor(v, step){ return Math.floor(v\/step)*step; }\nfunction niceCeil(v, step){ return Math.ceil(v\/step)*step; }\nfunction curveToPixelX(x, rect, xMin, xMax){ return rect.x+(x-xMin)\/(xMax-xMin)*rect.w; }\nfunction curveToPixelY(y, rect, yMin, yMax){ return rect.y+rect.h-(y-yMin)\/(yMax-yMin)*rect.h; }\nfunction pixelToCurveX(px, rect, xMin, xMax){ return xMin+(px-rect.x)\/rect.w*(xMax-xMin); }\nfunction pixelToCurveY(py, rect, yMin, yMax){ return yMin+(rect.y+rect.h-py)\/rect.h*(yMax-yMin); }\nfunction mouseCanvasPos(evt, canvas){\n  var r=canvas.getBoundingClientRect();\n  return {x:(evt.clientX-r.left)*canvas.width\/r.width, y:(evt.clientY-r.top)*canvas.height\/r.height};\n}\nfunction insideRect(p, rect){ return p.x>=rect.x && p.x<=rect.x+rect.w && p.y>=rect.y && p.y<=rect.y+rect.h; }\nfunction defaultCurveRanges(cfg,result,fit){\n  var depths=[];\n  for(var i=0;i<result.points.length;i++) depths.push(result.points[i].depth);\n\n  \/\/ \u201c\u8fd8\u539f\u56fe\u50cf\u5927\u5c0f\u201d\u7684\u8303\u56f4\u4e25\u683c\u53d6\u5f53\u524d\u62df\u5408\u66f2\u7ebf\u6570\u636e\u7684 X\/Y \u6700\u5c0f\u503c\u548c\u6700\u5927\u503c\u3002\n  \/\/ \u62df\u5408\u66f2\u7ebf\u7684\u6709\u6548 X \u57df\u4ecd\u4e3a 0 ~ \u6700\u5927\u8ba1\u7b97\u6df1\u5ea6\u3002\n  var xMin=0;\n  var xMax=maxArray(depths,1);\n  if(!(xMax>xMin)) xMax=xMin+1;\n\n  \/\/ \u5bf9\u6574\u4e2a\u62df\u5408 X \u57df\u91c7\u6837\uff0c\u5f97\u5230\u62df\u5408\u66f2\u7ebf\u5b9e\u9645\u7684 Y \u6700\u5c0f\/\u6700\u5927\u503c\uff0c\n  \/\/ \u4e0d\u518d\u989d\u5916\u589e\u52a0 ns \u4ee5\u4e0b\u6216 peakIndex \u4ee5\u4e0a\u7684\u7559\u767d\u3002\n  var yMin=Infinity, yMax=-Infinity;\n  var sampleCount=Math.max(200, Math.min(2000, cfg.fitPoints*4));\n  for(i=0;i<sampleCount;i++){\n    var x=xMin+(xMax-xMin)*i\/(sampleCount-1);\n    var y=modelValue(cfg.formula,x,fit.params,cfg.ns,result.deltaN);\n    if(isFinite(y)){\n      if(y<yMin) yMin=y;\n      if(y>yMax) yMax=y;\n    }\n  }\n\n  \/\/ \u6781\u7aef\u60c5\u51b5\u4e0b\u9632\u6b62\u5750\u6807\u8f74\u9ad8\u5ea6\u4e3a 0\u3002\n  if(!isFinite(yMin) || !isFinite(yMax)){\n    yMin=cfg.ns;\n    yMax=result.peakIndex;\n  }\n  if(!(yMax>yMin)){\n    var eps=Math.max(1e-6,Math.abs(yMin)*1e-6);\n    yMin-=eps;\n    yMax+=eps;\n  }\n\n  return {xMin:xMin,xMax:xMax,yMin:yMin,yMax:yMax};\n}\nfunction drawCurveAxes(ctx,rect,xMin,xMax,yMin,yMax){\n  ctx.strokeStyle='#f3e0e3'; ctx.lineWidth=1; ctx.font='12px Arial'; ctx.fillStyle='#4b4042'; ctx.textAlign='center';\n  var xStep=0.5;\n  \/\/ Keep 0.5 \u03bcm ticks around normal\/detail views. If the user zooms far out,\n  \/\/ automatically thin grid lines to avoid drawing thousands of ticks.\n  var maxGridLines=220;\n  while((xMax-xMin)\/xStep>maxGridLines) xStep*=2;\n  var first=niceCeil(xMin,xStep);\n  for(var x=first; x<=xMax+1e-9; x+=xStep){\n    var px=curveToPixelX(x,rect,xMin,xMax);\n    var major=Math.abs((x\/1)-Math.round(x\/1))<1e-9;\n    ctx.strokeStyle=major?'#ead6d8':'#f6ebec';\n    ctx.beginPath(); ctx.moveTo(px,rect.y); ctx.lineTo(px,rect.y+rect.h); ctx.stroke();\n    if(major || (xMax-xMin)<=8){ ctx.fillStyle='#4b4042'; ctx.fillText(fmt(x, (xMax-xMin)<=8?1:0), px, rect.y+rect.h+22); }\n  }\n  ctx.textAlign='right';\n  var yStep=(yMax-yMin)\/5;\n  for(var i=0;i<=5;i++){\n    var yVal=yMin+yStep*i, py=curveToPixelY(yVal,rect,yMin,yMax);\n    ctx.strokeStyle='#ead6d8'; ctx.beginPath(); ctx.moveTo(rect.x,py); ctx.lineTo(rect.x+rect.w,py); ctx.stroke();\n    ctx.fillStyle='#4b4042'; ctx.fillText(fmt(yVal,4), rect.x-12, py+4);\n  }\n  ctx.strokeStyle='#111'; ctx.lineWidth=1.8; ctx.strokeRect(rect.x,rect.y,rect.w,rect.h);\n  ctx.fillStyle='#111'; ctx.font='18px Arial'; ctx.textAlign='center'; ctx.fillText('Depth (\u03bcm)',rect.x+rect.w\/2,ctx.canvas.height-20);\n  ctx.save(); ctx.translate(24,rect.y+rect.h\/2); ctx.rotate(-Math.PI\/2); ctx.fillText('Index',0,0); ctx.restore();\n  ctx.font='bold 20px Arial'; ctx.fillText('\u6298\u5c04\u7387 vs \u6df1\u5ea6',ctx.canvas.width\/2,30);\n}\nfunction drawCurve(){\n  if(!state.last) return;\n  var canvas=id('curveCanvas'), ctx=canvas.getContext('2d'), cfg=state.last.cfg, result=state.last.result, fit=state.last.fit;\n  var rect={x:80,y:55,w:900,h:500};\n  var home=defaultCurveRanges(cfg,result,fit);\n  if(!state.curveHome) state.curveHome={xMin:home.xMin,xMax:home.xMax,yMin:home.yMin,yMax:home.yMax};\n  if(!state.curveView) state.curveView={xMin:home.xMin,xMax:home.xMax,yMin:home.yMin,yMax:home.yMax};\n  state.curveView=clampCurveViewToHome(state.curveView);\n  var view=state.curveView;\n  ctx.clearRect(0,0,canvas.width,canvas.height); ctx.fillStyle='#fff'; ctx.fillRect(0,0,canvas.width,canvas.height);\n  drawCurveAxes(ctx,rect,view.xMin,view.xMax,view.yMin,view.yMax);\n  function tx(x){ return curveToPixelX(x,rect,view.xMin,view.xMax); }\n  function ty(y){ return curveToPixelY(y,rect,view.yMin,view.yMax); }\n  state.curveData={rect:rect, view:{xMin:view.xMin,xMax:view.xMax,yMin:view.yMin,yMax:view.yMax}};\n\n  ctx.save();\n  ctx.beginPath(); ctx.rect(rect.x,rect.y,rect.w,rect.h); ctx.clip();\n\n  ctx.strokeStyle='#b31524'; ctx.lineWidth=3; ctx.beginPath();\n  \/\/ Only generate and draw physical curve data in the valid depth domain:\n  \/\/ [0, maxDepth]. The axes themselves may be zoomed outside this range,\n  \/\/ but the curve will not be extended to negative or far-away depths.\n  var dataXMin=state.curveHome.xMin;\n  var dataXMax=state.curveHome.xMax;\n  var drawXMin=Math.max(view.xMin,dataXMin);\n  var drawXMax=Math.min(view.xMax,dataXMax);\n  var started=false;\n  if(drawXMax>drawXMin){\n    var validWidth=Math.max(1e-12,dataXMax-dataXMin);\n    var visibleRatio=(drawXMax-drawXMin)\/validWidth;\n    var N=Math.ceil(cfg.fitPoints*visibleRatio);\n    N=Math.max(40,Math.min(500,N));\n    if(N<2) N=2;\n    for(var i=0;i<N;i++){\n      var x=drawXMin+(drawXMax-drawXMin)*i\/(N-1);\n      var y=modelValue(cfg.formula,x,fit.params,cfg.ns,result.deltaN);\n      var px=tx(x), py=ty(y);\n      if(!started){ ctx.moveTo(px,py); started=true; } else ctx.lineTo(px,py);\n    }\n    ctx.stroke();\n  }\n\n  var hover=state.curveHover;\n  var nearestIndex=-1, nearestDist=1e9;\n  if(hover && insideRect(hover,rect)){\n    for(i=0;i<result.points.length;i++){\n      var pp=result.points[i];\n      var dx=tx(pp.depth)-hover.x, dy=ty(pp.neff)-hover.y, dd=Math.sqrt(dx*dx+dy*dy);\n      if(dd<nearestDist){ nearestDist=dd; nearestIndex=i; }\n    }\n  }\n  for(i=0;i<result.points.length;i++){\n    var p=result.points[i], radius=(i===nearestIndex && nearestDist<14)?8:5;\n    ctx.beginPath(); ctx.fillStyle='#111'; ctx.strokeStyle='#fff'; ctx.lineWidth=2;\n    ctx.arc(tx(p.depth),ty(p.neff),radius,0,Math.PI*2); ctx.fill(); ctx.stroke();\n    ctx.fillStyle='#b31524'; ctx.font='13px Arial'; ctx.fillText(p.pol+' m='+p.mode,tx(p.depth)+8,ty(p.neff)-8);\n  }\n\n  if(hover && insideRect(hover,rect)){\n    var hx=pixelToCurveX(hover.x,rect,view.xMin,view.xMax);\n    \/\/ The enlarged moving point is shown only when the mouse x lies on the\n    \/\/ actual calculated\/fitted curve domain [0, maxDepth].\n    if(hx>=state.curveHome.xMin && hx<=state.curveHome.xMax){\n      var hy=modelValue(cfg.formula,hx,fit.params,cfg.ns,result.deltaN);\n      var hpx=tx(hx), hpy=ty(hy);\n      ctx.strokeStyle='rgba(179,18,34,.65)'; ctx.lineWidth=1.5; ctx.setLineDash([5,5]);\n      ctx.beginPath(); ctx.moveTo(hpx,rect.y); ctx.lineTo(hpx,rect.y+rect.h); ctx.stroke(); ctx.setLineDash([]);\n      ctx.beginPath(); ctx.fillStyle='#fff'; ctx.strokeStyle='#b31524'; ctx.lineWidth=3; ctx.arc(hpx,hpy,8,0,Math.PI*2); ctx.fill(); ctx.stroke();\n      var tip='x='+fmt(hx,4)+' \u03bcm, n='+fmt(hy,6);\n      ctx.font='13px Arial'; var tw=ctx.measureText(tip).width+16, th=28;\n      var bx=Math.min(Math.max(hpx+12,rect.x+4),rect.x+rect.w-tw-4); var by=Math.max(rect.y+4,hpy-36);\n      ctx.fillStyle='rgba(255,255,255,.94)'; ctx.strokeStyle='#e0c5c8'; ctx.fillRect(bx,by,tw,th); ctx.strokeRect(bx,by,tw,th);\n      ctx.fillStyle='#111'; ctx.fillText(tip,bx+8,by+18);\n    }\n  }\n\n  if(state.curveDrag && state.curveDrag.active){\n    var x0=state.curveDrag.start.x, y0=state.curveDrag.start.y, x1=state.curveDrag.current.x, y1=state.curveDrag.current.y;\n    var rx=Math.min(x0,x1), ry=Math.min(y0,y1), rw=Math.abs(x1-x0), rh=Math.abs(y1-y0);\n    ctx.fillStyle='rgba(179,18,34,.12)'; ctx.strokeStyle='rgba(179,18,34,.8)'; ctx.lineWidth=1.5; ctx.setLineDash([4,3]);\n    ctx.fillRect(rx,ry,rw,rh); ctx.strokeRect(rx,ry,rw,rh); ctx.setLineDash([]);\n  }\n  ctx.restore();\n\n  ctx.fillStyle='#111'; ctx.font='14px Arial'; ctx.textAlign='left';\n  ctx.fillText(formulaText(cfg.formula,fit,cfg.ns,result.deltaN),rect.x+20,rect.y+28);\n  ctx.fillText('R\u00b2 = '+fmt(fit.r2,6),rect.x+20,rect.y+50);\n}\nfunction clampCurveViewToHome(v){\n  if(!state.curveHome) return v;\n  var home=state.curveHome;\n\n  \/\/ Important: do NOT clamp the axis to [0, maxDepth] here.\n  \/\/ The user may zoom\/pan axes freely. Curve data itself is clipped in drawCurve()\n  \/\/ to the physical domain [0, maxDepth], so no extra negative\/far-depth curve\n  \/\/ samples are generated or displayed.\n  if(!isFinite(v.xMin) || !isFinite(v.xMax) || !isFinite(v.yMin) || !isFinite(v.yMax)){\n    return {xMin:home.xMin,xMax:home.xMax,yMin:home.yMin,yMax:home.yMax};\n  }\n\n  var minXWidth=0.05;\n  var minYWidth=1e-5;\n  if(v.xMax<v.xMin){ var tx=v.xMin; v.xMin=v.xMax; v.xMax=tx; }\n  if(v.yMax<v.yMin){ var ty=v.yMin; v.yMin=v.yMax; v.yMax=ty; }\n\n  if(v.xMax-v.xMin<minXWidth){\n    var cx=(v.xMin+v.xMax)\/2;\n    v.xMin=cx-minXWidth\/2;\n    v.xMax=cx+minXWidth\/2;\n  }\n  if(v.yMax-v.yMin<minYWidth){\n    var cy=(v.yMin+v.yMax)\/2;\n    v.yMin=cy-minYWidth\/2;\n    v.yMax=cy+minYWidth\/2;\n  }\n\n  \/\/ A very loose safety cap avoids accidental browser freezes if the wheel is\n  \/\/ scrolled for a long time. This does not affect normal zoom\/pan use.\n  var homeWidth=Math.max(1e-6,home.xMax-home.xMin);\n  var maxWidth=Math.max(1000,homeWidth*200);\n  if(v.xMax-v.xMin>maxWidth){\n    var center=(v.xMin+v.xMax)\/2;\n    v.xMin=center-maxWidth\/2;\n    v.xMax=center+maxWidth\/2;\n  }\n  return v;\n}\nfunction resetCurveZoom(){ if(state.curveHome){ state.curveView={xMin:state.curveHome.xMin,xMax:state.curveHome.xMax,yMin:state.curveHome.yMin,yMax:state.curveHome.yMax}; drawCurve(); } }\nfunction setupCurveInteractions(){\n  var canvas=id('curveCanvas'); if(!canvas) return;\n  var menu=document.createElement('div'); menu.className='context-menu'; menu.innerHTML='<button type=\"button\" id=\"curveResetBtn\">\u8fd8\u539f\u56fe\u50cf\u5927\u5c0f<\/button>'; document.body.appendChild(menu);\n  document.getElementById('curveResetBtn').onclick=function(){ menu.style.display='none'; resetCurveZoom(); };\n  document.addEventListener('click',function(){ menu.style.display='none'; });\n  canvas.addEventListener('mousemove',function(evt){\n    if(!state.last || !state.curveData) return;\n    var p=mouseCanvasPos(evt,canvas), rect=state.curveData.rect;\n    if(state.curveDrag && state.curveDrag.active){ state.curveDrag.current={x:clamp(p.x,rect.x,rect.x+rect.w),y:clamp(p.y,rect.y,rect.y+rect.h)}; }\n    state.curveHover=p; drawCurve();\n  });\n  canvas.addEventListener('mouseleave',function(){ state.curveHover=null; if(state.curveDrag) state.curveDrag.active=false; drawCurve(); });\n  canvas.addEventListener('mousedown',function(evt){\n    if(evt.button!==0 || !state.last || !state.curveData) return;\n    var p=mouseCanvasPos(evt,canvas), rect=state.curveData.rect;\n    if(!insideRect(p,rect)) return;\n    state.curveDrag={active:true,start:{x:p.x,y:p.y},current:{x:p.x,y:p.y}}; evt.preventDefault(); drawCurve();\n  });\n  canvas.addEventListener('mouseup',function(evt){\n    if(!state.curveDrag || !state.curveDrag.active || !state.curveData) return;\n    var rect=state.curveData.rect, view=state.curveData.view;\n    var a=state.curveDrag.start, b=state.curveDrag.current;\n    state.curveDrag.active=false;\n    if(Math.abs(a.x-b.x)>8 && Math.abs(a.y-b.y)>8){\n      var x1=pixelToCurveX(Math.min(a.x,b.x),rect,view.xMin,view.xMax);\n      var x2=pixelToCurveX(Math.max(a.x,b.x),rect,view.xMin,view.xMax);\n      var yLow=pixelToCurveY(Math.max(a.y,b.y),rect,view.yMin,view.yMax);\n      var yHigh=pixelToCurveY(Math.min(a.y,b.y),rect,view.yMin,view.yMax);\n      if(x2-x1>1e-6 && yHigh-yLow>1e-9){ state.curveView=clampCurveViewToHome({xMin:x1,xMax:x2,yMin:yLow,yMax:yHigh}); }\n    }\n    drawCurve();\n  });\n  canvas.addEventListener('wheel',function(evt){\n    if(!state.last || !state.curveData || !state.curveView) return;\n    evt.preventDefault();\n    var p=mouseCanvasPos(evt,canvas), rect=state.curveData.rect; if(!insideRect(p,rect)) return;\n    var view=state.curveView, mx=pixelToCurveX(p.x,rect,view.xMin,view.xMax), my=pixelToCurveY(p.y,rect,view.yMin,view.yMax);\n    var factor=evt.deltaY<0 ? 0.85 : 1.18;\n    var newXMin=mx-(mx-view.xMin)*factor, newXMax=mx+(view.xMax-mx)*factor;\n    var newYMin=my-(my-view.yMin)*factor, newYMax=my+(view.yMax-my)*factor;\n    if(newXMax-newXMin<0.05 || newYMax-newYMin<1e-5) return;\n    state.curveView=clampCurveViewToHome({xMin:newXMin,xMax:newXMax,yMin:newYMin,yMax:newYMax}); drawCurve();\n  }, {passive:false});\n  canvas.addEventListener('contextmenu',function(evt){\n    if(!state.last) return; evt.preventDefault();\n    menu.style.display='block'; menu.style.left=evt.clientX+'px'; menu.style.top=evt.clientY+'px';\n  });\n}\nfunction jet(t){\n  t=clamp(t,0,1); var stops=[[0,5,5,90],[0.18,0,40,210],[0.36,0,180,255],[0.52,80,220,110],[0.68,255,230,30],[0.84,245,85,25],[1,150,0,0]];\n  for(var i=0;i<stops.length-1;i++){ var a=stops[i], b=stops[i+1]; if(t>=a[0] && t<=b[0]){ var u=(t-a[0])\/(b[0]-a[0]); return [Math.round(a[1]*(1-u)+b[1]*u),Math.round(a[2]*(1-u)+b[2]*u),Math.round(a[3]*(1-u)+b[3]*u)]; } }\n  return [150,0,0];\n}\nfunction drawMap2D(){\n  if(!state.last) return; var canvas=id('mapCanvas'), ctx=canvas.getContext('2d'), cfg=state.last.cfg, result=state.last.result, fit=state.last.fit;\n  ctx.clearRect(0,0,canvas.width,canvas.height); ctx.fillStyle='#fff'; ctx.fillRect(0,0,canvas.width,canvas.height);\n  var rect={x:72,y:45,w:860,h:520}; var depthVals=[]; for(var di=0;di<result.points.length;di++) depthVals.push(result.points[di].depth); var maxDepth=maxArray(depthVals,1);\n  var xMin=0, xMax=Math.max(20,cfg.guideWidth*4), yMin=0, yMax=Math.max(20,maxDepth*2.2); var centerX=cfg.guideWidth*1.25, sigma0=cfg.guideWidth\/3.2, ellipseDepth=yMax*0.78;\n  var img=ctx.createImageData(rect.w,rect.h);\n  for(var py=0;py<rect.h;py++){\n    var y=yMin+(yMax-yMin)*py\/(rect.h-1), nDepth=modelValue(cfg.formula,y,fit.params,cfg.ns,result.deltaN);\n    var taper=Math.sqrt(Math.max(0.05*0.05,1-sqr(clamp(y\/ellipseDepth,0,1))));\n    var envelope=Math.sqrt(Math.max(0.02*0.02,1-sqr(clamp(y\/(ellipseDepth*1.05),0,1))));\n    var sigma=sigma0*taper;\n    for(var px=0;px<rect.w;px++){\n      var x=xMin+(xMax-xMin)*px\/(rect.w-1), lateral=Math.exp(-sqr(x-centerX)\/(2*sqr(sigma)));\n      var n=cfg.ns+(nDepth-cfg.ns)*lateral*envelope, tt=(n-cfg.ns)\/(result.peakIndex-cfg.ns), rgb=jet(tt), idx=(py*rect.w+px)*4;\n      img.data[idx]=rgb[0]; img.data[idx+1]=rgb[1]; img.data[idx+2]=rgb[2]; img.data[idx+3]=255;\n    }\n  }\n  ctx.putImageData(img,rect.x,rect.y);\n  ctx.strokeStyle='#111'; ctx.lineWidth=1.8; ctx.strokeRect(rect.x,rect.y,rect.w,rect.h); ctx.font='14px Arial'; ctx.fillStyle='#111'; ctx.textAlign='center';\n  for(var i=0;i<=4;i++){ var xx=rect.x+rect.w*i\/4, vx=xMin+(xMax-xMin)*i\/4; ctx.fillText(fmt(vx,0),xx,rect.y+rect.h+24); ctx.strokeStyle='rgba(255,255,255,.45)'; ctx.beginPath(); ctx.moveTo(xx,rect.y); ctx.lineTo(xx,rect.y+rect.h); ctx.stroke(); }\n  ctx.textAlign='right'; for(i=0;i<=4;i++){ var yy=rect.y+rect.h*i\/4, vy=yMin+(yMax-yMin)*i\/4; ctx.fillText(fmt(vy,0),rect.x-12,yy+5); ctx.strokeStyle='rgba(255,255,255,.45)'; ctx.beginPath(); ctx.moveTo(rect.x,yy); ctx.lineTo(rect.x+rect.w,yy); ctx.stroke(); }\n  ctx.textAlign='center'; ctx.font='18px Arial'; ctx.fillStyle='#111'; ctx.fillText('x [\u03bcm]',rect.x+rect.w\/2,canvas.height-20); ctx.save(); ctx.translate(24,rect.y+rect.h\/2); ctx.rotate(-Math.PI\/2); ctx.fillText('y [\u03bcm]',0,0); ctx.restore();\n  for(i=0;i<result.points.length;i++){ var p=result.points[i]; var mx=rect.x+(centerX-xMin)\/(xMax-xMin)*rect.w, my=rect.y+(p.depth-yMin)\/(yMax-yMin)*rect.h; ctx.beginPath(); ctx.fillStyle='#fff'; ctx.strokeStyle='#111'; ctx.lineWidth=1.5; ctx.arc(mx,my,6,0,Math.PI*2); ctx.fill(); ctx.stroke(); }\n  function textBox(text,x,y){ var lines=text.split('\\n'); ctx.font='14px Arial'; var w=0; for(var li=0;li<lines.length;li++) w=Math.max(w,ctx.measureText(lines[li]).width); w+=18; var h=lines.length*18+12; ctx.fillStyle='rgba(255,255,255,.88)'; ctx.strokeStyle='#555'; ctx.fillRect(x,y,w,h); ctx.strokeRect(x,y,w,h); ctx.fillStyle='#111'; ctx.textAlign='center'; for(li=0;li<lines.length;li++) ctx.fillText(lines[li],x+w\/2,y+20+li*18); }\n  textBox('n_waveguide\\n\u0394n='+fmt(result.deltaN,4),rect.x+rect.w*0.74,rect.y+rect.h*0.08); textBox('n_glass\\n'+fmt(cfg.ns,4),rect.x+rect.w*0.12,rect.y+rect.h*0.78);\n  var bx=rect.x+rect.w+28, by=rect.y, bw=22, bh=rect.h, grad=ctx.createLinearGradient(0,by+bh,0,by); var stops=[0,0.2,0.4,0.6,0.8,1]; for(i=0;i<stops.length;i++){ var rgb2=jet(stops[i]); grad.addColorStop(stops[i],'rgb('+rgb2[0]+','+rgb2[1]+','+rgb2[2]+')'); } ctx.fillStyle=grad; ctx.fillRect(bx,by,bw,bh); ctx.strokeStyle='#111'; ctx.strokeRect(bx,by,bw,bh); ctx.textAlign='left'; ctx.font='14px Arial'; for(i=0;i<=5;i++){ var t=i\/5, cy=by+bh*(1-t), vv=cfg.ns+(result.peakIndex-cfg.ns)*t; ctx.fillText(fmt(vv,2),bx+bw+8,cy+5); } ctx.save(); ctx.translate(bx+bw+58,by+bh\/2); ctx.rotate(-Math.PI\/2); ctx.fillText('Index',-20,0); ctx.restore();\n}\nfunction exportCanvas(canvasId,name){ var link=document.createElement('a'); link.download=name; link.href=id(canvasId).toDataURL('image\/png'); link.click(); }\nfunction exportCsv(){ if(!state.last) return; var rows=['mode,pol,neff,depth_um']; for(var i=0;i<state.last.result.points.length;i++){ var p=state.last.result.points[i]; rows.push([p.mode,p.pol,p.neff,p.depth].join(',')); } var blob=new Blob([rows.join('\\n')],{type:'text\/csv'}); var link=document.createElement('a'); link.href=URL.createObjectURL(blob); link.download='refractive_index_profile.csv'; link.click(); URL.revokeObjectURL(link.href); }\nfunction switchTab(tab){ state.activeTab=tab; var buttons=document.querySelectorAll('.tab'); for(var i=0;i<buttons.length;i++) buttons[i].classList.toggle('active',buttons[i].getAttribute('data-tab')===tab); id('curvePanel').style.display=(tab==='curve'?'block':'none'); id('mapPanel').style.display=(tab==='map2d'?'block':'none'); }\nfunction init(){ setupCurveInteractions(); id('formulaMirror').innerHTML=id('formula').innerHTML; id('formulaMirror').value=id('formula').value; id('formula').onchange=function(){ syncFormulaSelects('formula'); if(state.last) calculateAll(); }; id('formulaMirror').onchange=function(){ id('formula').value=id('formulaMirror').value; if(state.last) calculateAll(); }; id('btnAddTE').onclick=function(){ addData('TE'); }; id('btnAddTM').onclick=function(){ addData('TM'); }; id('btnAddActive').onclick=function(){ addData(id('activePol').value); }; id('btnRemoveLast').onclick=function(){ var pol=id('activePol').value.toLowerCase(); state[pol].pop(); renderLists(); }; id('btnClear').onclick=function(){ state.te=[]; state.tm=[]; state.last=null; renderLists(); }; id('btnCalc').onclick=calculateAll; id('btnCalcTop').onclick=calculateAll; id('btnLoadDemo').onclick=loadDemo; id('btnPngCurve').onclick=function(){ exportCanvas('curveCanvas','profile_curve.png'); }; id('btnPngMap').onclick=function(){ exportCanvas('mapCanvas','profile_2d_map.png'); }; id('btnCsv').onclick=exportCsv; id('btnPrint').onclick=function(){ window.print(); }; var tabs=document.querySelectorAll('.tab'); for(var i=0;i<tabs.length;i++){ tabs[i].onclick=function(){ switchTab(this.getAttribute('data-tab')); }; } renderLists(); loadDemo(); }\nwindow.addEventListener('load', init);\n})();\n<\/script>\n<\/body>\n<\/html>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97\u5668 \u6298\u5c04\u7387\u5206\u5e03 \u8f7d\u5165\u793a\u4f8b\u5f00<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-10451","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97 - VoyaWave<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/voyawave.com\/zh-hans\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97 - VoyaWave\" \/>\n<meta property=\"og:description\" content=\"\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97\u5668 \u6298\u5c04\u7387\u5206\u5e03 \u8f7d\u5165\u793a\u4f8b\u5f00\" \/>\n<meta property=\"og:url\" content=\"https:\/\/voyawave.com\/zh-hans\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\/\" \/>\n<meta property=\"og:site_name\" content=\"VoyaWave\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-11T07:59:23+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/voyawave.com\\\/zh-hans\\\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\\\/\",\"url\":\"https:\\\/\\\/voyawave.com\\\/zh-hans\\\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\\\/\",\"name\":\"\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97 - VoyaWave\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/springgreen-quail-104003.hostingersite.com\\\/#website\"},\"datePublished\":\"2026-08-06T08:37:19+00:00\",\"dateModified\":\"2026-08-11T07:59:23+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/voyawave.com\\\/zh-hans\\\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\\\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/voyawave.com\\\/zh-hans\\\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/voyawave.com\\\/zh-hans\\\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/voyawave.com\\\/zh-hans\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/springgreen-quail-104003.hostingersite.com\\\/#website\",\"url\":\"https:\\\/\\\/springgreen-quail-104003.hostingersite.com\\\/\",\"name\":\"Shenzhen VoyaWave Optics Technology Co., Ltd.\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/springgreen-quail-104003.hostingersite.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/springgreen-quail-104003.hostingersite.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/springgreen-quail-104003.hostingersite.com\\\/#organization\",\"name\":\"\u542f\u626c\u5149\u5b66\",\"url\":\"https:\\\/\\\/springgreen-quail-104003.hostingersite.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\\\/\\\/springgreen-quail-104003.hostingersite.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/voyawave.com\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/2-240920110542592-scaled.png\",\"contentUrl\":\"https:\\\/\\\/voyawave.com\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/2-240920110542592-scaled.png\",\"width\":2560,\"height\":766,\"caption\":\"\u542f\u626c\u5149\u5b66\"},\"image\":{\"@id\":\"https:\\\/\\\/springgreen-quail-104003.hostingersite.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97 - VoyaWave","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/voyawave.com\/zh-hans\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\/","og_locale":"zh_CN","og_type":"article","og_title":"\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97 - VoyaWave","og_description":"\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97\u5668 \u6298\u5c04\u7387\u5206\u5e03 \u8f7d\u5165\u793a\u4f8b\u5f00","og_url":"https:\/\/voyawave.com\/zh-hans\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\/","og_site_name":"VoyaWave","article_modified_time":"2026-08-11T07:59:23+00:00","twitter_card":"summary_large_image","twitter_misc":{"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"1 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/voyawave.com\/zh-hans\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\/","url":"https:\/\/voyawave.com\/zh-hans\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\/","name":"\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97 - VoyaWave","isPartOf":{"@id":"https:\/\/springgreen-quail-104003.hostingersite.com\/#website"},"datePublished":"2026-08-06T08:37:19+00:00","dateModified":"2026-08-11T07:59:23+00:00","breadcrumb":{"@id":"https:\/\/voyawave.com\/zh-hans\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/voyawave.com\/zh-hans\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/voyawave.com\/zh-hans\/%e6%8a%98%e5%b0%84%e7%8e%87%e5%88%86%e5%b8%83%e8%ae%a1%e7%ae%97\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/voyawave.com\/zh-hans\/"},{"@type":"ListItem","position":2,"name":"\u6298\u5c04\u7387\u5206\u5e03\u8ba1\u7b97"}]},{"@type":"WebSite","@id":"https:\/\/springgreen-quail-104003.hostingersite.com\/#website","url":"https:\/\/springgreen-quail-104003.hostingersite.com\/","name":"Shenzhen VoyaWave Optics Technology Co., Ltd.","description":"","publisher":{"@id":"https:\/\/springgreen-quail-104003.hostingersite.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/springgreen-quail-104003.hostingersite.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"zh-Hans"},{"@type":"Organization","@id":"https:\/\/springgreen-quail-104003.hostingersite.com\/#organization","name":"\u542f\u626c\u5149\u5b66","url":"https:\/\/springgreen-quail-104003.hostingersite.com\/","logo":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/springgreen-quail-104003.hostingersite.com\/#\/schema\/logo\/image\/","url":"https:\/\/voyawave.com\/wp-content\/uploads\/2025\/05\/2-240920110542592-scaled.png","contentUrl":"https:\/\/voyawave.com\/wp-content\/uploads\/2025\/05\/2-240920110542592-scaled.png","width":2560,"height":766,"caption":"\u542f\u626c\u5149\u5b66"},"image":{"@id":"https:\/\/springgreen-quail-104003.hostingersite.com\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/voyawave.com\/zh-hans\/wp-json\/wp\/v2\/pages\/10451","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/voyawave.com\/zh-hans\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/voyawave.com\/zh-hans\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/voyawave.com\/zh-hans\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/voyawave.com\/zh-hans\/wp-json\/wp\/v2\/comments?post=10451"}],"version-history":[{"count":22,"href":"https:\/\/voyawave.com\/zh-hans\/wp-json\/wp\/v2\/pages\/10451\/revisions"}],"predecessor-version":[{"id":10616,"href":"https:\/\/voyawave.com\/zh-hans\/wp-json\/wp\/v2\/pages\/10451\/revisions\/10616"}],"wp:attachment":[{"href":"https:\/\/voyawave.com\/zh-hans\/wp-json\/wp\/v2\/media?parent=10451"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}