pac-proxy-cli 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
REMOTE_SERVER_URL=http://
|
|
1
|
+
REMOTE_SERVER_URL=http://pac.lonae.com
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.app-layout[data-v-c794e021]{min-height:100vh}.topbar[data-v-c794e021]{position:fixed;left:200px;right:0;top:0;height:52px;display:flex;align-items:center;gap:1rem;padding:0 1.5rem;background:#f1f5f9;border-bottom:1px solid var(--border);z-index:20}.logo[data-v-c794e021]{font-weight:700;font-size:1.1rem}.mode-tag[data-v-c794e021]{padding:.2rem .5rem;border-radius:4px;font-size:.8rem}.mode-tag.local[data-v-c794e021]{background:#dbeafe;color:#1d4ed8}.mode-tag.remote[data-v-c794e021]{background:#e9d5ff;color:#6b21a8}.switch-mode[data-v-c794e021]{font-size:.85rem;color:var(--text-secondary)}.switch-mode[data-v-c794e021]:hover{color:var(--btn-primary)}.top-nav[data-v-c794e021]{display:flex;gap:1rem;margin-left:auto}.top-nav a[data-v-c794e021]{color:var(--text-secondary)}.top-nav a.router-link-active[data-v-c794e021]{color:var(--btn-primary);font-weight:500}.top-right[data-v-c794e021]{margin-left:auto;display:flex;align-items:center;gap:.75rem}.username[data-v-c794e021]{font-size:.9rem;color:var(--text-secondary)}.logout-btn[data-v-c794e021]{font-size:.85rem;color:var(--text-secondary);background:none;border:none;cursor:pointer;padding:.25rem 0}.logout-btn[data-v-c794e021]:hover{color:var(--btn-primary)}.sidebar[data-v-c794e021]{position:fixed;left:0;top:0;bottom:0;width:200px;height:100vh;background:#fff;border-right:1px solid var(--border);display:flex;flex-direction:column;z-index:10}.side-nav[data-v-c794e021]{display:flex;flex-direction:column;padding:1rem 0}.side-nav a[data-v-c794e021]{color:var(--text-primary);padding:.6rem 1.25rem;font-size:.95rem;border-left:3px solid transparent}.side-nav a[data-v-c794e021]:hover{background:#f1f5f9;color:var(--btn-primary)}.side-nav a.active[data-v-c794e021]{background:#eff6ff;color:var(--btn-primary);border-left-color:var(--btn-primary)}.main[data-v-c794e021]{margin-left:200px;margin-top:52px;padding:1.5rem;min-height:calc(100vh - 52px)}.main.main-standalone[data-v-c794e021]{margin-left:0;margin-top:0;padding:0;min-height:100vh}.mode-select[data-v-b465f762]{min-height:100vh;display:flex;align-items:center;justify-content:center;background:var(--bg-main);padding:2rem}.card[data-v-b465f762]{background:var(--bg-card);border-radius:12px;padding:2.5rem;max-width:480px;width:100%;box-shadow:0 1px 3px #00000014}.card h1[data-v-b465f762]{font-size:1.5rem;margin-bottom:.5rem}.desc[data-v-b465f762]{color:var(--text-secondary);font-size:.95rem;margin-bottom:1.5rem}.options[data-v-b465f762]{display:flex;flex-direction:column;gap:1rem}.option[data-v-b465f762]{padding:1.25rem 1.5rem;border:2px solid var(--border);border-radius:var(--radius);background:#fff;text-align:left;transition:border-color .2s,background .2s}.option[data-v-b465f762]:hover{border-color:var(--btn-primary);background:#f8fafc}.option .title[data-v-b465f762]{display:block;font-weight:600;margin-bottom:.25rem}.option .sub[data-v-b465f762]{font-size:.9rem;color:var(--text-secondary)}.auth-page[data-v-be60da76]{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:2rem}.card[data-v-be60da76]{background:var(--bg-card);border-radius:12px;padding:2rem;max-width:400px;width:100%;box-shadow:0 1px 3px #00000014}.card h1[data-v-be60da76]{font-size:1.5rem;margin-bottom:.5rem}.desc[data-v-be60da76]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1.5rem}.form[data-v-be60da76]{display:flex;flex-direction:column;gap:1rem}.field label[data-v-be60da76]{display:block;font-size:.9rem;margin-bottom:.35rem;color:var(--text-secondary)}.field input[data-v-be60da76]{width:100%;padding:.6rem .75rem;border:1px solid var(--border);border-radius:var(--radius)}.error[data-v-be60da76]{color:#dc2626;font-size:.9rem}.btn.primary[data-v-be60da76]{background:var(--btn-primary);color:#fff;padding:.65rem 1rem;font-weight:500}.btn.primary[data-v-be60da76]:hover:not(:disabled){background:var(--btn-primary-hover)}.btn.primary[data-v-be60da76]:disabled{opacity:.6;cursor:not-allowed}.footer[data-v-be60da76]{margin-top:1rem;font-size:.9rem;color:var(--text-secondary)}.auth-page[data-v-a1c8458c]{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:2rem}.card[data-v-a1c8458c]{background:var(--bg-card);border-radius:12px;padding:2rem;max-width:400px;width:100%;box-shadow:0 1px 3px #00000014}.card h1[data-v-a1c8458c]{font-size:1.5rem;margin-bottom:.5rem}.desc[data-v-a1c8458c]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1.5rem}.form[data-v-a1c8458c]{display:flex;flex-direction:column;gap:1rem}.field label[data-v-a1c8458c]{display:block;font-size:.9rem;margin-bottom:.35rem;color:var(--text-secondary)}.field input[data-v-a1c8458c]{width:100%;padding:.6rem .75rem;border:1px solid var(--border);border-radius:var(--radius)}.error[data-v-a1c8458c]{color:#dc2626;font-size:.9rem}.success[data-v-a1c8458c]{color:#16a34a;font-size:.9rem}.btn.primary[data-v-a1c8458c]{background:var(--btn-primary);color:#fff;padding:.65rem 1rem;font-weight:500}.btn.primary[data-v-a1c8458c]:hover:not(:disabled){background:var(--btn-primary-hover)}.btn.primary[data-v-a1c8458c]:disabled{opacity:.6;cursor:not-allowed}.footer[data-v-a1c8458c]{margin-top:1rem;font-size:.9rem;color:var(--text-secondary)}.proxy-settings h2[data-v-9e948823]{font-size:1.25rem;margin-bottom:1rem}.card[data-v-9e948823]{background:var(--bg-card);border-radius:var(--radius);padding:1.5rem;margin-bottom:1.5rem;box-shadow:0 1px 2px #0000000d}.card h3[data-v-9e948823]{font-size:1rem;margin-bottom:.35rem}.page-desc[data-v-9e948823],.desc[data-v-9e948823]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1rem}.saved-tip[data-v-9e948823]{color:var(--switch-on);font-size:.85rem;margin-top:.5rem}.proxy-buttons[data-v-9e948823]{display:flex;flex-wrap:wrap;gap:.75rem;margin-bottom:.25rem}.proxy-btn[data-v-9e948823]{padding:.5rem 1rem;font-size:.9rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-card);cursor:pointer;transition:background .2s,border-color .2s}.proxy-btn[data-v-9e948823]:hover:not(:disabled){background:var(--bg);border-color:var(--btn-primary)}.proxy-btn.active[data-v-9e948823]{background:var(--btn-primary);border-color:var(--btn-primary);color:#fff}.proxy-btn.active[data-v-9e948823]:hover:not(:disabled){background:var(--btn-primary-hover);border-color:var(--btn-primary-hover);color:#fff}.proxy-btn.clear.active[data-v-9e948823]{background:var(--text-secondary);border-color:var(--text-secondary);color:#fff}.proxy-btn.clear.active[data-v-9e948823]:hover:not(:disabled){background:#64748b;border-color:#64748b;color:#fff}.proxy-btn[data-v-9e948823]:disabled{opacity:.6;cursor:not-allowed}.ca-download[data-v-9e948823]{margin-top:1rem;padding-top:1rem;border-top:1px solid var(--border)}.ca-label[data-v-9e948823]{display:block;font-size:.9rem;color:var(--text-secondary);margin-bottom:.5rem}.btn-ca[data-v-9e948823]{display:inline-block;padding:.4rem .8rem;font-size:.9rem;background:var(--btn-primary);color:#fff;border-radius:var(--radius);text-decoration:none;margin-bottom:.5rem}.btn-ca[data-v-9e948823]:hover{background:var(--btn-primary-hover);color:#fff}.ca-hint[data-v-9e948823]{font-size:.85rem;color:var(--text-secondary);margin:0}.toggle-row[data-v-9e948823]{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.toggle-row .select-inline[data-v-9e948823]{min-width:140px;height:2.25rem;padding:.35rem 2rem .35rem .75rem;font-size:.9rem;border:1px solid var(--border);border-radius:var(--radius);background-color:#fff;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M6 8L1 3h10z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .6rem center}.toggle-row .select-inline[data-v-9e948823]:focus{outline:none;border-color:var(--btn-primary)}.toggle[data-v-9e948823]{width:44px;height:24px;border-radius:12px;background:var(--switch-off);padding:2px;transition:background .2s}.toggle.on[data-v-9e948823]{background:var(--switch-on)}.toggle .knob[data-v-9e948823]{display:block;width:20px;height:20px;border-radius:50%;background:#fff;transform:translate(0);transition:transform .2s}.toggle.on .knob[data-v-9e948823]{transform:translate(20px)}.field[data-v-9e948823]{margin-bottom:1rem}.field label[data-v-9e948823]{display:block;font-size:.9rem;margin-bottom:.35rem;color:var(--text-secondary)}.field input[data-v-9e948823],.field select[data-v-9e948823]{width:100%;padding:.5rem .75rem;border:1px solid var(--border);border-radius:var(--radius)}.row[data-v-9e948823]{display:grid;grid-template-columns:1fr 1fr;gap:1rem}.actions[data-v-9e948823]{margin-top:1rem}.btn.primary[data-v-9e948823]{background:var(--btn-primary);color:#fff;padding:.5rem 1rem;font-size:.9rem}.btn.primary[data-v-9e948823]:hover:not(:disabled){background:var(--btn-primary-hover)}.btn.primary[data-v-9e948823]:disabled{opacity:.6;cursor:not-allowed}.status-card .status-line[data-v-9e948823]{margin-bottom:.5rem}.status-on[data-v-9e948823]{color:var(--switch-on);font-weight:600}.status-off[data-v-9e948823]{color:var(--text-secondary)}.status-port[data-v-9e948823]{margin-left:.5rem;color:var(--text-secondary);font-size:.9rem}.hint[data-v-9e948823]{font-size:.9rem;color:var(--text-secondary);margin-top:.5rem}.hint strong[data-v-9e948823]{color:var(--text-primary)}.hint.error[data-v-9e948823]{color:#dc2626}.pac-rules h2[data-v-22317bbc]{font-size:1.25rem;margin-bottom:1rem}.page-desc[data-v-22317bbc]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1rem}.card[data-v-22317bbc]{background:var(--bg-card);border-radius:var(--radius);padding:1.5rem;box-shadow:0 1px 2px #0000000d}.desc[data-v-22317bbc]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1rem}.actions.top[data-v-22317bbc]{margin-bottom:1rem;display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}.btn.primary[data-v-22317bbc]{background:var(--btn-primary);color:#fff;padding:.5rem 1rem;font-size:.9rem}.copy-tip[data-v-22317bbc]{font-size:.85rem;color:var(--btn-primary)}.btn.small[data-v-22317bbc]{padding:.25rem .5rem;font-size:.85rem;margin-right:.5rem}.btn.small.danger[data-v-22317bbc]{background:#fef2f2;color:#dc2626}.btn.small.danger[data-v-22317bbc]:hover{background:#fee2e2}.table[data-v-22317bbc]{width:100%;border-collapse:collapse}.table th[data-v-22317bbc],.table td[data-v-22317bbc]{padding:.6rem .75rem;text-align:left;border-bottom:1px solid var(--border)}.table th[data-v-22317bbc]{font-weight:600;color:var(--text-secondary);font-size:.9rem}.table .empty[data-v-22317bbc]{color:var(--text-secondary);text-align:center}.modal[data-v-22317bbc]{position:fixed;top:0;right:0;bottom:0;left:0;background:#0006;display:flex;align-items:center;justify-content:center;z-index:100}.modal-content[data-v-22317bbc]{background:var(--bg-card);border-radius:var(--radius);padding:1.5rem;min-width:360px}.modal-content h3[data-v-22317bbc],.modal-content .field[data-v-22317bbc]{margin-bottom:1rem}.modal-content .field label[data-v-22317bbc]{display:block;font-size:.9rem;margin-bottom:.35rem;color:var(--text-secondary)}.modal-content .field input[data-v-22317bbc],.modal-content .field select[data-v-22317bbc]{width:100%;min-width:0;box-sizing:border-box;padding:.5rem .75rem;min-height:2.5rem;border:1px solid var(--border);border-radius:var(--radius);font-size:.95rem}.modal-content .field select[data-v-22317bbc]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M6 8L1 3h10z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .6rem center;padding-right:2rem}.modal-actions[data-v-22317bbc]{display:flex;gap:.75rem;justify-content:flex-end;margin-top:1rem}.btn[data-v-22317bbc]{padding:.5rem 1rem;background:#f1f5f9}.btn.primary[data-v-22317bbc]{background:var(--btn-primary);color:#fff}.traffic-page h2[data-v-1ee1603b]{font-size:1.25rem;margin-bottom:1rem}.page-desc[data-v-1ee1603b]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1rem}.card[data-v-1ee1603b]{background:var(--bg-card);border-radius:var(--radius);padding:1.5rem;box-shadow:0 1px 2px #0000000d}.capture-card[data-v-1ee1603b]{padding:1rem 1.5rem}.capture-banner[data-v-1ee1603b]{background:#eff6ff;color:#1e40af;padding:.5rem .75rem;border-radius:var(--radius);font-size:.9rem;margin-bottom:1rem}.toolbar[data-v-1ee1603b]{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;margin-bottom:1rem}.toolbar .search-input[data-v-1ee1603b],.toolbar .filter-select[data-v-1ee1603b],.toolbar .status-input[data-v-1ee1603b],.toolbar .sort-order-btn[data-v-1ee1603b],.toolbar .btn[data-v-1ee1603b]{box-sizing:border-box;height:2.25rem;padding:0 .6rem;border:1px solid var(--border);border-radius:var(--radius);font-size:.9rem;line-height:1.3}.toolbar .search-input[data-v-1ee1603b]{min-width:160px}.toolbar .filter-select[data-v-1ee1603b]{background:#fff;cursor:pointer;min-width:6rem}.toolbar .status-input[data-v-1ee1603b]{width:72px}.toolbar .sort-order-btn[data-v-1ee1603b]{background:#f8fafc;cursor:pointer;width:2.25rem;padding:0}.toolbar .btn[data-v-1ee1603b]{background:#f1f5f9}.actions.top[data-v-1ee1603b]{margin-bottom:1rem}.btn[data-v-1ee1603b]{padding:.5rem 1rem;font-size:.9rem;background:#f1f5f9}.btn.small[data-v-1ee1603b]{padding:.35rem .75rem;font-size:.85rem}.table-wrap[data-v-1ee1603b]{overflow-x:auto}.table[data-v-1ee1603b]{width:100%;border-collapse:collapse}.table th[data-v-1ee1603b],.table td[data-v-1ee1603b]{padding:.5rem .75rem;text-align:left;border-bottom:1px solid var(--border)}.table th[data-v-1ee1603b]{font-weight:600;color:var(--text-secondary);font-size:.9rem}.table .empty[data-v-1ee1603b]{color:var(--text-secondary);text-align:center}.url-cell[data-v-1ee1603b]{max-width:320px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.action-proxy[data-v-1ee1603b]{color:var(--btn-primary)}.action-direct[data-v-1ee1603b]{color:var(--text-secondary)}.row-clickable[data-v-1ee1603b]{cursor:pointer}.row-clickable[data-v-1ee1603b]:hover{background:#f8fafc}.method-tag[data-v-1ee1603b]{font-size:.8rem;padding:.15rem .4rem;border-radius:4px;font-weight:500}.method-tag.GET[data-v-1ee1603b]{background:#dbeafe;color:#1d4ed8}.method-tag.POST[data-v-1ee1603b]{background:#d1fae5;color:#047857}.method-tag.PUT[data-v-1ee1603b]{background:#fef3c7;color:#b45309}.method-tag.DELETE[data-v-1ee1603b]{background:#fee2e2;color:#b91c1c}.method-tag.HEAD[data-v-1ee1603b],.method-tag.OPTIONS[data-v-1ee1603b]{background:#f1f5f9;color:#64748b}.status-tag[data-v-1ee1603b]{font-size:.85rem;padding:.15rem .4rem;border-radius:4px}.status-2xx[data-v-1ee1603b]{background:#d1fae5;color:#047857}.status-3xx[data-v-1ee1603b]{background:#e0e7ff;color:#3730a3}.status-4xx[data-v-1ee1603b]{background:#fee2e2;color:#b91c1c}.status-5xx[data-v-1ee1603b]{background:#fecaca;color:#991b1b}.btn-link[data-v-1ee1603b]{background:none;border:none;color:var(--btn-primary);cursor:pointer;font-size:.9rem;padding:0}.btn-link[data-v-1ee1603b]:hover{text-decoration:underline}.pagination[data-v-1ee1603b]{margin-top:1rem;display:flex;align-items:center;gap:.75rem}.pagination-info[data-v-1ee1603b]{font-size:.9rem;color:var(--text-secondary)}.drawer-mask[data-v-1ee1603b]{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000004d;z-index:100}.drawer[data-v-1ee1603b]{position:fixed;top:0;right:0;width:min(560px,100vw);height:100vh;background:var(--bg-card);box-shadow:-2px 0 12px #00000026;z-index:101;display:flex;flex-direction:column;overflow:hidden}.drawer-header[data-v-1ee1603b]{display:flex;align-items:center;justify-content:space-between;padding:1rem 1.25rem;border-bottom:1px solid var(--border);flex-shrink:0}.drawer-title[data-v-1ee1603b]{font-size:1rem;font-weight:600}.drawer-close[data-v-1ee1603b]{width:2rem;height:2rem;border:none;background:none;font-size:1.5rem;line-height:1;cursor:pointer;color:var(--text-secondary)}.drawer-close[data-v-1ee1603b]:hover{color:#0f172a}.drawer-url-section[data-v-1ee1603b]{margin-bottom:1.25rem;padding-bottom:1rem;border-bottom:1px solid var(--border)}.drawer-url-head[data-v-1ee1603b]{display:flex;align-items:center;justify-content:space-between;gap:.5rem;margin-bottom:.35rem}.drawer-method-tag[data-v-1ee1603b]{font-size:.8rem;font-weight:600;padding:.15rem .4rem;border-radius:4px;background:#e2e8f0;color:#475569}.btn-copy-url[data-v-1ee1603b]{padding:.35rem .6rem;font-size:.85rem;border:1px solid var(--border);border-radius:var(--radius);background:#f1f5f9;cursor:pointer;color:var(--text-primary)}.btn-copy-url[data-v-1ee1603b]:hover{background:#e2e8f0}.drawer-url[data-v-1ee1603b]{margin:0;padding:.5rem .6rem;background:#f8fafc;border-radius:var(--radius);font-size:.85rem;line-height:1.4;white-space:pre-wrap;word-break:break-all;max-height:5rem;overflow:auto;user-select:text;-webkit-user-select:text}.drawer-tabs[data-v-1ee1603b]{display:flex;gap:.25rem;padding:.5rem 1rem;border-bottom:1px solid var(--border);flex-shrink:0}.drawer-tabs button[data-v-1ee1603b]{padding:.4rem .75rem;font-size:.9rem;border:none;background:none;border-radius:var(--radius);cursor:pointer;color:var(--text-secondary)}.drawer-tabs button.active[data-v-1ee1603b]{background:var(--btn-primary);color:#fff}.drawer-body[data-v-1ee1603b]{flex:1;overflow:auto;padding:1rem 1.25rem}.detail-section[data-v-1ee1603b]{margin-bottom:1.25rem}.detail-section h4[data-v-1ee1603b]{font-size:.85rem;margin-bottom:.35rem;color:var(--text-secondary)}.headers-pre[data-v-1ee1603b],.body-pre[data-v-1ee1603b]{margin:0;padding:.75rem;background:#f8fafc;border-radius:var(--radius);font-size:.8rem;line-height:1.4;overflow-x:auto;white-space:pre-wrap;word-break:break-all;max-height:280px;overflow-y:auto}:root{--bg-sidebar: #1e293b;--bg-sidebar-hover: #334155;--bg-sidebar-active: #2563eb;--text-sidebar: #e2e8f0;--text-sidebar-muted: #94a3b8;--bg-main: #f8fafc;--bg-card: #ffffff;--text-primary: #0f172a;--text-secondary: #64748b;--border: #e2e8f0;--switch-on: #22c55e;--switch-off: #cbd5e1;--btn-primary: #2563eb;--btn-primary-hover: #1d4ed8;--radius: 8px;--font: "DM Sans", -apple-system, BlinkMacSystemFont, sans-serif}*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--font);background:var(--bg-main);color:var(--text-primary);line-height:1.5;min-height:100vh}#app{min-height:100vh;display:flex;flex-direction:column}button{font-family:inherit;cursor:pointer;border:none;border-radius:var(--radius)}input,select{font-family:inherit;border-radius:var(--radius)}a{color:var(--btn-primary);text-decoration:none}a:hover{text-decoration:underline}
|
|
@@ -22,6 +22,6 @@
|
|
|
22
22
|
* vue-router v4.6.4
|
|
23
23
|
* (c) 2025 Eduardo San Martin Morote
|
|
24
24
|
* @license MIT
|
|
25
|
-
*/let Uc=()=>location.protocol+"//"+location.host;function bi(e,t){const{pathname:n,search:s,hash:o}=t,r=e.indexOf("#");if(r>-1){let i=o.includes(e.slice(r))?e.slice(r).length:1,l=o.slice(i);return l[0]!=="/"&&(l="/"+l),Ko(l,"")}return Ko(n,e)+s+o}function Lc(e,t,n,s){let o=[],r=[],i=null;const l=({state:g})=>{const v=bi(e,location),O=n.value,w=t.value;let E=0;if(g){if(n.value=v,t.value=g,i&&i===O){i=null;return}E=w?g.position-w.position:0}else s(v);o.forEach(C=>{C(n.value,O,{delta:E,type:Ds.pop,direction:E?E>0?ys.forward:ys.back:ys.unknown})})};function a(){i=n.value}function f(g){o.push(g);const v=()=>{const O=o.indexOf(g);O>-1&&o.splice(O,1)};return r.push(v),v}function c(){if(document.visibilityState==="hidden"){const{history:g}=window;if(!g.state)return;g.replaceState(Z({},g.state,{scroll:os()}),"")}}function p(){for(const g of r)g();r=[],window.removeEventListener("popstate",l),window.removeEventListener("pagehide",c),document.removeEventListener("visibilitychange",c)}return window.addEventListener("popstate",l),window.addEventListener("pagehide",c),document.addEventListener("visibilitychange",c),{pauseListeners:a,listen:f,destroy:p}}function zo(e,t,n,s=!1,o=!1){return{back:e,current:t,forward:n,replaced:s,position:window.history.length,scroll:o?os():null}}function kc(e){const{history:t,location:n}=window,s={value:bi(e,n)},o={value:t.state};o.value||r(s.value,{back:null,current:s.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function r(a,f,c){const p=e.indexOf("#"),g=p>-1?(n.host&&document.querySelector("base")?e:e.slice(p))+a:Uc()+e+a;try{t[c?"replaceState":"pushState"](f,"",g),o.value=f}catch(v){console.error(v),n[c?"replace":"assign"](g)}}function i(a,f){r(a,Z({},t.state,zo(o.value.back,a,o.value.forward,!0),f,{position:o.value.position}),!0),s.value=a}function l(a,f){const c=Z({},o.value,t.state,{forward:a,scroll:os()});r(c.current,c,!0),r(a,Z({},zo(s.value,a,null),{position:c.position+1},f),!1),s.value=a}return{location:s,state:o,push:l,replace:i}}function $c(e){e=xc(e);const t=kc(e),n=Lc(e,t.state,t.location,t.replace);function s(r,i=!0){i||n.pauseListeners(),history.go(r)}const o=Z({location:"",base:e,go:s,createHref:Ec.bind(null,e)},t,n);return Object.defineProperty(o,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(o,"state",{enumerable:!0,get:()=>t.state.value}),o}let It=function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.Group=2]="Group",e}({});var me=function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.ParamRegExp=2]="ParamRegExp",e[e.ParamRegExpEnd=3]="ParamRegExpEnd",e[e.EscapeNext=4]="EscapeNext",e}(me||{});const jc={type:It.Static,value:""},Vc=/[a-zA-Z0-9_]/;function Hc(e){if(!e)return[[]];if(e==="/")return[[jc]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(v){throw new Error(`ERR (${n})/"${f}": ${v}`)}let n=me.Static,s=n;const o=[];let r;function i(){r&&o.push(r),r=[]}let l=0,a,f="",c="";function p(){f&&(n===me.Static?r.push({type:It.Static,value:f}):n===me.Param||n===me.ParamRegExp||n===me.ParamRegExpEnd?(r.length>1&&(a==="*"||a==="+")&&t(`A repeatable param (${f}) must be alone in its segment. eg: '/:ids+.`),r.push({type:It.Param,value:f,regexp:c,repeatable:a==="*"||a==="+",optional:a==="*"||a==="?"})):t("Invalid state to consume buffer"),f="")}function g(){f+=a}for(;l<e.length;){if(a=e[l++],a==="\\"&&n!==me.ParamRegExp){s=n,n=me.EscapeNext;continue}switch(n){case me.Static:a==="/"?(f&&p(),i()):a===":"?(p(),n=me.Param):g();break;case me.EscapeNext:g(),n=s;break;case me.Param:a==="("?n=me.ParamRegExp:Vc.test(a)?g():(p(),n=me.Static,a!=="*"&&a!=="?"&&a!=="+"&&l--);break;case me.ParamRegExp:a===")"?c[c.length-1]=="\\"?c=c.slice(0,-1)+a:n=me.ParamRegExpEnd:c+=a;break;case me.ParamRegExpEnd:p(),n=me.Static,a!=="*"&&a!=="?"&&a!=="+"&&l--,c="";break;default:t("Unknown state");break}}return n===me.ParamRegExp&&t(`Unfinished custom RegExp for param "${f}"`),p(),i(),o}const Qo="[^/]+?",Fc={sensitive:!1,strict:!1,start:!0,end:!0};var we=function(e){return e[e._multiplier=10]="_multiplier",e[e.Root=90]="Root",e[e.Segment=40]="Segment",e[e.SubSegment=30]="SubSegment",e[e.Static=40]="Static",e[e.Dynamic=20]="Dynamic",e[e.BonusCustomRegExp=10]="BonusCustomRegExp",e[e.BonusWildcard=-50]="BonusWildcard",e[e.BonusRepeatable=-20]="BonusRepeatable",e[e.BonusOptional=-8]="BonusOptional",e[e.BonusStrict=.7000000000000001]="BonusStrict",e[e.BonusCaseSensitive=.25]="BonusCaseSensitive",e}(we||{});const Bc=/[.+*?^${}()[\]/\\]/g;function Kc(e,t){const n=Z({},Fc,t),s=[];let o=n.start?"^":"";const r=[];for(const f of e){const c=f.length?[]:[we.Root];n.strict&&!f.length&&(o+="/");for(let p=0;p<f.length;p++){const g=f[p];let v=we.Segment+(n.sensitive?we.BonusCaseSensitive:0);if(g.type===It.Static)p||(o+="/"),o+=g.value.replace(Bc,"\\$&"),v+=we.Static;else if(g.type===It.Param){const{value:O,repeatable:w,optional:E,regexp:C}=g;r.push({name:O,repeatable:w,optional:E});const x=C||Qo;if(x!==Qo){v+=we.BonusCustomRegExp;try{`${x}`}catch(D){throw new Error(`Invalid custom RegExp for param "${O}" (${x}): `+D.message)}}let A=w?`((?:${x})(?:/(?:${x}))*)`:`(${x})`;p||(A=E&&f.length<2?`(?:/${A})`:"/"+A),E&&(A+="?"),o+=A,v+=we.Dynamic,E&&(v+=we.BonusOptional),w&&(v+=we.BonusRepeatable),x===".*"&&(v+=we.BonusWildcard)}c.push(v)}s.push(c)}if(n.strict&&n.end){const f=s.length-1;s[f][s[f].length-1]+=we.BonusStrict}n.strict||(o+="/?"),n.end?o+="$":n.strict&&!o.endsWith("/")&&(o+="(?:/|$)");const i=new RegExp(o,n.sensitive?"":"i");function l(f){const c=f.match(i),p={};if(!c)return null;for(let g=1;g<c.length;g++){const v=c[g]||"",O=r[g-1];p[O.name]=v&&O.repeatable?v.split("/"):v}return p}function a(f){let c="",p=!1;for(const g of e){(!p||!c.endsWith("/"))&&(c+="/"),p=!1;for(const v of g)if(v.type===It.Static)c+=v.value;else if(v.type===It.Param){const{value:O,repeatable:w,optional:E}=v,C=O in f?f[O]:"";if(Je(C)&&!w)throw new Error(`Provided param "${O}" is an array but it is not repeatable (* or + modifiers)`);const x=Je(C)?C.join("/"):C;if(!x)if(E)g.length<2&&(c.endsWith("/")?c=c.slice(0,-1):p=!0);else throw new Error(`Missing required param "${O}"`);c+=x}}return c||"/"}return{re:i,score:s,keys:r,parse:l,stringify:a}}function Gc(e,t){let n=0;for(;n<e.length&&n<t.length;){const s=t[n]-e[n];if(s)return s;n++}return e.length<t.length?e.length===1&&e[0]===we.Static+we.Segment?-1:1:e.length>t.length?t.length===1&&t[0]===we.Static+we.Segment?1:-1:0}function xi(e,t){let n=0;const s=e.score,o=t.score;for(;n<s.length&&n<o.length;){const r=Gc(s[n],o[n]);if(r)return r;n++}if(Math.abs(o.length-s.length)===1){if(Yo(s))return 1;if(Yo(o))return-1}return o.length-s.length}function Yo(e){const t=e[e.length-1];return e.length>0&&t[t.length-1]<0}const Wc={strict:!1,end:!0,sensitive:!1};function qc(e,t,n){const s=Kc(Hc(e.path),n),o=Z(s,{record:e,parent:t,children:[],alias:[]});return t&&!o.record.aliasOf==!t.record.aliasOf&&t.children.push(o),o}function Jc(e,t){const n=[],s=new Map;t=Bo(Wc,t);function o(p){return s.get(p)}function r(p,g,v){const O=!v,w=Zo(p);w.aliasOf=v&&v.record;const E=Bo(t,p),C=[w];if("alias"in p){const D=typeof p.alias=="string"?[p.alias]:p.alias;for(const F of D)C.push(Zo(Z({},w,{components:v?v.record.components:w.components,path:F,aliasOf:v?v.record:w})))}let x,A;for(const D of C){const{path:F}=D;if(g&&F[0]!=="/"){const ce=g.record.path,re=ce[ce.length-1]==="/"?"":"/";D.path=g.record.path+(F&&re+F)}if(x=qc(D,g,E),v?v.alias.push(x):(A=A||x,A!==x&&A.alias.push(x),O&&p.name&&!er(x)&&i(p.name)),Si(x)&&a(x),w.children){const ce=w.children;for(let re=0;re<ce.length;re++)r(ce[re],x,v&&v.children[re])}v=v||x}return A?()=>{i(A)}:dn}function i(p){if(yi(p)){const g=s.get(p);g&&(s.delete(p),n.splice(n.indexOf(g),1),g.children.forEach(i),g.alias.forEach(i))}else{const g=n.indexOf(p);g>-1&&(n.splice(g,1),p.record.name&&s.delete(p.record.name),p.children.forEach(i),p.alias.forEach(i))}}function l(){return n}function a(p){const g=Yc(p,n);n.splice(g,0,p),p.record.name&&!er(p)&&s.set(p.record.name,p)}function f(p,g){let v,O={},w,E;if("name"in p&&p.name){if(v=s.get(p.name),!v)throw Qt(de.MATCHER_NOT_FOUND,{location:p});E=v.record.name,O=Z(Xo(g.params,v.keys.filter(A=>!A.optional).concat(v.parent?v.parent.keys.filter(A=>A.optional):[]).map(A=>A.name)),p.params&&Xo(p.params,v.keys.map(A=>A.name))),w=v.stringify(O)}else if(p.path!=null)w=p.path,v=n.find(A=>A.re.test(w)),v&&(O=v.parse(w),E=v.record.name);else{if(v=g.name?s.get(g.name):n.find(A=>A.re.test(g.path)),!v)throw Qt(de.MATCHER_NOT_FOUND,{location:p,currentLocation:g});E=v.record.name,O=Z({},g.params,p.params),w=v.stringify(O)}const C=[];let x=v;for(;x;)C.unshift(x.record),x=x.parent;return{name:E,path:w,params:O,matched:C,meta:Qc(C)}}e.forEach(p=>r(p));function c(){n.length=0,s.clear()}return{addRoute:r,resolve:f,removeRoute:i,clearRoutes:c,getRoutes:l,getRecordMatcher:o}}function Xo(e,t){const n={};for(const s of t)s in e&&(n[s]=e[s]);return n}function Zo(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:zc(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function zc(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const s in e.components)t[s]=typeof n=="object"?n[s]:n;return t}function er(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Qc(e){return e.reduce((t,n)=>Z(t,n.meta),{})}function Yc(e,t){let n=0,s=t.length;for(;n!==s;){const r=n+s>>1;xi(e,t[r])<0?s=r:n=r+1}const o=Xc(e);return o&&(s=t.lastIndexOf(o,s-1)),s}function Xc(e){let t=e;for(;t=t.parent;)if(Si(t)&&xi(e,t)===0)return t}function Si({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function tr(e){const t=Ge(rs),n=Ge(no),s=ve(()=>{const a=Dt(e.to);return t.resolve(a)}),o=ve(()=>{const{matched:a}=s.value,{length:f}=a,c=a[f-1],p=n.matched;if(!c||!p.length)return-1;const g=p.findIndex(zt.bind(null,c));if(g>-1)return g;const v=nr(a[f-2]);return f>1&&nr(c)===v&&p[p.length-1].path!==v?p.findIndex(zt.bind(null,a[f-2])):g}),r=ve(()=>o.value>-1&&su(n.params,s.value.params)),i=ve(()=>o.value>-1&&o.value===n.matched.length-1&&vi(n.params,s.value.params));function l(a={}){if(nu(a)){const f=t[Dt(e.replace)?"replace":"push"](Dt(e.to)).catch(dn);return e.viewTransition&&typeof document<"u"&&"startViewTransition"in document&&document.startViewTransition(()=>f),f}return Promise.resolve()}return{route:s,href:ve(()=>s.value.href),isActive:r,isExactActive:i,navigate:l}}function Zc(e){return e.length===1?e[0]:e}const eu=kr({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"},viewTransition:Boolean},useLink:tr,setup(e,{slots:t}){const n=xn(tr(e)),{options:s}=Ge(rs),o=ve(()=>({[sr(e.activeClass,s.linkActiveClass,"router-link-active")]:n.isActive,[sr(e.exactActiveClass,s.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const r=t.default&&Zc(t.default(n));return e.custom?r:ci("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:o.value},r)}}}),tu=eu;function nu(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function su(e,t){for(const n in t){const s=t[n],o=e[n];if(typeof s=="string"){if(s!==o)return!1}else if(!Je(o)||o.length!==s.length||s.some((r,i)=>r.valueOf()!==o[i].valueOf()))return!1}return!0}function nr(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const sr=(e,t,n)=>e??t??n,ou=kr({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const s=Ge(Ls),o=ve(()=>e.route||s.value),r=Ge(Jo,0),i=ve(()=>{let f=Dt(r);const{matched:c}=o.value;let p;for(;(p=c[f])&&!p.components;)f++;return f}),l=ve(()=>o.value.matched[i.value]);Pn(Jo,ve(()=>i.value+1)),Pn(Mc,l),Pn(Ls,o);const a=Y();return ln(()=>[a.value,l.value,e.name],([f,c,p],[g,v,O])=>{c&&(c.instances[p]=f,v&&v!==c&&f&&f===g&&(c.leaveGuards.size||(c.leaveGuards=v.leaveGuards),c.updateGuards.size||(c.updateGuards=v.updateGuards))),f&&c&&(!v||!zt(c,v)||!g)&&(c.enterCallbacks[p]||[]).forEach(w=>w(f))},{flush:"post"}),()=>{const f=o.value,c=e.name,p=l.value,g=p&&p.components[c];if(!g)return or(n.default,{Component:g,route:f});const v=p.props[c],O=v?v===!0?f.params:typeof v=="function"?v(f):v:null,E=ci(g,Z({},O,t,{onVnodeUnmounted:C=>{C.component.isUnmounted&&(p.instances[c]=null)},ref:a}));return or(n.default,{Component:E,route:f})||E}}});function or(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const ru=ou;function iu(e){const t=Jc(e.routes,e),n=e.parseQuery||Ic,s=e.stringifyQuery||qo,o=e.history,r=tn(),i=tn(),l=tn(),a=ul(bt);let f=bt;Ht&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const c=ms.bind(null,b=>""+b),p=ms.bind(null,hc),g=ms.bind(null,yn);function v(b,U){let N,$;return yi(b)?(N=t.getRecordMatcher(b),$=U):$=b,t.addRoute($,N)}function O(b){const U=t.getRecordMatcher(b);U&&t.removeRoute(U)}function w(){return t.getRoutes().map(b=>b.record)}function E(b){return!!t.getRecordMatcher(b)}function C(b,U){if(U=Z({},U||a.value),typeof b=="string"){const m=vs(n,b,U.path),y=t.resolve({path:m.path},U),S=o.createHref(m.fullPath);return Z(m,y,{params:g(y.params),hash:yn(m.hash),redirectedFrom:void 0,href:S})}let N;if(b.path!=null)N=Z({},b,{path:vs(n,b.path,U.path).path});else{const m=Z({},b.params);for(const y in m)m[y]==null&&delete m[y];N=Z({},b,{params:p(m)}),U.params=p(U.params)}const $=t.resolve(N,U),z=b.hash||"";$.params=c(g($.params));const u=vc(s,Z({},b,{hash:fc(z),path:$.path})),d=o.createHref(u);return Z({fullPath:u,hash:z,query:s===qo?Nc(b.query):b.query||{}},$,{redirectedFrom:void 0,href:d})}function x(b){return typeof b=="string"?vs(n,b,a.value.path):Z({},b)}function A(b,U){if(f!==b)return Qt(de.NAVIGATION_CANCELLED,{from:U,to:b})}function D(b){return re(b)}function F(b){return D(Z(x(b),{replace:!0}))}function ce(b,U){const N=b.matched[b.matched.length-1];if(N&&N.redirect){const{redirect:$}=N;let z=typeof $=="function"?$(b,U):$;return typeof z=="string"&&(z=z.includes("?")||z.includes("#")?z=x(z):{path:z},z.params={}),Z({query:b.query,hash:b.hash,params:z.path!=null?{}:b.params},z)}}function re(b,U){const N=f=C(b),$=a.value,z=b.state,u=b.force,d=b.replace===!0,m=ce(N,$);if(m)return re(Z(x(m),{state:typeof m=="object"?Z({},z,m.state):z,force:u,replace:d}),U||N);const y=N;y.redirectedFrom=U;let S;return!u&&yc(s,$,N)&&(S=Qt(de.NAVIGATION_DUPLICATED,{to:y,from:$}),Ye($,$,!0,!1)),(S?Promise.resolve(S):De(y,$)).catch(_=>ct(_)?ct(_,de.NAVIGATION_GUARD_REDIRECT)?_:_t(_):X(_,y,$)).then(_=>{if(_){if(ct(_,de.NAVIGATION_GUARD_REDIRECT))return re(Z({replace:d},x(_.to),{state:typeof _.to=="object"?Z({},z,_.to.state):z,force:u}),U||y)}else _=Qe(y,$,!0,d,z);return ze(y,$,_),_})}function je(b,U){const N=A(b,U);return N?Promise.reject(N):Promise.resolve()}function Be(b){const U=$t.values().next().value;return U&&typeof U.runWithContext=="function"?U.runWithContext(b):b()}function De(b,U){let N;const[$,z,u]=Dc(b,U);N=_s($.reverse(),"beforeRouteLeave",b,U);for(const m of $)m.leaveGuards.forEach(y=>{N.push(Et(y,b,U))});const d=je.bind(null,b,U);return N.push(d),Ve(N).then(()=>{N=[];for(const m of r.list())N.push(Et(m,b,U));return N.push(d),Ve(N)}).then(()=>{N=_s(z,"beforeRouteUpdate",b,U);for(const m of z)m.updateGuards.forEach(y=>{N.push(Et(y,b,U))});return N.push(d),Ve(N)}).then(()=>{N=[];for(const m of u)if(m.beforeEnter)if(Je(m.beforeEnter))for(const y of m.beforeEnter)N.push(Et(y,b,U));else N.push(Et(m.beforeEnter,b,U));return N.push(d),Ve(N)}).then(()=>(b.matched.forEach(m=>m.enterCallbacks={}),N=_s(u,"beforeRouteEnter",b,U,Be),N.push(d),Ve(N))).then(()=>{N=[];for(const m of i.list())N.push(Et(m,b,U));return N.push(d),Ve(N)}).catch(m=>ct(m,de.NAVIGATION_CANCELLED)?m:Promise.reject(m))}function ze(b,U,N){l.list().forEach($=>Be(()=>$(b,U,N)))}function Qe(b,U,N,$,z){const u=A(b,U);if(u)return u;const d=U===bt,m=Ht?history.state:{};N&&($||d?o.replace(b.fullPath,Z({scroll:d&&m&&m.scroll},z)):o.push(b.fullPath,z)),a.value=b,Ye(b,U,N,d),_t()}let k;function L(){k||(k=o.listen((b,U,N)=>{if(!Ct.listening)return;const $=C(b),z=ce($,Ct.currentRoute.value);if(z){re(Z(z,{replace:!0,force:!0}),$).catch(dn);return}f=$;const u=a.value;Ht&&Cc(Wo(u.fullPath,N.delta),os()),De($,u).catch(d=>ct(d,de.NAVIGATION_ABORTED|de.NAVIGATION_CANCELLED)?d:ct(d,de.NAVIGATION_GUARD_REDIRECT)?(re(Z(x(d.to),{force:!0}),$).then(m=>{ct(m,de.NAVIGATION_ABORTED|de.NAVIGATION_DUPLICATED)&&!N.delta&&N.type===Ds.pop&&o.go(-1,!1)}).catch(dn),Promise.reject()):(N.delta&&o.go(-N.delta,!1),X(d,$,u))).then(d=>{d=d||Qe($,u,!1),d&&(N.delta&&!ct(d,de.NAVIGATION_CANCELLED)?o.go(-N.delta,!1):N.type===Ds.pop&&ct(d,de.NAVIGATION_ABORTED|de.NAVIGATION_DUPLICATED)&&o.go(-1,!1)),ze($,u,d)}).catch(dn)}))}let K=tn(),ue=tn(),oe;function X(b,U,N){_t(b);const $=ue.list();return $.length?$.forEach(z=>z(b,U,N)):console.error(b),Promise.reject(b)}function lt(){return oe&&a.value!==bt?Promise.resolve():new Promise((b,U)=>{K.add([b,U])})}function _t(b){return oe||(oe=!b,L(),K.list().forEach(([U,N])=>b?N(b):U()),K.reset()),b}function Ye(b,U,N,$){const{scrollBehavior:z}=e;if(!Ht||!z)return Promise.resolve();const u=!N&&Ac(Wo(b.fullPath,0))||($||!N)&&history.state&&history.state.scroll||null;return zs().then(()=>z(b,U,u)).then(d=>d&&Rc(d)).catch(d=>X(d,b,U))}const Pe=b=>o.go(b);let kt;const $t=new Set,Ct={currentRoute:a,listening:!0,addRoute:v,removeRoute:O,clearRoutes:t.clearRoutes,hasRoute:E,getRoutes:w,resolve:C,options:e,push:D,replace:F,go:Pe,back:()=>Pe(-1),forward:()=>Pe(1),beforeEach:r.add,beforeResolve:i.add,afterEach:l.add,onError:ue.add,isReady:lt,install(b){b.component("RouterLink",tu),b.component("RouterView",ru),b.config.globalProperties.$router=Ct,Object.defineProperty(b.config.globalProperties,"$route",{enumerable:!0,get:()=>Dt(a)}),Ht&&!kt&&a.value===bt&&(kt=!0,D(o.location).catch($=>{}));const U={};for(const $ in bt)Object.defineProperty(U,$,{get:()=>a.value[$],enumerable:!0});b.provide(rs,Ct),b.provide(no,Ar(U)),b.provide(Ls,a);const N=b.unmount;$t.add(b),b.unmount=function(){$t.delete(b),$t.size<1&&(f=bt,k&&k(),k=null,a.value=bt,kt=!1,oe=!1),N()}}};function Ve(b){return b.reduce((U,N)=>U.then(()=>Be(N)),Promise.resolve())}return Ct}function is(){return Ge(rs)}function Ei(e){return Ge(no)}const ye=xn({mode:null,user:null,remoteBaseUrl:"",token:""});function so(){return Mn(ye)}function oo(e){ye.mode=e,typeof localStorage<"u"&&localStorage.setItem("pac_proxy_mode",e)}function wi(){if(typeof localStorage<"u"){const e=localStorage.getItem("pac_proxy_mode");(e==="local"||e==="remote")&&(ye.mode=e);const t=localStorage.getItem("pac_proxy_token");t&&(ye.token=t);const n=localStorage.getItem("pac_proxy_remote_base_url");if(n&&typeof n=="string"&&(ye.remoteBaseUrl=n),ye.mode==="remote"&&ye.token)try{const s=JSON.parse(atob(ye.token.split(".")[1]));ye.user={username:s.username}}catch{}}return ye.mode}function Ri(e){ye.user=e}function Ci(e){ye.remoteBaseUrl=e||"",typeof localStorage<"u"&&(e?localStorage.setItem("pac_proxy_remote_base_url",e):localStorage.removeItem("pac_proxy_remote_base_url"))}function Ai(e){ye.token=e,typeof localStorage<"u"&&(e?localStorage.setItem("pac_proxy_token",e):localStorage.removeItem("pac_proxy_token"))}function lu(){return ye.token||typeof localStorage<"u"&&localStorage.getItem("pac_proxy_token")}function au(){ye.token="",ye.user=null,ye.remoteBaseUrl="",ye.mode=null,typeof localStorage<"u"&&(localStorage.removeItem("pac_proxy_token"),localStorage.removeItem("pac_proxy_mode"),localStorage.removeItem("pac_proxy_remote_base_url"))}const cu=()=>{const e=lu(),t={"Content-Type":"application/json"};return e&&(t.Authorization="Bearer "+e),t};async function pe(e,t={}){const n=await fetch("/api/local"+e,{...t,headers:{"Content-Type":"application/json",...t.headers}});if(!n.ok)throw new Error((await n.json().catch(()=>({}))).error||n.statusText);return n.json()}async function bs(e,t,n={}){const s=(e||"").trim().replace(/\/$/,"");if(!s)throw new Error("未配置远程服务器地址。请在 packages/node-cli/.env 中配置 REMOTE_SERVER_URL(填 node-server 的地址,例如 http://127.0.0.1:3000),重启 node-cli 后重新登录。");const o=s+"/api"+t,r=await fetch(o,{...n,headers:{...cu(),...n.headers}});if(!r.ok)throw new Error((await r.json().catch(()=>({}))).error||r.statusText);return r.json()}function Pi(e,t){const n={getProxy:()=>pe("/proxy"),setProxy:s=>pe("/proxy",{method:"PUT",body:JSON.stringify(s)})};return e==="local"?{...n,getPacRules:()=>pe("/pac-rules"),setPacRules:s=>pe("/pac-rules",{method:"PUT",body:JSON.stringify(s)}),getConfig:()=>pe("/config")}:{...n,getPacRules:()=>bs(t,"/pac-rules"),setPacRules:async s=>{await bs(t,"/pac-rules",{method:"PUT",body:JSON.stringify(s)}),await pe("/pac-rules",{method:"PUT",body:JSON.stringify(s)})},getConfig:()=>bs(t,"/config")}}const Lt=(e,t)=>{const n=e.__vccOpts||e;for(const[s,o]of t)n[s]=o;return n},uu={class:"app-layout"},fu={key:0,class:"topbar"},du={class:"top-nav"},pu={key:0,class:"top-right"},hu={class:"username"},gu={key:1,class:"sidebar"},mu={class:"side-nav"},vu={__name:"App",setup(e){const t=Ei(),n=is(),s=so(),o=ve(()=>s.mode||"local"),r=ve(()=>o.value==="remote"),i=ve(()=>s.user),l=ve(()=>o.value==="local"?"本地模式":"远程模式"),a=ve(()=>t.path!=="/"),f=ve(()=>t.path!=="/"&&!t.path.startsWith("/login")&&!t.path.startsWith("/register")),c=ve(()=>t.path==="/"||t.path.startsWith("/login")||t.path.startsWith("/register"));async function p(){try{const g=await pe("/config");await pe("/config",{method:"PUT",body:JSON.stringify({...g,mode:"local"})})}catch{}au(),n.push("/")}return(g,v)=>{const O=$n("router-link"),w=$n("router-view");return W(),q("div",uu,[a.value?(W(),q("header",fu,[v[3]||(v[3]=h("span",{class:"logo"},"PAC 代理控制台",-1)),h("span",{class:Ce(["mode-tag",o.value])},J(l.value),3),fe(O,{to:"/",class:"switch-mode"},{default:ft(()=>[...v[0]||(v[0]=[Le("切换模式",-1)])]),_:1}),h("nav",du,[fe(O,{to:"/"},{default:ft(()=>[...v[1]||(v[1]=[Le("首页",-1)])]),_:1}),fe(O,{to:"/console"},{default:ft(()=>[...v[2]||(v[2]=[Le("控制台",-1)])]),_:1})]),r.value&&i.value?(W(),q("div",pu,[h("span",hu,J(i.value.username),1),h("button",{type:"button",class:"logout-btn",onClick:p},"退出登录")])):he("",!0)])):he("",!0),f.value?(W(),q("aside",gu,[h("nav",mu,[fe(O,{to:"/console/proxy","active-class":"active"},{default:ft(()=>[...v[4]||(v[4]=[Le("代理设置",-1)])]),_:1}),fe(O,{to:"/console/pac-rules","active-class":"active"},{default:ft(()=>[...v[5]||(v[5]=[Le("PAC 规则",-1)])]),_:1}),fe(O,{to:"/console/traffic","active-class":"active"},{default:ft(()=>[...v[6]||(v[6]=[Le("流量记录",-1)])]),_:1})])])):he("",!0),h("main",{class:Ce(["main",{"main-standalone":c.value}])},[fe(w)],2)])}}},yu=Lt(vu,[["__scopeId","data-v-e7869e57"]]),_u={class:"mode-select"},bu={class:"card"},xu={class:"options"},Su={__name:"ModeSelect",setup(e){const t=is();async function n(s){if(oo(s),s==="local"){try{const o=await pe("/config");await pe("/config",{method:"PUT",body:JSON.stringify({...o,mode:"local"})})}catch{}t.push("/console")}else t.push("/login")}return(s,o)=>(W(),q("div",_u,[h("div",bu,[o[4]||(o[4]=h("h1",null,"选择运行模式",-1)),o[5]||(o[5]=h("p",{class:"desc"},"请选择控制台使用方式,选择后可随时在设置中切换。",-1)),h("div",xu,[h("button",{class:"option local",onClick:o[0]||(o[0]=r=>n("local"))},[...o[2]||(o[2]=[h("span",{class:"title"},"本地模式",-1),h("span",{class:"sub"},"无需登录,配置保存在本机,由 node-cli 维护",-1)])]),h("button",{class:"option remote",onClick:o[1]||(o[1]=r=>n("remote"))},[...o[3]||(o[3]=[h("span",{class:"title"},"远程模式",-1),h("span",{class:"sub"},"需注册/登录,配置与数据保存在云端",-1)])])])])]))}},Eu=Lt(Su,[["__scopeId","data-v-b465f762"]]),wu={class:"auth-page"},Ru={class:"card"},Cu={class:"field"},Au={class:"field"},Pu={key:0,class:"error"},Tu=["disabled"],Ou={class:"footer"},Iu={__name:"Login",setup(e){const t=is(),n=Y(""),s=Y(""),o=Y(""),r=Y(""),i=Y(!1);Yt(async()=>{try{const a=await fetch("/api/local/remote-server-url"),{url:f}=await a.json();n.value=f||""}catch{n.value=""}});async function l(){if(r.value="",!n.value){r.value="请在 node-cli 目录下的 .env 中配置 REMOTE_SERVER_URL";return}i.value=!0;try{const a=n.value.replace(/\/$/,""),f=await fetch(a+"/api/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:s.value,password:o.value})}),c=await f.json().catch(()=>({}));if(!f.ok)throw new Error(c.error||"登录失败");oo("remote"),Ci(a),Ai(c.token),Ri(c.user||{username:s.value});try{const p=await pe("/config");await pe("/config",{method:"PUT",body:JSON.stringify({...p,mode:"remote"})});const g=await fetch(a+"/api/pac-rules",{headers:{Authorization:"Bearer "+c.token}}).then(v=>v.json()).catch(()=>[]);Array.isArray(g)&&await pe("/pac-rules",{method:"PUT",body:JSON.stringify(g)})}catch{}t.push("/console")}catch(a){r.value=a.message}finally{i.value=!1}}return(a,f)=>{const c=$n("router-link");return W(),q("div",wu,[h("div",Ru,[f[6]||(f[6]=h("h1",null,"登录",-1)),f[7]||(f[7]=h("p",{class:"desc"},"远程模式需登录后使用云端配置。",-1)),h("form",{onSubmit:ss(l,["prevent"]),class:"form"},[h("div",Cu,[f[2]||(f[2]=h("label",null,"用户名",-1)),Ae(h("input",{"onUpdate:modelValue":f[0]||(f[0]=p=>s.value=p),type:"text",required:""},null,512),[[We,s.value]])]),h("div",Au,[f[3]||(f[3]=h("label",null,"密码",-1)),Ae(h("input",{"onUpdate:modelValue":f[1]||(f[1]=p=>o.value=p),type:"password",required:""},null,512),[[We,o.value]])]),r.value?(W(),q("p",Pu,J(r.value),1)):he("",!0),h("button",{type:"submit",class:"btn primary",disabled:i.value},"登录",8,Tu)],32),h("p",Ou,[f[5]||(f[5]=Le("还没有账号? ",-1)),fe(c,{to:"/register"},{default:ft(()=>[...f[4]||(f[4]=[Le("注册",-1)])]),_:1})])])])}}},Nu=Lt(Iu,[["__scopeId","data-v-be60da76"]]),Mu={class:"auth-page"},Du={class:"card"},Uu={class:"field"},Lu={class:"field"},ku={key:0,class:"error"},$u={key:1,class:"success"},ju=["disabled"],Vu={class:"footer"},Hu={__name:"Register",setup(e){const t=is(),n=Y(""),s=Y(""),o=Y(""),r=Y(""),i=Y(""),l=Y(!1);Yt(async()=>{try{const f=await fetch("/api/local/remote-server-url"),{url:c}=await f.json();n.value=c||""}catch{n.value=""}});async function a(){if(r.value="",i.value="",!n.value){r.value="请在 node-cli 目录下的 .env 中配置 REMOTE_SERVER_URL";return}l.value=!0;try{const f=n.value.replace(/\/$/,""),c=await fetch(f+"/api/auth/register",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:s.value,password:o.value})}),p=await c.json().catch(()=>({}));if(!c.ok)throw new Error(p.error||"注册失败");i.value="注册成功,正在自动登录…";const g=await fetch(f+"/api/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:s.value,password:o.value})}),v=await g.json().catch(()=>({}));if(!g.ok)throw new Error(v.error||"自动登录失败");oo("remote"),Ci(f),Ai(v.token),Ri(v.user||{username:s.value}),i.value="注册成功,已自动登录";try{const O=await pe("/config");await pe("/config",{method:"PUT",body:JSON.stringify({...O,mode:"remote"})});const w=await fetch(f+"/api/pac-rules",{headers:{Authorization:"Bearer "+v.token}}).then(E=>E.json()).catch(()=>[]);Array.isArray(w)&&await pe("/pac-rules",{method:"PUT",body:JSON.stringify(w)})}catch{}t.push("/console")}catch(f){r.value=f.message}finally{l.value=!1}}return(f,c)=>{const p=$n("router-link");return W(),q("div",Mu,[h("div",Du,[c[6]||(c[6]=h("h1",null,"注册",-1)),c[7]||(c[7]=h("p",{class:"desc"},"注册后可在远程模式下同步配置。",-1)),h("form",{onSubmit:ss(a,["prevent"]),class:"form"},[h("div",Uu,[c[2]||(c[2]=h("label",null,"用户名",-1)),Ae(h("input",{"onUpdate:modelValue":c[0]||(c[0]=g=>s.value=g),type:"text",required:""},null,512),[[We,s.value]])]),h("div",Lu,[c[3]||(c[3]=h("label",null,"密码",-1)),Ae(h("input",{"onUpdate:modelValue":c[1]||(c[1]=g=>o.value=g),type:"password",required:""},null,512),[[We,o.value]])]),r.value?(W(),q("p",ku,J(r.value),1)):he("",!0),i.value?(W(),q("p",$u,J(i.value),1)):he("",!0),h("button",{type:"submit",class:"btn primary",disabled:l.value},"注册",8,ju)],32),h("p",Vu,[c[5]||(c[5]=Le("已有账号? ",-1)),fe(p,{to:"/login"},{default:ft(()=>[...c[4]||(c[4]=[Le("登录",-1)])]),_:1})])])])}}},Fu=Lt(Hu,[["__scopeId","data-v-a1c8458c"]]),Bu={class:"proxy-settings"},Ku={class:"card"},Gu={class:"proxy-buttons"},Wu=["disabled"],qu=["disabled"],Ju=["disabled"],zu=["disabled"],Qu={key:0,class:"saved-tip"},Yu={key:1,class:"ca-download"},Xu={class:"card"},Zu={class:"field"},ef={class:"row"},tf={class:"field"},nf={class:"field"},sf={class:"actions"},of=["disabled"],rf={key:0,class:"card status-card"},lf={class:"status-line"},af={key:0,class:"status-port"},cf={key:0,class:"hint"},uf={key:1,class:"hint error"},ff={key:2,class:"hint"},df={key:3,class:"hint"},pf="/api/local/ca-cert",hf={__name:"ProxySettings",setup(e){const t=so();function n(){return Pi(t.mode,t.remoteBaseUrl)}async function s(){return pe("/proxy")}async function o(w){return pe("/proxy",{method:"PUT",body:JSON.stringify(w)})}const r=Y({enabled:!1,mode:"pac",upstream:"socks5://127.0.0.1:1080",httpPort:5175,httpsPort:5176,applySystemProxy:!0}),i=Y(!1),l=Y(null),a=Y(!1);let f=null;async function c(){try{const w=await fetch("/api/local/proxy-status");l.value=await w.json()}catch{l.value={running:!1,port:null}}}function p(){a.value=!0,f&&clearTimeout(f),f=setTimeout(()=>{a.value=!1},2e3)}function g(){return{enabled:!!r.value.enabled,mode:r.value.mode||"pac",upstream:String(r.value.upstream??"").trim(),httpPort:Number(r.value.httpPort)||5175,httpsPort:Number(r.value.httpsPort)||5176,applySystemProxy:r.value.applySystemProxy!==!1}}async function v(w){if(!i.value){w==="clear"?(r.value.enabled=!1,r.value.applySystemProxy=!0):(r.value.enabled=!0,r.value.mode=w,r.value.applySystemProxy=!0),i.value=!0;try{const E=g();if(await o(E),t.mode==="remote")try{const C=await n().getPacRules();await pe("/pac-rules",{method:"PUT",body:JSON.stringify(C)})}catch{}await c(),p()}catch{}finally{i.value=!1}}}Yt(async()=>{try{const w=await s();if(r.value={...r.value,...w},t.mode==="remote")try{const E=await n().getPacRules();await pe("/pac-rules",{method:"PUT",body:JSON.stringify(E)})}catch{}await c()}catch{}});async function O(){i.value=!0;try{const w=g();if(await o(w),t.mode==="remote")try{const C=await n().getPacRules();await pe("/pac-rules",{method:"PUT",body:JSON.stringify(C)})}catch{}await c();const E=Number(w.httpPort)||5175;w.enabled?w.applySystemProxy?alert(`已保存,并已尝试自动设置系统代理(127.0.0.1:${E})。`):alert(`已保存。请将系统或浏览器代理设置为 127.0.0.1:${E}。`):alert("已保存")}catch(w){alert("保存失败:"+w.message)}finally{i.value=!1}}return(w,E)=>(W(),q("div",Bu,[E[19]||(E[19]=h("h2",null,"代理设置",-1)),E[20]||(E[20]=h("p",{class:"page-desc"},"代理配置仅保存在本机,与本地/远程模式无关。",-1)),h("div",Ku,[E[9]||(E[9]=h("h3",null,"代理模式",-1)),E[10]||(E[10]=h("p",{class:"desc"},"一键设置本机系统代理或清除(支持 macOS、Windows、Linux GNOME)。",-1)),h("div",Gu,[h("button",{class:Ce(["btn proxy-btn",{active:r.value.enabled&&r.value.mode==="global"}]),onClick:E[0]||(E[0]=C=>v("global")),disabled:i.value,type:"button"}," 全局代理 ",10,Wu),h("button",{class:Ce(["btn proxy-btn",{active:r.value.enabled&&r.value.mode==="pac"}]),onClick:E[1]||(E[1]=C=>v("pac")),disabled:i.value,type:"button"}," PAC 代理 ",10,qu),h("button",{class:Ce(["btn proxy-btn",{active:r.value.enabled&&r.value.mode==="mitm"}]),onClick:E[2]||(E[2]=C=>v("mitm")),disabled:i.value,type:"button"}," 抓包代理 ",10,Ju),h("button",{class:Ce(["btn proxy-btn clear",{active:!r.value.enabled}]),onClick:E[3]||(E[3]=C=>v("clear")),disabled:i.value,type:"button"}," 清除代理设置 ",10,zu)]),a.value?(W(),q("p",Qu,"已生效")):he("",!0),r.value.enabled&&r.value.mode==="mitm"?(W(),q("div",Yu,[E[7]||(E[7]=h("span",{class:"ca-label"},"CA 证书(用于解密 HTTPS,需安装到系统/浏览器信任):",-1)),h("a",{class:"btn btn-ca",href:pf,download:"pac-proxy-ca.crt",target:"_blank",rel:"noopener"},"下载 CA 证书"),E[8]||(E[8]=h("p",{class:"ca-hint"},"仅限本机抓包使用,请勿安装到他人设备或生产环境。",-1))])):he("",!0)]),h("div",Xu,[E[14]||(E[14]=h("h3",null,"上游代理与端口",-1)),E[15]||(E[15]=h("p",{class:"desc"},"上游代理地址(如 SOCKS5:socks5://127.0.0.1:1080、 http://proxy.xxxx.com)。本地模式下可将 SOCKS5 转为 HTTP 代理并根据规则执行策略。",-1)),h("div",Zu,[E[11]||(E[11]=h("label",null,"上游代理地址",-1)),Ae(h("input",{"onUpdate:modelValue":E[4]||(E[4]=C=>r.value.upstream=C),placeholder:"socks5://127.0.0.1:1080"},null,512),[[We,r.value.upstream]])]),h("div",ef,[h("div",tf,[E[12]||(E[12]=h("label",null,"HTTP 代理端口",-1)),Ae(h("input",{"onUpdate:modelValue":E[5]||(E[5]=C=>r.value.httpPort=C),type:"number",min:"1",max:"65535"},null,512),[[We,r.value.httpPort,void 0,{number:!0}]])]),h("div",nf,[E[13]||(E[13]=h("label",null,"HTTPS 代理端口",-1)),Ae(h("input",{"onUpdate:modelValue":E[6]||(E[6]=C=>r.value.httpsPort=C),type:"number",min:"1",max:"65535"},null,512),[[We,r.value.httpsPort,void 0,{number:!0}]])])]),h("div",sf,[h("button",{class:"btn primary",onClick:O,disabled:i.value},"保存设置",8,of)])]),l.value!==null?(W(),q("div",rf,[E[18]||(E[18]=h("h3",null,"代理状态",-1)),h("p",lf,[h("span",{class:Ce(l.value.running?"status-on":"status-off")},J(l.value.running?"运行中":"已关闭"),3),l.value.running?(W(),q("span",af,"端口 "+J(l.value.port),1)):he("",!0)]),l.value.running&&r.value.applySystemProxy&&l.value.systemProxyOk!==!1?(W(),q("p",cf," 已尝试自动设置"+J(r.value.mode==="pac"?" PAC 代理":r.value.mode==="mitm"?"抓包代理":"系统代理")+"(127.0.0.1:"+J(l.value.port)+")。若未生效请检查终端或下方提示。 ",1)):l.value.running&&r.value.applySystemProxy&&l.value.systemProxyError?(W(),q("p",uf," 自动设置系统代理失败:"+J(l.value.systemProxyError)+" 请手动在「系统设置 → 网络 → 代理」中设置,或关闭「自动设置系统代理」。 ",1)):l.value.running?(W(),q("p",ff,[E[16]||(E[16]=Le(" 请将系统或浏览器的 HTTP/HTTPS 代理设置为 ",-1)),h("strong",null,"127.0.0.1:"+J(l.value.port),1),E[17]||(E[17]=Le(",代理才会生效。 ",-1))])):r.value.enabled?(W(),q("p",df," 保存后若仍显示已关闭,请查看终端是否有「代理服务已启动」或端口占用报错。 ")):he("",!0)])):he("",!0)]))}},gf=Lt(hf,[["__scopeId","data-v-9e948823"]]),mf={class:"pac-rules"},vf={key:0,class:"page-desc"},yf={class:"card"},_f={class:"actions top"},bf=["disabled"],xf=["disabled"],Sf={key:0,class:"copy-tip"},Ef={class:"table"},wf=["onClick"],Rf=["onClick"],Cf={key:0},Af={class:"modal-content"},Pf={class:"field"},Tf={class:"field"},Of={class:"field"},If={class:"modal-actions"},Nf=["disabled"],Mf={__name:"PacRules",setup(e){const t=so();function n(){return Pi(t.mode,t.remoteBaseUrl)}const s=Y([]),o=Y(null),r=Y({pattern:"",action:"proxy",priority:0}),i=Y(!1),l=Y(!1),a=ve(()=>[...s.value].sort((C,x)=>(x.priority??0)-(C.priority??0)));Yt(f);async function f(){try{if(s.value=await n().getPacRules(),Array.isArray(s.value)||(s.value=[]),t.mode==="remote")try{await pe("/pac-rules",{method:"PUT",body:JSON.stringify(s.value)})}catch{}}catch{s.value=[]}}function c(C=null){C?r.value={id:C.id,pattern:C.pattern,action:C.action||"proxy",priority:C.priority??0}:r.value={pattern:"",action:"proxy",priority:0},o.value=!0}async function p(){const{id:C,pattern:x,action:A,priority:D}=r.value;if(!x.trim()){alert("请填写 URL 匹配字符");return}i.value=!0;try{let F=[...s.value];if(C){const ce=F.findIndex(re=>re.id===C);ce>=0&&(F[ce]={...F[ce],pattern:x.trim(),action:A,priority:D})}else F.push({id:String(Date.now()),pattern:x.trim(),action:A||"proxy",priority:Number(D)||0});await n().setPacRules(F),s.value=F,o.value=null}catch(F){alert("保存失败:"+F.message)}finally{i.value=!1}}async function g(C){if(!confirm("确定删除该规则?"))return;const x=s.value.filter(A=>A.id!==C.id);try{await n().setPacRules(x),s.value=x}catch(A){alert("删除失败:"+A.message)}}function v(){return JSON.stringify(s.value,null,2)}function O(){return s.value.map(C=>(C.pattern||"").trim()).filter(Boolean).join(`
|
|
25
|
+
*/let Uc=()=>location.protocol+"//"+location.host;function bi(e,t){const{pathname:n,search:s,hash:o}=t,r=e.indexOf("#");if(r>-1){let i=o.includes(e.slice(r))?e.slice(r).length:1,l=o.slice(i);return l[0]!=="/"&&(l="/"+l),Ko(l,"")}return Ko(n,e)+s+o}function Lc(e,t,n,s){let o=[],r=[],i=null;const l=({state:g})=>{const v=bi(e,location),O=n.value,w=t.value;let E=0;if(g){if(n.value=v,t.value=g,i&&i===O){i=null;return}E=w?g.position-w.position:0}else s(v);o.forEach(C=>{C(n.value,O,{delta:E,type:Ds.pop,direction:E?E>0?ys.forward:ys.back:ys.unknown})})};function a(){i=n.value}function f(g){o.push(g);const v=()=>{const O=o.indexOf(g);O>-1&&o.splice(O,1)};return r.push(v),v}function c(){if(document.visibilityState==="hidden"){const{history:g}=window;if(!g.state)return;g.replaceState(Z({},g.state,{scroll:os()}),"")}}function p(){for(const g of r)g();r=[],window.removeEventListener("popstate",l),window.removeEventListener("pagehide",c),document.removeEventListener("visibilitychange",c)}return window.addEventListener("popstate",l),window.addEventListener("pagehide",c),document.addEventListener("visibilitychange",c),{pauseListeners:a,listen:f,destroy:p}}function zo(e,t,n,s=!1,o=!1){return{back:e,current:t,forward:n,replaced:s,position:window.history.length,scroll:o?os():null}}function kc(e){const{history:t,location:n}=window,s={value:bi(e,n)},o={value:t.state};o.value||r(s.value,{back:null,current:s.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function r(a,f,c){const p=e.indexOf("#"),g=p>-1?(n.host&&document.querySelector("base")?e:e.slice(p))+a:Uc()+e+a;try{t[c?"replaceState":"pushState"](f,"",g),o.value=f}catch(v){console.error(v),n[c?"replace":"assign"](g)}}function i(a,f){r(a,Z({},t.state,zo(o.value.back,a,o.value.forward,!0),f,{position:o.value.position}),!0),s.value=a}function l(a,f){const c=Z({},o.value,t.state,{forward:a,scroll:os()});r(c.current,c,!0),r(a,Z({},zo(s.value,a,null),{position:c.position+1},f),!1),s.value=a}return{location:s,state:o,push:l,replace:i}}function $c(e){e=xc(e);const t=kc(e),n=Lc(e,t.state,t.location,t.replace);function s(r,i=!0){i||n.pauseListeners(),history.go(r)}const o=Z({location:"",base:e,go:s,createHref:Ec.bind(null,e)},t,n);return Object.defineProperty(o,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(o,"state",{enumerable:!0,get:()=>t.state.value}),o}let It=function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.Group=2]="Group",e}({});var me=function(e){return e[e.Static=0]="Static",e[e.Param=1]="Param",e[e.ParamRegExp=2]="ParamRegExp",e[e.ParamRegExpEnd=3]="ParamRegExpEnd",e[e.EscapeNext=4]="EscapeNext",e}(me||{});const jc={type:It.Static,value:""},Vc=/[a-zA-Z0-9_]/;function Hc(e){if(!e)return[[]];if(e==="/")return[[jc]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(v){throw new Error(`ERR (${n})/"${f}": ${v}`)}let n=me.Static,s=n;const o=[];let r;function i(){r&&o.push(r),r=[]}let l=0,a,f="",c="";function p(){f&&(n===me.Static?r.push({type:It.Static,value:f}):n===me.Param||n===me.ParamRegExp||n===me.ParamRegExpEnd?(r.length>1&&(a==="*"||a==="+")&&t(`A repeatable param (${f}) must be alone in its segment. eg: '/:ids+.`),r.push({type:It.Param,value:f,regexp:c,repeatable:a==="*"||a==="+",optional:a==="*"||a==="?"})):t("Invalid state to consume buffer"),f="")}function g(){f+=a}for(;l<e.length;){if(a=e[l++],a==="\\"&&n!==me.ParamRegExp){s=n,n=me.EscapeNext;continue}switch(n){case me.Static:a==="/"?(f&&p(),i()):a===":"?(p(),n=me.Param):g();break;case me.EscapeNext:g(),n=s;break;case me.Param:a==="("?n=me.ParamRegExp:Vc.test(a)?g():(p(),n=me.Static,a!=="*"&&a!=="?"&&a!=="+"&&l--);break;case me.ParamRegExp:a===")"?c[c.length-1]=="\\"?c=c.slice(0,-1)+a:n=me.ParamRegExpEnd:c+=a;break;case me.ParamRegExpEnd:p(),n=me.Static,a!=="*"&&a!=="?"&&a!=="+"&&l--,c="";break;default:t("Unknown state");break}}return n===me.ParamRegExp&&t(`Unfinished custom RegExp for param "${f}"`),p(),i(),o}const Qo="[^/]+?",Fc={sensitive:!1,strict:!1,start:!0,end:!0};var we=function(e){return e[e._multiplier=10]="_multiplier",e[e.Root=90]="Root",e[e.Segment=40]="Segment",e[e.SubSegment=30]="SubSegment",e[e.Static=40]="Static",e[e.Dynamic=20]="Dynamic",e[e.BonusCustomRegExp=10]="BonusCustomRegExp",e[e.BonusWildcard=-50]="BonusWildcard",e[e.BonusRepeatable=-20]="BonusRepeatable",e[e.BonusOptional=-8]="BonusOptional",e[e.BonusStrict=.7000000000000001]="BonusStrict",e[e.BonusCaseSensitive=.25]="BonusCaseSensitive",e}(we||{});const Bc=/[.+*?^${}()[\]/\\]/g;function Kc(e,t){const n=Z({},Fc,t),s=[];let o=n.start?"^":"";const r=[];for(const f of e){const c=f.length?[]:[we.Root];n.strict&&!f.length&&(o+="/");for(let p=0;p<f.length;p++){const g=f[p];let v=we.Segment+(n.sensitive?we.BonusCaseSensitive:0);if(g.type===It.Static)p||(o+="/"),o+=g.value.replace(Bc,"\\$&"),v+=we.Static;else if(g.type===It.Param){const{value:O,repeatable:w,optional:E,regexp:C}=g;r.push({name:O,repeatable:w,optional:E});const x=C||Qo;if(x!==Qo){v+=we.BonusCustomRegExp;try{`${x}`}catch(D){throw new Error(`Invalid custom RegExp for param "${O}" (${x}): `+D.message)}}let A=w?`((?:${x})(?:/(?:${x}))*)`:`(${x})`;p||(A=E&&f.length<2?`(?:/${A})`:"/"+A),E&&(A+="?"),o+=A,v+=we.Dynamic,E&&(v+=we.BonusOptional),w&&(v+=we.BonusRepeatable),x===".*"&&(v+=we.BonusWildcard)}c.push(v)}s.push(c)}if(n.strict&&n.end){const f=s.length-1;s[f][s[f].length-1]+=we.BonusStrict}n.strict||(o+="/?"),n.end?o+="$":n.strict&&!o.endsWith("/")&&(o+="(?:/|$)");const i=new RegExp(o,n.sensitive?"":"i");function l(f){const c=f.match(i),p={};if(!c)return null;for(let g=1;g<c.length;g++){const v=c[g]||"",O=r[g-1];p[O.name]=v&&O.repeatable?v.split("/"):v}return p}function a(f){let c="",p=!1;for(const g of e){(!p||!c.endsWith("/"))&&(c+="/"),p=!1;for(const v of g)if(v.type===It.Static)c+=v.value;else if(v.type===It.Param){const{value:O,repeatable:w,optional:E}=v,C=O in f?f[O]:"";if(Je(C)&&!w)throw new Error(`Provided param "${O}" is an array but it is not repeatable (* or + modifiers)`);const x=Je(C)?C.join("/"):C;if(!x)if(E)g.length<2&&(c.endsWith("/")?c=c.slice(0,-1):p=!0);else throw new Error(`Missing required param "${O}"`);c+=x}}return c||"/"}return{re:i,score:s,keys:r,parse:l,stringify:a}}function Gc(e,t){let n=0;for(;n<e.length&&n<t.length;){const s=t[n]-e[n];if(s)return s;n++}return e.length<t.length?e.length===1&&e[0]===we.Static+we.Segment?-1:1:e.length>t.length?t.length===1&&t[0]===we.Static+we.Segment?1:-1:0}function xi(e,t){let n=0;const s=e.score,o=t.score;for(;n<s.length&&n<o.length;){const r=Gc(s[n],o[n]);if(r)return r;n++}if(Math.abs(o.length-s.length)===1){if(Yo(s))return 1;if(Yo(o))return-1}return o.length-s.length}function Yo(e){const t=e[e.length-1];return e.length>0&&t[t.length-1]<0}const Wc={strict:!1,end:!0,sensitive:!1};function qc(e,t,n){const s=Kc(Hc(e.path),n),o=Z(s,{record:e,parent:t,children:[],alias:[]});return t&&!o.record.aliasOf==!t.record.aliasOf&&t.children.push(o),o}function Jc(e,t){const n=[],s=new Map;t=Bo(Wc,t);function o(p){return s.get(p)}function r(p,g,v){const O=!v,w=Zo(p);w.aliasOf=v&&v.record;const E=Bo(t,p),C=[w];if("alias"in p){const D=typeof p.alias=="string"?[p.alias]:p.alias;for(const F of D)C.push(Zo(Z({},w,{components:v?v.record.components:w.components,path:F,aliasOf:v?v.record:w})))}let x,A;for(const D of C){const{path:F}=D;if(g&&F[0]!=="/"){const ce=g.record.path,re=ce[ce.length-1]==="/"?"":"/";D.path=g.record.path+(F&&re+F)}if(x=qc(D,g,E),v?v.alias.push(x):(A=A||x,A!==x&&A.alias.push(x),O&&p.name&&!er(x)&&i(p.name)),Si(x)&&a(x),w.children){const ce=w.children;for(let re=0;re<ce.length;re++)r(ce[re],x,v&&v.children[re])}v=v||x}return A?()=>{i(A)}:dn}function i(p){if(yi(p)){const g=s.get(p);g&&(s.delete(p),n.splice(n.indexOf(g),1),g.children.forEach(i),g.alias.forEach(i))}else{const g=n.indexOf(p);g>-1&&(n.splice(g,1),p.record.name&&s.delete(p.record.name),p.children.forEach(i),p.alias.forEach(i))}}function l(){return n}function a(p){const g=Yc(p,n);n.splice(g,0,p),p.record.name&&!er(p)&&s.set(p.record.name,p)}function f(p,g){let v,O={},w,E;if("name"in p&&p.name){if(v=s.get(p.name),!v)throw Qt(de.MATCHER_NOT_FOUND,{location:p});E=v.record.name,O=Z(Xo(g.params,v.keys.filter(A=>!A.optional).concat(v.parent?v.parent.keys.filter(A=>A.optional):[]).map(A=>A.name)),p.params&&Xo(p.params,v.keys.map(A=>A.name))),w=v.stringify(O)}else if(p.path!=null)w=p.path,v=n.find(A=>A.re.test(w)),v&&(O=v.parse(w),E=v.record.name);else{if(v=g.name?s.get(g.name):n.find(A=>A.re.test(g.path)),!v)throw Qt(de.MATCHER_NOT_FOUND,{location:p,currentLocation:g});E=v.record.name,O=Z({},g.params,p.params),w=v.stringify(O)}const C=[];let x=v;for(;x;)C.unshift(x.record),x=x.parent;return{name:E,path:w,params:O,matched:C,meta:Qc(C)}}e.forEach(p=>r(p));function c(){n.length=0,s.clear()}return{addRoute:r,resolve:f,removeRoute:i,clearRoutes:c,getRoutes:l,getRecordMatcher:o}}function Xo(e,t){const n={};for(const s of t)s in e&&(n[s]=e[s]);return n}function Zo(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:zc(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function zc(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const s in e.components)t[s]=typeof n=="object"?n[s]:n;return t}function er(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Qc(e){return e.reduce((t,n)=>Z(t,n.meta),{})}function Yc(e,t){let n=0,s=t.length;for(;n!==s;){const r=n+s>>1;xi(e,t[r])<0?s=r:n=r+1}const o=Xc(e);return o&&(s=t.lastIndexOf(o,s-1)),s}function Xc(e){let t=e;for(;t=t.parent;)if(Si(t)&&xi(e,t)===0)return t}function Si({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function tr(e){const t=Ge(rs),n=Ge(no),s=ve(()=>{const a=Dt(e.to);return t.resolve(a)}),o=ve(()=>{const{matched:a}=s.value,{length:f}=a,c=a[f-1],p=n.matched;if(!c||!p.length)return-1;const g=p.findIndex(zt.bind(null,c));if(g>-1)return g;const v=nr(a[f-2]);return f>1&&nr(c)===v&&p[p.length-1].path!==v?p.findIndex(zt.bind(null,a[f-2])):g}),r=ve(()=>o.value>-1&&su(n.params,s.value.params)),i=ve(()=>o.value>-1&&o.value===n.matched.length-1&&vi(n.params,s.value.params));function l(a={}){if(nu(a)){const f=t[Dt(e.replace)?"replace":"push"](Dt(e.to)).catch(dn);return e.viewTransition&&typeof document<"u"&&"startViewTransition"in document&&document.startViewTransition(()=>f),f}return Promise.resolve()}return{route:s,href:ve(()=>s.value.href),isActive:r,isExactActive:i,navigate:l}}function Zc(e){return e.length===1?e[0]:e}const eu=kr({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"},viewTransition:Boolean},useLink:tr,setup(e,{slots:t}){const n=xn(tr(e)),{options:s}=Ge(rs),o=ve(()=>({[sr(e.activeClass,s.linkActiveClass,"router-link-active")]:n.isActive,[sr(e.exactActiveClass,s.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const r=t.default&&Zc(t.default(n));return e.custom?r:ci("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:o.value},r)}}}),tu=eu;function nu(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function su(e,t){for(const n in t){const s=t[n],o=e[n];if(typeof s=="string"){if(s!==o)return!1}else if(!Je(o)||o.length!==s.length||s.some((r,i)=>r.valueOf()!==o[i].valueOf()))return!1}return!0}function nr(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const sr=(e,t,n)=>e??t??n,ou=kr({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const s=Ge(Ls),o=ve(()=>e.route||s.value),r=Ge(Jo,0),i=ve(()=>{let f=Dt(r);const{matched:c}=o.value;let p;for(;(p=c[f])&&!p.components;)f++;return f}),l=ve(()=>o.value.matched[i.value]);Pn(Jo,ve(()=>i.value+1)),Pn(Mc,l),Pn(Ls,o);const a=Y();return ln(()=>[a.value,l.value,e.name],([f,c,p],[g,v,O])=>{c&&(c.instances[p]=f,v&&v!==c&&f&&f===g&&(c.leaveGuards.size||(c.leaveGuards=v.leaveGuards),c.updateGuards.size||(c.updateGuards=v.updateGuards))),f&&c&&(!v||!zt(c,v)||!g)&&(c.enterCallbacks[p]||[]).forEach(w=>w(f))},{flush:"post"}),()=>{const f=o.value,c=e.name,p=l.value,g=p&&p.components[c];if(!g)return or(n.default,{Component:g,route:f});const v=p.props[c],O=v?v===!0?f.params:typeof v=="function"?v(f):v:null,E=ci(g,Z({},O,t,{onVnodeUnmounted:C=>{C.component.isUnmounted&&(p.instances[c]=null)},ref:a}));return or(n.default,{Component:E,route:f})||E}}});function or(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const ru=ou;function iu(e){const t=Jc(e.routes,e),n=e.parseQuery||Ic,s=e.stringifyQuery||qo,o=e.history,r=tn(),i=tn(),l=tn(),a=ul(bt);let f=bt;Ht&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const c=ms.bind(null,b=>""+b),p=ms.bind(null,hc),g=ms.bind(null,yn);function v(b,U){let N,$;return yi(b)?(N=t.getRecordMatcher(b),$=U):$=b,t.addRoute($,N)}function O(b){const U=t.getRecordMatcher(b);U&&t.removeRoute(U)}function w(){return t.getRoutes().map(b=>b.record)}function E(b){return!!t.getRecordMatcher(b)}function C(b,U){if(U=Z({},U||a.value),typeof b=="string"){const m=vs(n,b,U.path),y=t.resolve({path:m.path},U),S=o.createHref(m.fullPath);return Z(m,y,{params:g(y.params),hash:yn(m.hash),redirectedFrom:void 0,href:S})}let N;if(b.path!=null)N=Z({},b,{path:vs(n,b.path,U.path).path});else{const m=Z({},b.params);for(const y in m)m[y]==null&&delete m[y];N=Z({},b,{params:p(m)}),U.params=p(U.params)}const $=t.resolve(N,U),z=b.hash||"";$.params=c(g($.params));const u=vc(s,Z({},b,{hash:fc(z),path:$.path})),d=o.createHref(u);return Z({fullPath:u,hash:z,query:s===qo?Nc(b.query):b.query||{}},$,{redirectedFrom:void 0,href:d})}function x(b){return typeof b=="string"?vs(n,b,a.value.path):Z({},b)}function A(b,U){if(f!==b)return Qt(de.NAVIGATION_CANCELLED,{from:U,to:b})}function D(b){return re(b)}function F(b){return D(Z(x(b),{replace:!0}))}function ce(b,U){const N=b.matched[b.matched.length-1];if(N&&N.redirect){const{redirect:$}=N;let z=typeof $=="function"?$(b,U):$;return typeof z=="string"&&(z=z.includes("?")||z.includes("#")?z=x(z):{path:z},z.params={}),Z({query:b.query,hash:b.hash,params:z.path!=null?{}:b.params},z)}}function re(b,U){const N=f=C(b),$=a.value,z=b.state,u=b.force,d=b.replace===!0,m=ce(N,$);if(m)return re(Z(x(m),{state:typeof m=="object"?Z({},z,m.state):z,force:u,replace:d}),U||N);const y=N;y.redirectedFrom=U;let S;return!u&&yc(s,$,N)&&(S=Qt(de.NAVIGATION_DUPLICATED,{to:y,from:$}),Ye($,$,!0,!1)),(S?Promise.resolve(S):De(y,$)).catch(_=>ct(_)?ct(_,de.NAVIGATION_GUARD_REDIRECT)?_:_t(_):X(_,y,$)).then(_=>{if(_){if(ct(_,de.NAVIGATION_GUARD_REDIRECT))return re(Z({replace:d},x(_.to),{state:typeof _.to=="object"?Z({},z,_.to.state):z,force:u}),U||y)}else _=Qe(y,$,!0,d,z);return ze(y,$,_),_})}function je(b,U){const N=A(b,U);return N?Promise.reject(N):Promise.resolve()}function Be(b){const U=$t.values().next().value;return U&&typeof U.runWithContext=="function"?U.runWithContext(b):b()}function De(b,U){let N;const[$,z,u]=Dc(b,U);N=_s($.reverse(),"beforeRouteLeave",b,U);for(const m of $)m.leaveGuards.forEach(y=>{N.push(Et(y,b,U))});const d=je.bind(null,b,U);return N.push(d),Ve(N).then(()=>{N=[];for(const m of r.list())N.push(Et(m,b,U));return N.push(d),Ve(N)}).then(()=>{N=_s(z,"beforeRouteUpdate",b,U);for(const m of z)m.updateGuards.forEach(y=>{N.push(Et(y,b,U))});return N.push(d),Ve(N)}).then(()=>{N=[];for(const m of u)if(m.beforeEnter)if(Je(m.beforeEnter))for(const y of m.beforeEnter)N.push(Et(y,b,U));else N.push(Et(m.beforeEnter,b,U));return N.push(d),Ve(N)}).then(()=>(b.matched.forEach(m=>m.enterCallbacks={}),N=_s(u,"beforeRouteEnter",b,U,Be),N.push(d),Ve(N))).then(()=>{N=[];for(const m of i.list())N.push(Et(m,b,U));return N.push(d),Ve(N)}).catch(m=>ct(m,de.NAVIGATION_CANCELLED)?m:Promise.reject(m))}function ze(b,U,N){l.list().forEach($=>Be(()=>$(b,U,N)))}function Qe(b,U,N,$,z){const u=A(b,U);if(u)return u;const d=U===bt,m=Ht?history.state:{};N&&($||d?o.replace(b.fullPath,Z({scroll:d&&m&&m.scroll},z)):o.push(b.fullPath,z)),a.value=b,Ye(b,U,N,d),_t()}let k;function L(){k||(k=o.listen((b,U,N)=>{if(!Ct.listening)return;const $=C(b),z=ce($,Ct.currentRoute.value);if(z){re(Z(z,{replace:!0,force:!0}),$).catch(dn);return}f=$;const u=a.value;Ht&&Cc(Wo(u.fullPath,N.delta),os()),De($,u).catch(d=>ct(d,de.NAVIGATION_ABORTED|de.NAVIGATION_CANCELLED)?d:ct(d,de.NAVIGATION_GUARD_REDIRECT)?(re(Z(x(d.to),{force:!0}),$).then(m=>{ct(m,de.NAVIGATION_ABORTED|de.NAVIGATION_DUPLICATED)&&!N.delta&&N.type===Ds.pop&&o.go(-1,!1)}).catch(dn),Promise.reject()):(N.delta&&o.go(-N.delta,!1),X(d,$,u))).then(d=>{d=d||Qe($,u,!1),d&&(N.delta&&!ct(d,de.NAVIGATION_CANCELLED)?o.go(-N.delta,!1):N.type===Ds.pop&&ct(d,de.NAVIGATION_ABORTED|de.NAVIGATION_DUPLICATED)&&o.go(-1,!1)),ze($,u,d)}).catch(dn)}))}let K=tn(),ue=tn(),oe;function X(b,U,N){_t(b);const $=ue.list();return $.length?$.forEach(z=>z(b,U,N)):console.error(b),Promise.reject(b)}function lt(){return oe&&a.value!==bt?Promise.resolve():new Promise((b,U)=>{K.add([b,U])})}function _t(b){return oe||(oe=!b,L(),K.list().forEach(([U,N])=>b?N(b):U()),K.reset()),b}function Ye(b,U,N,$){const{scrollBehavior:z}=e;if(!Ht||!z)return Promise.resolve();const u=!N&&Ac(Wo(b.fullPath,0))||($||!N)&&history.state&&history.state.scroll||null;return zs().then(()=>z(b,U,u)).then(d=>d&&Rc(d)).catch(d=>X(d,b,U))}const Pe=b=>o.go(b);let kt;const $t=new Set,Ct={currentRoute:a,listening:!0,addRoute:v,removeRoute:O,clearRoutes:t.clearRoutes,hasRoute:E,getRoutes:w,resolve:C,options:e,push:D,replace:F,go:Pe,back:()=>Pe(-1),forward:()=>Pe(1),beforeEach:r.add,beforeResolve:i.add,afterEach:l.add,onError:ue.add,isReady:lt,install(b){b.component("RouterLink",tu),b.component("RouterView",ru),b.config.globalProperties.$router=Ct,Object.defineProperty(b.config.globalProperties,"$route",{enumerable:!0,get:()=>Dt(a)}),Ht&&!kt&&a.value===bt&&(kt=!0,D(o.location).catch($=>{}));const U={};for(const $ in bt)Object.defineProperty(U,$,{get:()=>a.value[$],enumerable:!0});b.provide(rs,Ct),b.provide(no,Ar(U)),b.provide(Ls,a);const N=b.unmount;$t.add(b),b.unmount=function(){$t.delete(b),$t.size<1&&(f=bt,k&&k(),k=null,a.value=bt,kt=!1,oe=!1),N()}}};function Ve(b){return b.reduce((U,N)=>U.then(()=>Be(N)),Promise.resolve())}return Ct}function is(){return Ge(rs)}function Ei(e){return Ge(no)}const ye=xn({mode:null,user:null,remoteBaseUrl:"",token:""});function so(){return Mn(ye)}function oo(e){ye.mode=e,typeof localStorage<"u"&&localStorage.setItem("pac_proxy_mode",e)}function wi(){if(typeof localStorage<"u"){const e=localStorage.getItem("pac_proxy_mode");(e==="local"||e==="remote")&&(ye.mode=e);const t=localStorage.getItem("pac_proxy_token");t&&(ye.token=t);const n=localStorage.getItem("pac_proxy_remote_base_url");if(n&&typeof n=="string"&&(ye.remoteBaseUrl=n),ye.mode==="remote"&&ye.token)try{const s=JSON.parse(atob(ye.token.split(".")[1]));ye.user={username:s.username}}catch{}}return ye.mode}function Ri(e){ye.user=e}function Ci(e){ye.remoteBaseUrl=e||"",typeof localStorage<"u"&&(e?localStorage.setItem("pac_proxy_remote_base_url",e):localStorage.removeItem("pac_proxy_remote_base_url"))}function Ai(e){ye.token=e,typeof localStorage<"u"&&(e?localStorage.setItem("pac_proxy_token",e):localStorage.removeItem("pac_proxy_token"))}function lu(){return ye.token||typeof localStorage<"u"&&localStorage.getItem("pac_proxy_token")}function au(){ye.token="",ye.user=null,ye.remoteBaseUrl="",ye.mode=null,typeof localStorage<"u"&&(localStorage.removeItem("pac_proxy_token"),localStorage.removeItem("pac_proxy_mode"),localStorage.removeItem("pac_proxy_remote_base_url"))}const cu=()=>{const e=lu(),t={"Content-Type":"application/json"};return e&&(t.Authorization="Bearer "+e),t};async function pe(e,t={}){const n=await fetch("/api/local"+e,{...t,headers:{"Content-Type":"application/json",...t.headers}});if(!n.ok)throw new Error((await n.json().catch(()=>({}))).error||n.statusText);return n.json()}async function bs(e,t,n={}){const s=(e||"").trim().replace(/\/$/,"");if(!s)throw new Error("未配置远程服务器地址。请在 packages/node-cli/.env 中配置 REMOTE_SERVER_URL(填 node-server 的地址,例如 http://127.0.0.1:3000),重启 node-cli 后重新登录。");const o=s+"/api"+t,r=await fetch(o,{...n,headers:{...cu(),...n.headers}});if(!r.ok)throw new Error((await r.json().catch(()=>({}))).error||r.statusText);return r.json()}function Pi(e,t){const n={getProxy:()=>pe("/proxy"),setProxy:s=>pe("/proxy",{method:"PUT",body:JSON.stringify(s)})};return e==="local"?{...n,getPacRules:()=>pe("/pac-rules"),setPacRules:s=>pe("/pac-rules",{method:"PUT",body:JSON.stringify(s)}),getConfig:()=>pe("/config")}:{...n,getPacRules:()=>bs(t,"/pac-rules"),setPacRules:async s=>{await bs(t,"/pac-rules",{method:"PUT",body:JSON.stringify(s)}),await pe("/pac-rules",{method:"PUT",body:JSON.stringify(s)})},getConfig:()=>bs(t,"/config")}}const Lt=(e,t)=>{const n=e.__vccOpts||e;for(const[s,o]of t)n[s]=o;return n},uu={class:"app-layout"},fu={key:0,class:"topbar"},du={class:"top-nav"},pu={key:0,class:"top-right"},hu={class:"username"},gu={key:1,class:"sidebar"},mu={class:"side-nav"},vu={__name:"App",setup(e){const t=Ei(),n=is(),s=so(),o=ve(()=>s.mode||"local"),r=ve(()=>o.value==="remote"),i=ve(()=>s.user),l=ve(()=>o.value==="local"?"本地模式":"远程模式"),a=ve(()=>t.path!=="/"),f=ve(()=>t.path!=="/"&&!t.path.startsWith("/login")&&!t.path.startsWith("/register")),c=ve(()=>t.path==="/"||t.path.startsWith("/login")||t.path.startsWith("/register"));async function p(){try{const g=await pe("/config");await pe("/config",{method:"PUT",body:JSON.stringify({...g,mode:"local"})})}catch{}au(),n.push("/")}return(g,v)=>{const O=$n("router-link"),w=$n("router-view");return W(),q("div",uu,[a.value?(W(),q("header",fu,[v[3]||(v[3]=h("span",{class:"logo"},"PAC 代理控制台",-1)),h("span",{class:Ce(["mode-tag",o.value])},J(l.value),3),fe(O,{to:"/",class:"switch-mode"},{default:ft(()=>[...v[0]||(v[0]=[Le("切换模式",-1)])]),_:1}),h("nav",du,[fe(O,{to:"/"},{default:ft(()=>[...v[1]||(v[1]=[Le("首页",-1)])]),_:1}),fe(O,{to:"/console"},{default:ft(()=>[...v[2]||(v[2]=[Le("控制台",-1)])]),_:1})]),r.value&&i.value?(W(),q("div",pu,[h("span",hu,J(i.value.username),1),h("button",{type:"button",class:"logout-btn",onClick:p},"退出登录")])):he("",!0)])):he("",!0),f.value?(W(),q("aside",gu,[h("nav",mu,[fe(O,{to:"/console/proxy","active-class":"active"},{default:ft(()=>[...v[4]||(v[4]=[Le("代理设置",-1)])]),_:1}),fe(O,{to:"/console/pac-rules","active-class":"active"},{default:ft(()=>[...v[5]||(v[5]=[Le("PAC 规则",-1)])]),_:1}),fe(O,{to:"/console/traffic","active-class":"active"},{default:ft(()=>[...v[6]||(v[6]=[Le("流量记录",-1)])]),_:1})])])):he("",!0),h("main",{class:Ce(["main",{"main-standalone":c.value}])},[fe(w)],2)])}}},yu=Lt(vu,[["__scopeId","data-v-c794e021"]]),_u={class:"mode-select"},bu={class:"card"},xu={class:"options"},Su={__name:"ModeSelect",setup(e){const t=is();async function n(s){if(oo(s),s==="local"){try{const o=await pe("/config");await pe("/config",{method:"PUT",body:JSON.stringify({...o,mode:"local"})})}catch{}t.push("/console")}else t.push("/login")}return(s,o)=>(W(),q("div",_u,[h("div",bu,[o[4]||(o[4]=h("h1",null,"选择运行模式",-1)),o[5]||(o[5]=h("p",{class:"desc"},"请选择控制台使用方式,选择后可随时在设置中切换。",-1)),h("div",xu,[h("button",{class:"option local",onClick:o[0]||(o[0]=r=>n("local"))},[...o[2]||(o[2]=[h("span",{class:"title"},"本地模式",-1),h("span",{class:"sub"},"无需登录,配置保存在本机,由 node-cli 维护",-1)])]),h("button",{class:"option remote",onClick:o[1]||(o[1]=r=>n("remote"))},[...o[3]||(o[3]=[h("span",{class:"title"},"远程模式",-1),h("span",{class:"sub"},"需注册/登录,配置与数据保存在云端",-1)])])])])]))}},Eu=Lt(Su,[["__scopeId","data-v-b465f762"]]),wu={class:"auth-page"},Ru={class:"card"},Cu={class:"field"},Au={class:"field"},Pu={key:0,class:"error"},Tu=["disabled"],Ou={class:"footer"},Iu={__name:"Login",setup(e){const t=is(),n=Y(""),s=Y(""),o=Y(""),r=Y(""),i=Y(!1);Yt(async()=>{try{const a=await fetch("/api/local/remote-server-url"),{url:f}=await a.json();n.value=f||""}catch{n.value=""}});async function l(){if(r.value="",!n.value){r.value="请在 node-cli 目录下的 .env 中配置 REMOTE_SERVER_URL";return}i.value=!0;try{const a=n.value.replace(/\/$/,""),f=await fetch(a+"/api/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:s.value,password:o.value})}),c=await f.json().catch(()=>({}));if(!f.ok)throw new Error(c.error||"登录失败");oo("remote"),Ci(a),Ai(c.token),Ri(c.user||{username:s.value});try{const p=await pe("/config");await pe("/config",{method:"PUT",body:JSON.stringify({...p,mode:"remote"})});const g=await fetch(a+"/api/pac-rules",{headers:{Authorization:"Bearer "+c.token}}).then(v=>v.json()).catch(()=>[]);Array.isArray(g)&&await pe("/pac-rules",{method:"PUT",body:JSON.stringify(g)})}catch{}t.push("/console")}catch(a){r.value=a.message}finally{i.value=!1}}return(a,f)=>{const c=$n("router-link");return W(),q("div",wu,[h("div",Ru,[f[6]||(f[6]=h("h1",null,"登录",-1)),f[7]||(f[7]=h("p",{class:"desc"},"远程模式需登录后使用云端配置。",-1)),h("form",{onSubmit:ss(l,["prevent"]),class:"form"},[h("div",Cu,[f[2]||(f[2]=h("label",null,"用户名",-1)),Ae(h("input",{"onUpdate:modelValue":f[0]||(f[0]=p=>s.value=p),type:"text",required:""},null,512),[[We,s.value]])]),h("div",Au,[f[3]||(f[3]=h("label",null,"密码",-1)),Ae(h("input",{"onUpdate:modelValue":f[1]||(f[1]=p=>o.value=p),type:"password",required:""},null,512),[[We,o.value]])]),r.value?(W(),q("p",Pu,J(r.value),1)):he("",!0),h("button",{type:"submit",class:"btn primary",disabled:i.value},"登录",8,Tu)],32),h("p",Ou,[f[5]||(f[5]=Le("还没有账号? ",-1)),fe(c,{to:"/register"},{default:ft(()=>[...f[4]||(f[4]=[Le("注册",-1)])]),_:1})])])])}}},Nu=Lt(Iu,[["__scopeId","data-v-be60da76"]]),Mu={class:"auth-page"},Du={class:"card"},Uu={class:"field"},Lu={class:"field"},ku={key:0,class:"error"},$u={key:1,class:"success"},ju=["disabled"],Vu={class:"footer"},Hu={__name:"Register",setup(e){const t=is(),n=Y(""),s=Y(""),o=Y(""),r=Y(""),i=Y(""),l=Y(!1);Yt(async()=>{try{const f=await fetch("/api/local/remote-server-url"),{url:c}=await f.json();n.value=c||""}catch{n.value=""}});async function a(){if(r.value="",i.value="",!n.value){r.value="请在 node-cli 目录下的 .env 中配置 REMOTE_SERVER_URL";return}l.value=!0;try{const f=n.value.replace(/\/$/,""),c=await fetch(f+"/api/auth/register",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:s.value,password:o.value})}),p=await c.json().catch(()=>({}));if(!c.ok)throw new Error(p.error||"注册失败");i.value="注册成功,正在自动登录…";const g=await fetch(f+"/api/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:s.value,password:o.value})}),v=await g.json().catch(()=>({}));if(!g.ok)throw new Error(v.error||"自动登录失败");oo("remote"),Ci(f),Ai(v.token),Ri(v.user||{username:s.value}),i.value="注册成功,已自动登录";try{const O=await pe("/config");await pe("/config",{method:"PUT",body:JSON.stringify({...O,mode:"remote"})});const w=await fetch(f+"/api/pac-rules",{headers:{Authorization:"Bearer "+v.token}}).then(E=>E.json()).catch(()=>[]);Array.isArray(w)&&await pe("/pac-rules",{method:"PUT",body:JSON.stringify(w)})}catch{}t.push("/console")}catch(f){r.value=f.message}finally{l.value=!1}}return(f,c)=>{const p=$n("router-link");return W(),q("div",Mu,[h("div",Du,[c[6]||(c[6]=h("h1",null,"注册",-1)),c[7]||(c[7]=h("p",{class:"desc"},"注册后可在远程模式下同步配置。",-1)),h("form",{onSubmit:ss(a,["prevent"]),class:"form"},[h("div",Uu,[c[2]||(c[2]=h("label",null,"用户名",-1)),Ae(h("input",{"onUpdate:modelValue":c[0]||(c[0]=g=>s.value=g),type:"text",required:""},null,512),[[We,s.value]])]),h("div",Lu,[c[3]||(c[3]=h("label",null,"密码",-1)),Ae(h("input",{"onUpdate:modelValue":c[1]||(c[1]=g=>o.value=g),type:"password",required:""},null,512),[[We,o.value]])]),r.value?(W(),q("p",ku,J(r.value),1)):he("",!0),i.value?(W(),q("p",$u,J(i.value),1)):he("",!0),h("button",{type:"submit",class:"btn primary",disabled:l.value},"注册",8,ju)],32),h("p",Vu,[c[5]||(c[5]=Le("已有账号? ",-1)),fe(p,{to:"/login"},{default:ft(()=>[...c[4]||(c[4]=[Le("登录",-1)])]),_:1})])])])}}},Fu=Lt(Hu,[["__scopeId","data-v-a1c8458c"]]),Bu={class:"proxy-settings"},Ku={class:"card"},Gu={class:"proxy-buttons"},Wu=["disabled"],qu=["disabled"],Ju=["disabled"],zu=["disabled"],Qu={key:0,class:"saved-tip"},Yu={key:1,class:"ca-download"},Xu={class:"card"},Zu={class:"field"},ef={class:"row"},tf={class:"field"},nf={class:"field"},sf={class:"actions"},of=["disabled"],rf={key:0,class:"card status-card"},lf={class:"status-line"},af={key:0,class:"status-port"},cf={key:0,class:"hint"},uf={key:1,class:"hint error"},ff={key:2,class:"hint"},df={key:3,class:"hint"},pf="/api/local/ca-cert",hf={__name:"ProxySettings",setup(e){const t=so();function n(){return Pi(t.mode,t.remoteBaseUrl)}async function s(){return pe("/proxy")}async function o(w){return pe("/proxy",{method:"PUT",body:JSON.stringify(w)})}const r=Y({enabled:!1,mode:"pac",upstream:"socks5://127.0.0.1:1080",httpPort:5175,httpsPort:5176,applySystemProxy:!0}),i=Y(!1),l=Y(null),a=Y(!1);let f=null;async function c(){try{const w=await fetch("/api/local/proxy-status");l.value=await w.json()}catch{l.value={running:!1,port:null}}}function p(){a.value=!0,f&&clearTimeout(f),f=setTimeout(()=>{a.value=!1},2e3)}function g(){return{enabled:!!r.value.enabled,mode:r.value.mode||"pac",upstream:String(r.value.upstream??"").trim(),httpPort:Number(r.value.httpPort)||5175,httpsPort:Number(r.value.httpsPort)||5176,applySystemProxy:r.value.applySystemProxy!==!1}}async function v(w){if(!i.value){w==="clear"?(r.value.enabled=!1,r.value.applySystemProxy=!0):(r.value.enabled=!0,r.value.mode=w,r.value.applySystemProxy=!0),i.value=!0;try{const E=g();if(await o(E),t.mode==="remote")try{const C=await n().getPacRules();await pe("/pac-rules",{method:"PUT",body:JSON.stringify(C)})}catch{}await c(),p()}catch{}finally{i.value=!1}}}Yt(async()=>{try{const w=await s();if(r.value={...r.value,...w},t.mode==="remote")try{const E=await n().getPacRules();await pe("/pac-rules",{method:"PUT",body:JSON.stringify(E)})}catch{}await c()}catch{}});async function O(){i.value=!0;try{const w=g();if(await o(w),t.mode==="remote")try{const C=await n().getPacRules();await pe("/pac-rules",{method:"PUT",body:JSON.stringify(C)})}catch{}await c();const E=Number(w.httpPort)||5175;w.enabled?w.applySystemProxy?alert(`已保存,并已尝试自动设置系统代理(127.0.0.1:${E})。`):alert(`已保存。请将系统或浏览器代理设置为 127.0.0.1:${E}。`):alert("已保存")}catch(w){alert("保存失败:"+w.message)}finally{i.value=!1}}return(w,E)=>(W(),q("div",Bu,[E[19]||(E[19]=h("h2",null,"代理设置",-1)),E[20]||(E[20]=h("p",{class:"page-desc"},"代理配置仅保存在本机,与本地/远程模式无关。",-1)),h("div",Ku,[E[9]||(E[9]=h("h3",null,"代理模式",-1)),E[10]||(E[10]=h("p",{class:"desc"},"一键设置本机系统代理或清除(支持 macOS、Windows、Linux GNOME)。",-1)),h("div",Gu,[h("button",{class:Ce(["btn proxy-btn",{active:r.value.enabled&&r.value.mode==="global"}]),onClick:E[0]||(E[0]=C=>v("global")),disabled:i.value,type:"button"}," 全局代理 ",10,Wu),h("button",{class:Ce(["btn proxy-btn",{active:r.value.enabled&&r.value.mode==="pac"}]),onClick:E[1]||(E[1]=C=>v("pac")),disabled:i.value,type:"button"}," PAC 代理 ",10,qu),h("button",{class:Ce(["btn proxy-btn",{active:r.value.enabled&&r.value.mode==="mitm"}]),onClick:E[2]||(E[2]=C=>v("mitm")),disabled:i.value,type:"button"}," 抓包代理 ",10,Ju),h("button",{class:Ce(["btn proxy-btn clear",{active:!r.value.enabled}]),onClick:E[3]||(E[3]=C=>v("clear")),disabled:i.value,type:"button"}," 清除代理设置 ",10,zu)]),a.value?(W(),q("p",Qu,"已生效")):he("",!0),r.value.enabled&&r.value.mode==="mitm"?(W(),q("div",Yu,[E[7]||(E[7]=h("span",{class:"ca-label"},"CA 证书(用于解密 HTTPS,需安装到系统/浏览器信任):",-1)),h("a",{class:"btn btn-ca",href:pf,download:"pac-proxy-ca.crt",target:"_blank",rel:"noopener"},"下载 CA 证书"),E[8]||(E[8]=h("p",{class:"ca-hint"},"仅限本机抓包使用,请勿安装到他人设备或生产环境。",-1))])):he("",!0)]),h("div",Xu,[E[14]||(E[14]=h("h3",null,"上游代理与端口",-1)),E[15]||(E[15]=h("p",{class:"desc"},"上游代理地址(如 SOCKS5:socks5://127.0.0.1:1080、 http://proxy.xxxx.com)。本地模式下可将 SOCKS5 转为 HTTP 代理并根据规则执行策略。",-1)),h("div",Zu,[E[11]||(E[11]=h("label",null,"上游代理地址",-1)),Ae(h("input",{"onUpdate:modelValue":E[4]||(E[4]=C=>r.value.upstream=C),placeholder:"socks5://127.0.0.1:1080"},null,512),[[We,r.value.upstream]])]),h("div",ef,[h("div",tf,[E[12]||(E[12]=h("label",null,"HTTP 代理端口",-1)),Ae(h("input",{"onUpdate:modelValue":E[5]||(E[5]=C=>r.value.httpPort=C),type:"number",min:"1",max:"65535"},null,512),[[We,r.value.httpPort,void 0,{number:!0}]])]),h("div",nf,[E[13]||(E[13]=h("label",null,"HTTPS 代理端口",-1)),Ae(h("input",{"onUpdate:modelValue":E[6]||(E[6]=C=>r.value.httpsPort=C),type:"number",min:"1",max:"65535"},null,512),[[We,r.value.httpsPort,void 0,{number:!0}]])])]),h("div",sf,[h("button",{class:"btn primary",onClick:O,disabled:i.value},"保存设置",8,of)])]),l.value!==null?(W(),q("div",rf,[E[18]||(E[18]=h("h3",null,"代理状态",-1)),h("p",lf,[h("span",{class:Ce(l.value.running?"status-on":"status-off")},J(l.value.running?"运行中":"已关闭"),3),l.value.running?(W(),q("span",af,"端口 "+J(l.value.port),1)):he("",!0)]),l.value.running&&r.value.applySystemProxy&&l.value.systemProxyOk!==!1?(W(),q("p",cf," 已尝试自动设置"+J(r.value.mode==="pac"?" PAC 代理":r.value.mode==="mitm"?"抓包代理":"系统代理")+"(127.0.0.1:"+J(l.value.port)+")。若未生效请检查终端或下方提示。 ",1)):l.value.running&&r.value.applySystemProxy&&l.value.systemProxyError?(W(),q("p",uf," 自动设置系统代理失败:"+J(l.value.systemProxyError)+" 请手动在「系统设置 → 网络 → 代理」中设置,或关闭「自动设置系统代理」。 ",1)):l.value.running?(W(),q("p",ff,[E[16]||(E[16]=Le(" 请将系统或浏览器的 HTTP/HTTPS 代理设置为 ",-1)),h("strong",null,"127.0.0.1:"+J(l.value.port),1),E[17]||(E[17]=Le(",代理才会生效。 ",-1))])):r.value.enabled?(W(),q("p",df," 保存后若仍显示已关闭,请查看终端是否有「代理服务已启动」或端口占用报错。 ")):he("",!0)])):he("",!0)]))}},gf=Lt(hf,[["__scopeId","data-v-9e948823"]]),mf={class:"pac-rules"},vf={key:0,class:"page-desc"},yf={class:"card"},_f={class:"actions top"},bf=["disabled"],xf=["disabled"],Sf={key:0,class:"copy-tip"},Ef={class:"table"},wf=["onClick"],Rf=["onClick"],Cf={key:0},Af={class:"modal-content"},Pf={class:"field"},Tf={class:"field"},Of={class:"field"},If={class:"modal-actions"},Nf=["disabled"],Mf={__name:"PacRules",setup(e){const t=so();function n(){return Pi(t.mode,t.remoteBaseUrl)}const s=Y([]),o=Y(null),r=Y({pattern:"",action:"proxy",priority:0}),i=Y(!1),l=Y(!1),a=ve(()=>[...s.value].sort((C,x)=>(x.priority??0)-(C.priority??0)));Yt(f);async function f(){try{if(s.value=await n().getPacRules(),Array.isArray(s.value)||(s.value=[]),t.mode==="remote")try{await pe("/pac-rules",{method:"PUT",body:JSON.stringify(s.value)})}catch{}}catch{s.value=[]}}function c(C=null){C?r.value={id:C.id,pattern:C.pattern,action:C.action||"proxy",priority:C.priority??0}:r.value={pattern:"",action:"proxy",priority:0},o.value=!0}async function p(){const{id:C,pattern:x,action:A,priority:D}=r.value;if(!x.trim()){alert("请填写 URL 匹配字符");return}i.value=!0;try{let F=[...s.value];if(C){const ce=F.findIndex(re=>re.id===C);ce>=0&&(F[ce]={...F[ce],pattern:x.trim(),action:A,priority:D})}else F.push({id:String(Date.now()),pattern:x.trim(),action:A||"proxy",priority:Number(D)||0});await n().setPacRules(F),s.value=F,o.value=null}catch(F){alert("保存失败:"+F.message)}finally{i.value=!1}}async function g(C){if(!confirm("确定删除该规则?"))return;const x=s.value.filter(A=>A.id!==C.id);try{await n().setPacRules(x),s.value=x}catch(A){alert("删除失败:"+A.message)}}function v(){return JSON.stringify(s.value,null,2)}function O(){return s.value.map(C=>(C.pattern||"").trim()).filter(Boolean).join(`
|
|
26
26
|
`)}async function w(){if(s.value.length)try{await navigator.clipboard.writeText(O()),l.value=!0,setTimeout(()=>{l.value=!1},1500)}catch(C){alert("复制失败:"+C.message)}}function E(){if(!s.value.length)return;const C=new Blob([v()],{type:"application/json"}),x=URL.createObjectURL(C),A=document.createElement("a");A.href=x,A.download=`pac-rules-${new Date().toISOString().slice(0,10)}.json`,A.click(),URL.revokeObjectURL(x)}return(C,x)=>(W(),q("div",mf,[x[13]||(x[13]=h("h2",null,"PAC 规则",-1)),Dt(t).mode==="remote"?(W(),q("p",vf,"远程模式下规则保存在云端,PAC 模式时由本机按云端规则执行。")):he("",!0),h("div",yf,[x[8]||(x[8]=h("p",{class:"desc"},"管理 PAC 代理的匹配规则。按优先级从高到低匹配,命中后选择「代理」或「直连」。",-1)),h("div",_f,[h("button",{class:"btn primary",onClick:x[0]||(x[0]=A=>c())},"新增规则"),h("button",{class:"btn",onClick:w,disabled:!s.value.length},"复制",8,bf),h("button",{class:"btn",onClick:E,disabled:!s.value.length},"导出",8,xf),l.value?(W(),q("span",Sf,"已复制到剪贴板")):he("",!0)]),h("table",Ef,[x[7]||(x[7]=h("thead",null,[h("tr",null,[h("th",null,"URL 匹配字符"),h("th",null,"动作"),h("th",null,"优先级"),h("th",null,"操作")])],-1)),h("tbody",null,[(W(!0),q(Me,null,Cs(a.value,A=>(W(),q("tr",{key:A.id},[h("td",null,J(A.pattern),1),h("td",null,J(A.action==="proxy"?"代理":"直连"),1),h("td",null,J(A.priority),1),h("td",null,[h("button",{class:"btn small",onClick:D=>c(A)},"编辑",8,wf),h("button",{class:"btn small danger",onClick:D=>g(A)},"删除",8,Rf)])]))),128)),s.value.length?he("",!0):(W(),q("tr",Cf,[...x[6]||(x[6]=[h("td",{colspan:"4",class:"empty"},"暂无规则,请点击「新增规则」",-1)])]))])])]),o.value?(W(),q("div",{key:1,class:"modal",onClick:x[5]||(x[5]=ss(A=>o.value=null,["self"]))},[h("div",Af,[h("h3",null,J(o.value.id?"编辑规则":"新增规则"),1),h("div",Pf,[x[9]||(x[9]=h("label",null,"URL 匹配字符",-1)),Ae(h("input",{"onUpdate:modelValue":x[1]||(x[1]=A=>r.value.pattern=A),placeholder:"例如 *.google.com"},null,512),[[We,r.value.pattern]])]),h("div",Tf,[x[11]||(x[11]=h("label",null,"动作",-1)),Ae(h("select",{"onUpdate:modelValue":x[2]||(x[2]=A=>r.value.action=A)},[...x[10]||(x[10]=[h("option",{value:"proxy"},"代理",-1),h("option",{value:"direct"},"直连",-1)])],512),[[Nn,r.value.action]])]),h("div",Of,[x[12]||(x[12]=h("label",null,"优先级(数字越大越优先)",-1)),Ae(h("input",{"onUpdate:modelValue":x[3]||(x[3]=A=>r.value.priority=A),type:"number"},null,512),[[We,r.value.priority,void 0,{number:!0}]])]),h("div",If,[h("button",{class:"btn",onClick:x[4]||(x[4]=A=>o.value=null)},"取消"),h("button",{class:"btn primary",onClick:p,disabled:i.value},"保存",8,Nf)])])])):he("",!0)]))}},Df=Lt(Mf,[["__scopeId","data-v-22317bbc"]]),Uf={class:"traffic-page"},Lf={class:"page-desc"},kf={key:0,class:"card"},$f={class:"actions top"},jf=["disabled"],Vf={class:"table"},Hf={class:"url-cell"},Ff={key:0},Bf={key:1,class:"card capture-card"},Kf={class:"toolbar"},Gf=["title"],Wf=["disabled"],qf={class:"table-wrap"},Jf={class:"table capture-table"},zf=["onClick"],Qf=["title"],Yf=["onClick"],Xf={key:0},Zf={key:0,class:"pagination"},ed={class:"pagination-info"},td=["disabled"],nd=["disabled"],sd={key:3,class:"drawer"},od={class:"drawer-tabs"},rd={class:"drawer-body"},id={class:"drawer-url-section"},ld={class:"drawer-url-head"},ad={class:"drawer-method-tag"},cd={class:"drawer-url"},ud={class:"detail-section"},fd={class:"headers-pre"},dd={class:"detail-section"},pd={class:"body-pre"},hd={class:"detail-section"},gd={class:"headers-pre"},md={class:"detail-section"},vd={class:"body-pre"},xs=50,yd={__name:"Traffic",setup(e){const t=Y([]),n=Y(!1),s=Y(!1),o=Y(!1),r=Y([]),i=Y(0),l=Y(0),a=Y({q:"",method:"",status:"",type:"",sort:"time",order:"desc"});let f=null;const c=Y(null),p=Y("request"),g=Y(!1),v=Ei();function O(k){return k?new Date(k).toLocaleString("zh-CN",{hour12:!1}):"-"}function w(k){return!k||typeof k!="object"?"":Object.entries(k).map(([L,K])=>`${L}: ${K}`).join(`
|
|
27
27
|
`)}function E(k){if(k==null||k==="")return"(空)";const L=typeof k=="string"?k:String(k);try{const K=JSON.parse(L);return JSON.stringify(K,null,2)}catch{return L}}function C(k){return k>=200&&k<300?"status-2xx":k>=300&&k<400?"status-3xx":k>=400&&k<500?"status-4xx":k>=500?"status-5xx":""}async function x(){if(!o.value){o.value=!0;try{const L=await(await fetch("/api/local/proxy")).json();s.value=(L.mode||"")==="mitm"}catch{s.value=!1}finally{o.value=!1}}}async function A(){n.value=!0;try{const k=await fetch("/api/local/traffic");t.value=await k.json(),Array.isArray(t.value)||(t.value=[])}catch{t.value=[]}finally{n.value=!1}}function D(){f&&clearTimeout(f),f=setTimeout(F,300)}async function F(){n.value=!0;try{const k=new URLSearchParams;a.value.q&&k.set("q",a.value.q),a.value.method&&k.set("method",a.value.method);const L=String(a.value.status??"").trim();L!==""&&!Number.isNaN(Number(L))&&k.set("status",L),a.value.type&&k.set("type",a.value.type),k.set("sort",a.value.sort),k.set("order",a.value.order),k.set("limit",String(xs)),k.set("offset",String(l.value));const ue=await(await fetch("/api/local/capture?"+k.toString())).json();r.value=ue.list||[],i.value=ue.total??0}catch{r.value=[],i.value=0}finally{n.value=!1}}function ce(){l.value=Math.max(0,l.value-xs),F()}function re(){l.value+=xs,F()}function je(){a.value.order=a.value.order==="desc"?"asc":"desc",F()}function Be(k){c.value=k,p.value="request"}function De(){c.value=null}async function ze(){var k;if((k=c.value)!=null&&k.url)try{await navigator.clipboard.writeText(c.value.url),g.value=!0,setTimeout(()=>{g.value=!1},1500)}catch{alert("复制失败")}}async function Qe(){await x(),s.value?(l.value=0,await F()):await A()}return Yt(Qe),ln(()=>v.path,k=>{k==="/console/traffic"&&Qe()}),(k,L)=>(W(),q("div",Uf,[L[20]||(L[20]=h("h2",null,"流量记录",-1)),h("p",Lf,J(s.value?"抓包代理下可查看解密后的请求与响应。":"经本机代理的最近网络请求,最多保留 500 条。"),1),s.value?(W(),q("div",Bf,[L[14]||(L[14]=h("div",{class:"capture-banner"},"当前为抓包代理,可查看解密后的请求与响应。",-1)),h("div",Kf,[Ae(h("input",{"onUpdate:modelValue":L[0]||(L[0]=K=>a.value.q=K),type:"text",placeholder:"搜索 URL…",class:"search-input",onInput:D},null,544),[[We,a.value.q]]),Ae(h("select",{"onUpdate:modelValue":L[1]||(L[1]=K=>a.value.method=K),class:"filter-select",onChange:F},[...L[9]||(L[9]=[Ro('<option value="" data-v-1ee1603b>全部方法</option><option value="GET" data-v-1ee1603b>GET</option><option value="POST" data-v-1ee1603b>POST</option><option value="PUT" data-v-1ee1603b>PUT</option><option value="PATCH" data-v-1ee1603b>PATCH</option><option value="DELETE" data-v-1ee1603b>DELETE</option><option value="HEAD" data-v-1ee1603b>HEAD</option><option value="OPTIONS" data-v-1ee1603b>OPTIONS</option>',8)])],544),[[Nn,a.value.method]]),Ae(h("input",{"onUpdate:modelValue":L[2]||(L[2]=K=>a.value.status=K),type:"text",placeholder:"状态码",class:"status-input",onInput:D},null,544),[[We,a.value.status]]),Ae(h("select",{"onUpdate:modelValue":L[3]||(L[3]=K=>a.value.type=K),class:"filter-select",onChange:F},[...L[10]||(L[10]=[Ro('<option value="" data-v-1ee1603b>全部类型</option><option value="document" data-v-1ee1603b>document</option><option value="xhr" data-v-1ee1603b>xhr</option><option value="script" data-v-1ee1603b>script</option><option value="stylesheet" data-v-1ee1603b>stylesheet</option><option value="image" data-v-1ee1603b>image</option><option value="font" data-v-1ee1603b>font</option><option value="other" data-v-1ee1603b>other</option>',8)])],544),[[Nn,a.value.type]]),Ae(h("select",{"onUpdate:modelValue":L[4]||(L[4]=K=>a.value.sort=K),class:"filter-select",onChange:F},[...L[11]||(L[11]=[h("option",{value:"time"},"按时间",-1),h("option",{value:"method"},"按方法",-1),h("option",{value:"status"},"按状态",-1),h("option",{value:"url"},"按 URL",-1)])],544),[[Nn,a.value.sort]]),h("button",{type:"button",class:"sort-order-btn",onClick:je,title:a.value.order==="desc"?"倒序":"正序"},J(a.value.order==="desc"?"↓":"↑"),9,Gf),h("button",{class:"btn",onClick:F,disabled:n.value},"刷新",8,Wf)]),h("div",qf,[h("table",Jf,[L[13]||(L[13]=h("thead",null,[h("tr",null,[h("th",null,"时间"),h("th",null,"方法"),h("th",null,"URL"),h("th",null,"状态"),h("th",null,"类型"),h("th")])],-1)),h("tbody",null,[(W(!0),q(Me,null,Cs(r.value,K=>(W(),q("tr",{key:K.id,onClick:ue=>Be(K),class:"row-clickable"},[h("td",null,J(O(K.time)),1),h("td",null,[h("span",{class:Ce(["method-tag",K.method])},J(K.method),3)]),h("td",{class:"url-cell",title:K.url},J(K.url),9,Qf),h("td",null,[h("span",{class:Ce(["status-tag",C(K.statusCode)])},J(K.statusCode),3)]),h("td",null,J(K.type),1),h("td",null,[h("button",{type:"button",class:"btn-link",onClick:ss(ue=>Be(K),["stop"])},"详情",8,Yf)])],8,zf))),128)),!r.value.length&&!n.value?(W(),q("tr",Xf,[...L[12]||(L[12]=[h("td",{colspan:"6",class:"empty"},"暂无抓包记录,请通过抓包代理访问网页。",-1)])])):he("",!0)])])]),i.value>0?(W(),q("div",Zf,[h("span",ed,"共 "+J(i.value)+" 条",1),h("button",{class:"btn small",disabled:l.value<=0,onClick:ce},"上一页",8,td),h("button",{class:"btn small",disabled:l.value+r.value.length>=i.value,onClick:re},"下一页",8,nd)])):he("",!0)])):(W(),q("div",kf,[h("div",$f,[h("button",{class:"btn",onClick:A,disabled:n.value},"刷新",8,jf)]),h("table",Vf,[L[8]||(L[8]=h("thead",null,[h("tr",null,[h("th",null,"时间"),h("th",null,"类型"),h("th",null,"方法"),h("th",null,"URL / 主机"),h("th",null,"动作")])],-1)),h("tbody",null,[(W(!0),q(Me,null,Cs(t.value,K=>(W(),q("tr",{key:K.time+(K.url||"")},[h("td",null,J(O(K.time)),1),h("td",null,J(K.type),1),h("td",null,J(K.method),1),h("td",Hf,J(K.url),1),h("td",null,[h("span",{class:Ce(K.action==="proxy"?"action-proxy":"action-direct")},J(K.action==="proxy"?"代理":"直连"),3)])]))),128)),!t.value.length&&!n.value?(W(),q("tr",Ff,[...L[7]||(L[7]=[h("td",{colspan:"5",class:"empty"},"暂无记录,请确保代理已开启并有流量经过。",-1)])])):he("",!0)])])])),c.value?(W(),q("div",{key:2,class:"drawer-mask",onClick:De})):he("",!0),c.value?(W(),q("div",sd,[h("div",{class:"drawer-header"},[L[15]||(L[15]=h("span",{class:"drawer-title"},"详情",-1)),h("button",{type:"button",class:"drawer-close",onClick:De},"×")]),h("div",od,[h("button",{type:"button",class:Ce({active:p.value==="request"}),onClick:L[5]||(L[5]=K=>p.value="request")},"请求",2),h("button",{type:"button",class:Ce({active:p.value==="response"}),onClick:L[6]||(L[6]=K=>p.value="response")},"响应",2)]),h("div",rd,[h("div",id,[h("div",ld,[h("span",ad,J(c.value.method),1),h("button",{type:"button",class:"btn-copy-url",onClick:ze},J(g.value?"已复制":"复制 URL"),1)]),h("pre",cd,J(c.value.url),1)]),p.value==="request"?(W(),q(Me,{key:0},[h("div",ud,[L[16]||(L[16]=h("h4",null,"Request Headers",-1)),h("pre",fd,J(w(c.value.requestHeaders)),1)]),h("div",dd,[L[17]||(L[17]=h("h4",null,"Request Body",-1)),h("pre",pd,J(E(c.value.requestBody)),1)])],64)):(W(),q(Me,{key:1},[h("div",hd,[L[18]||(L[18]=h("h4",null,"Response Headers",-1)),h("pre",gd,J(w(c.value.responseHeaders)),1)]),h("div",md,[L[19]||(L[19]=h("h4",null,"Response Body",-1)),h("pre",vd,J(E(c.value.responseBody)),1)])],64))])])):he("",!0)]))}},_d=Lt(yd,[["__scopeId","data-v-1ee1603b"]]),bd=[{path:"/",name:"ModeSelect",component:Eu,meta:{title:"选择模式"}},{path:"/login",name:"Login",component:Nu,meta:{title:"登录"}},{path:"/register",name:"Register",component:Fu,meta:{title:"注册"}},{path:"/console",redirect:"/console/traffic"},{path:"/console/traffic",name:"Traffic",component:_d,meta:{title:"流量记录"}},{path:"/console/proxy",name:"ProxySettings",component:gf,meta:{title:"代理设置"}},{path:"/console/pac-rules",name:"PacRules",component:Df,meta:{title:"PAC 规则"}}],Ti=iu({history:$c(),routes:bd});Ti.beforeEach((e,t,n)=>{const s=wi();e.path!=="/"&&!e.path.startsWith("/login")&&!e.path.startsWith("/register")&&!s?n("/"):n()});wi();const Oi=Xa(yu);Oi.use(Ti);Oi.mount("#app");
|
package/dist/index.html
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700&display=swap" rel="stylesheet" />
|
|
10
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
10
|
+
<script type="module" crossorigin src="/assets/index-BE710q9W.js"></script>
|
|
11
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BCu498Mr.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="app"></div>
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.app-layout[data-v-e7869e57]{display:flex;flex-direction:column;min-height:100vh}.topbar[data-v-e7869e57]{display:flex;align-items:center;gap:1rem;padding:.75rem 1.5rem;background:#f1f5f9;border-bottom:1px solid var(--border)}.logo[data-v-e7869e57]{font-weight:700;font-size:1.1rem}.mode-tag[data-v-e7869e57]{padding:.2rem .5rem;border-radius:4px;font-size:.8rem}.mode-tag.local[data-v-e7869e57]{background:#dbeafe;color:#1d4ed8}.mode-tag.remote[data-v-e7869e57]{background:#e9d5ff;color:#6b21a8}.switch-mode[data-v-e7869e57]{font-size:.85rem;color:var(--text-secondary)}.switch-mode[data-v-e7869e57]:hover{color:var(--btn-primary)}.top-nav[data-v-e7869e57]{display:flex;gap:1rem;margin-left:auto}.top-nav a[data-v-e7869e57]{color:var(--text-secondary)}.top-nav a.router-link-active[data-v-e7869e57]{color:var(--btn-primary);font-weight:500}.top-right[data-v-e7869e57]{margin-left:auto;display:flex;align-items:center;gap:.75rem}.username[data-v-e7869e57]{font-size:.9rem;color:var(--text-secondary)}.logout-btn[data-v-e7869e57]{font-size:.85rem;color:var(--text-secondary);background:none;border:none;cursor:pointer;padding:.25rem 0}.logout-btn[data-v-e7869e57]:hover{color:var(--btn-primary)}.sidebar[data-v-e7869e57]{position:fixed;left:0;top:49px;bottom:0;width:200px;background:#fff;border-right:1px solid var(--border);display:flex;flex-direction:column;z-index:10}.side-nav[data-v-e7869e57]{display:flex;flex-direction:column;padding:1rem 0}.side-nav a[data-v-e7869e57]{color:var(--text-primary);padding:.6rem 1.25rem;font-size:.95rem;border-left:3px solid transparent}.side-nav a[data-v-e7869e57]:hover{background:#f1f5f9;color:var(--btn-primary)}.side-nav a.active[data-v-e7869e57]{background:#eff6ff;color:var(--btn-primary);border-left-color:var(--btn-primary)}.main[data-v-e7869e57]{margin-left:200px;margin-top:49px;padding:1.5rem;min-height:calc(100vh - 49px)}.main.main-standalone[data-v-e7869e57]{margin-left:0;margin-top:0;padding:0;min-height:100vh}.mode-select[data-v-b465f762]{min-height:100vh;display:flex;align-items:center;justify-content:center;background:var(--bg-main);padding:2rem}.card[data-v-b465f762]{background:var(--bg-card);border-radius:12px;padding:2.5rem;max-width:480px;width:100%;box-shadow:0 1px 3px #00000014}.card h1[data-v-b465f762]{font-size:1.5rem;margin-bottom:.5rem}.desc[data-v-b465f762]{color:var(--text-secondary);font-size:.95rem;margin-bottom:1.5rem}.options[data-v-b465f762]{display:flex;flex-direction:column;gap:1rem}.option[data-v-b465f762]{padding:1.25rem 1.5rem;border:2px solid var(--border);border-radius:var(--radius);background:#fff;text-align:left;transition:border-color .2s,background .2s}.option[data-v-b465f762]:hover{border-color:var(--btn-primary);background:#f8fafc}.option .title[data-v-b465f762]{display:block;font-weight:600;margin-bottom:.25rem}.option .sub[data-v-b465f762]{font-size:.9rem;color:var(--text-secondary)}.auth-page[data-v-be60da76]{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:2rem}.card[data-v-be60da76]{background:var(--bg-card);border-radius:12px;padding:2rem;max-width:400px;width:100%;box-shadow:0 1px 3px #00000014}.card h1[data-v-be60da76]{font-size:1.5rem;margin-bottom:.5rem}.desc[data-v-be60da76]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1.5rem}.form[data-v-be60da76]{display:flex;flex-direction:column;gap:1rem}.field label[data-v-be60da76]{display:block;font-size:.9rem;margin-bottom:.35rem;color:var(--text-secondary)}.field input[data-v-be60da76]{width:100%;padding:.6rem .75rem;border:1px solid var(--border);border-radius:var(--radius)}.error[data-v-be60da76]{color:#dc2626;font-size:.9rem}.btn.primary[data-v-be60da76]{background:var(--btn-primary);color:#fff;padding:.65rem 1rem;font-weight:500}.btn.primary[data-v-be60da76]:hover:not(:disabled){background:var(--btn-primary-hover)}.btn.primary[data-v-be60da76]:disabled{opacity:.6;cursor:not-allowed}.footer[data-v-be60da76]{margin-top:1rem;font-size:.9rem;color:var(--text-secondary)}.auth-page[data-v-a1c8458c]{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:2rem}.card[data-v-a1c8458c]{background:var(--bg-card);border-radius:12px;padding:2rem;max-width:400px;width:100%;box-shadow:0 1px 3px #00000014}.card h1[data-v-a1c8458c]{font-size:1.5rem;margin-bottom:.5rem}.desc[data-v-a1c8458c]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1.5rem}.form[data-v-a1c8458c]{display:flex;flex-direction:column;gap:1rem}.field label[data-v-a1c8458c]{display:block;font-size:.9rem;margin-bottom:.35rem;color:var(--text-secondary)}.field input[data-v-a1c8458c]{width:100%;padding:.6rem .75rem;border:1px solid var(--border);border-radius:var(--radius)}.error[data-v-a1c8458c]{color:#dc2626;font-size:.9rem}.success[data-v-a1c8458c]{color:#16a34a;font-size:.9rem}.btn.primary[data-v-a1c8458c]{background:var(--btn-primary);color:#fff;padding:.65rem 1rem;font-weight:500}.btn.primary[data-v-a1c8458c]:hover:not(:disabled){background:var(--btn-primary-hover)}.btn.primary[data-v-a1c8458c]:disabled{opacity:.6;cursor:not-allowed}.footer[data-v-a1c8458c]{margin-top:1rem;font-size:.9rem;color:var(--text-secondary)}.proxy-settings h2[data-v-9e948823]{font-size:1.25rem;margin-bottom:1rem}.card[data-v-9e948823]{background:var(--bg-card);border-radius:var(--radius);padding:1.5rem;margin-bottom:1.5rem;box-shadow:0 1px 2px #0000000d}.card h3[data-v-9e948823]{font-size:1rem;margin-bottom:.35rem}.page-desc[data-v-9e948823],.desc[data-v-9e948823]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1rem}.saved-tip[data-v-9e948823]{color:var(--switch-on);font-size:.85rem;margin-top:.5rem}.proxy-buttons[data-v-9e948823]{display:flex;flex-wrap:wrap;gap:.75rem;margin-bottom:.25rem}.proxy-btn[data-v-9e948823]{padding:.5rem 1rem;font-size:.9rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-card);cursor:pointer;transition:background .2s,border-color .2s}.proxy-btn[data-v-9e948823]:hover:not(:disabled){background:var(--bg);border-color:var(--btn-primary)}.proxy-btn.active[data-v-9e948823]{background:var(--btn-primary);border-color:var(--btn-primary);color:#fff}.proxy-btn.active[data-v-9e948823]:hover:not(:disabled){background:var(--btn-primary-hover);border-color:var(--btn-primary-hover);color:#fff}.proxy-btn.clear.active[data-v-9e948823]{background:var(--text-secondary);border-color:var(--text-secondary);color:#fff}.proxy-btn.clear.active[data-v-9e948823]:hover:not(:disabled){background:#64748b;border-color:#64748b;color:#fff}.proxy-btn[data-v-9e948823]:disabled{opacity:.6;cursor:not-allowed}.ca-download[data-v-9e948823]{margin-top:1rem;padding-top:1rem;border-top:1px solid var(--border)}.ca-label[data-v-9e948823]{display:block;font-size:.9rem;color:var(--text-secondary);margin-bottom:.5rem}.btn-ca[data-v-9e948823]{display:inline-block;padding:.4rem .8rem;font-size:.9rem;background:var(--btn-primary);color:#fff;border-radius:var(--radius);text-decoration:none;margin-bottom:.5rem}.btn-ca[data-v-9e948823]:hover{background:var(--btn-primary-hover);color:#fff}.ca-hint[data-v-9e948823]{font-size:.85rem;color:var(--text-secondary);margin:0}.toggle-row[data-v-9e948823]{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.toggle-row .select-inline[data-v-9e948823]{min-width:140px;height:2.25rem;padding:.35rem 2rem .35rem .75rem;font-size:.9rem;border:1px solid var(--border);border-radius:var(--radius);background-color:#fff;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M6 8L1 3h10z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .6rem center}.toggle-row .select-inline[data-v-9e948823]:focus{outline:none;border-color:var(--btn-primary)}.toggle[data-v-9e948823]{width:44px;height:24px;border-radius:12px;background:var(--switch-off);padding:2px;transition:background .2s}.toggle.on[data-v-9e948823]{background:var(--switch-on)}.toggle .knob[data-v-9e948823]{display:block;width:20px;height:20px;border-radius:50%;background:#fff;transform:translate(0);transition:transform .2s}.toggle.on .knob[data-v-9e948823]{transform:translate(20px)}.field[data-v-9e948823]{margin-bottom:1rem}.field label[data-v-9e948823]{display:block;font-size:.9rem;margin-bottom:.35rem;color:var(--text-secondary)}.field input[data-v-9e948823],.field select[data-v-9e948823]{width:100%;padding:.5rem .75rem;border:1px solid var(--border);border-radius:var(--radius)}.row[data-v-9e948823]{display:grid;grid-template-columns:1fr 1fr;gap:1rem}.actions[data-v-9e948823]{margin-top:1rem}.btn.primary[data-v-9e948823]{background:var(--btn-primary);color:#fff;padding:.5rem 1rem;font-size:.9rem}.btn.primary[data-v-9e948823]:hover:not(:disabled){background:var(--btn-primary-hover)}.btn.primary[data-v-9e948823]:disabled{opacity:.6;cursor:not-allowed}.status-card .status-line[data-v-9e948823]{margin-bottom:.5rem}.status-on[data-v-9e948823]{color:var(--switch-on);font-weight:600}.status-off[data-v-9e948823]{color:var(--text-secondary)}.status-port[data-v-9e948823]{margin-left:.5rem;color:var(--text-secondary);font-size:.9rem}.hint[data-v-9e948823]{font-size:.9rem;color:var(--text-secondary);margin-top:.5rem}.hint strong[data-v-9e948823]{color:var(--text-primary)}.hint.error[data-v-9e948823]{color:#dc2626}.pac-rules h2[data-v-22317bbc]{font-size:1.25rem;margin-bottom:1rem}.page-desc[data-v-22317bbc]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1rem}.card[data-v-22317bbc]{background:var(--bg-card);border-radius:var(--radius);padding:1.5rem;box-shadow:0 1px 2px #0000000d}.desc[data-v-22317bbc]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1rem}.actions.top[data-v-22317bbc]{margin-bottom:1rem;display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}.btn.primary[data-v-22317bbc]{background:var(--btn-primary);color:#fff;padding:.5rem 1rem;font-size:.9rem}.copy-tip[data-v-22317bbc]{font-size:.85rem;color:var(--btn-primary)}.btn.small[data-v-22317bbc]{padding:.25rem .5rem;font-size:.85rem;margin-right:.5rem}.btn.small.danger[data-v-22317bbc]{background:#fef2f2;color:#dc2626}.btn.small.danger[data-v-22317bbc]:hover{background:#fee2e2}.table[data-v-22317bbc]{width:100%;border-collapse:collapse}.table th[data-v-22317bbc],.table td[data-v-22317bbc]{padding:.6rem .75rem;text-align:left;border-bottom:1px solid var(--border)}.table th[data-v-22317bbc]{font-weight:600;color:var(--text-secondary);font-size:.9rem}.table .empty[data-v-22317bbc]{color:var(--text-secondary);text-align:center}.modal[data-v-22317bbc]{position:fixed;top:0;right:0;bottom:0;left:0;background:#0006;display:flex;align-items:center;justify-content:center;z-index:100}.modal-content[data-v-22317bbc]{background:var(--bg-card);border-radius:var(--radius);padding:1.5rem;min-width:360px}.modal-content h3[data-v-22317bbc],.modal-content .field[data-v-22317bbc]{margin-bottom:1rem}.modal-content .field label[data-v-22317bbc]{display:block;font-size:.9rem;margin-bottom:.35rem;color:var(--text-secondary)}.modal-content .field input[data-v-22317bbc],.modal-content .field select[data-v-22317bbc]{width:100%;min-width:0;box-sizing:border-box;padding:.5rem .75rem;min-height:2.5rem;border:1px solid var(--border);border-radius:var(--radius);font-size:.95rem}.modal-content .field select[data-v-22317bbc]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M6 8L1 3h10z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .6rem center;padding-right:2rem}.modal-actions[data-v-22317bbc]{display:flex;gap:.75rem;justify-content:flex-end;margin-top:1rem}.btn[data-v-22317bbc]{padding:.5rem 1rem;background:#f1f5f9}.btn.primary[data-v-22317bbc]{background:var(--btn-primary);color:#fff}.traffic-page h2[data-v-1ee1603b]{font-size:1.25rem;margin-bottom:1rem}.page-desc[data-v-1ee1603b]{color:var(--text-secondary);font-size:.9rem;margin-bottom:1rem}.card[data-v-1ee1603b]{background:var(--bg-card);border-radius:var(--radius);padding:1.5rem;box-shadow:0 1px 2px #0000000d}.capture-card[data-v-1ee1603b]{padding:1rem 1.5rem}.capture-banner[data-v-1ee1603b]{background:#eff6ff;color:#1e40af;padding:.5rem .75rem;border-radius:var(--radius);font-size:.9rem;margin-bottom:1rem}.toolbar[data-v-1ee1603b]{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;margin-bottom:1rem}.toolbar .search-input[data-v-1ee1603b],.toolbar .filter-select[data-v-1ee1603b],.toolbar .status-input[data-v-1ee1603b],.toolbar .sort-order-btn[data-v-1ee1603b],.toolbar .btn[data-v-1ee1603b]{box-sizing:border-box;height:2.25rem;padding:0 .6rem;border:1px solid var(--border);border-radius:var(--radius);font-size:.9rem;line-height:1.3}.toolbar .search-input[data-v-1ee1603b]{min-width:160px}.toolbar .filter-select[data-v-1ee1603b]{background:#fff;cursor:pointer;min-width:6rem}.toolbar .status-input[data-v-1ee1603b]{width:72px}.toolbar .sort-order-btn[data-v-1ee1603b]{background:#f8fafc;cursor:pointer;width:2.25rem;padding:0}.toolbar .btn[data-v-1ee1603b]{background:#f1f5f9}.actions.top[data-v-1ee1603b]{margin-bottom:1rem}.btn[data-v-1ee1603b]{padding:.5rem 1rem;font-size:.9rem;background:#f1f5f9}.btn.small[data-v-1ee1603b]{padding:.35rem .75rem;font-size:.85rem}.table-wrap[data-v-1ee1603b]{overflow-x:auto}.table[data-v-1ee1603b]{width:100%;border-collapse:collapse}.table th[data-v-1ee1603b],.table td[data-v-1ee1603b]{padding:.5rem .75rem;text-align:left;border-bottom:1px solid var(--border)}.table th[data-v-1ee1603b]{font-weight:600;color:var(--text-secondary);font-size:.9rem}.table .empty[data-v-1ee1603b]{color:var(--text-secondary);text-align:center}.url-cell[data-v-1ee1603b]{max-width:320px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.action-proxy[data-v-1ee1603b]{color:var(--btn-primary)}.action-direct[data-v-1ee1603b]{color:var(--text-secondary)}.row-clickable[data-v-1ee1603b]{cursor:pointer}.row-clickable[data-v-1ee1603b]:hover{background:#f8fafc}.method-tag[data-v-1ee1603b]{font-size:.8rem;padding:.15rem .4rem;border-radius:4px;font-weight:500}.method-tag.GET[data-v-1ee1603b]{background:#dbeafe;color:#1d4ed8}.method-tag.POST[data-v-1ee1603b]{background:#d1fae5;color:#047857}.method-tag.PUT[data-v-1ee1603b]{background:#fef3c7;color:#b45309}.method-tag.DELETE[data-v-1ee1603b]{background:#fee2e2;color:#b91c1c}.method-tag.HEAD[data-v-1ee1603b],.method-tag.OPTIONS[data-v-1ee1603b]{background:#f1f5f9;color:#64748b}.status-tag[data-v-1ee1603b]{font-size:.85rem;padding:.15rem .4rem;border-radius:4px}.status-2xx[data-v-1ee1603b]{background:#d1fae5;color:#047857}.status-3xx[data-v-1ee1603b]{background:#e0e7ff;color:#3730a3}.status-4xx[data-v-1ee1603b]{background:#fee2e2;color:#b91c1c}.status-5xx[data-v-1ee1603b]{background:#fecaca;color:#991b1b}.btn-link[data-v-1ee1603b]{background:none;border:none;color:var(--btn-primary);cursor:pointer;font-size:.9rem;padding:0}.btn-link[data-v-1ee1603b]:hover{text-decoration:underline}.pagination[data-v-1ee1603b]{margin-top:1rem;display:flex;align-items:center;gap:.75rem}.pagination-info[data-v-1ee1603b]{font-size:.9rem;color:var(--text-secondary)}.drawer-mask[data-v-1ee1603b]{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000004d;z-index:100}.drawer[data-v-1ee1603b]{position:fixed;top:0;right:0;width:min(560px,100vw);height:100vh;background:var(--bg-card);box-shadow:-2px 0 12px #00000026;z-index:101;display:flex;flex-direction:column;overflow:hidden}.drawer-header[data-v-1ee1603b]{display:flex;align-items:center;justify-content:space-between;padding:1rem 1.25rem;border-bottom:1px solid var(--border);flex-shrink:0}.drawer-title[data-v-1ee1603b]{font-size:1rem;font-weight:600}.drawer-close[data-v-1ee1603b]{width:2rem;height:2rem;border:none;background:none;font-size:1.5rem;line-height:1;cursor:pointer;color:var(--text-secondary)}.drawer-close[data-v-1ee1603b]:hover{color:#0f172a}.drawer-url-section[data-v-1ee1603b]{margin-bottom:1.25rem;padding-bottom:1rem;border-bottom:1px solid var(--border)}.drawer-url-head[data-v-1ee1603b]{display:flex;align-items:center;justify-content:space-between;gap:.5rem;margin-bottom:.35rem}.drawer-method-tag[data-v-1ee1603b]{font-size:.8rem;font-weight:600;padding:.15rem .4rem;border-radius:4px;background:#e2e8f0;color:#475569}.btn-copy-url[data-v-1ee1603b]{padding:.35rem .6rem;font-size:.85rem;border:1px solid var(--border);border-radius:var(--radius);background:#f1f5f9;cursor:pointer;color:var(--text-primary)}.btn-copy-url[data-v-1ee1603b]:hover{background:#e2e8f0}.drawer-url[data-v-1ee1603b]{margin:0;padding:.5rem .6rem;background:#f8fafc;border-radius:var(--radius);font-size:.85rem;line-height:1.4;white-space:pre-wrap;word-break:break-all;max-height:5rem;overflow:auto;user-select:text;-webkit-user-select:text}.drawer-tabs[data-v-1ee1603b]{display:flex;gap:.25rem;padding:.5rem 1rem;border-bottom:1px solid var(--border);flex-shrink:0}.drawer-tabs button[data-v-1ee1603b]{padding:.4rem .75rem;font-size:.9rem;border:none;background:none;border-radius:var(--radius);cursor:pointer;color:var(--text-secondary)}.drawer-tabs button.active[data-v-1ee1603b]{background:var(--btn-primary);color:#fff}.drawer-body[data-v-1ee1603b]{flex:1;overflow:auto;padding:1rem 1.25rem}.detail-section[data-v-1ee1603b]{margin-bottom:1.25rem}.detail-section h4[data-v-1ee1603b]{font-size:.85rem;margin-bottom:.35rem;color:var(--text-secondary)}.headers-pre[data-v-1ee1603b],.body-pre[data-v-1ee1603b]{margin:0;padding:.75rem;background:#f8fafc;border-radius:var(--radius);font-size:.8rem;line-height:1.4;overflow-x:auto;white-space:pre-wrap;word-break:break-all;max-height:280px;overflow-y:auto}:root{--bg-sidebar: #1e293b;--bg-sidebar-hover: #334155;--bg-sidebar-active: #2563eb;--text-sidebar: #e2e8f0;--text-sidebar-muted: #94a3b8;--bg-main: #f8fafc;--bg-card: #ffffff;--text-primary: #0f172a;--text-secondary: #64748b;--border: #e2e8f0;--switch-on: #22c55e;--switch-off: #cbd5e1;--btn-primary: #2563eb;--btn-primary-hover: #1d4ed8;--radius: 8px;--font: "DM Sans", -apple-system, BlinkMacSystemFont, sans-serif}*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--font);background:var(--bg-main);color:var(--text-primary);line-height:1.5;min-height:100vh}#app{min-height:100vh;display:flex;flex-direction:column}button{font-family:inherit;cursor:pointer;border:none;border-radius:var(--radius)}input,select{font-family:inherit;border-radius:var(--radius)}a{color:var(--btn-primary);text-decoration:none}a:hover{text-decoration:underline}
|