1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3987],{3208:(e,t,r)=>{r.d(t,{j:()=>c});var a=r(85047);r(31615);var s=r(62937),n=r(11787),l=r(21410),i=r(97839),o=r(34961);function c({items:e,ariaLabel:t="åæä½",align:r="end",triggerClassName:d,contentClassName:u}){return 0===e.length?null:(0,a.jsxs)(i.rI,{children:[(0,a.jsx)(i.ty,{asChild:!0,children:(0,a.jsx)(l.$,{type:"button",variant:"ghost",size:"icon",className:(0,o.cn)("h-8 w-8 shrink-0",d),"aria-label":t,children:(0,a.jsx)(s.A,{className:"h-4 w-4"})})}),(0,a.jsx)(i.SQ,{align:r,className:u,children:e.map(e=>{let t=e.icon,r=!0===e.loading;return(0,a.jsxs)(i._2,{disabled:!0===e.disabled||r,className:(0,o.cn)(e.destructive&&"text-destructive focus:bg-destructive/10 focus:text-destructive"),onSelect:()=>{e.disabled||r||e.onSelect()},children:[r?(0,a.jsx)(n.A,{className:"h-4 w-4 shrink-0 animate-spin","aria-hidden":!0}):t?(0,a.jsx)(t,{className:"h-4 w-4 shrink-0","aria-hidden":!0}):null,(0,a.jsx)("span",{className:"flex-1",children:e.label})]},e.id)})})]})}},9409:(e,t,r)=>{r.d(t,{$z:()=>i,L9:()=>o,Uu:()=>l,mj:()=>c,pY:()=>d});var a=r(18654),s=r(58678);function n(e){if(!e)return!1;if("object"==typeof e){if("AbortError"===("string"==typeof e?.name?e.name:""))return!0;let t=("string"==typeof e?.message?e.message:"").toLowerCase();if(t.includes("terminated")||t.includes("aborted")||t.includes("abort"))return!0}if("string"==typeof e){let t=e.toLowerCase();if(t.includes("terminated")||t.includes("aborted")||t.includes("abort"))return!0}return!1}async function l(e,t){if(!e)return Promise.resolve([]);try{let r=await fetch(`/api/stock/search?q=${encodeURIComponent(e)}`,{signal:t?.signal});if(!r.ok){let e=r.headers.get("content-type"),t={message:r.statusText};throw t=e&&e.includes("application/json")?await r.json().catch(()=>({message:r.statusText})):{message:await r.text().catch(()=>"")||r.statusText},Error(`Failed to search stock symbols: ${t.error?.message||t.message||r.statusText}`)}let a=await r.json(),n=(0,s.Xp)(s.N).safeParse(a);if(!n.success)throw Error("Invalid search response");return n.data.data}catch(e){if(n(e))throw e;if((0,a.vV)("Error in searchStockSymbols:",e),e instanceof Error){let t=e.message;if(t.includes("timeout")||t.includes("è¶
æ"))throw Error("æå°è«æ±è¶
æï¼è«ç¨å¾å試");if(t.includes("network")||t.includes("fetch")||t.includes("é£ç·"))throw Error("ç¡æ³é£æ¥å°è¡ç¥¨è³ææåï¼è«æª¢æ¥ç¶²è·¯é£ç·");if(t.includes("Failed to search"))throw Error(t.replace("Search stock symbols failed: ","")||"æå°è¡ç¥¨å¤±æ");throw Error(`æå°è¡ç¥¨å¤±æ: ${t}`)}throw Error("æå°è¡ç¥¨æç¼çæªç¥é¯èª¤")}}async function i(e,t){if(!e)return Promise.reject(Error("Stock symbol cannot be empty."));try{let r=await fetch(`/api/stock/price?symbol=${encodeURIComponent(e)}`,{signal:t?.signal});if(!r.ok){let t=r.headers.get("content-type"),a={message:r.statusText};throw a=t&&t.includes("application/json")?await r.json().catch(()=>({message:r.statusText})):{message:await r.text().catch(()=>"")||r.statusText},Error(`Failed to fetch stock quote for ${e}: ${a.error?.message||a.message||r.statusText}`)}let n=await r.json(),l=(0,s.Xp)(s.Ux).safeParse(n);if(!l.success)throw(0,a.vV)("Invalid quote data structure received:",n),Error(`Invalid quote data received for ${e}.`);return l.data.data}catch(t){if(n(t))throw t;if((0,a.vV)(`Error in fetchStockQuote for symbol ${e}:`,t),t instanceof Error)throw Error(`Fetch stock quote for ${e} failed: ${t.message}`);throw Error(`An unknown error occurred while fetching quote for ${e}.`)}}async function o(e){if(!e||0===e.length)return{};let t=Array.from(new Set(e.filter(Boolean)));if(0===t.length)return{};try{let e=encodeURIComponent(t.join(",")),r=`/api/stock/industry?symbols=${e}`,a=new URL(r,window.location.origin).toString(),s=await fetch(a);if(!s.ok){let e=s.headers.get("content-type")??"";if(e.includes("application/json")){let e=await s.json().catch(()=>({})),t="object"==typeof e.error&&e.error?.message?e.error.message:"string"==typeof e.error?e.error:e.message;throw Error(t||s.statusText)}let t=await s.text().catch(()=>"");
1if(e.includes("text/html")||t.trimStart().startsWith("<!"))throw Error(`Stock industry API HTTP ${s.status}ï¼æ¶å° HTMLï¼éå¸¸çº 404 ææªè¨»åç Route Handlerï¼`);throw Error(t.slice(0,240)||s.statusText)}let n=await s.json();return n?.data||n}catch(e){return(0,a.vV)("Error in fetchIndustriesBySymbols:",e),{}}}async function c(e,t){if(!e)return Promise.resolve([]);try{let r=await fetch(`/api/stock/us/search?q=${encodeURIComponent(e)}`,{signal:t?.signal});if(!r.ok){let e=await r.json().catch(()=>({message:r.statusText}));throw Error(`Failed to search US stock symbols: ${e.message||r.statusText}`)}let a=await r.json(),n=(0,s.Xp)(s.N).safeParse(a);if(!n.success)throw Error("Invalid search response");return n.data.data}catch(e){if(n(e))throw e;if((0,a.vV)("Error in searchUSStockSymbols:",e),e instanceof Error)throw Error(`Search US stock symbols failed: ${e.message}`);throw Error("An unknown error occurred while searching US stock symbols.")}}async function d(e,t){if(!e)return Promise.reject(Error("Stock symbol cannot be empty."));try{let r=await fetch(`/api/stock/us/price?symbol=${encodeURIComponent(e)}`,{signal:t?.signal});if(!r.ok){let t=await r.json().catch(()=>({message:r.statusText}));throw Error(`Failed to fetch US stock quote for ${e}: ${t.message||r.statusText}`)}let n=await r.json(),l=(0,s.Xp)(s.Ux).safeParse(n);if(!l.success)throw(0,a.vV)("Invalid quote data structure received:",n),Error(`Invalid quote data received for ${e}.`);return l.data.data}catch(t){if(n(t))throw t;if((0,a.vV)(`Error in fetchUSStockQuote for symbol ${e}:`,t),t instanceof Error)throw Error(`Fetch US stock quote for ${e} failed: ${t.message}`);throw Error(`An unknown error occurred while fetching quote for ${e}.`)}}},25799:(e,t,r)=>{r.r(t),r.d(t,{default:()=>ej});var a=r(85047),s=r(31615),n=r(21016),l=r(7004),i=r(82721),o=r(19548);let c="stockHistory";function d(){return new Promise((e,t)=>{let r=indexedDB.open("FinanceAppCache",1);r.onerror=()=>t(r.error),r.onsuccess=()=>e(r.result),r.onupgradeneeded=e=>{let t=e.target.result;t.objectStoreNames.contains(c)||t.createObjectStore(c)}})}async function u(e,t,r,a="TW"){if(!("indexedDB"in window))return null;try{let s=await d(),n=`stock_history_${a}_${e}_${t}_${r}`;return new Promise((l,i)=>{let o=s.transaction([c],"readonly").objectStore(c).get(n);o.onerror=()=>i(o.error),o.onsuccess=()=>{let s=o.result;if(!s)return void l(null);if(Date.now()>s.expiresAt){h(e,t,r,a).catch(()=>{}),l(null);return}l(s.data)}})}catch(s){return o.Cp(s instanceof Error?s:Error(String(s)),{level:"error",extra:{message:"è®å IndexedDB ç·©å失æ",symbol:e,startDate:t,endDate:r,market:a},tags:{source:"indexeddb.getCachedHistory"}}),null}}async function m(e,t,r,a,s="TW"){if("indexedDB"in window)try{let n=await d(),l=`stock_history_${s}_${e}_${t}_${r}`,i={data:a,timestamp:Date.now(),expiresAt:Date.now()+864e5};return new Promise((e,t)=>{let r=n.transaction([c],"readwrite").objectStore(c).put(i,l);r.onerror=()=>t(r.error),r.onsuccess=()=>e()})}catch(a){o.Cp(a instanceof Error?a:Error(String(a)),{level:"error",extra:{message:"å²å IndexedDB ç·©å失æ",symbol:e,startDate:t,endDate:r,market:s},tags:{source:"indexeddb.setCachedHistory"}})}}async function h(e,t,r,a="TW"){if("indexedDB"in window)try{let s=await d(),n=`stock_history_${a}_${e}_${t}_${r}`;return new Promise((e,t)=>{let r=s.transaction([c],"readwrite").objectStore(c).delete(n);r.onerror=()=>t(r.error),r.onsuccess=()=>e()})}catch(s){o.Cp(s instanceof Error?s:Error(String(s)),{level:"error",extra:{message:"åªé¤ IndexedDB ç·©å失æ",symbol:e,startDate:t,endDate:r,market:a},tags:{source:"indexeddb.deleteCachedHistory"}})}}function f(e){return 0===e.length?0:e.reduce((e,t)=>e+t,0)/e.length}function g(e,t,r,a,s,n=!1,l,i,o=0){let c,d,u=new Date(r),m=(new Date(a).getTime()-u.getTime())/315576e5;if(i&&i.length>=2){let e=function(e,t=.1){if(e.length<2)return null;let r=[...e].sort((e,t)=>e.date.localeCompare(t.date)),a=new Date(r[0].date).getTime(),s=r.map(e=>(new Date(e.date).getTime()-a)/315576e5),n=r.map(e=>e.amount),l=t;for(let e=0;e<64;e++){let e=0,t=0;for(let r=0;r<n.length;r++){let a=s[r],i=Math.pow(1+l,a);if(!Number.isFinite(i)||0===i)return null;e+=n[r]/i,0!==a&&(t-=a*n[r]/(i*(1+l)))}if(1e-7>Math.abs(e))return l;if(1e-12>Math.abs(t))break;let r=l-e/t;if(!Number.isFinite(r))break;if(1e-8>Math.abs(r-l))return r;l=r}return Number.isFinite(l)?l:null}(i);c=null!=e?100*e:0}else c=m>0&&e>0?(Math.pow(t/e,1/m)-1)*100:0;d=n&&s.length>0?s[0].value:e;let h=0;for(let e of s)if(e.value>d&&(d=e.value),d>0){let t=(d-e.value)/d*100;t>h&&(h=t)}let p=[];for(let e=1;e<s.length;e++){let t=s[e-1],r=s[e];if(n&&l&&l.has(r.date))continue;let a=t.value,i=r.value;a>0&&p.push((i-a)/a)}let x=0===p.length?0:252*f(p),y=p.length<2?0:function(e){if(e.length<2)return 0;let t=f(e);return Math.sqrt(e.reduce((e,r)=>e+(r-t)**2,0)/(e.length-1))}(p)*Math.sqrt(252),v=0===p.length?0:Math.sqrt(p.reduce((e,t)=>
1e+(t<0?t*t:0),0)/p.length)*Math.sqrt(252);return{totalReturn:e>0?(t-e)/e*100:0,annualizedReturn:c,maxDrawdown:h,sharpeRatio:function(e,t,r=0){return t<=0?0:(e-r)/t}(x,y,o),sortinoRatio:function(e,t,r=0){return t<=0?0:(e-r)/t}(x,v,o)}}function p(e,t){if(!e.portfolio||0===e.portfolio.length)throw Error("æè³çµåé
ç½®çºç©º");if("buy-hold"!==e.strategy)throw Error("æè³çµå忏¬ç®åå
æ¯æ´è²·å
¥ææçç¥");try{return function(e,t){let r=e.portfolio;if(0===r.length)throw Error("æè³çµåçºç©º");let a=[],s=[],n=new Set;t.forEach(e=>{e.forEach(e=>n.add(e.date))});let l=Array.from(n).sort(),i=new Map;r.forEach(e=>{let r=t.get(e.symbol)||[],a=new Map;r.forEach(e=>{a.set(e.date,e.close),e.close}),i.set(e.symbol,a)});let o=r.map(e=>{let t=i.get(e.symbol);return new Set(t&&Array.from(t.keys())||[])}),c=l.filter(e=>o.every(t=>t.has(e))).find(t=>t>=e.startDate)??null;if(!c)throw Error("ç¡æ³æ¾å°æè³çµåèµ·å§æ¥ï¼è«ç¢ºèªæææ¨çå¨åéå
§ææ¸æï¼");let d=new Map;r.forEach(e=>{let t=i.get(e.symbol),r=(t?Array.from(t.entries()).filter(([e])=>e<=c).sort((e,t)=>t[0].localeCompare(e[0])):[])[0];d.set(e.symbol,r?r[1]:0)});let u=(e,t)=>{let r=i.get(e),a=r?.get(t);return null!=a&&a>0?(d.set(e,a),a):d.get(e)||0},m=new Map,h=e.initialCapital;r.forEach(t=>{let r=u(t.symbol,c);if(r<=0)return;let s=Math.floor(e.initialCapital*t.weight/(1+e.buyFee)/r);if(s<=0)return;let n=s*r*(1+e.buyFee);h-=n,m.set(t.symbol,s),a.push({date:c,type:"buy",symbol:t.symbol,price:r,quantity:s,cost:n,revenue:0})});let f=e.rebalanceConfig,p=(f?.threshold??5)/100,x=f?.frequency??"annually",y=new Set;{let t="",r="";for(let a of l){if(a<e.startDate||a>e.endDate)continue;let s=new Date(a),n=`${s.getFullYear()}-${s.getMonth()+1}`;t&&n!==t&&y.add(r),t=n,r=a}r&&y.add(r)}let v=null;for(let t of l){if(t<c||t>e.endDate)continue;let n=0,l=new Map;r.forEach(e=>{let r=u(e.symbol,t),a=(m.get(e.symbol)??0)*r;l.set(e.symbol,a),n+=a});let i=n+h,o=new Date(t),d=(o.getFullYear(),o.getMonth()+1),g=y.has(t),j=f?.enabled&&("annually"===x?12===d:3===d||6===d||9===d||12===d)&&g&&t!==c&&v!==t,b=!1;if(j&&i>0){let e=new Map;for(let t of(r.forEach(t=>{let r=l.get(t.symbol)??0;e.set(t.symbol,r/i)}),r)){let r=t.weight;if(Math.abs((e.get(t.symbol)??0)-r)>p){b=!0;break}}}if(b&&j){v=t;let s=new Map;r.forEach(e=>{s.set(e.symbol,i*e.weight)}),r.forEach(r=>{let n=u(r.symbol,t);if(n<=0)return;let i=l.get(r.symbol)??0,o=(s.get(r.symbol)??0)-i,c=m.get(r.symbol)??0;if(!(Math.abs(o)<.5*n))if(o>0){let s=Math.floor(o/(n*(1+e.buyFee)));if(s>0){let l=s*n*(1+e.buyFee);l<=h&&(h-=l,m.set(r.symbol,c+s),a.push({date:t,type:"buy",symbol:r.symbol,price:n,quantity:s,cost:l,revenue:0}))}}else{let s=Math.min(c,Math.floor(Math.abs(o)/n));if(s>0){let l=s*n*(1-e.sellFee-e.sellTax);h+=l,m.set(r.symbol,c-s),a.push({date:t,type:"sell",symbol:r.symbol,price:n,quantity:s,cost:0,revenue:l})}}})}let w=0;r.forEach(e=>{let r=u(e.symbol,t),a=m.get(e.symbol)??0;w+=a*r}),s.push({date:t,value:w+h,cash:h,holdings:w})}let j=l.filter(t=>t<=e.endDate),b=j.length>0?j[j.length-1]:e.endDate;r.forEach(t=>{let r=m.get(t.symbol)??0;if(r<=0)return;let s=u(t.symbol,b);if(s<=0)return;let n=r*s*(1-e.sellFee-e.sellTax);h+=n,m.set(t.symbol,0),a.push({date:b,type:"sell",symbol:t.symbol,price:s,quantity:r,cost:0,revenue:n})});let w=h,N=g(e.initialCapital,w,c,e.endDate,s);return{buyTrades:a.filter(e=>"buy"===e.type),sellTrades:a.filter(e=>"sell"===e.type),equityCurve:s,performance:{...N,finalValue:w}}}(e,t)}catch(e){if(e instanceof Error)throw Error(`æè³çµå忏¬è¨ç®å¤±æ: ${e.message}`);throw Error("æè³çµå忏¬è¨ç®å¤±æ: æªç¥é¯èª¤")}}function x(e,t){let r;if(0===t.length)throw Error("æ·å²å¹æ ¼æ¸æçºç©ºï¼è«æª¢æ¥æ¥æç¯ååè¡ç¥¨ä»£ç¢¼æ¯å¦æ£ç¢º");let a=t.find(t=>t.date>=e.startDate);for(let a=t.length-1;a>=0;a--)if(t[a].date<=e.endDate){r=t[a];break}if(!a)throw Error(`ç¡æ³æ¾å°éå§æ¥æ ${e.startDate} ç广 ¼æ¸æ`);if(!r)throw Error(`ç¡æ³æ¾å°çµææ¥æ ${e.endDate} ç广 ¼æ¸æ`);try{if("buy-hold"===e.strategy)return function(e,t){let r,a=[],s=[],n=t.find(t=>t.date>=e.startDate)?.close;for(let a=t.length-1;a>=0;a--)if(t[a].date<=e.endDate){r=t[a].close;break}if(!n||!r)throw Error("ç¡æ³æ¾å°éå§æçµææ¥æç广 ¼");e.initialCapital,e.buyFee;let l=Math.floor(e.initialCapital/(1+e.buyFee)/n),i=l*n*(1+e.buyFee),o=e.initialCapital-i;a.push({date:e.startDate,type:"buy",price:n,quantity:l,cost:i,revenue:0});let c=n;for(let r of t){if(r.date<e.startDate)continue;if(r.date>e.endDate)break;let t=r.close||c;c=t;let a=l*t,n=a+o;s.push({date:r.date,value:n,cash:o,holdings:a})}let d=l*r*(1-e.sellFee-e.sellTax),u=d+o;a.push({date:e.endDate,type:"sell",price:r,quantity:l,cost:0,revenue:d});
1let m=g(e.initialCapital,u,e.startDate,e.endDate,s);return{buyTrades:a.filter(e=>"buy"===e.type),sellTrades:a.filter(e=>"sell"===e.type),equityCurve:s,performance:{...m,finalValue:u}}}(e,t);return function(e,t){let r;if(!e.dcaConfig)throw Error("宿å®é¡çç¥éè¦ dcaConfig");let a=[],s=[];e.initialCapital;let n=[],l=new Date(e.startDate),i=new Date(e.endDate),o=new Date(l.getFullYear(),l.getMonth(),1);for(;o<=i;){let r=o.getFullYear(),a=o.getMonth(),s=new Date(r,a+1,0).getDate(),c=new Date(r,a,Math.min(e.dcaConfig.monthlyDate,s));if(c>=l&&c<=i){let s=c.toISOString().split("T")[0],l=new Date(r,a+1,1).toISOString().split("T")[0],i=t.find(t=>t.date>=s&&t.date<l&&t.date<=e.endDate);if(i)n.includes(i.date)||n.push(i.date);else{let s=new Date(r,a+1,0).toISOString().split("T")[0],l=t.filter(t=>{let n=new Date(t.date);return n.getFullYear()===r&&n.getMonth()===a&&t.date<=s&&t.date<=e.endDate}).sort((e,t)=>t.date.localeCompare(e.date))[0];l&&!n.includes(l.date)&&n.push(l.date)}}o.setMonth(a+1),o.setDate(1)}n.sort((e,t)=>e.localeCompare(t));let c=new Map,d=0;for(let r of n){let s=t.find(e=>e.date===r);if(!s)continue;let n=s.close;if(!n||n<=0)continue;let l=e.dcaConfig.monthlyAmount,i=Math.floor(l/(1+e.buyFee)/n);if(0===i)continue;let o=i*n*(1+e.buyFee);d+=l,d-=o;let u={date:r,type:"buy",price:n,quantity:i,cost:o,revenue:0};a.push(u),c.set(r,u)}let u=0,m=0,h=t.find(t=>t.date>=e.startDate)?.close||0;for(let r of t){if(r.date<e.startDate)continue;if(r.date>e.endDate)break;let t=c.get(r.date);t&&(u+=e.dcaConfig.monthlyAmount,u-=t.cost,m+=t.quantity);let a=r.close||h;h=a;let n=m*a,l=n+u;s.push({date:r.date,value:l,cash:u,holdings:n})}for(let a=t.length-1;a>=0;a--)if(t[a].date<=e.endDate){r=t[a];break}if(!r)throw Error("ç¡æ³æ¾å°çµææ¥æç广 ¼");let f=r.close,p=m*f*(1-e.sellFee-e.sellTax),x=p+u;m>0&&a.push({date:e.endDate,type:"sell",price:f,quantity:m,cost:0,revenue:p});let y=a.filter(e=>"buy"===e.type).length*e.dcaConfig.monthlyAmount,v=new Set(a.filter(e=>"buy"===e.type).map(e=>e.date)),j=[...a.filter(e=>"buy"===e.type).map(t=>({date:t.date,amount:-e.dcaConfig.monthlyAmount})),{date:e.endDate,amount:x}],b=g(y,x,e.startDate,e.endDate,s,!0,v,j);return{buyTrades:a.filter(e=>"buy"===e.type),sellTrades:a.filter(e=>"sell"===e.type),equityCurve:s,performance:{...b,finalValue:x}}}(e,t)}catch(e){if(e instanceof Error)throw Error(`忏¬è¨ç®å¤±æ: ${e.message}`);throw Error("忏¬è¨ç®å¤±æ: æªç¥é¯èª¤")}}var y=r(27295);function v(e,t){let r=(t?e.filter(e=>t.includes(e.id)):e).filter(e=>"stocks"===e.type&&e.symbol&&""!==String(e.symbol).trim());if(0===r.length)return[];let a=r.map(e=>({investment:e,valueTWD:(0,y.Vx)({quantity:e.quantity??0,price:e.price??0,currency:e.currency??"TWD"})})),s=a.reduce((e,t)=>e+t.valueTWD,0);return 0===s?[]:a.map(({investment:e,valueTWD:t})=>({symbol:e.symbol??"",stockName:(e.name||e.symbol)??"",weight:t/s,market:e.market??"TW",investmentId:e.id}))}function j(e){if(0===e.length)return{valid:!1,error:"æè³çµåçºç©º"};let t=e.reduce((e,t)=>e+t.weight,0);if(Math.abs(t-1)>.01)return{valid:!1,error:`æ¬é總åæçº 100%ï¼ç®åçº ${(100*t).toFixed(2)}%`};let r=e.map(e=>e.symbol),a=new Set(r);return r.length!==a.size?{valid:!1,error:"æè³çµåä¸å
å«éè¤çæ¨ç"}:e.some(e=>!e.symbol||""===String(e.symbol).trim())?{valid:!1,error:"æè³çµåä¸å
å«ç¡æçæ¨ç代碼"}:{valid:!0}}function b(e){if(0===e.length)return[];let t=e.reduce((e,t)=>e+t.weight,0);return 0===t?e:e.map(e=>({...e,weight:e.weight/t}))}var w=r(47026),N=r(28979),k=r(8958);async function A(e,t,r,a,s="TW",n){let l=s??"TW";if(n?.aborted)throw new DOMException("Aborted","AbortError");let i=await u(e,t,r,l);if(i)return a({current:1,total:1,message:"å¾ç·©åè¼å
¥æ·å²æ¸æ..."}),i;if("US"===l){a({current:0,total:1,message:`æ£å¨æ¥è©¢ç¾è¡ ${e} æ·å²æ¸æ...`});let s=new URLSearchParams({symbol:e,startDate:t,endDate:r}),l=await fetch(`/api/stock/us/history?${s.toString()}`,{signal:n}),i=await l.json();if(!l.ok||i.error)throw Error(i.error?.message??i.message??l.statusText??"æ¥è©¢ç¾è¡æ·å²å¤±æ");let o=i.data??i;if(!Array.isArray(o)||0===o.length)throw Error("ç¡æ³åå¾ä»»ä½ç¾è¡æ·å²å¹æ ¼æ¸æ");return await m(e,t,r,o,"US"),a({current:1,total:1,message:"æ·å²æ¸ææ¥è©¢å®æ"}),o}let o=new Date(t),c=new Date(r),d=[],h=new Date(o);for(;h<=c;
1)d.push({year:h.getFullYear(),month:h.getMonth()+1}),h.setMonth(h.getMonth()+1);a({current:0,total:d.length,message:`æºåæ¥è©¢ ${d.length} åæçæ·å²æ¸æ...`});let f=[];for(let t=0;t<d.length;t+=4){if(n?.aborted)throw new DOMException("Aborted","AbortError");let r=d.slice(t,t+4);for(let s of(a({current:t,total:d.length,message:`æ£å¨æ¥è©¢ ${r[0].year}å¹´${r[0].month}æâ¦ çæ·å²æ¸æ...`}),await Promise.all(r.map(async({year:t,month:r})=>{try{let a=await fetch(`/api/stock/history?symbol=${encodeURIComponent(e)}&year=${t}&month=${r}`,{signal:n}),s=await a.json();if(!a.ok||s.error)return[];return Array.isArray(s.data)?s.data:[]}catch(e){if(e?.name==="AbortError")throw e;return[]}}))))f.push(...s);if(t+4<d.length){let e=200+150*Math.random();await new Promise(t=>setTimeout(t,e))}}if(0===f.length)throw Error("ç¡æ³åå¾ä»»ä½æ·å²å¹æ ¼æ¸æ");let g=f.filter(e=>{let t=new Date(e.date);return t>=o&&t<=c}).sort((e,t)=>e.date.localeCompare(t.date));return await m(e,t,r,g,"TW"),a({current:d.length,total:d.length,message:"æ·å²æ¸ææ¥è©¢å®æ"}),g}async function C(e,t,r,a,s){let n=new Map,l=e.length;for(let i=0;i<e.length;i++){if(s?.aborted)throw new DOMException("Aborted","AbortError");let o=e[i],c=o.market??"TW";a({current:i,total:l,message:`æ£å¨æ¥è©¢ ${o.stockName||o.symbol} çæ·å²æ¸æ... (${i+1}/${l})`});try{let e=await A(o.symbol,t,r,e=>{a({current:i+e.current/Math.max(1,e.total)*.9,total:l,message:`${o.stockName||o.symbol}: ${e.message}`})},c,s);e.length>0&&n.set(o.symbol,e)}catch(e){if(e?.name==="AbortError")throw e}if(i<e.length-1){let e=200+150*Math.random();await new Promise(t=>setTimeout(t,e))}}return a({current:l,total:l,message:"æ·å²æ¸ææ¥è©¢å®æ"}),n}var E=r(73521),S=r(82520),T=r(21410),M=r(866),I=r(96968),D=r(99185),_=r(62557),$=r(55840),F=r(5779),P=r(34961);r(18534);let q=s.forwardRef(({className:e,...t},r)=>(0,a.jsx)($.uB,{ref:r,className:(0,P.cn)("flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",e),...t}));q.displayName=$.uB.displayName,s.forwardRef(({className:e,...t},r)=>(0,a.jsxs)("div",{className:"flex items-center border-b px-3","cmdk-input-wrapper":"",children:[(0,a.jsx)(F.A,{className:"mr-2 h-4 w-4 shrink-0 opacity-50"}),(0,a.jsx)($.uB.Input,{ref:r,className:(0,P.cn)("flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",e),...t})]})).displayName=$.uB.Input.displayName;let R=s.forwardRef(({className:e,...t},r)=>(0,a.jsx)($.uB.List,{ref:r,className:(0,P.cn)("max-h-[300px] overflow-y-auto overflow-x-hidden",e),...t}));R.displayName=$.uB.List.displayName;let Y=s.forwardRef((e,t)=>(0,a.jsx)($.uB.Empty,{ref:t,className:"py-6 text-center text-sm",...e}));Y.displayName=$.uB.Empty.displayName;let W=s.forwardRef(({className:e,...t},r)=>(0,a.jsx)($.uB.Group,{ref:r,className:(0,P.cn)("overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",e),...t}));W.displayName=$.uB.Group.displayName,s.forwardRef(({className:e,...t},r)=>(0,a.jsx)($.uB.Separator,{ref:r,className:(0,P.cn)("-mx-1 h-px bg-border",e),...t})).displayName=$.uB.Separator.displayName;let B=s.forwardRef(({className:e,...t},r)=>(0,a.jsx)($.uB.Item,{ref:r,className:(0,P.cn)("relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",e),...t}));B.displayName=$.uB.Item.displayName;var O=r(3953),U=r(21582),L=r(68341),J=r(9409),V=r(15418),z=r(81321),Z=r(67316),G=r(63955);let H="ç®å忏¬å
æ¯æ´è¡ç¥¨ï¼æ¨çæè³çµå䏿²æè¡ç¥¨é¨ä½ã",X=V.Ik({symbol:V.Yj(),stockName:V.Yj(),weight:V.ai().min(0).max(1),market:V.k5(["TW","US"]).optional(),investmentId:V.Yj().optional()}),K=V.Ik({enabled:V.zM(),frequency:V.k5(["quarterly","annually"]),threshold:V.ai().min(0).max(100).optional()}
1),Q=V.Ik({symbol:V.Yj().optional(),stockName:V.Yj().optional(),market:V.k5(["TW","US"]).optional(),portfolioSource:V.k5(["single","current","selected"]).optional(),portfolio:V.YO(X).optional(),selectedInvestmentIds:V.YO(V.Yj()).optional(),rebalanceConfig:K.optional(),strategy:V.k5(["buy-hold","dca"]),startDate:V.Yj().regex(/^\d{4}-\d{2}-\d{2}$/,"æ¥ææ ¼å¼é¯èª¤"),endDate:V.Yj().regex(/^\d{4}-\d{2}-\d{2}$/,"æ¥ææ ¼å¼é¯èª¤"),initialCapital:V.ai(),buyFee:V.ai().min(0).max(1,"è²·å
¥æçºè²»çæå¨ 0-1 ä¹é"),sellFee:V.ai().min(0).max(1,"è³£åºæçºè²»çæå¨ 0-1 ä¹é"),sellTax:V.ai().min(0).max(1,"è³£åºäº¤æç¨
çæå¨ 0-1 ä¹é"),dcaConfig:V.Ik({monthlyDate:V.ai().min(1).max(28),monthlyAmount:V.ai().min(1e3,"宿å®é¡éé¡è³å°éè¦ 1,000 å
")}).optional(),enableSound:V.zM().default(!0)}).refine(e=>new Date(e.startDate)<new Date(e.endDate),{message:"éå§æ¥æå¿
é æ©æ¼çµææ¥æ",path:["endDate"]}).refine(e=>("buy-hold"!==e.strategy||!!(e.portfolio&&e.portfolio.length>0))&&(!e.portfolio||!(e.portfolio.length>0))||e.initialCapital>=1e3,{message:"åå§æ¬éè³å°éè¦ 1,000 å
",path:["initialCapital"]}).superRefine((e,t)=>{if(e.portfolio&&e.portfolio.length>0){let r=j(e.portfolio);r.valid||t.addIssue({code:z.eq.custom,message:r.error,path:["portfolio"]}),"buy-hold"!==e.strategy&&t.addIssue({code:z.eq.custom,message:"æè³çµå忏¬å
æ¯æ´è²·å
¥ææçç¥",path:["strategy"]})}else e.symbol?.trim()||t.addIssue({code:z.eq.custom,message:"è«é¸æè¡ç¥¨ä»£ç¢¼",path:["symbol"]}),e.stockName?.trim()||t.addIssue({code:z.eq.custom,message:"è«è¼¸å
¥è¡ç¥¨å稱",path:["stockName"]})});function ee({onSubmit:e,isRunning:t}){let{toast:r}=(0,i.dj)(),{user:l,viewingUserId:o}=(0,E.A)(),{investments:c}=(0,G.sC)(o||l?.uid),[d,u]=(0,s.useState)("single"),[m,h]=(0,s.useState)("TW"),[f,g]=(0,s.useState)("buy-hold"),[p,x]=(0,s.useState)(""),[w,N]=(0,s.useState)(""),[k,A]=(0,s.useState)(""),[C,$]=(0,s.useState)(""),[F,P]=(0,s.useState)("1000000"),[V,z]=(0,s.useState)("0.001425"),[X,K]=(0,s.useState)("0.001425"),[et,er]=(0,s.useState)("0.003"),[ea,es]=(0,s.useState)("1"),[en,el]=(0,s.useState)("10000"),[ei,eo]=(0,s.useState)(!0),[ec,ed]=(0,s.useState)([]),[eu,em]=(0,s.useState)([]),[eh,ef]=(0,s.useState)(!1),[eg,ep]=(0,s.use
1State)("annually"),[ex,ey]=(0,s.useState)("5"),[ev,ej]=(0,s.useState)(!1),[eb,ew]=(0,s.useState)(""),[eN,ek]=(0,s.useState)([]),[eA,eC]=(0,s.useState)(!1),[eE,eS]=(0,s.useState)(null),eT=(0,s.useRef)(null);(0,s.useEffect)(()=>{if("current"===d&&c.length>0){em(v(c));let e=c.filter(e=>"stocks"===e.type&&e.symbol).reduce((e,t)=>e+(0,y.Vx)({quantity:t.quantity??0,price:t.price??0,currency:t.currency??"TWD"}),0);e>0&&"1000000"===F&&P(String(Math.round(e)))}else"selected"===d&&ec.length>0?em(v(c,ec)):("single"===d||"selected"===d&&0===ec.length)&&em([])},[d,c,ec,F]);let eM=(e,t)=>{em(b(eu.map(r=>r.symbol===e?{...r,weight:Math.max(0,Math.min(100,t))/100}:r)))},eI=c.filter(e=>"stocks"===e.type&&e.symbol),eD=e=>{let t=new Date,r=new Date;r.setFullYear(t.getFullYear()-e),A(r.toISOString().split("T")[0]),$(t.toISOString().split("T")[0])},e_=e=>{let t=eN.find(t=>t.value===e);t&&(x(e),N(t.label),ew("")),ej(!1)};return(0,a.jsxs)(S.Zp,{children:[(0,a.jsx)(S.aR,{children:(0,a.jsx)(S.ZB,{children:"忏¬è¨å®"})}),(0,a.jsx)(S.Wu,{children:(0,a.jsxs)("form",{onSubmit:t=>{t.preventDefault();let a="single"!==d&&eu.length>0;if(!a&&(!p?.trim()||!w?.trim()))return void r({title:"è«é¸æè¡ç¥¨",description:"è«å
鏿è¦å測çè¡ç¥¨ä»£ç¢¼ï¼ææ¹ç¨æè³çµå模å¼",variant:"destructive"});if(a){let e=j(eu);if(!e.valid)return void r({title:"æè³çµåé©è失æ",description:e.error,variant:"destructive"})}let s=a?"buy-hold":f,n={...a?{portfolioSource:d,portfolio:eu,selectedInvestmentIds:"selected"===d?ec:void 0,rebalanceConfig:{enabled:eh,frequency:eg,threshold:Number(ex)||5}}:{symbol:p,stockName:w,market:m},strategy:s,startDate:k,endDate:C,initialCapital:"dca"===s?0:Number(F),buyFee:Number(V),sellFee:Number(X),sellTax:Number(et),dcaConfig:"dca"===s?{monthlyDate:Number(ea),monthlyAmount:Number(en)}:void 0,enableSound:ei};try{Q.parse(n),e(n)}catch(e){if(e instanceof Z.G){let t=e.issues[0];r({title:"é©èé¯èª¤",description:t?.message||"表å®é©è失æï¼è«æª¢æ¥è¼¸å
¥çè³æ",variant:"destructive"});return}}},className:"space-y-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{children:"忏¬æ¨¡å¼"}),(0,a.jsxs)(D.z,{value:d,onValueChange:e=>u(e),children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(D.C,{value:"single",id:"mode-single"}),(0,a.jsx)(I.J,{htmlFor:"mode-single",className:"font-normal",children:"å®ä¸æ¨ç"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(D.C,{value:"current",id:"mode-current"}),(0,a.jsx)(I.J,{htmlFor:"mode-current",className:"font-normal",children:"使ç¨ç¶åæè³çµå"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(D.C,{value:"selected",id:"mode-selected"}),(0,a.jsx)(I.J,{htmlFor:"mode-selected",className:"font-normal",children:"鏿æè³é
ç®"})]})]}),(0,a.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"忏¬ç®åå
æ¯æ´è¡ç¥¨æ¨çã"})]}),"single"===d&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{children:"å¸å ´"}),(0,a.jsxs)(D.z,{value:m,onValueChange:e=>{h(e),x(""),N(""),ek([]),ew(""),er("US"===e?"0":"0.003")},children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(D.C,{value:"TW",id:"market-tw"}),(0,a.jsx)(I.J,{htmlFor:"market-tw",className:"font-normal",children:"å°è¡"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(D.C,{value:"US",id:"market-us"}),(0,a.jsx)(I.J,{htmlFor:"market-us",className:"font-normal",children:"ç¾è¡"})]})]})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{children:"è¡ç¥¨ä»£ç¢¼"}),(0,a.jsxs)(O.AM,{open:ev,onOpenChange:ej,children:[(0,a.jsx)(O.dT,{asChild:!0,children:(0,a.jsx)("div",{className:"relative",children:(0,a.jsx)(M.p,{placeholder:"輸å
¥è¡ç¥¨ä»£èæå稱...",value:eb,onChange:e=>(e=>{if(ew(e),eT.current&&clearTimeout(eT.current),e.length<2){ek([]),eC(!1),eS(null),ej(!1);return}ej(!0),eC(!0),eS(null),eT.current=setTimeout(async()=>{try{let t="US"===m?J.mj:J.Uu,r=(await t(e)).slice(0,20);ek(r),eS(null),ej(r.length>0)}catch(r){let t=r instanceof Error?r.message:"æå°æç¼çæªç¥é¯èª¤";ek([]),eS(t),ej(e.length>=2)}finally{eC(!1)}},300)})(e.target.value),onFocus:()=>{eb.length>=2&&(eN.length>0||eA)&&ej(!0)}})})}),(0,a.jsx)(O.hl,{className:"w-[var(--radix-popover-trigger-width)] p-0",align:"start",onOpenAutoFocus:e=>e.preventDefault(),children:(0,a.jsx)(q,{shouldFilter:!1,children:(0,a.jsxs)(R,{className:"max-h-[300px]",children:[(0,a.jsx)(Y,{children:eA?"æå°ä¸...":eE?(0,a.jsx)("span",{className:"text-destructive",children:eE}):eb.length>=2?"æ¾ä¸å°ç¸éè¡ç¥¨":"è«è¼¸å
¥è³å° 2 ååå
"}),(0,a.jsx)(W,{children:eN.map(e=>(0,a.jsxs)(B,{value:e.value,onSelect:e_,children:[(0,a.jsx)(L.A,{className:`mr-2 h-4 w-4 ${p===e.value?"opacity-100":"opacity-0"}`}),e.label," (",e.value,")"]},e.value))})]})})})]}),p&&(0,a.jsxs)("div",{className:"text-sm text-muted-foreground mt-1",children:["已鏿: ",w," (",p,") \xb7 ","US"===m?"ç¾è¡":"å°è¡"]}
1)]})]}),"current"===d&&(0,a.jsxs)("div",{className:"border p-4 rounded-lg space-y-2",children:[(0,a.jsx)(I.J,{children:"æè³çµåé 覽"}),"current"===d&&0===eu.length&&c.length>0&&(0,a.jsxs)(n.Fc,{variant:"default",children:[(0,a.jsx)(n.XL,{children:"ç¡æ³è¼å
¥æè³çµå"}),(0,a.jsx)(n.TN,{children:H})]}),eu.length>0?(0,a.jsxs)("div",{className:"space-y-1",children:[(0,a.jsx)("p",{className:"text-xs text-muted-foreground",children:"ç®åå
æ¯æ´è¡ç¥¨ï¼ä»¥ä¸çºç´å
¥å測çè¡ç¥¨é¨ä½ã"}),eu.map((e,t)=>(0,a.jsxs)("div",{className:"flex justify-between items-center text-sm",children:[(0,a.jsxs)("span",{children:[e.stockName," (",e.symbol,")"]}),(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(M.p,{type:"number",className:"w-20 h-8 text-right",min:0,max:100,step:1,value:Math.round(100*e.weight),onChange:t=>eM(e.symbol,Number(t.target.value)||0)}),(0,a.jsx)("span",{className:"text-muted-foreground",children:"%"})]})]},e.symbol)),(0,a.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"æ¬é總åå°èªåæ£è¦åçº 100%"})]}):!("current"===d&&c.length>0)&&(0,a.jsx)("p",{className:"text-sm text-muted-foreground",children:H})]}),"selected"===d&&(0,a.jsxs)("div",{className:"border p-4 rounded-lg space-y-2",children:[(0,a.jsx)(I.J,{children:"鏿æè³é
ç®"}),(0,a.jsx)("p",{className:"text-xs text-muted-foreground",children:"ç®åå
æ¯æ´è¡ç¥¨ï¼å
ååºè¡ç¥¨é¨ä½ä¾å¾é¸ã"}),(0,a.jsx)("div",{className:"max-h-60 overflow-y-auto space-y-2",children:eI.map(e=>(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(_.S,{id:`inv-${e.id}`,checked:ec.includes(e.id),onCheckedChange:t=>{t?ed([...ec,e.id]):ed(ec.filter(t=>t!==e.id))}}),(0,a.jsxs)(I.J,{htmlFor:`inv-${e.id}`,className:"font-normal flex-1 cursor-pointer",children:[e.name," (",e.symbol,")"]})]},e.id))}),eu.length>0&&(0,a.jsxs)("div",{className:"mt-2 pt-2 border-t",children:[(0,a.jsx)(I.J,{className:"text-sm",children:"æ¬éï¼å¯ç·¨è¼¯ï¼"}),(0,a.jsx)("div",{className:"space-y-1 mt-1",children:eu.map(e=>(0,a.jsxs)("div",{className:"flex justify-between items-center text-sm",children:[(0,a.jsx)("span",{children:e.stockName}),(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(M.p,{type:"number",className:"w-20 h-8 text-right",min:0,max:100,value:Math.round(100*e.weight),onChange:t=>eM(e.symbol,Number(t.target.value)||0)}),(0,a.jsx)("span",{className:"text-muted-foreground",children:"%"})]})]},e.symbol))})]})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{children:"交æçç¥"}),(0,a.jsxs)(D.z,{value:"single"!==d&&eu.length>0?"buy-hold":f,onValueChange:e=>g(e),disabled:"single"!==d&&eu.length>0,children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(D.C,{value:"buy-hold",id:"buy-hold"}),(0,a.jsx)(I.J,{htmlFor:"buy-hold",className:"font-normal",children:"è²·å
¥ææ"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(D.C,{value:"dca",id:"dca"}),(0,a.jsx)(I.J,{htmlFor:"dca",className:"font-normal",children:"宿å®é¡"})]})]}),"single"!==d&&eu.length>0&&(0,a.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"æè³çµå忏¬å
æ¯æ´è²·å
¥ææ"})]}),"single"!==d&&eu.length>0&&(0,a.jsxs)("div",{className:"border p-4 rounded-lg space-y-2",children:[(0,a.jsx)(I.J,{children:"宿å平衡"}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(_.S,{id:"rebalance-enabled",checked:eh,onCheckedChange:e=>ef(!0===e)}),(0,a.jsx)(I.J,{htmlFor:"rebalance-enabled",className:"font-normal",children:"åç¨å平衡"})]}),eh&&(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-2 mt-2",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{className:"text-sm",children:"é »ç"}),(0,a.jsxs)(U.l6,{value:eg,onValueChange:e=>ep(e),children:[(0,a.jsx)(U.bq,{children:(0,a.jsx)(U.yv,{})}),(0,a.jsxs)(U.gC,{children:[(0,a.jsx)(U.eb,{value:"quarterly",children:"æ¯å£"}),(0,a.jsx)(U.eb,{value:"annually",children:"æ¯å¹´"})]})]})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{className:"text-sm",children:"æ¬éåå·®é¾å¼ (%)"}),(0,a.jsx)(M.p,{type:"number",min:1,max:50,value:ex,onChange:e=>ey(e.target.value)})]})]}),eh&&eu.some(e=>"US"===e.market)&&eu.some(e=>(e.market??"TW")==="TW")&&(0,a.jsx)("p",{className:"text-xs text-muted-foreground mt-2",children:"å°ç¾æ··åçµåæåå¸å ´ç¨ç«å測å¾å併淨å¼ï¼è·¨å¸å ´åå¹³è¡¡ä¸æç¼çã"})]}),("buy-hold"===f||"single"!==d&&eu.length>0)&&(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{children:"åå§æ¬é (å
)"}),(0,a.jsx)(M.p,{type:"number",value:F,onChange:e=>P(e.target.value),min:"1000",step:"1000",required:!0})]}),"dca"===f&&(0,a.jsxs)("div",{className:"space-y-2 border p-4 rounded-lg",children:[(0,a.jsx)(I.J,{children:"宿å®é¡è¨å®"}),(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-2",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{children:"æ¯æåºå®æ¥æ (1-28)"}),(0,a.jsx)(M.p,{type:"number",value:ea,onChange:e=>es(e.target.value),min:"1",max:"28",required:!0})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{children:"åºå®éé¡ (å
)"}),(0,a.jsx)(M.p,{type:"number",value:en,onChange:e=>el(e.target.value),min:"1000",step:"1000",required:!0})]})]})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{children:"æéç¯å"}),(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-2",children:[(0,a.jsx)("div",{children:(0,a.jsx)(M.p,{type:"date",value:k,onChange:e=>A(e.target.value),required:!0})}),(0,a.jsx)("div",{children:(0,a.jsx)(M.p,{type:"date",value:C,onChange:e=>$(e.target.value),required:!0})})]}),(0,a.jsxs)("div",{className:"flex gap-2 mt-2",children:[(0,a.jsx)(T.$,{type:"button",variant:"outline",size:"sm",onClick:()=>eD(1),children:"æè¿1å¹´"}),(0,a.jsx)(T.$,{type:"button",variant:"outline",size:"sm",onClick:()=>eD(3),children:"æè¿3å¹´"}),(0,a.jsx)(T.$,{type:"button",variant:"outline",size:"sm",onClick:()=>eD(5),children:"æè¿5å¹´"}),(0,a.jsx)(T.$,{type:"button",variant:"outline",size:"sm",onClick:()=>eD(10),children:"æè¿10å¹´"})]})]}),(0,a.jsxs)("div",{className:"grid grid-cols-3 gap-2",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{children:"è²·å
¥æçºè²» (%)"}),(0,a.jsx)(M.p,{type:"number",value:(100*Number(V)).toFixed(4),onChange:e=>z((Number(e.target.value)/100).toString()),min:"0",max:"1",step:"0.0001"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{children:"è³£åºæçºè²» (%)"}),(0,a.jsx)(M.p,{type:"number",value:(100*Number(X)).toFixed(4),onChange:e=>K((Number(e.target.value)/100).toString()),min:"0",max:"1",step:"0.0001"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)(I.J,{children:"è³£åºäº¤æç¨
(%)"}),(0,a.jsx)(M.p,{type:"number",value:(100*Number(et)).toFixed(4),onChange:e=>er((Number(e.target.value)/100).toString()),min:"0",max:"1",step:"0.0001"})]})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)(_.S,{id:"enable-sound",checked:ei,onCheckedChange:e=>eo(!0===e)}),(0,a.jsx)(I.J,{htmlFor:"enable-sound",className:"font-normal",children:"åç¨é³ææé"})]}),(0,a.jsx)("div",{className:"flex gap-2",children:(0,a.jsx)(T.$,{type:"submit",className:"flex-1",disabled:t||!k||!C||"single"===d&&!p||"single"!==d&&0===eu.length,children:t?"å·è¡ä¸...":"å·è¡å測"})})]})})]})}var et=r(15203);function er({progress:e,onCancel:t}){let r=e.total>0?e.current/e.total*100:0;return(0,a.jsx)(S.Zp,{children:(0,a.jsx)(S.Wu,{className:"pt-6",children:(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between text-sm",children:[(0,a.jsx)("span",{className:"text-muted-foreground",children:e.message}),(0,a.jsxs)("span",{className:"font-medium",children:[Math.round(r),"%"]})]}),(0,a.jsx)(et.k,{value:r,className:"h-2"}),e.total>1&&(0,a.jsxs)("div",{className:"text-xs text-muted-foreground text-center",children:[e.current," / ",e.total]}),t&&(0,a.jsx)("div",{className:"flex justify-end pt-1",children:(0,a.jsx)(T.$,{type:"button",variant:"outline",size:"sm",onClick:t,children:"åæ¶"})})]})})})}var ea=r(41819),es=r(75020),en=r(92737),el=r(94430),ei=r(32326),eo=r(57321),ec=r(34071),ed=r(35617);function eu({performance:e,usConversionNote:t}){let r=[{title:"ç¸½å ±é
¬ç",value:`${e.totalReturn>=0?"+":""}${e.totalReturn.toFixed(2)}%`,icon:es.A,color:e.totalReturn>=0?"text-green-600":"text-red-600"},{title:"å¹´åå ±é
¬ç",value:`${e.annualizedReturn>=0?"+":""}${e.annualizedReturn.toFixed(2)}%`,icon:es.A,color:e.annualizedReturn>=0?"text-green-600":"text-red-600"},{title:"æå¤§åæ¤",value:`-${e.maxDrawdown.toFixed(2)}%`,icon:en.A,color:"text-red-600"},{title:"夿®æ¯ç",value:e.sharpeRatio.toFixed(2),icon:el.A,color:"text-blue-600",description:"è¡¡é風éªèª¿æ´å¾å ±é
¬ï¼æ¸å¼è¶é«è¡¨ç¤ºé¢¨éªå ±é
¬æ¯è¶å¥½ï¼é常 >1 çºä½³ï¼"},{title:"ç´¢æè«¾æ¯ç",value:e.sortinoRatio.toFixed(2),icon:ei.A,color:"text-purple-600",description:"é¡ä¼¼å¤æ®æ¯çï¼ä½åªèæ
®ä¸è¡é¢¨éªï¼æ´é©åè©ä¼°ä¸è·é¢¨éªï¼é常 >1 çºä½³ï¼"},{title:"æçµè³ç¢",value:(0,ed.C)(e.finalValue),icon:eo.A,color:"text-foreground"}];return(0,a.jsxs)("div",{className:"space-y-2",children:[t&&(0,a.jsx)("p",{className:"text-sm text-muted-foreground",children:"å«ç¾è¡é¨åå·²æç®çºæ°å°å¹£ï¼ä¾ç®åå¯çï¼"}),(0,a.jsx)("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:r.map((e,t)=>{let r=e.icon,s="description"in e&&e.description;return(0,a.jsxs)(S.Zp,{children:[(0,a.jsxs)(S.aR,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(S.ZB,{className:"text-sm font-medium",children:e.title}),s&&(0,a.jsx)(ea.m_,{content:(0,a.jsx)("p",{className:"max-w-xs",children:e.description}),children:(0,a.jsx)(ec.A,{className:"h-3.5 w-3.5 text-muted-foreground cursor-help"})})]}),(0,a.jsx)(r,{className:`h-4 w-4 ${e.color}`})]}),(0,a.jsx)(S.Wu,{children:(0,a.jsx)("div",{className:`text-2xl font-bold ${e.color}`,children:e.value})})]},t)})})]})}var em=r(87884),eh=r(18710),ef=r(99922);let eg=(0,eh.default)(async()=>(await r.e(7893).then(r.t.bind(r,67893,23))).default,{loadableGenerated:{webpack:()=>[67893]},ssr:!1});function ep({equityCurve:e,usConversionNote:t}){let{theme:r}=(0,ef.D)(),n=(0,s.useRef)(null);if((0,s.useEffect)(()=>{n.current?.chart&&n.current.chart.reflow()},[r]),(0,s.useEffect)(()=>{let e=n.current?.chart;if(!e)return;let t=e.container;if(!t)return;let r=!1,a=0,s=0,l=0,i=t=>{t.preventDefault();let r=e.xAxis[0];if(!r)return;let a=r.min,s=r.max,n=(a+s)/2,l=(s-a)*(t.deltaY>0?1.1:.9),i=r.dataMin,o=r.dataMax,c=(o-i)*.01,d=o-i;
1if(l>=c&&l<=d){let e=Math.max(i,n-l/2),t=Math.min(o,n+l/2);r.setExtremes(e,t,!0,!1)}},o=n=>{let i=e.xAxis[0];i&&(null!==i.min||null!==i.max)&&0===n.button&&(n.preventDefault(),r=!0,a=n.clientX,s=i.min||i.dataMin,l=i.max||i.dataMax,t.style.cursor="grabbing")},c=n=>{if(!r)return;n.preventDefault();let i=e.xAxis[0];if(!i)return;let o=n.clientX-a,c=l-s,d=i.dataMin,u=i.dataMax,m=o/(e.plotWidth||t.offsetWidth)*c,h=s-m,f=l-m;h>=d&&f<=u?i.setExtremes(h,f,!0,!1):h<d?i.setExtremes(d,d+c,!0,!1):f>u&&i.setExtremes(u-c,u,!0,!1)},d=()=>{r&&(r=!1,t.style.cursor="")},u=t=>{t.preventDefault(),t.stopPropagation();let r=e.xAxis[0];r&&(null!==r.min||null!==r.max)&&r.setExtremes(null,null,!0,!1)},m=e=>{1===e.button&&e.preventDefault()};return t.addEventListener("wheel",i,{passive:!1}),t.addEventListener("mousedown",o),t.addEventListener("mousemove",c),t.addEventListener("mouseup",d),t.addEventListener("mouseleave",d),t.addEventListener("dblclick",u),t.addEventListener("contextmenu",m),()=>{t.removeEventListener("wheel",i),t.removeEventListener("mousedown",o),t.removeEventListener("mousemove",c),t.removeEventListener("mouseup",d),t.removeEventListener("mouseleave",d),t.removeEventListener("dblclick",u),t.removeEventListener("contextmenu",m)}},[e.length]),0===e.length)return(0,a.jsxs)(S.Zp,{children:[(0,a.jsx)(S.aR,{children:(0,a.jsx)(S.ZB,{children:"æ·¨å¼æ²ç·å"})}),(0,a.jsx)(S.Wu,{children:(0,a.jsx)("div",{className:"text-center py-12 text-muted-foreground",children:"ç¡æ¸æå¯é¡¯ç¤º"})})]});let l={chart:{type:"line",backgroundColor:"transparent",height:400,resetZoomButton:null},title:{text:void 0},xAxis:{type:"datetime",title:{text:"æ¥æ"},labels:{format:"{value:%Y-%m-%d}"}},yAxis:{title:{text:"æ·¨å¼ (å
)"},labels:{format:"{value:,.0f}"}},tooltip:{shared:!0,xDateFormat:"%Y/%m/%d",headerFormat:"<b>{point.key}</b><br/>",pointFormat:"æ·¨å¼: {point.y:,.0f} å
<br/>"},plotOptions:{line:{enableMouseTracking:!0}},series:[{name:"æ·¨å¼",type:"line",data:e.map(e=>[new Date(e.date).getTime(),e.value]),color:"dark"===r?"#60a5fa":"#3b82f6",lineWidth:2}],legend:{enabled:!1},credits:{enabled:!1}};return(0,a.jsxs)(S.Zp,{children:[(0,a.jsxs)(S.aR,{className:"flex flex-row items-center justify-between",children:[(0,a.jsx)(S.ZB,{children:"æ·¨å¼æ²ç·å"}),(0,a.jsx)(T.$,{onClick:()=>{if(n.current?.chart){let e=n.current.chart.xAxis[0];e&&e.setExtremes(null,null,!0,!1)}},variant:"outline",size:"sm",type:"button",children:"é置縮æ¾"})]}),(0,a.jsxs)(S.Wu,{children:[(0,a.jsxs)("div",{className:"text-xs text-muted-foreground mb-2 space-y-1",children:[t&&(0,a.jsx)("p",{children:"å«ç¾è¡é¨åå·²æç®çºæ°å°å¹£ï¼ä¾ç®åå¯çï¼"}),(0,a.jsx)("p",{children:"æç¤ºï¼æ»¾åæ»é¼ 滾輪å¯ç¸®æ¾ X 軸ï¼ç¸®æ¾å¾å·¦éµæåå¯å¹³ç§»ï¼éæå¯éç½®"})]}),(0,a.jsx)(eg,{ref:n,highcharts:em.A,options:l})]})]})}var ex=r(2962);function ey({buyTrades:e,sellTrades:t,portfolio:r}){let s=[...e.map(e=>({...e,type:"buy"})),...t.map(e=>({...e,type:"sell"}))].sort((e,t)=>e.date.localeCompare(t.date)),n=s.some(e=>null!=e.symbol&&""!==e.symbol),l=r?new Map(r.map(e=>[e.symbol,e.market??"TW"])):null,i=null!=l&&Array.from(l.values()).some(e=>"US"===e);return 0===s.length?(0,a.jsxs)(S.Zp,{children:[(0,a.jsx)(S.aR,{children:(0,a.jsx)(S.ZB,{children:"交æè¨é"})}),(0,a.jsx)(S.Wu,{children:(0,a.jsx)("div",{className:"text-center py-12 text-muted-foreground",children:"ç¡äº¤æè¨é"})})]}):(0,a.jsxs)(S.Zp,{children:[(0,a.jsx)(S.aR,{children:(0,a.jsx)(S.ZB,{children:"交æè¨é"})}),(0,a.jsx)(S.Wu,{children:(0,a.jsxs)(ex.XI,{children:[(0,a.jsx)(ex.A0,{children:(0,a.jsxs)(ex.Hj,{children:[(0,a.jsx)(ex.nd,{children:"æ¥æ"}),n&&(0,a.jsx)(ex.nd,{children:"æ¨ç"}),i&&(0,a.jsx)(ex.nd,{children:"å¸å ´"}),(0,a.jsx)(ex.nd,{children:"é¡å"}),(0,a.jsx)(ex.nd,{children:"广 ¼"}),(0,a.jsx)(ex.nd,{children:"æ¸é"}),(0,a.jsx)(ex.nd,{children:"éé¡"}),(0,a.jsx)(ex.nd,{children:"æçºè²»/ç¨
"})]})}),(0,a.jsx)(ex.BF,{children:s.map((e,t)=>(0,a.jsxs)(ex.Hj,{children:[(0,a.jsx)(ex.nA,{children:new Date(e.date).toLocaleDateString("zh-TW")}),n&&(0,a.jsx)(ex.nA,{className:"text-muted-foreground",children:e.symbol??"â"}),i&&(0,a.jsx)(ex.nA,{className:"text-muted-foreground",children:e.symbol?l?.get(e.symbol)==="US"?"ç¾è¡":"å°è¡":"â"}),(0,a.jsx)(ex.nA,{children:(0,a.jsx)("span",{className:`px-2 py-1 rounded text-xs ${"buy"===e.type?"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200":"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200"}`,children:"buy"===e.type?"è²·å
¥":"è³£åº"})}
1),(0,a.jsx)(ex.nA,{children:e.price.toLocaleString("zh-TW")}),(0,a.jsx)(ex.nA,{children:e.quantity.toLocaleString("zh-TW")}),(0,a.jsx)(ex.nA,{children:"buy"===e.type?(0,ed.C)(e.cost):(0,ed.C)(e.revenue)}),(0,a.jsx)(ex.nA,{className:"text-muted-foreground",children:"buy"===e.type?(0,ed.C)(e.cost-e.quantity*e.price):(0,ed.C)(e.quantity*e.price-e.revenue)})]},`${e.date}-${e.symbol??""}-${t}`))})]})})]})}var ev=r(36093);function ej(){let{user:e}=(0,E.A)(),{isRunning:t,progress:r,results:c,error:d,currentConfig:u,runBacktest:m,cancel:h,reset:f}=function(){let[e,t]=(0,s.useState)(!1),[r,a]=(0,s.useState)(null),[n,l]=(0,s.useState)(null),[i,c]=(0,s.useState)(null),[d,u]=(0,s.useState)(null),m=(0,s.useRef)(null),h=(0,s.useCallback)(async r=>{if(e)return;let s=r.portfolio&&r.portfolio.length>0;t(!0),a(null),l(null),c(null),u(r),m.current=new AbortController;try{let e=3;if(a({current:0,total:e,message:s?"æ£å¨æ¥è©¢æè³çµåæ·å²å¹æ ¼...":"æ£å¨æ¥è©¢æ·å²å¹æ ¼æ¸æ..."}),s){let t=await C(r.portfolio,r.startDate,r.endDate,t=>{e=t.total+1,a({current:t.current,total:e,message:t.message})},m.current?.signal);if(m.current?.signal.aborted)return;let s=r.portfolio.filter(e=>t.has(e.symbol));if(0===s.length)throw Error("ç¡æ³åå¾ä»»ä½æ¨ççæ·å²å¹æ ¼æ¸æï¼è«æª¢æ¥æ¥æç¯åèæ¨ç");let n=b(s.map(e=>({...e,weight:e.weight}))),i={...r,portfolio:n};a({current:e-1,total:e,message:"æ£å¨è¨ç®åæ¸¬çµæ..."}),await new Promise((r,s)=>{requestAnimationFrame(()=>{(async()=>{try{let s,o=n.filter(e=>(e.market??"TW")==="TW"),c=n.filter(e=>"US"===e.market),d=o.reduce((e,t)=>e+t.weight,0),u=c.reduce((e,t)=>e+t.weight,0);if(0===c.length)s=p(i,t);else if(0===o.length){await (0,w.Y9)().catch(()=>{});let e=w.NZ.usd;if(!e||e<=0)throw Error("ç¡æ³åå¾ USD å¯çï¼è«ç¨å¾å試");let r=(0,w.v)(i.initialCapital,"usd"),a={...i,initialCapital:r};s={...s=p(a,t),performance:{...s.performance,finalValue:(0,w.A7)(s.performance.finalValue,"usd")},equityCurve:s.equityCurve.map(e=>({...e,value:(0,w.A7)(e.value,"usd"),cash:(0,w.A7)(e.cash,"usd"),holdings:(0,w.A7)(e.holdings,"usd")})),buyTrades:s.buyTrades.map(e=>({...e,cost:(0,w.A7)(e.cost,"usd"),revenue:(0,w.A7)(e.revenue,"usd")})),sellTrades:s.sellTrades.map(e=>({...e,cost:(0,w.A7)(e.cost,"usd"),revenue:(0,w.A7)(e.revenue,"usd")}))}}else{await (0,w.Y9)().catch(()=>{});let e=w.NZ.usd;if(!e||e<=0)throw Error("ç¡æ³åå¾ USD å¯çï¼è«ç¨å¾å試");let r=i.initialCapital*d,a=(0,w.v)(i.initialCapital*u,"usd"),n=new Map;o.forEach(e=>{let r=t.get(e.symbol);r&&n.set(e.symbol,r)});let l=new Map;c.forEach(e=>{let r=t.get(e.symbol);r&&l.set(e.symbol,r)});let m=b(o.map(e=>({...e,weight:e.weight}))),h=b(c.map(e=>({...e,weight:e.weight}))),f={...i,portfolio:m,initialCapital:r},x={...i,portfolio:h,initialCapital:a},y=p(f,n),v=p(x,l),j=(0,w.A7)(v.performance.finalValue,"usd"),N=new Map(y.equityCurve.map(e=>[e.date,e])),k=new Map(v.equityCurve.map(e=>[e.date,e])),A=Array.from(new Set([...N.keys(),...k.keys()])).sort().map(e=>{let t=N.get(e),r=k.get(e),a=t?.value??0,s=r?(0,w.A7)(r.value,"usd"):0;return{date:e,value:a+s,cash:(t?.cash??0)+(r?(0,w.A7)(r.cash,"usd"):0),holdings:(t?.holdings??0)+(r?(0,w.A7)(r.holdings,"usd"):0)}});s={buyTrades:[...y.buyTrades,...v.buyTrades.map(e=>({...e,cost:(0,w.A7)(e.cost,"usd"),revenue:(0,w.A7)(e.revenue,"usd")}))],sellTrades:[...y.sellTrades,...v.sellTrades.map(e=>({...e,cost:(0,w.A7)(e.cost,"usd"),revenue:(0,w.A7)(e.revenue,"usd")}))],equityCurve:A,performance:{...g(i.initialCapital,y.performance.finalValue+j,i.startDate,i.endDate,A),finalValue:y.performance.finalValue+j}}}l(s),a({current:e,total:e,message:"忏¬å®æ"}),r()}catch(e){s(e)}})()})})}else{if(!r.symbol)throw Error("è«é¸æè¡ç¥¨ä»£ç¢¼ææè³çµå");let t=r.market??"TW",s=await A(r.symbol,r.startDate,r.endDate,t=>{e=t.total+1,a({current:t.current,total:e,message:t.message})},t,m.current?.signal);if(m.current?.signal.aborted)return;a({current:e-1,total:e,message:"æ£å¨è¨ç®åæ¸¬çµæ..."}),await new Promise((n,i)=>{requestAnimationFrame(()=>{(async()=>{try{let i;if("US"===t){await (0,w.Y9)().catch(()=>{});let e=w.NZ.usd;if(!e||e<=0)throw Error("ç¡æ³åå¾ USD å¯çï¼è«ç¨å¾å試");let t=(0,w.v)(r.initialCapital,"usd"),a={...r,initialCapital:t,dcaConfig:r.dcaConfig?{...r.dcaConfig,monthlyAmount:(0,w.v)(r.dcaConfig.monthlyAmount,"usd")}:void 0};i={...i=x(a,s),performance:{...i.performance,finalValue:(0,w.A7)(i.performance.finalValue,"usd")},equityCurve:i.equityCurve.map(e=>({...e,value:(0,w.A7)(e.value,"usd"),cash:(0,w.A7)(e.cash,"usd"),holdings:(0,w.A7)(e.holdings,"usd")})),buyTrades:i.buyTrades.map(e=>({...e,cost:(0,w.A7)(e.cost,"usd"),revenue:(0,w.A7)(e.revenue,"usd")})),sellTrades:i.sellTrades.map(e=>({...e,cost:(0,w.A7)(e.cost,"usd"),revenue:(0,w.A7)(e.revenue,"usd")}))}}else i=x(r,s);l(i),a({current:e,total:e,message:"忏¬å®æ"}),n()}catch(e){i(e)}})()})})}{let e=function(){try{let e=localStorage.getItem(k.RZ);if(e){let t=JSON.parse(e);return{enabled:t.enabled??k.wK.enabled,categories:{alerts:t.categories?.alerts??k.wK.categories.alerts,tasks:t.categories?.tasks??k.wK.categories.tasks},volume:t.volume??k.wK.volume}}}catch(e){}return k.wK}();e.enabled&&e.categories.tasks&&!1!==r.enableSound&&N.jY.playSound("BACKTEST_COMPLETE",e).catch(e=>{})}}catch(e){if(m.current?.signal.aborted||e?.name==="AbortError")return void c("已忶忏¬");c(e instanceof Error?e.message:"忏¬å·è¡å¤±æ"),o.Cp(e instanceof Error?e:Error(String(e)),{level:"error",extra:{message:"忏¬å¤±æ",config:r},tags:{source:"useBacktest.runBacktest"}})}finally{t(!1),m.current=null}},[e]);return{isRunning:e,progress:r,results:n,error:i,currentConfig:d,runBacktest:h,cancel:(0,s.useCallback)(()=>{m.current&&m.current.abort(),t(!1),a(null)},[]),reset:(0,s.useCallback)(()=>{m.current&&m.current.abort(),t(!1),a(null),l(null),c(null),u(null)},[])}}
1(),[y,v]=(0,s.useState)(!1);(0,s.useEffect)(()=>{if(c&&u&&!y&&1){let e=u.portfolio&&u.portfolio.length>0,t=new CustomEvent("backtest-complete",{detail:{symbol:e?void 0:u.symbol,stockName:e?`æè³çµåï¼${u.portfolio.length} æªï¼`:u.stockName,totalReturn:c.performance.totalReturn}});window.dispatchEvent(t),v(!0)}},[c,u,y]);let j=async e=>{v(!1);try{await m(e)}catch(e){e instanceof Error&&(0,i.oR)({title:"忏¬å¤±æ",description:e.message||"å·è¡å測æç¼çé¯èª¤",variant:"destructive"})}};return(0,a.jsxs)("div",{className:"space-y-6",children:[(0,a.jsx)(ee,{onSubmit:j,isRunning:t}),r&&(0,a.jsx)(er,{progress:r,onCancel:t?h:void 0}),d&&(0,a.jsxs)(n.Fc,{variant:"destructive",children:[(0,a.jsx)(l.A,{className:"h-4 w-4"}),(0,a.jsx)(n.TN,{children:d})]}),c&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eu,{performance:c.performance,usConversionNote:u?.market==="US"||(u?.portfolio?.some(e=>"US"===e.market)??!1)}),(0,a.jsx)(ev.N,{renderFullscreenContent:()=>(0,a.jsx)("div",{className:"h-[70vh] min-h-[400px]",children:(0,a.jsx)(ep,{equityCurve:c.equityCurve,usConversionNote:u?.market==="US"||(u?.portfolio?.some(e=>"US"===e.market)??!1)})}),children:(0,a.jsx)(ep,{equityCurve:c.equityCurve,usConversionNote:u?.market==="US"||(u?.portfolio?.some(e=>"US"===e.market)??!1)})}),(0,a.jsx)(ey,{buyTrades:c.buyTrades,sellTrades:c.sellTrades,portfolio:u?.portfolio})]})]})}},27387:(e,t,r)=>{r.d(t,{x:()=>l});var a=r(57376),s=r(31615),n=r(30233);function l(e){let t=(0,s.useMemo)(()=>(0,n.l)(),[]),r=(0,s.useMemo)(()=>[],[]),l=(0,s.useMemo)(()=>[],[]),i=(0,s.useMemo)(()=>[],[]),o=(0,s.useMemo)(()=>[],[]),{data:c,error:d,isLoading:u,mutate:m}=(0,a.Ay)(e?["tx/accounts",e]:null,async([,e])=>{let r=await t.transactions.getAllAccounts(e);if(!r.ok)throw Error(r.error||"fetch_failed");return r.data||[]}),{data:h,error:f,isLoading:g,mutate:p}=(0,a.Ay)(e?["tx/monthlyBalances",e]:null,async([,e])=>{let r=await t.transactions.getMonthlyBalances(e);if(!r.ok)throw Error(r.error||"fetch_failed");return r.data||[]}),{data:x,error:y,isLoading:v}=(0,a.Ay)(e?["tx/investments",e]:null,async([,e])=>{let r=await t.transactions.getInvestments(e);if(!r.ok)throw Error(r.error||"fetch_failed");return r.data||[]}),{data:j,error:b,isLoading:w}=(0,a.Ay)(e?["tx/ruleSources",e]:null,async([,e])=>{let r=await t.transactions.getAllSourceAccountIdsWithRules(e);if(!r.ok)throw Error(r.error||"fetch_failed");return r.data||[]}),N=async(r,a)=>{if(!e)throw Error("missing_user");let s=await t.transactions.addOrUpdateMonthlyBalance(e,r,a);if(!s.ok)throw Error(s.error||"update_failed");await p()},k=async(r,a)=>{if(!e)throw Error("missing_user");let s=await t.transactions.addOrUpdateMonthlyBalance(e,r,a);if(!s.ok)throw Error(s.error||"update_failed")},A=async r=>{if(!e)throw Error("missing_user");let a=await t.transactions.commitMonthlyBalanceOps(e,r);if(!a.ok)throw Error(a.error||"commit_failed");await p()},C=async r=>{if(!e)throw Error("missing_user");let a=await t.transactions.commitMonthlyBalanceOps(e,r);if(!a.ok)throw Error(a.error||"commit_failed")},E=async()=>{await p()},S=async e=>{let r=await t.transactions.deleteMonthlyBalance(e);if(!r.ok)throw Error(r.error||"delete_failed");await p()},T=async r=>{if(!e)throw Error("missing_user");let a=await t.transactions.addOrUpdateMonthlyUnallocated(e,r);if(!a.ok)throw Error(a.error||"update_failed")},M=async r=>{if(!e)throw Error("missing_user");let a=await t.transactions.getMonthlyUnallocated(e,r);if(!a.ok)throw Error(a.error||"fetch_failed");return a.data||null};return{loading:u||g||v||w,error:d?.message||f?.message||y?.message||b?.message||null,accounts:c??r,monthlyBalances:h??l,investments:x??i,sourceAccountIdsWithRules:j??o,mutate:m,addOrUpdateMonthlyBalance:N,addOrUpdateMonthlyBalanceNoMutate:k,commitMonthlyBalanceOps:A,commitMonthlyBalanceOpsNoMutate:C,refreshMonthlyBalances:E,deleteMonthlyBalance:S,addOrUpdateMonthlyUnallocated:T,getMonthlyUnallocated:M}}},36093:(e,t,r)=>{r.d(t,{N:()=>c});var a=r(85047),s=r(69454),n=r(31615),l=r(42165),i=r(21410),o=r(34961);function c({children:e,renderFullscreenContent:t,className:r,disableClickToFullscreen:d=!1}
1){let[u,m]=(0,n.useState)(!1),h=(0,n.useRef)(null),f=(0,n.useRef)(null),g=(0,n.useCallback)(()=>m(!1),[]),p=(0,n.useCallback)(e=>{h.current?.contains(e.target)||g()},[g]);(0,n.useEffect)(()=>{if(!u)return;let e=e=>{"Escape"===e.key&&g()};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[u,g]),(0,n.useEffect)(()=>{u||f.current?.focus({preventScroll:!0})},[u]),(0,n.useEffect)(()=>{if(!u)return;let e=setTimeout(()=>{window.dispatchEvent(new CustomEvent("dashboard-columns-resized"))},100),t=setTimeout(()=>{window.dispatchEvent(new CustomEvent("dashboard-columns-resized"))},450);return()=>{clearTimeout(e),clearTimeout(t)}},[u]);let x=(0,n.useCallback)(()=>{u||"u">typeof document&&document.querySelector("[data-chart-fullscreen-overlay]")||m(!0)},[u]),y=u&&"u">typeof document?(0,a.jsxs)("div",{"data-chart-fullscreen-overlay":!0,className:"fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-4",role:"dialog","aria-modal":"true","aria-label":"å表å
¨è¢å¹æª¢è¦",children:[(0,a.jsx)("div",{className:"absolute inset-0 -z-10",onClick:p,onKeyDown:e=>"Escape"===e.key&&g(),"aria-hidden":"true"}),(0,a.jsxs)("div",{ref:h,className:(0,o.cn)("relative flex min-h-[70vh] max-h-[90vh] w-full max-w-[90vw] flex-col rounded-lg border bg-background shadow-lg","animate-in fade-in-0 zoom-in-95 duration-200"),children:[(0,a.jsx)(i.$,{type:"button",variant:"ghost",size:"icon",className:"absolute right-2 top-2 z-10 shrink-0 rounded-full text-muted-foreground hover:bg-muted hover:text-foreground",onClick:g,"aria-label":"éé",children:(0,a.jsx)(l.A,{className:"h-5 w-5"})}),(0,a.jsx)("div",{className:"flex min-h-0 flex-1 flex-col overflow-auto p-4 pt-12",children:(0,a.jsx)("div",{className:"flex min-h-[400px] flex-1 flex-col",children:t()})})]})]}):null;return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{ref:f,...d?{className:(0,o.cn)("pointer-events-none",r),"aria-hidden":!0}:{role:"button",tabIndex:0,className:(0,o.cn)("cursor-pointer outline-none",r),onClick:e=>{e.stopPropagation(),x()},onKeyDown:e=>{("Enter"===e.key||" "===e.key)&&(e.preventDefault(),e.stopPropagation(),x())}},children:e}),"u">typeof document&&null!=y?(0,s.createPortal)(y,document.body):null]})}},41819:(e,t,r)=>{r.d(t,{Bc:()=>i,m_:()=>o});var a=r(85047),s=r(31615),n=r(583),l=r(34961);let i=n.Kq;n.l9,n.UC;let o=s.forwardRef(({className:e,color:t="gray",children:r,content:s,open:o,onOpenChange:c,defaultOpen:d,delayDuration:u,...m},h)=>(0,a.jsx)(i,{delayDuration:u,children:(0,a.jsxs)(n.bL,{open:o,onOpenChange:c,defaultOpen:d,children:[(0,a.jsx)(n.l9,{asChild:!0,children:r}),(0,a.jsxs)(n.UC,{ref:h,className:(0,l.cn)("z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2","gray"===t&&"bg-gray-100 text-gray-900","red"===t&&"bg-red-100 text-red-900","blue"===t&&"bg-blue-100 text-blue-900","green"===t&&"bg-green-100 text-green-900","yellow"===t&&"bg-yellow-100 text-yellow-900","purple"===t&&"bg-purple-100 text-purple-900","pink"===t&&"bg-pink-100 text-pink-900","orange"===t&&"bg-orange-100 text-orange-900",e),...m,children:[s,(0,a.jsx)(n.i3,{className:"fill-popover"})]})]})}));o.displayName="Tooltip"},58678:(e,t,r)=>{r.d(t,{N:()=>l,Ux:()=>i,Xp:()=>u,ks:()=>c,wh:()=>d}),r(7492);var a=r(15418),s=r(35810);r(18654);let n=a.Ik({label:a.Yj(),value:a.Yj(),type:a.Yj()}),l=a.YO(n),i=a.Ik({price:a.ai(),currency:a.Yj(),change:a.ai(),changePercent:a.ai(),name:a.Yj().optional(),industry:a.Yj().optional(),timestamp:a.ai().optional(),marketState:a.Yj().optional()}),o=a.Ik({label:a.Yj(),value:a.Yj(),type:a.eu("Fund")}),c=a.YO(o),d=a.Ik({fundCode:a.Yj(),fundName:a.Yj(),currency:a.Yj(),nav:a.ai(),navDate:a.Yj()}),u=e=>a.Ik({data:e});a.Ik({bondCode:a.Yj(),bondName:a.Yj().optional().default(""),lastYield:a.Yj(),change:a.Yj(),highe
1st:a.Yj(),lowest:a.Yj(),volume:a.Yj(),lastClose:a.Yj(),time:a.Yj(),date:a.Yj()}),a.Ik({id:a.Yj(),userId:a.Yj().optional(),planId:a.Yj(),merchantTradeNo:a.Yj().optional().default(""),periodAmount:s.ai(),periodType:a.k5(["D","M","Y"]).optional(),frequency:s.ai().optional(),execTimes:s.ai().optional(),currentExecTimes:s.ai().optional(),status:a.Yj(),nextPaymentDate:a.KC([a.ai(),a.Yj(),a.p6()]).nullish()})},60996:(e,t,r)=>{r.d(t,{A:()=>n});var a=r(85047);let s=(0,r(18710).default)(async()=>(await r.e(7893).then(r.t.bind(r,67893,23))).default,{loadableGenerated:{webpack:()=>[67893]},ssr:!1,loading:()=>(0,a.jsx)("div",{style:{height:"100%",width:"100%",display:"flex",alignItems:"center",justifyContent:"center"},children:"è¼å
¥å表ä¸..."})});function n(e){let t={style:{height:"100%",width:"100%",...e?.containerProps?.style??{}},...e?.containerProps??{}};return(0,a.jsx)(s,{...e,containerProps:t})}},63955:(e,t,r)=>{r.d(t,{yD:()=>X,iY:()=>o.WL,Ub:()=>m,sC:()=>i,r_:()=>S}),r(21076);var a=r(57376),s=r(31615),n=r(30233),l=r(89088);function i(e){let t=(0,s.useMemo)(()=>(0,n.l)(),[]),r=(0,s.useMemo)(()=>[],[]),i=e?["investments/list",e]:null,{data:o,error:c,mutate:d}=(0,a.Ay)(i,async([,e])=>{let r=await t.investments.list(e);if(!r.ok)throw Error(r.error||"fetch_failed");return r.data||[]}),u=!e||void 0!==o||void 0!==c,m=async r=>{if(!e)throw Error("missing_user");let a=await t.investments.create(e,r);if(!a.ok)throw Error(a.error||"create_failed");return await d(),await (0,l.BS)(e),a.data},h=async(r,a)=>{let s=await t.investments.update(r,a);if(!s.ok)throw Error(s.error||"update_failed");await d(),await (0,l.BS)(e)},f=async r=>{let a=await t.investments.remove(r);if(!a.ok)throw Error(a.error||"delete_failed");await d(),await (0,l.BS)(e)};return{loading:!!e&&!u,error:c?.message||null,investments:o??r,mutate:d,create:m,update:h,remove:f}}var o=r(71467),c=r(99922);r(91595);var d=r(9409);r(82721);var u=r(43174);function m(e){let[t,r]=(0,s.useState)({}),[a,n]=(0,s.useState)(!1);return(0,s.useEffect)(()=>{let t=e.filter(e=>"stocks"===(0,u.GR)(e)&&e.symbol).map(e=>e.symbol);0===t.length?r({}):(n(!0),(0,d.L9)(t).then(r).catch(()=>r({})).finally(()=>n(!1)))},[e]),{industryMap:t,industryLoading:a}}var h=r(76458),f=r(24571),g=r(15418);let p=g.Ik({investmentId:g.Yj().min(1,"æè³é
ç® ID ä¸è½çºç©º"),targetPercentage:g.ai().min(0).max(100,"ç®æ¨æ¯ä¾å¿
é å¨ 0-100 ä¹é")}),x=g.Ik({type:g.eu("static"),items:g.YO(p),totalPercentage:g.ai().min(0).max(100).default(100)}),y=g.Ik({age:g.ai().int().positive("年齡å¿
é çºæ£æ´æ¸"),items:g.YO(p)}),v=g.Ik({type:g.eu("glide_path"),nodes:g.YO(y).min(2,"Glide Path è³å°éè¦ 2 åç¯é»"),interpolation:g.k5(["linear","step"]).default("linear")}),j=g.gM("type",[x,v]),b=g.Ik({userId:g.Yj().min(1,"userId ä¸è½çºç©º"),name:g.Yj().min(1,"å稱ä¸è½çºç©º"),description:g.Yj().optional(),targetAllocation:j,selectedInvestmentIds:g.YO(g.Yj()).min(1,"è³å°éè¦é¸æä¸åæè³é
ç®"),createdAt:g.bz().optional(),updatedAt:g.bz().optional()});function w(e){let t=e.reduce((e,t)=>e+t.targetPercentage,0);return t<=0?e.map(e=>({...e,targetPercentage:0})):1e-6>Math.abs(t-100)?e:e.map(e=>({...e,targetPercentage:e.targetPercentage/t*100}))}function N(e,t){if(!e.nodes.length)return[];let r=[...e.nodes].sort((e,t)=>e.age-t.age);if(t<=r[0].age)return w(r[0].items);if(t>=r[r.length-1].age)return w(r[r.length-1].items);if("linear"===e.interpolation){for(let e=0;e<r.length-1;e++)if(t>=r[e].age&&t<=r[e+1].age){let a=r[e+1].age-r[e].age,s=a>0?(t-r[e].age)/a:0;return function(e,t,r){let a=new Map(e.map(e=>[e.investmentId,e.targetPercentage])),s=new Map(t.map(e=>[e.investmentId,e.targetPercentage])),n=new Set([...a.keys(),...s.keys()]),l=[];for(let e of n){let t=a.get(e)??0,n=t+((s.get(e)??0)-t)*r;l.push({investmentId:e,targetPercentage:Math.max(0,Math.min(100,n))})}return w(l)}(r[e].items,r[e+1].items,s)}}for(let e=r.length-1;e>=0;e--)if(t>=r[e].age)return w(r[e].items);return w(r[0].items)}let k="rebalance_targets";function A(e){let t={};for(let[r,a]of Object.entries(e))void 0!==a&&("number"!=typeof a||Number.isFinite(a))&&(t[r]=a);return t}let C={async create(e,t){try{if(!e)return{ok:!1,error:"userId ä¸è½çºç©º"};let r={...t,userId:e,createdAt:f.Timestamp.now(),updatedAt:f.Timestamp.now()},a=b.parse(r),s=A(a),n=await (0,f.gS)((0,f.rJ)(h.db,k),s);return console.log("[rebalanceTargetsRepository] ç®æ¨é
置已建ç«ï¼ID:",n.id),{ok:!0,data:n.id}}catch(e){return{ok:!1,error:e?.message||"rebalance_target_create_failed"}}},async getTargets(e){try{let t=(0,f.P)((0,f.rJ)(h.db,k),(0,f._M)("userId","==",e),(0,f.My)("updatedAt","desc")),r=(await (0,f.GG)(t)).docs.map(e=>({id:e.id,...e.data()}));return{ok:!0,data:r}}catch(e){return{ok:!1,error:e?.message||"rebalance_targets_list_failed"}}},async getTarget(e){try{let t=(0,f.doc)(h.db,k,e),r=await (0,f.getDoc)(t);if(!r.exists())return{ok:!1,error:"rebalance_target_not_found"};let a={id:r.id,...r.data()};return{ok:!0,data:a}}catch(e){return{ok:!1,error:e?.message||"rebalance_target_get_failed"}}},async update(e,t){try{let r=(0,f.doc)(h.db,k,e);if(!(await (0,f.getDoc)(r)).exists())return{ok:!1,error:"rebalance_target_not_found"};let a={...t,updatedAt:f.Timestamp.now()},s=A(a);return await (0,f.mZ)(r,s),{ok:!0}}catch(e){return{ok:!1,error:e?.message||"rebalance_target_update_failed"}}},async delete(e){try{let t=(0,f.doc)(h.db,k,e);return await (0,f.kd)(t),{ok:!0}}catch(e){return{ok:!1,error:e?.message||"rebalance_target_delete_failed"}}},async getTargetForAge(e,t){try{let r=await this.getTarget(e);if(!r.ok||!r.data)return{ok:!1,error:r.error||"rebalance_target_not_found"};let a=r.data;if("static"===a.targetAllocation.type)return{ok:!0,data:a.targetAllocation.items};let s=a.targetAllocation;return{ok:!0,data:N(s,t)}}catch(e){return{ok:!1,error:e?.message||"glide_path_calculation_failed"}}}},E="rebalance_targets";
1function S(e){let[t,r]=(0,s.useState)([]),[a,n]=(0,s.useState)(!0),[l,i]=(0,s.useState)(null);(0,s.useEffect)(()=>{if(!e){r([]),n(!1);return}n(!0),i(null);let t=(0,f.P)((0,f.rJ)(h.db,E),(0,f._M)("userId","==",e),(0,f.My)("updatedAt","desc")),a=null,s=null;return a=(0,f.aQ)(t,e=>{try{let t=e.docs.map(e=>({id:e.id,...e.data()}));console.log("[useRebalanceTargets] ç£è½å¨æ´æ°ï¼ç®æ¨é
ç½®æ¸é:",t.length),r(t),i(null)}catch(e){console.error("[useRebalanceTargets] èçç£è½å¨æ¸æå¤±æ:",e),i(e?.message||"è¼å
¥å¤±æ")}finally{n(!1)}},t=>{console.error("[useRebalanceTargets] ç£è½å¨é¯èª¤:",t);let a=t?.code,l=t?.message||"",o=String(a||"");if("failed-precondition"===a||"9"===o||l.includes("index")||l.includes("requires an index")){let t;console.warn("[useRebalanceTargets] ç´¢å¼æªå°±ç·ï¼ä½¿ç¨åç¨æ¥è©¢ï¼ä¸ä½¿ç¨ orderByï¼"),t=(0,f.P)((0,f.rJ)(h.db,E),(0,f._M)("userId","==",e)),s=(0,f.aQ)(t,e=>{try{let t=e.docs.map(e=>({id:e.id,...e.data()}));t.sort((e,t)=>{let r=e.updatedAt?.toMillis?.()||e.updatedAt?.seconds*1e3||0;return(t.updatedAt?.toMillis?.()||t.updatedAt?.seconds*1e3||0)-r}),console.log("[useRebalanceTargets] åç¨æ¥è©¢æ´æ°ï¼ç®æ¨é
ç½®æ¸é:",t.length),r(t),i(null)}catch(e){console.error("[useRebalanceTargets] åç¨æ¥è©¢èç失æ:",e),i(e?.message||"è¼å
¥å¤±æ")}finally{n(!1)}},e=>{console.error("[useRebalanceTargets] åç¨æ¥è©¢é¯èª¤:",e),i(e?.message||"è¼å
¥å¤±æ"),n(!1)})}else i(t?.message||"è¼å
¥å¤±æ"),n(!1)}),()=>{a&&a(),s&&s()}},[e]);let o=(0,s.useCallback)(async()=>{if(!e)return void r([])},[e]),c=(0,s.useCallback)(async t=>{if(!e)throw Error("ç¨æ¶æªç»å
¥");let r=await C.create(e,t);if(r.ok)return r.data;throw Error(r.error||"建ç«å¤±æ")},[e]),d=(0,s.useCallback)(async(e,t)=>{let r=await C.update(e,t);if(r.ok);else throw Error(r.error||"æ´æ°å¤±æ")},[]);return{targets:t,loading:a,error:l,createTarget:c,updateTarget:d,deleteTarget:(0,s.useCallback)(async e=>{let t=await C.delete(e);if(t.ok);else throw Error(t.error||"åªé¤å¤±æ")},[]),getTargetForAge:(0,s.useCallback)(async(e,t)=>{let r=await C.getTargetForAge(e,t);if(r.ok&&r.data)return r.data;throw Error(r.error||"åå¾å¤±æ")},[]),refresh:o}}var T=r(85047);r(6386),r(25799);var M=r(82520),I=r(38187),D=r(21410);r(3208),r(47026);var _=r(27295),$=r(866),F=r(96968),P=r(21582),q=r(54296),R=r(42119),Y=r(39558);let W={conservative:{name:"ä¿å®å",description:"30% è¡ç¥¨ / 50% åµå¸ / 20% å
¶ä»",items:{stocks:30,bonds:50,funds:10,other:10}},balanced:{name:"平衡å",description:"50% è¡ç¥¨ / 30% åµå¸ / 20% å
¶ä»",items:{stocks:50,bonds:30,funds:15,other:5}},aggressive:{name:"ç©æ¥µå",description:"70% è¡ç¥¨ / 20% åµå¸ / 10% å
¶ä»",items:{stocks:70,bonds:20,funds:8,other:2}}};function B({investments:e,selectedInvestmentIds:t,targetAllocation:r,onSave:a,onCancel:n}){let[l,i]=(0,s.useState)(r?.type??"static"),[o,c]=(0,s.useState)(r?.type==="static"?r.items:[]),[d,u]=(0,s.useState)(r?.type==="glide_path"?r.nodes:[{age:30,items:[]},{age:65,items:[]}]),[m,h]=(0,s.useState)(r?.type==="glide_path"?r.interpolation:"linear"),[f,g]=(0,s.useState)(t);(0,s.useMemo)(()=>e.filter(e=>!f.includes(e.id)),[e,f]);let p=(0,s.useMemo)(()=>e.filter(e=>f.includes(e.id)),[e,f]),x=(0,s.useMemo)(()=>"static"===l?o.reduce((e,t)=>e+t.targetPercentage,0):0,[l,o]);return(0,T.jsxs)(M.Zp,{children:[(0,T.jsxs)(M.aR,{children:[(0,T.jsx)(M.ZB,{children:"ç®æ¨é
ç½®è¨å®"}),(0,T.jsx)(M.BT,{children:"è¨å®æè³çµåçç®æ¨é
ç½®æ¯ä¾"})]}),(0,T.jsxs)(M.Wu,{className:"space-y-6",children:[(0,T.jsxs)("div",{children:[(0,T.jsx)(F.J,{children:"鏿æè³é
ç®"}),(0,T.jsx)("div",{className:"mt-2 space-y-2 max-h-48 overflow-y-auto border rounded-md p-2",children:e.map(e=>(0,T.jsxs)("label",{className:"flex items-center space-x-2 cursor-pointer hover:bg-muted/50 p-2 rounded",children:[(0,T.jsx)("input",{type:"checkbox",checked:f.includes(e.id),onChange:()=>{var t;return t=e.id,void g(e=>e.includes(t)?e.filter(e=>e!==t):[...e,t])},className:"rounded"}),(0,T.jsxs)("span",{className:"text-sm",children:[e.name," (",e.symbol,")"]})]},e.id))})]}),(0,T.jsxs)("div",{children:[(0,T.jsx)(F.J,{children:"é
ç½®é¡å"}),(0,T.jsxs)(P.l6,{value:l,onValueChange:e=>i(e),children:[(0,T.jsx)(P.bq,{className:"mt-2",children:(0,T.jsx)(P.yv,{})}),(0,T.jsxs)(P.gC,{children:[(0,T.jsx)(P.eb,{value:"static",children:"éæ
é
ç½®"}),(0,T.jsx)(P.eb,{value:"glide_path",children:"Glide Pathï¼é¨å¹´é½¡è®åï¼"})]})]})]}),"static"===l&&(0,T.jsxs)("div",{className:"space-y-4",children:[(0,T.jsxs)("div",{className:"flex items-center justify-between",children:[(0,T.jsx)(F.J,{children:"ç®æ¨æ¯ä¾è¨å®"}),(0,T.jsx)("div",{className:"flex gap-2",children:Object.keys(W).map(e=>(0,T.jsx)(D.$,{variant:"outline",size:"sm",onClick:()=>(e=>{let t=W[e];if(!t)return;let r=[],a=100;for(let[e,s]of Object.entries(t.items)){let t=p.filter(t=>t.type===e);if(0===t.length)continue;let n=Math.round(s/t.length*10)/10;for(let e of t)r.push({investmentId:e.id,targetPercentage:n}),a-=n}if(a>0&&p.length>0){let e=Math.round(a/p.length*10)/10;for(let t of p){let a=r.find(e=>e.investmentId===t.id);a?a.targetPercentage=Math.round((a.targetPercentage+e)*10)/10:r.push({investmentId:t.id,targetPercentage:e})}}c(r)})(e),children:W[e].name},e))})]}),(0,T.jsx)("div",{className:"space-y-2",children:p.map(e=>
1{let t=o.find(t=>t.investmentId===e.id);return(0,T.jsxs)("div",{className:"flex items-center gap-4",children:[(0,T.jsx)(F.J,{className:"w-48",children:e.name}),(0,T.jsx)($.p,{type:"number",min:"0",max:"100",step:"0.1",value:t?.targetPercentage?t.targetPercentage.toFixed(1):"0.0",onChange:t=>{var r;let a;return r=e.id,a=Math.round(10*Math.max(0,Math.min(100,parseFloat(t.target.value)||0)))/10,void c(e=>e.find(e=>e.investmentId===r)?e.map(e=>e.investmentId===r?{...e,targetPercentage:a}:e):[...e,{investmentId:r,targetPercentage:a}])},className:"w-32"}),(0,T.jsx)("span",{className:"text-sm text-muted-foreground",children:"%"})]},e.id)})}),(0,T.jsxs)("div",{className:"text-sm text-muted-foreground",children:["總æ¯ä¾: ",x.toFixed(1),"%"]})]}),"glide_path"===l&&(0,T.jsxs)("div",{className:"space-y-4",children:[(0,T.jsxs)("div",{className:"flex items-center justify-between",children:[(0,T.jsx)(F.J,{children:"æå¼æ¹å¼"}),(0,T.jsxs)(P.l6,{value:m,onValueChange:e=>h(e),children:[(0,T.jsx)(P.bq,{className:"w-48",children:(0,T.jsx)(P.yv,{})}),(0,T.jsxs)(P.gC,{children:[(0,T.jsx)(P.eb,{value:"linear",children:"ç·æ§æå¼"}),(0,T.jsx)(P.eb,{value:"step",children:"鿢¯å¼"})]})]})]}),(0,T.jsx)("div",{className:"space-y-4",children:d.map((e,t)=>{let r=e.items.reduce((e,t)=>e+t.targetPercentage,0);return(0,T.jsxs)(M.Zp,{children:[(0,T.jsx)(M.aR,{className:"pb-3",children:(0,T.jsxs)("div",{className:"flex items-center justify-between",children:[(0,T.jsxs)(M.ZB,{className:"text-base",children:["年齡 ",e.age," æ²"]}),(0,T.jsxs)("div",{className:"flex items-center gap-2",children:[(0,T.jsx)($.p,{type:"number",min:"1",value:e.age,onChange:e=>{var r;return r={age:parseInt(e.target.value)||30},void u(e=>{let a=[...e];return a[t]={...a[t],...r},a.sort((e,t)=>e.age-t.age)})},className:"w-20"}),d.length>2&&(0,T.jsx)(D.$,{variant:"ghost",size:"sm",onClick:()=>{!(d.length<=2)&&u(e=>e.filter((e,r)=>r!==t))},children:(0,T.jsx)(q.A,{className:"h-4 w-4"})})]})]})}),(0,T.jsxs)(M.Wu,{className:"space-y-2",children:[p.map(r=>{let a=e.items.find(e=>e.investmentId===r.id);return(0,T.jsxs)("div",{className:"flex items-center gap-4",children:[(0,T.jsx)(F.J,{className:"w-48",children:r.name}),(0,T.jsx)($.p,{type:"number",min:"0",max:"100",step:"0.1",value:a?.targetPercentage?a.targetPercentage.toFixed(1):"0.0",onChange:e=>{var a;let s;return a=r.id,s=Math.round(10*Math.max(0,Math.min(100,parseFloat(e.target.value)||0)))/10,void u(e=>{let r=[...e],n=r[t];return n.items.find(e=>e.investmentId===a)?n.items=n.items.map(e=>e.investmentId===a?{...e,targetPercentage:s}:e):n.items=[...n.items,{investmentId:a,targetPercentage:s}],r})},className:"w-32"}),(0,T.jsx)("span",{className:"text-sm text-muted-foreground",children:"%"})]},r.id)}),(0,T.jsxs)("div",{className:"text-sm text-muted-foreground",children:["總æ¯ä¾: ",r.toFixed(1),"%"]})]})]},t)})}),(0,T.jsxs)(D.$,{variant:"outline",onClick:()=>{let e=Math.max(...d.map(e=>e.age),30);u(t=>[...t,{age:e+5,items:[]}].sort((e,t)=>e.age-t.age))},className:"w-full",children:[(0,T.jsx)(R.A,{className:"h-4 w-4 mr-2"}),"æ°å¢ç¯é»"]})]}),(0,T.jsxs)("div",{className:"flex justify-end gap-2",children:[n&&(0,T.jsx)(D.$,{variant:"outline",onClick:n,children:"åæ¶"}),(0,T.jsxs)(D.$,{onClick:()=>{let e;if(0===f.length)return void alert("è«è³å°é¸æä¸åæè³é
ç®");if("static"===l){if(Math.abs(x-100)>.15)return void alert(`總æ¯ä¾å¿
é çº 100%ï¼ç®åçº ${x.toFixed(1)}%`);let t=[...o];if(t.length>0){let e=100-t.reduce((e,t)=>e+t.targetPercentage,0);if(Math.abs(e)>.05){let r=t[t.length-1];r.targetPercentage=Math.round((r.targetPercentage+e)*10)/10,r.targetPercentage=Math.max(0,Math.min(100,r.targetPercentage))}}e={type:"static",items:t,totalPercentage:100}}else{if(d.length<2)return void alert("Glide Path è³å°éè¦ 2 åç¯é»");try{let t=d.map(e=>{let t=e.items.reduce((e,t)=>e+t.targetPercentage,0);if(Math.abs(t-100)>.15)throw alert(`ç¯é»å¹´é½¡ ${e.age} ç總æ¯ä¾å¿
é çº 100%ï¼ç®åçº ${t.toFixed(1)}%`),Error(`ç¯é»å¹´é½¡ ${e.age} ç總æ¯ä¾å¿
é çº 100%ï¼ç®åçº ${t.toFixed(1)}%`);let r=[...e.items];if(r.length>0){let e=100-t;if(Math.abs(e)>.05){let t=r[r.length-1];t.targetPercentage=Math.round((t.targetPercentage+e)*10)/10,t.targetPercentage=Math.max(0,Math.min(100,t.targetPercentage))}}return{...e,items:r}});e={type:"glide_path",nodes:t,interpolation:m}}catch(e){return}}a(e,f)},children:[(0,T.jsx)(Y.A,{className:"h-4 w-4 mr-2"}),"å²å"]}
1)]})]})]})}var O=r(87884),U=r(60996);function L({glidePath:e,investments:t,currentAge:r}){let{theme:a}=(0,c.D)(),n=(0,s.useMemo)(()=>{let e=new Map;return t.forEach(t=>e.set(t.id,t)),e},[t]),l=(0,s.useMemo)(()=>{let t=[...e.nodes].sort((e,t)=>e.age-t.age),r=t[0].age,a=t[t.length-1].age,s=new Set;t.forEach(e=>{e.items.forEach(e=>s.add(e.investmentId))});let l=[];for(let i of s){let s=n.get(i);if(!s)continue;let o=[];if("linear"===e.interpolation)for(let t=r;t<=a;t++){let r=N(e,t).find(e=>e.investmentId===i);o.push([t,r?.targetPercentage??0])}else t.forEach(e=>{let t=e.items.find(e=>e.investmentId===i);o.push([e.age,t?.targetPercentage??0])});l.push({type:"line",name:s.name,data:o})}return l},[e,n]),i=(0,s.useMemo)(()=>{let t="dark"===a;return{chart:{type:"line",backgroundColor:"transparent",height:400},title:{text:void 0},xAxis:{title:{text:"年齡"},min:Math.min(...e.nodes.map(e=>e.age))-5,max:Math.max(...e.nodes.map(e=>e.age))+5,plotLines:r?[{value:r,color:t?"#ef4444":"#dc2626",width:2,dashStyle:"Dash",label:{text:`ç¶å年齡: ${r} æ²`,align:"right",style:{color:t?"#ef4444":"#dc2626"}}}]:void 0},yAxis:{title:{text:"ç®æ¨æ¯ä¾ (%)"},min:0,max:100},tooltip:{shared:!0,useHTML:!0,headerFormat:"<b>年齡 {point.key} æ²</b><br/>",pointFormat:'<span style="color:{series.color}">â</span> {series.name}: {point.y:.1f}%<br/>'},plotOptions:{line:{marker:{enabled:!0,radius:4},lineWidth:2}},series:l,legend:{enabled:!0,layout:"vertical",align:"right",verticalAlign:"middle"},credits:{enabled:!1}}},[l,a,r,e.nodes]);return 0===e.nodes.length?(0,T.jsxs)(M.Zp,{children:[(0,T.jsx)(M.aR,{children:(0,T.jsx)(M.ZB,{children:"Glide Path è¦è¦ºå"})}),(0,T.jsx)(M.Wu,{children:(0,T.jsx)("div",{className:"flex items-center justify-center h-96 text-muted-foreground",children:"æ²æå¯é¡¯ç¤ºçæ¸æ"})})]}):(0,T.jsxs)(M.Zp,{children:[(0,T.jsx)(M.aR,{children:(0,T.jsx)(M.ZB,{children:"Glide Path è¦è¦ºå"})}),(0,T.jsx)(M.Wu,{children:(0,T.jsx)("div",{className:"w-full h-96",children:(0,T.jsx)(U.A,{highcharts:O.A,options:i})})})]})}var J=r(30554),V=r(30155),z=r(35617);let Z={full:"å®å
¨å平衡",buy_only:"å
è²·å
¥çç¥",gradual:"漸é²å¼å平衡"};function G({plan:e,investments:t}){let{theme:r}=(0,c.D)(),a=(0,s.useMemo)(()=>{let e=new Map;return t.forEach(t=>e.set(t.id,t)),e},[t]),n=(0,s.useMemo)(()=>{let t=[],r=[],s=[];for(let n of Object.keys(e.beforeAllocation)){let l=e.beforeAllocation[n]??0,i=e.afterAllocation[n]??0;if(l>0||i>0){let o=e.adjustments.find(e=>e.investmentId===n),c=o?.investmentName||a.get(n)?.name||`æè³é
ç® ${n.slice(0,8)}`;t.push(c),r.push(l),s.push(i)}}return{categories:t,beforeData:r,afterData:s}},[e,a]),l=(0,s.useMemo)(()=>{let e="dark"===r;return{chart:{type:"column",backgroundColor:"transparent",height:300},title:{text:void 0},xAxis:{categories:n.categories,title:{text:"æè³é
ç®"}},yAxis:{title:{text:"é
ç½®æ¯ä¾ (%)"},min:0,max:100},tooltip:{shared:!0,useHTML:!0,headerFormat:"<b>{point.key}</b><br/>",pointFormat:'<span style="color:{series.color}">â</span> {series.name}: {point.y:.1f}%<br/>'},plotOptions:{column:{grouping:!1,pointPadding:.2,borderWidth:0}},series:[{type:"column",name:"å平衡å",data:n.beforeData,color:e?"#6b7280":"#9ca3af"},{type:"column",name:"å平衡å¾",data:n.afterData,color:e?"#3b82f6":"#2563eb"}],credits:{enabled:!1}}},[n,r]),i=e.totalBuyAmount-e.totalSellAmount;return(0,T.jsxs)(M.Zp,{children:[(0,T.jsx)(M.aR,{children:(0,T.jsxs)("div",{className:"flex items-center justify-between",children:[(0,T.jsx)(M.ZB,{children:Z[e.strategy]||e.strategy}),(0,T.jsxs)(I.E,{variant:"outline",children:["總å¹å¼: ",(0,z.C)(e.totalValue)]})]})}),(0,T.jsxs)(M.Wu,{className:"space-y-4",children:[(0,T.jsx)("div",{className:"w-full h-80",children:(0,T.jsx)(U.A,{highcharts:O.A,options:l})}),(0,T.jsxs)("div",{children:[(0,T.jsx)("h4",{className:"font-semibold mb-2",children:"ææ¬æç´°"}),(0,T.jsxs)("div",{className:"space-y-2",children:[(0,T.jsxs)("div",{className:"flex items-center justify-between text-sm",children:[(0,T.jsx)("span",{className:"text-muted-foreground",children:"總買å
¥éé¡"}),(0,T.jsxs)("span",{className:"text-green-600 flex items-center gap-1",children:[(0,T.jsx)(J.A,{className:"h-4 w-4"}),(0,z.C)(e.totalBuyAmount)]})]}),"buy_only"===e.strategy&&e.totalBuyAmount>0&&(0,T.jsxs)("p",{className:"text-xs text-muted-foreground",children:["å
è²·å
¥çç¥éé¡å¤æå
¥ç¾éç´ ",(0,z.C)(e.totalBuyAmount)]}),(0,T.jsxs)("div",{className:"flex items-center justify-between text-sm",children:[(0,T.jsx)("span",{className:"text-muted-foreground",children:"總賣åºéé¡"}),(0,T.jsxs)("span",{className:"text-red-600 flex items-center gap-1",children:[(0,T.jsx)(V.A,{className:"h-4 w-4"}),(0,z.C)(e.totalSellAmount)]})]}),(0,T.jsxs)("div",{className:"flex items-center justify-between text-sm font-semibold pt-2 border-t",children:[(0,T.jsx)("span",{children:"淨調æ´éé¡"}),(0,T.jsxs)("span",{className:i>=0?"text-green-600":"text-red-600",children:[i>=0?"+":"",(0,z.C)(Math.abs(i))]})]})]})]}),(0,T.jsxs)("div",{children:[(0,T.jsx)("h4",{className:"font-semibold mb-2",children:"調æ´å»ºè°"}),(0,T.jsx)("div",{className:"space-y-2 max-h-64 overflow-y-auto",children:0===e.adjustments.length?(0,T.jsx)("p",{className:"text-sm text-muted-foreground",children:"ç¡é調æ´"}):e.adjustments.map(e=>{let t=e.adjustmentAmount>0,r=Math.abs(e.adjustmentAmount);return(0,T.jsxs)("div",{className:"flex items-center justify-between p-2 rounded border",children:[(0,T.jsxs)("div",{className:"flex-1",children:[(0,T.jsx)("div",{className:"font-medium text-sm",children:e.investmentName}),(0,T.jsxs)("div",{className:"text-xs text-muted-foreground",children:[e.currentPercentage.toFixed(1),"% â ",e.targetPercentage.toFixed(1),"%"]})]}),(0,T.jsxs)("div",{className:"flex flex-col items-end gap-1",children:[(0,T.jsx)("div",{className:"flex items-center gap-2",children:t?(0,T.jsxs)(I.E,{variant:"outline",className:"text-green-600 border-green-600",children:[(0,T.jsx)(J.A,{className:"h-3 w-3 mr-1"}),"è²·å
¥ ",(0,z.C)(r)]}):(0,T.jsxs)(I.E,{variant:"outline",className:"text-red-600 border-red-600",children:[(0,T.jsx)(V.A,{className:"h-3 w-3 mr-1"}),"è³£åº ",(0,z.C)(r)]})}),e.taxImpact&&e.taxImpact>0&&(0,T.jsxs)("div",{className:"text-xs text-orange-600",children:["ä¼°è¨ç¨
è² ï¼ç¤ºæï¼: ",(0,z.C)(e.taxImpact)]})]})]},e.investmentId)})})]}),e.minTransactionThreshold>0&&(0,T.jsxs)("div",{className:"text-xs text-muted-foreground",children:["æå°äº¤æéé¡: ",(0,z.C)(e.minTransactionThreshold)]})]})]})}var H=r(18534);function X({investments:e,targets:t,onTargetCreate:r,onTargetUpdate:a,onTargetDelete:n,currentAge:l}){var i;
1let[o,c]=(0,s.useState)(""),[d,u]=(0,s.useState)(!1),[m,h]=(0,s.useState)(null),[f,g]=(0,s.useState)(""),[p,x]=(0,s.useState)(""),[y,v]=(0,s.useState)(!0),j=(0,s.useMemo)(()=>t.find(e=>e.id===o)??null,[t,o]);(0,s.useEffect)(()=>{o&&!t.find(e=>e.id===o)&&c("")},[t,o]);let[b,w]=(0,s.useState)(null),k=(0,s.useRef)(null);(0,s.useEffect)(()=>{b&&t.find(e=>e.id===b)&&(c(b),w(null),k.current=null)},[t,b]);let A=(i=j?.targetAllocation.type==="glide_path"?j.targetAllocation:null,i&&null!=l&&Number.isFinite(l)?N(i,l):null),C=(0,s.useMemo)(()=>{let t;if(!j)return[];let r={considerTax:y};if("glide_path"===j.targetAllocation.type){if(!A)return[];t=A}else t=j.targetAllocation.items;return["full","buy_only","gradual"].map(a=>(function(e,t,r,a={}){let s,n,l=a.gradualProgress??.5,i=a.considerTax??!0,o=t.map(e=>e.investmentId),c=e.filter(e=>o.includes(e.id)),d=0===(n=(s=e.filter(e=>o.includes(e.id))).reduce((e,t)=>e+(0,_.Vx)({quantity:t.quantity,price:t.price,currency:t.currency}),0))?[]:s.map(e=>{let t=(0,_.Vx)({quantity:e.quantity,price:e.price,currency:e.currency});return{investmentId:e.id,investmentName:e.name,value:t,percentage:n>0?t/n*100:0}}),u=d.reduce((e,t)=>e+t.value,0);if(0===u){var m;return m=r,{strategy:m,totalValue:u,adjustments:[],beforeAllocation:{},afterAllocation:{},totalBuyAmount:0,totalSellAmount:0,minTransactionThreshold:0}}let h=new Map(t.map(e=>[e.investmentId,e.targetPercentage])),f=[];for(let e of d){let t,a=h.get(e.investmentId)??0,s=u*a/100,n=s-e.value,o=n;"buy_only"===r&&n<0?o=0:"gradual"===r&&(o=n*l);let d=c.find(t=>t.id===e.investmentId);if(!d)continue;let m=d.price,g=d.currency,p=(0,_.Vx)({quantity:1,price:m,currency:g}),x=p>0?o/p:0;if(o<0&&i){let e=(0,_.uL)({quantity:Math.abs(x),price:m,currency:g,averageCost:d.averageCost,totalCost:d.totalCost,purchasePrice:d.purchasePrice});e.profitLoss>0&&(t=.2*e.profitLoss)}f.push({investmentId:e.investmentId,investmentName:e.investmentName,currentValue:e.value,currentPercentage:e.percentage,targetValue:s,targetPercentage:a,adjustmentAmount:o,adjustmentQuantity:x,taxImpact:t})}let g=f.filter(e=>Math.abs(e.adjustmentAmount)>=1),p=i?[...g].sort((e,t)=>e.adjustmentAmount<0&&t.adjustmentAmount>=0?-1:e.adjustmentAmount>=0&&t.adjustmentAmount<0?1:e.adjustmentAmount<0&&t.adjustmentAmount<0?(e.taxImpact??0)-(t.taxImpact??0):Math.abs(t.adjustmentAmount)-Math.abs(e.adjustmentAmount)):g,x=u+p.reduce((e,t)=>e+t.adjustmentAmount,0),y={};for(let e of d){let t=p.find(t=>t.investmentId===e.investmentId);if(t){let r=e.value+t.adjustmentAmount;y[e.investmentId]=x>0?r/x*100:0}else y[e.investmentId]=x>0?e.value/x*100:e.percentage}let v=p.filter(e=>e.adjustmentAmount>0).reduce((e,t)=>e+t.adjustmentAmount,0),j=p.filter(e=>e.adjustmentAmount<0).reduce((e,t)=>e+Math.abs(t.adjustmentAmount),0),b={};for(let e of d)b[e.investmentId]=e.percentage;return{strategy:r,totalValue:u,adjustments:p,beforeAllocation:b,afterAllocation:y,totalBuyAmount:v,totalSellAmount:j,minTransactionThreshold:0}})(e,t,a,r))},[j,e,y,A]),E=async(e,a)=>{let s={name:f.trim()||`ç®æ¨é
ç½® ${t.length+1}`,description:p.trim()||void 0,targetAllocation:e,selectedInvestmentIds:a};try{let e=await r(s);u(!1),g(""),x(""),e&&(w(e),k.current=e,setTimeout(()=>{k.current===e&&(c(e),w(null),k.current=null)},5e3))}catch{w(null),k.current=null}},S=async(e,t)=>{m&&(await a(m.id,{name:f.trim()||m.name,description:p.trim()||void 0,targetAllocation:e,selectedInvestmentIds:t}),u(!1),h(null))},I=async()=>{j&&confirm(`確å®è¦åªé¤ã${j.name}ãåï¼`)&&(await n(j.id),c(""))};return(0,T.jsxs)("div",{className:"space-y-6",children:[(0,T.jsxs)(M.Zp,{children:[(0,T.jsx)(M.aR,{children:(0,T.jsxs)("div",{className:"flex items-center justify-between",children:[(0,T.jsx)(M.ZB,{children:"ç®æ¨é
ç½®"}),(0,T.jsxs)(D.$,{variant:"outline",size:"sm",onClick:()=>{h(null),g(""),x(""),u(!0)},children:[(0,T.jsx)(R.A,{className:"h-4 w-4 mr-2"}),"æ°å¢é
ç½®"]})]})}),(0,T.jsxs)(M.Wu,{className:"space-y-4",children:[(0,T.jsxs)("div",{children:[(0,T.jsx)(F.J,{children:"é¸æç®æ¨é
ç½®"}),(0,T.jsxs)(P.l6,{value:o,onValueChange:c,children:[(0,T.jsx)(P.bq,{className:"mt-2",children:(0,T.jsx)(P.yv,{placeholder:"è«é¸æç®æ¨é
ç½®"})}),(0,T.jsx)(P.gC,{children:0===t.length?(0,T.jsx)("div",{className:"px-2 py-1.5 text-sm text-muted-foreground",children:"æ«ç¡ç®æ¨é
ç½®"}):t.map(e=>(0,T.jsx)(P.eb,{value:e.id,children:e.name},e.id))})]},t.length)]}),j&&(0,T.jsxs)("div",{className:"flex gap-2",children:[(0,T.jsx)(D.$,{variant:"outline",size:"sm",onClick:()=>{j&&(h(j),g(j.name),x(j.description||""),u(!0))},children:"編輯"}),(0,T.jsx)(D.$,{variant:"outline",size:"sm",onClick:I,children:"åªé¤"})]}),j?.targetAllocation.type==="glide_path"&&(0,T.jsx)(L,{glidePath:j.targetAllocation,investments:e,currentAge:l})]})]}),j&&(0,T.jsxs)(M.Zp,{children:[(0,T.jsx)(M.aR,{children:(0,T.jsx)(M.ZB,{children:"è¨ç®é¸é
"})}),(0,T.jsxs)(M.Wu,{className:"space-y-4",children:[(0,T.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,T.jsx)("input",{type:"checkbox",id:"considerTax",checked:y,onChange:e=>v(e.target.checked),className:"rounded"}),(0,T.jsx)(F.J,{htmlFor:"considerTax",className:"cursor-pointer",children:"èæ
®ç¨
åå½±é¿ï¼æåºï¼"})]}),(0,T.jsx)("p",{className:"text-xs text-muted-foreground",children:"åç¨å¾æä¾ä¼°è¨ç¨
è² ï¼åè¨ç²å©\xd720%ï¼æåºè³£åºåªå
é åºï¼ä¸æèª¿æ´å»ºè°è²·è³£éé¡ã"})]})]}),j&&(0,T.jsxs)("div",{children:[(0,T.jsx)("h3",{className:"text-lg font-semibold mb-4",children:"åå¹³è¡¡æ¹æ¡æ¯è¼"}),0===C.length?(0,T.jsx)(M.Zp,{children:(0,T.jsx)(M.Wu,{className:"py-6",children:(0,T.jsx)("p",{className:"text-center text-sm text-muted-foreground",children:"ç¡æ³è¨ç®åå¹³è¡¡æ¹æ¡ãè«ç¢ºèªå·²é¸ææè³é
ç®ä¸ç®æ¨é
置已è¨å®ã"})})}):(0,T.jsx)("div",{className:"grid gap-4 md:grid-cols-3",children:C.map(t=>(0,T.jsx)(G,{plan:t,investments:e},t.strategy))})]}),(0,T.jsx)(H.lG,{open:d,onOpenChange:u,children:(0,T.jsxs)(H.Cf,{className:"max-w-2xl max-h-[90vh] overflow-y-auto",children:[(0,T.jsxs)(H.c7,{children:[(0,T.jsx)(H.L3,{children:m?"ç·¨è¼¯ç®æ¨é
ç½®":"æ°å¢ç®æ¨é
ç½®"}),(0,T.jsx)(H.rr,{children:"è¨å®æè³çµåçç®æ¨é
ç½®æ¯ä¾"})]}),(0,T.jsxs)("div",{className:"space-y-4",children:[(0,T.jsxs)("div",{children:[(0,T.jsx)(F.J,{children:"å稱"}),(0,T.jsx)($.p,{value:f,onChange:e=>
1g(e.target.value),placeholder:"ä¾å¦ï¼éä¼çµå",className:"mt-1"})]}),(0,T.jsxs)("div",{children:[(0,T.jsx)(F.J,{children:"æè¿°ï¼é¸å¡«ï¼"}),(0,T.jsx)($.p,{value:p,onChange:e=>x(e.target.value),placeholder:"ç°¡ç說æ",className:"mt-1"})]}),(0,T.jsx)(B,{investments:e,targetAllocation:m?.targetAllocation??null,selectedInvestmentIds:m?.selectedInvestmentIds??[],onSave:m?S:E,onCancel:()=>{u(!1),h(null)}})]})]})})]})}},71467:(e,t,r)=>{r.d(t,{WL:()=>c,_m:()=>i,bm:()=>o});var a=r(31615),s=r(43174),n=r(47026),l=r(10055);function i(e){return(0,a.useMemo)(()=>{let t=new Map;return e.forEach(e=>{let r=(0,l.jU)({quantity:e.quantity||0,price:e.price||0}),a=(0,n.A7)(r,(0,n.WC)(e.currency||"twd")),i=(0,s.GR)(e),{name:o,color:c}=(0,s.H0)(i);t.has(o)?t.get(o).y+=a:t.set(o,{name:o,y:a,color:c})}),Array.from(t.values()).sort((e,t)=>t.y-e.y)},[e])}function o(e,t){return(0,a.useMemo)(()=>{if(!Array.isArray(e)||0===e.length||!Array.isArray(t)||0===t.length)return[];let r=new Map;t.forEach(e=>r.set(e.id,e.name||e.id));let a=new Map;return e.forEach(e=>{let t=e.accountId||"unknown",s=r.get(t)||t,i=(0,l.jU)({quantity:e.quantity||0,price:e.price||0}),o=(0,n.A7)(i,(0,n.WC)(e.currency||"twd"));a.has(s)?a.get(s).y+=o:a.set(s,{name:s,y:o})}),Array.from(a.values()).sort((e,t)=>t.y-e.y)},[e,t])}function c(e,t){return(0,a.useMemo)(()=>{let r=e.filter(e=>"stocks"===(0,s.GR)(e)&&e.symbol);if(0===r.length)return[];let a=new Map;return r.forEach(e=>{let r=t[e.symbol]||"å
¶ä»",s=r&&String(r).trim()?String(r).trim():"å
¶ä»",i=(0,l.jU)({quantity:e.quantity||0,price:e.price||0}),o=(0,n.A7)(i,(0,n.WC)(e.currency||"twd"));a.has(s)?a.get(s).y+=o:a.set(s,{name:s,y:o,color:void 0})}),Array.from(a.values()).sort((e,t)=>t.y-e.y)},[e,t])}},82721:(e,t,r)=>{r.d(t,{dj:()=>u,oR:()=>d});var a=r(31615);let s=0,n=new Map,l=e=>{if(n.has(e))return;let t=setTimeout(()=>{n.delete(e),c({type:"REMOVE_TOAST",toastId:e})},1e6);n.set(e,t)},i=[],o={toasts:[]};function c(e){o=((e,t)=>{switch(t.type){case"ADD_TOAST":return{...e,toasts:[t.toast,...e.toasts].slice(0,1)};case"UPDATE_TOAST":return{...e,toasts:e.toasts.map(e=>e.id===t.toast.id?{...e,...t.toast}:e)};case"DISMISS_TOAST":{let{toastId:r}=t;return r?l(r):e.toasts.forEach(e=>{l(e.id)}),{...e,toasts:e.toasts.map(e=>e.id===r||void 0===r?{...e,open:!1}:e)}}case"REMOVE_TOAST":if(void 0===t.toastId)return{...e,toasts:[]};return{...e,toasts:e.toasts.filter(e=>e.id!==t.toastId)}}})(o,e),i.forEach(e=>{e(o)})}function d({...e}){let t=(s=(s+1)%Number.MAX_SAFE_INTEGER).toString(),r=()=>c({type:"DISMISS_TOAST",toastId:t});return c({type:"ADD_TOAST",toast:{...e,id:t,open:!0,onOpenChange:e=>{e||r()}}}),{id:t,dismiss:r,update:e=>c({type:"UPDATE_TOAST",toast:{...e,id:t}})}}function u(){let[e,t]=a.useState(o);return a.useEffect(()=>(i.push(t),()=>{let e=i.indexOf(t);e>-1&&i.splice(e,1)}),[e]),{...e,toast:d,dismiss:e=>c({type:"DISMISS_TOAST",toastId:e})}}},87884:(e,t,r)=>{let a;r.d(t,{A:()=>n});try{a=r(29744);let e=r(4442),t=r(46944),n=r(96846),l=r(79093),i=r(59704),o=r(11647),c=r(59667),d=r(90749),u=r(45913);function s(e){return"function"==typeof e?e(a):e&&"function"==typeof e.default?e.default(a):void 0}s(e),s(t),s(n),s(l),s(i),s(o),s(c),s(d),s(u),a.setOptions({exporting:{enabled:!1,fallbackToExportServer:!1,chartOptions:{chart:{backgroundColor:"transparent"}}}})}catch(e){a={setOptions:()=>{},version:"fallback"}}let n=a},91595:(e,t,r)=>{function a(e,t){let r=e.trim();if(!r)return t;let a=r.split(/\s+/).filter(Boolean);return a.length>=3?`hsl(${a[0]}, ${a[1]}, ${a[2]})`:`hsl(${r})`}function s(){let e=getComputedStyle(document.documentElement),t={chart1:a(e.getPropertyValue("--chart-1"),"hsl(12, 76%, 61%)"),chart2:a(e.getPropertyValue("--chart-2"),"hsl(173, 58%, 39%)"),chart3:a(e.getPropertyValue("--chart-3"),"hsl(197, 37%, 24%)"),chart4:a(e.getPropertyValue("--chart-4"),"hsl(43, 74%, 66%)"),chart5:a(e.getPropertyValue("--chart-5"),"hsl(27, 87%, 67%)"),text:a(e.getPropertyValue("--foreground"),"hsl(0, 0%, 3.9%)"),border:a(e.getPropertyValue("--border"),"hsl(0, 0%, 89.8%)"),background:a(e.getPropertyValue("--background"),"hsl(0, 0%, 100%)"),muted:a(e.getPropertyValue("--muted"),"hsl(0, 0%, 96.1%)"),mutedForeground:a(e.getPropertyValue("--muted-foreground"),"hsl(0, 0%, 45.1%)")};return{...t,primary:t.chart1,destructive:t.chart2}}r.d(t,{OY:()=>i,dt:()=>c,py:()=>s});let n={line:{series:{lineWidth:2,marker:{enabled:!0,radius:4,symbol:"circle"},states:{hover:{lineWidth:3}}}},area:{series:{fillOpacity:.15,lineWidth:2,marker:{enabled:!1,states:{hover:{enabled:!0,radius:4}}}}},pie:{series:{innerSize:"50%",borderWidth:0,dataLabels:{enabled:!0,format:"<b>{point.name}</b>: {point.percentage:.1f}%",style:{color:s().text},connectorColor:s().mutedForeground}}},column:{series:{borderRadius:6,borderWidth:0,states:{hover:{brightness:.1}}}}},l={chart:{style:{fontFamily:"Inter, system-ui, sans-serif"},backgroundColor:"transparent",spacing:[20,20,20,20]},credits:{enabled:!1},exporting:{enabled:!1},xAxis:{title:{text:null},labels:{style:{color:s().mutedForeground}},lineColor:s().border,tickColor:s().border,gridLineColor:s().muted},yAxis:{title:{text:null},labels:{style:{color:s().mutedForeground},format:"{value:,.0f}"},lineColor:s().border,tickColor:s().border,gridLineColor:s().muted},tooltip:{backgroundColor:s().background,borderWidth:1,borderColor:s().border,style:{color:s().text}},plotOptions:{series:{states:{hover:{brightness:.1}}},spline:{lineWidth:2,marker:{enabled:!0,radius:4,symbol:"circle"},states:{hover:{lineWidth:3}}}}};function i(){let e=s();return[e.chart1,e.chart2,e.chart3,e.chart4,e.chart5]}function o(e){return e&&"object"==typeof e&&!Array.isArray(e)}function c(e="line",t={}){let r=s();return function e(t,r){let a={...t};return o(t)&&o(r)&&Object.keys(r).forEach(s=>{o(r[s])&&s in t?a[s]=e(t[s],r[s]):a[s]=r[s]}),a}({...l,colors:i(),plotOptions:{...l.plotOptions,...n[e]?.series?{series:n[e].series}:{}},legend:{itemStyle:{color:r.text},itemHoverStyle:{color:r.mutedForeground}},responsive:{rules:[{condition:{maxWidth:500},chartOptions:{legend:{layout:"horizontal",align:"center",verticalAlign:"bottom"},yAxis:{labels:{align:"left",x:0,y:-5}}}}]}},t)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.