"use strict";const s=require("electron"),ae=require("openai"),$=require("util"),h=require("electron-log"),U=require("path"),ee=require("fs"),te=require("js-base64"),C=require("node:path"),ce=require("crypto"),le=require("electron-squirrel-startup"),de=require("net"),ue=require("http"),he=require("child_process"),pe=require("events");require("bytenode");const y=require("electron-updater");function ne(n){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const t in n)if(t!=="default"){const i=Object.getOwnPropertyDescriptor(n,t);Object.defineProperty(e,t,i.get?i:{enumerable:!0,get:()=>n[t]})}}return e.default=n,Object.freeze(e)}const S=ne(U),v=ne(ee);var r=(n=>(n.EXTERNAL_OPEN="external-open",n.WINDOW_MINIMIZE="window-minimize",n.WINDOW_MAXIMIZE="window-maximize",n.WINDOW_CLOSE="window-close",n.IS_WINDOW_MAXIMIZED="is-window-maximized",n.APP_SET_FRAMELESS="app:set-frameless",n.APP_LOAD_PAGE="app:load-page",n.TAB_CREATE="tab:create",n.TAB_LIST="tab:list",n.TAB_NAVIGATE="tab:navigate",n.TAB_RELOAD="tab:reload",n.TAB_BACK="tab:back",n.TAB_FORWARD="tab:forward",n.TAB_SWITCH="tab:switch",n.TAB_CLOSE="tab:close",n.LOG_TO_MAIN="log-to-main",n.READ_FILE="read-file",n.INVOKE="ipc:invoke",n.INVOKE_ASYNC="ipc:invokeAsync",n.APP_MINIMIZE="app:minimize",n.APP_MAXIMIZE="app:maximize",n.APP_QUIT="app:quit",n.FILE_READ="file:read",n.FILE_WRITE="file:write",n.GET_WINDOW_ID="get-window-id",n.CUSTOM_EVENT="custom:event",n.TIME_UPDATE="time:update",n.RENDERER_IS_READY="renderer-ready",n.SHOW_CONTEXT_MENU="show-context-menu",n.START_A_DIALOGUE="start-a-dialogue",n.OPEN_WINDOW="open-window",n.LOG_DEBUG="log-debug",n.LOG_INFO="log-info",n.LOG_WARN="log-warn",n.LOG_ERROR="log-error",n.CONFIG_UPDATED="config-updated",n.SET_CONFIG="set-config",n.GET_CONFIG="get-config",n.UPDATE_CONFIG="update-config",n.SET_THEME_MODE="set-theme-mode",n.GET_THEME_MODE="get-theme-mode",n.IS_DARK_THEME="is-dark-theme",n.THEME_MODE_UPDATED="theme-mode-updated",n.EXECUTE_SCRIPT="execute-script",n.OPEN_CHANNEL="open-channel",n.UPDATE_CHECK="update:check",n.UPDATE_DOWNLOAD="update:download",n.UPDATE_INSTALL="update:install",n.UPDATE_VERSION="update:version",n.UPDATE_STATUS_CHANGED="update:status-changed",n))(r||{});const ie={width:1440,height:900,minWidth:1440,minHeight:900};var w=(n=>(n.MAIN="main",n.SETTING="setting",n.DIALOG="dialog",n.LOADING="loading",n))(w||{}),g=(n=>(n.THEME_MODE="themeMode",n.PRIMARY_COLOR="primaryColor",n.LANGUAGE="language",n.FONT_SIZE="fontSize",n.MINIMIZE_TO_TRAY="minimizeToTray",n.PROVIDER="provider",n.DEFAULT_MODEL="defaultModel",n.AUTO_CHECK_UPDATE="autoCheckUpdate",n.AUTO_DOWNLOAD_UPDATE="autoDownloadUpdate",n))(g||{}),E=(n=>(n.CONVERSATION_ITEM="conversation-item",n.CONVERSATION_LIST="conversation-list",n.MESSAGE_ITEM="message-item",n))(E||{}),D=(n=>(n.PIN="pin",n.RENAME="rename",n.DEL="del",n))(D||{}),_=(n=>(n.NEW_CONVERSATION="newConversation",n.SORT_BY="sortBy",n.SORT_BY_CREATE_TIME="sortByCreateTime",n.SORT_BY_UPDATE_TIME="sortByUpdateTime",n.SORT_BY_NAME="sortByName",n.SORT_BY_MODEL="sortByModel",n.SORT_ASCENDING="sortAscending",n.SORT_DESCENDING="sortDescending",n.BATCH_OPERATIONS="batchOperations",n))(_||{}),O=(n=>(n.COPY="copy",n.DELETE="delete",n.SELECT="select",n))(O||{});class ge{}const fe=$.promisify(v.readdir),_e=$.promisify(v.stat),me=$.promisify(v.unlink);class z{static _instance;LOG_RETENTION_DAYS=7;CLEANUP_INTERVAL_MS=1440*60*1e3;constructor(){const e=S.join(s.app.getPath("userData"),"logs");try{v.existsSync(e)||v.mkdirSync(e,{recursive:!0})}catch(t){this.error("Failed to create log directory:",t)}h.transports.file.resolvePathFn=()=>{const t=new Date,i=`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`;return S.join(e,`${i}.log`)},h.transports.file.format="[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}",h.transports.file.maxSize=10*1024*1024,h.transports.console.level=process.env.NODE_ENV==="development"?"debug":"info",h.transports.file.level="debug",this._setupIpcEvents(),this._rewriteConsole(),this.info("LogService initialized successfully."),this._cleanupOldLogs(),setInterval(()=>this._cleanupOldLogs(),this.CLEANUP_INTERVAL_MS)}_setupIpcEvents(){s.ipcMain.on(r.LOG_DEBUG,(e,t,...i)=>this.debug(t,...i)),s.ipcMain.on(r.LOG_INFO,(e,t,...i)=>this.info(t,...i)),s.ipcMain.on(r.LOG_WARN,(e,t,...i)=>this.warn(t,...i)),s.ipcMain.on(r.LOG_ERROR,(e,t,...i)=>this.error(t,...i))}_rewriteConsole(){console.debug=h.debug,console.log=h.info,console.info=h.info,console.warn=h.warn,console.error=h.error}async _cleanupOldLogs(){try{const e=S.join(s.app.getPath("userData"),"logs");if(!v.existsSync(e))return;const t=new Date,i=new Date(t.getTime()-this.LOG_RETENTION_DAYS*24*60*60*1e3),o=await fe(e);let a=0;for(const c of o){if(!c.endsWith(".log"))continue;const d=S.join(e,c);try{const f=await _e(d);f.isFile()&&f.birthtime0&&this.info(`Successfully cleaned up ${a} old log files.`)}catch(e){this.error("Failed to cleanup old logs:",e)}}static getInstance(){return this._instance||(this._instance=new z),this._instance}debug(e,...t){h.debug(e,...t)}info(e,...t){h.info(e,...t)}warn(e,...t){h.warn(e,...t)}error(e,...t){h.error(e,...t)}logApiRequest(e,t={},i="POST"){this.info(`API Request: ${e}, Method: ${i}, Request: ${JSON.stringify(t)}`)}logApiResponse(e,t={},i=200,o=0){i>=400?this.error(`API Error Response: ${e}, Status: ${i}, Response Time: ${o}ms, Response: ${JSON.stringify(t)}`):this.debug(`API Response: ${e}, Status: ${i}, Response Time: ${o}ms, Response: ${JSON.stringify(t)}`)}logUserOperation(e,t="unknown",i={}){this.info(`User Operation: ${e} by ${t}, Details: ${JSON.stringify(i)}`)}}const u=z.getInstance();function we(n){const e=n.choices[0];return{isEnd:e?.finish_reason==="stop",result:e?.delta?.content??""}}class Ae extends ge{client;constructor(e,t){super(),this.client=new ae({apiKey:e,baseURL:t})}async chat(e,t){const i=Date.now(),o=e[e.length-1];u.logApiRequest("chat.completions.create",{model:t,lastMessage:o?.content?.substring(0,100)+(o?.content?.length>100?"...":""),messageCount:e.length},"POST");try{const a=await this.client.chat.completions.create({model:t,messages:e,stream:!0}),c=Date.now()-i;return u.logApiResponse("chat.completions.create",{success:!0},200,c),{async*[Symbol.asyncIterator](){for await(const d of a)yield we(d)}}}catch(a){const c=Date.now()-i;throw u.logApiResponse("chat.completions.create",{error:a instanceof Error?a.message:String(a)},500,c),a}}}function se(n,e){let t=null;return function(...i){t&&clearTimeout(t),t=setTimeout(()=>{n.apply(this,i)},e)}}function G(n){if(n===null||typeof n!="object")return n;if(Array.isArray(n))return n.map(t=>G(t));const e=Object.assign({},n);for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&(e[t]=G(e[t]));return e}function Te(n){try{return JSON.parse(JSON.stringify(n))}catch(e){return console.error("simpleCloneDeep failed:",e),n}}function ye(n){try{return JSON.parse(te.decode(n))}catch(e){return console.error("parseOpenAISetting failed:",e),{}}}const Ee={[g.THEME_MODE]:"system",[g.PRIMARY_COLOR]:"#BB5BE7",[g.LANGUAGE]:"zh",[g.FONT_SIZE]:14,[g.MINIMIZE_TO_TRAY]:!1,[g.PROVIDER]:"",[g.DEFAULT_MODEL]:null};class F{static _instance;_config;_configPath;_defaultConfig=Ee;_listeners=[];constructor(){this._configPath=S.join(s.app.getPath("userData"),"config.json"),this._config=this._loadConfig(),this._setupIpcEvents(),u.info("ConfigService initialized successfully.")}_setupIpcEvents(){const t=se(i=>this.update(i),200);s.ipcMain.handle(r.GET_CONFIG,(i,o)=>this.get(o)),s.ipcMain.on(r.SET_CONFIG,(i,o,a)=>this.set(o,a)),s.ipcMain.on(r.UPDATE_CONFIG,(i,o)=>t(o))}static getInstance(){return this._instance||(this._instance=new F),this._instance}_loadConfig(){try{if(v.existsSync(this._configPath)){const e=v.readFileSync(this._configPath,"utf-8"),t={...this._defaultConfig,...JSON.parse(e)};return u.info("Config loaded successfully from:",this._configPath),t}}catch(e){u.error("Failed to load config:",e)}return{...this._defaultConfig}}_saveConfig(){try{v.mkdirSync(S.dirname(this._configPath),{recursive:!0}),v.writeFileSync(this._configPath,JSON.stringify(this._config,null,2),"utf-8"),this._notifyListeners(),u.info("Config saved successfully to:",this._configPath)}catch(e){u.error("Failed to save config:",e)}}_notifyListeners(){s.BrowserWindow.getAllWindows().forEach(e=>e.webContents.send(r.CONFIG_UPDATED,this._config)),this._listeners.forEach(e=>e({...this._config}))}getConfig(){return Te(this._config)}get(e){return this._config[e]}set(e,t,i=!0){!(e in this._config)||this._config[e]===t||(this._config[e]=t,u.debug(`Config set: ${e} = ${t}`),i&&this._saveConfig())}update(e,t=!0){this._config={...this._config,...e},t&&this._saveConfig()}resetToDefault(){this._config={...this._defaultConfig},u.info("Config reset to default."),this._saveConfig()}onConfigChange(e){return this._listeners.push(e),()=>this._listeners=this._listeners.filter(t=>t!==e)}}const T=F.getInstance();process.env.BIGMODEL_API_KEY,new Date().getTime(),new Date().getTime(),process.env.DEEPSEEK_API_KEY,new Date().getTime(),new Date().getTime(),process.env.SILICONFLOW_API_KEY,new Date().getTime(),new Date().getTime(),process.env.QIANFAN_API_KEY,new Date().getTime(),new Date().getTime();const ve=()=>{let n=[],e=!1;const t=T.get(g.PROVIDER),i=o=>({...o,openAISetting:typeof o.openAISetting=="string"?ye(o.openAISetting??""):o.openAISetting});try{n=JSON.parse(te.decode(t)),e=!0}catch(o){u.error(`parse base64 provider failed: ${o}`)}if(!e)try{n=JSON.parse(t)}catch(o){u.error(`parse provider failed: ${o}`)}if(n.length)return n.map(i)},Me=()=>{try{return ve()}catch(n){return u.error(`get provider config failed: ${n}`),null}};function De(n){const e=Me();if(!e)throw new Error("provider config not found");for(const t of e)if(t.name===n){if(!t.openAISetting?.apiKey||!t.openAISetting?.baseURL)throw new Error("apiKey or baseURL not found");return new Ae(t.openAISetting.apiKey,t.openAISetting.baseURL)}}const Oe={minimize:"Minimize",maximize:"Maximize",restore:"Restore",close:"Close"},Ce={welcome:{helloMessage:"Hello, I'm Diona"},conversation:{placeholder:"Type a message...",newConversation:"New Conversation",selectModel:"Please select model",createConversation:"Create Conversation",searchPlaceholder:"Search conversations...",goSettings:"Go to",settings:"Settings Window",addModel:"to add a model",dialog:{title:"Confirm Deletion",content:"Are you sure you want to delete this conversation?",content_1:"Are you sure you want to delete the selected conversations? This action cannot be undone."},operations:{pin:"Pin Selected",del:"Delete Selected",selectAll:"Select All",cancel:"Cancel"}},sidebar:{conversations:"Conversations",settings:"Settings",help:"Help"},message:{dialog:{title:"Confirm Deletion",messageDelete:"Are you sure you want to delete this message?",batchDelete:"Are you sure you want to delete the selected messages?",copySuccess:"Copied successfully"},batchActions:{deleteSelected:"Delete Selected"},rendering:"Thinking...",stoppedGeneration:"(Stopped generating)",sending:"Sending",stopGeneration:"Stop generating",send:"Send"}},Ie={cancel:"Cancel",confirm:"Confirm"},Se={title:"Settings",base:"Basic Settings",provider:{modelConfig:"Model Configuration"},theme:{label:"Theme Settings",dark:"Dark Theme",light:"Light Theme",system:"System Theme",primaryColor:"Primary Color"},appearance:{fontSize:"Font Size",fontSizeOptions:{10:"Tiny (10px)",12:"Small (12px)",14:"Normal (14px)",16:"Medium (16px)",18:"Large (18px)",20:"Larger (20px)",24:"Extra Large (24px)"}},behavior:{minimizeToTray:"Minimize to tray when closed"},language:{label:"Language"},providers:{defaultModel:"Default Model",apiKey:"API Key",apiUrl:"API URL"}},be={conversation:{newConversation:"New Conversation",sortBy:"Sort By",sortByCreateTime:"Sort by Creation Time",sortByUpdateTime:"Sort by Update Time",sortByName:"Sort by Name",sortByModel:"Sort by Model",sortAscending:"Ascending",sortDescending:"Descending",pinConversation:"Pin Conversation",unpinConversation:"Unpin Conversation",renameConversation:"Rename Conversation",delConversation:"Delete Conversation",batchOperations:"Batch Operations"},message:{copyMessage:"Copy Message",deleteMessage:"Delete Message",selectMessage:"Select Message"}},Re={tooltip:"Diona Application",showWindow:"Show Window",exit:"Exit"},Ne={justNow:"Just now",minutes:"{count} minutes ago",hours:"{count} hours ago",days:"{count} days ago",months:"{count} months ago",years:"{count} years ago",weekday:{sun:"Sunday",mon:"Monday",tue:"Tuesday",wed:"Wednesday",thu:"Thursday",fri:"Friday",sat:"Saturday"}},Le={title:"Diona Application"},We={window:Oe,main:Ce,dialog:Ie,settings:Se,menu:be,tray:Re,timeAgo:Ne,app:Le},Ue={minimize:"最小化",maximize:"最大化",restore:"还原",close:"关闭"},ke={welcome:{helloMessage:"你好,我是迪奥娜"},conversation:{placeholder:"输入消息...",newConversation:"新对话",selectModel:"请选择模型",createConversation:"创建对话",searchPlaceholder:"搜索对话...",goSettings:"快去",settings:"设置窗口",addModel:"添加模型",dialog:{title:"确认删除",content:"确定要删除这个对话吗?",content_1:"确定要删除选中的对话吗?此操作不可撤销。"},operations:{pin:"置顶所选",del:"删除所选",selectAll:"全选",cancel:"取消"}},sidebar:{conversations:"对话",settings:"设置",help:"帮助"},message:{dialog:{title:"确认删除",messageDelete:"确认删除该条消息?",batchDelete:"确认删除选中的消息?",copySuccess:"复制成功"},batchActions:{deleteSelected:"删除选中项"},rendering:"思考中...",stoppedGeneration:"(已停止生成)",sending:"发送中",stopGeneration:"停止生成",send:"发送"}},Be={cancel:"取消",confirm:"确认"},Pe={title:"设置",base:"基础设置",provider:{modelConfig:"模型配置"},providers:{defaultModel:"默认模型",apiKey:"API密钥",apiUrl:"API地址"},theme:{label:"主题设置",dark:"深色主题",light:"浅色主题",system:"跟随系统",primaryColor:"主题颜色"},appearance:{fontSize:"字体大小",fontSizeOptions:{10:"极小 (10px)",12:"小 (12px)",14:"正常 (14px)",16:"中 (16px)",18:"大 (18px)",20:"较大 (20px)",24:"超大 (24px)"}},behavior:{minimizeToTray:"关闭时最小化到托盘"},language:{label:"语言设置"}},xe={conversation:{newConversation:"新建对话",sortBy:"排序方式",sortByCreateTime:"按创建时间排序",sortByUpdateTime:"按更新时间排序",sortByName:"按名称排序",sortByModel:"按模型排序",sortAscending:"递增",sortDescending:"递减",pinConversation:"置顶对话",unpinConversation:"取消置顶",renameConversation:"重命名对话",delConversation:"删除对话",batchOperations:"批量操作"},message:{copyMessage:"复制消息",deleteMessage:"删除消息",selectMessage:"选择消息"}},He={tooltip:"迪奥娜",showWindow:"显示窗口",exit:"退出"},Ge={justNow:"刚刚",minutes:"{count}分钟前",hours:"{count}小时前",days:"{count}天前",months:"{count}个月前",years:"{count}年前",weekday:{sun:"星期日",mon:"星期一",tue:"星期二",wed:"星期三",thu:"星期四",fri:"星期五",sat:"星期六"}},$e={title:"迪奥娜"},ze={window:Ue,main:ke,dialog:Be,settings:Pe,menu:xe,tray:He,timeAgo:Ge,app:$e},Fe={en:We,zh:ze};function B(){return n=>{if(n)try{const e=n?.split(".");let t=Fe[T.get(g.LANGUAGE)];for(const i of e)t=t[i];return t}catch(e){return u.error("failed to translate key:",n,e),n}}}let k;function oe(){if(k!=null)return k;const n=s.app.getAppPath();return k=C.join(n,"resources","icons","icon.ico"),k}class j{static _instance;_isDark=s.nativeTheme.shouldUseDarkColors;constructor(){const e=T.get(g.THEME_MODE);e&&(s.nativeTheme.themeSource=e,this._isDark=s.nativeTheme.shouldUseDarkColors),this._setupIpcEvent(),u.info("ThemeService initialized successfully.")}_setupIpcEvent(){s.ipcMain.handle(r.SET_THEME_MODE,(e,t)=>(s.nativeTheme.themeSource=t,T.set(g.THEME_MODE,t),s.nativeTheme.shouldUseDarkColors)),s.ipcMain.handle(r.GET_THEME_MODE,()=>s.nativeTheme.themeSource),s.ipcMain.handle(r.IS_DARK_THEME,()=>s.nativeTheme.shouldUseDarkColors),s.nativeTheme.on("updated",()=>{this._isDark=s.nativeTheme.shouldUseDarkColors,s.BrowserWindow.getAllWindows().forEach(e=>e.webContents.send(r.THEME_MODE_UPDATED,this._isDark))})}static getInstance(){return this._instance||(this._instance=new j),this._instance}get isDark(){return this._isDark}get themeMode(){return s.nativeTheme.themeSource}}const K=j.getInstance(),je={frame:!1,titleBarStyle:"hidden",trafficLightPosition:{x:-100,y:-100},show:!1,title:"NIANXX",darkTheme:K.isDark,backgroundColor:K.isDark?"#2C2C2C":"#FFFFFF",webPreferences:{nodeIntegration:!1,contextIsolation:!0,sandbox:!0,backgroundThrottling:!1,preload:MAIN_WINDOW_VITE_DEV_SERVER_URL?C.join(process.cwd(),"dist-electron/preload/preload.js"):C.join(__dirname,"preload.js")}};class Y{static _instance;_logo=oe();isDev=!!MAIN_WINDOW_VITE_DEV_SERVER_URL;_winStates={main:{instance:void 0,isHidden:!1,onCreate:[],onClosed:[]},setting:{instance:void 0,isHidden:!1,onCreate:[],onClosed:[]},dialog:{instance:void 0,isHidden:!1,onCreate:[],onClosed:[]},login:{instance:void 0,isHidden:!1,onCreate:[],onClosed:[]},loading:{instance:void 0,isHidden:!1,onCreate:[],onClosed:[]}};constructor(){this._setupIpcEvents(),u.info("WindowService initialized successfully.")}_isReallyClose(e){return e===w.MAIN?T.get(g.MINIMIZE_TO_TRAY)===!1:e!==w.SETTING}_setupIpcEvents(){const e=a=>{const c=s.BrowserWindow.fromWebContents(a.sender),d=this.getName(c);this.close(c,this._isReallyClose(d))},t=a=>{s.BrowserWindow.fromWebContents(a.sender)?.minimize()},i=a=>{this.toggleMax(s.BrowserWindow.fromWebContents(a.sender))},o=a=>s.BrowserWindow.fromWebContents(a.sender)?.isMaximized()??!1;s.ipcMain.on(r.WINDOW_CLOSE,e),s.ipcMain.on(r.WINDOW_MINIMIZE,t),s.ipcMain.on(r.WINDOW_MAXIMIZE,i),s.ipcMain.handle(r.IS_WINDOW_MAXIMIZED,o),s.ipcMain.handle(r.APP_LOAD_PAGE,(a,c)=>{const d=s.BrowserWindow.fromWebContents(a.sender);d&&this._loadPage(d,c)})}static getInstance(){return this._instance||(this._instance=new Y),this._instance}create(e,t,i){if(this.get(e))return;const o=this._isHiddenWin(e);let a=this._createWinInstance(e,{...t,...i});return this.isDev&&a.webContents.openDevTools(),!o&&this._setupWinLifecycle(a,e)._loadWindowTemplate(a,e),this._listenWinReady({win:a,isHiddenWin:o,size:t}),o||(this._winStates[e].instance=a,this._winStates[e].onCreate.forEach(c=>c(a))),o&&(this._winStates[e].isHidden=!1,u.info(`Hidden window show: ${e}`)),a}_setupWinLifecycle(e,t){const i=se(()=>!e?.isDestroyed()&&e?.webContents?.send(r.WINDOW_MAXIMIZE+"back",e?.isMaximized()),80);return e.once("closed",()=>{this._winStates[t].onClosed.forEach(o=>o(e)),e?.destroy(),e?.removeListener("resize",i),this._winStates[t].instance=void 0,this._winStates[t].isHidden=!1,u.info(`Window closed: ${t}`)}),e.on("resize",i),this}_listenWinReady(e){const t=()=>{e.win?.once("show",()=>setTimeout(()=>this._applySizeConstraints(e.win,e.size),2)),e.win?.show()};e.isHiddenWin?t():this._addLoadingView(e.win,e.size)?.(t)}_addLoadingView(e,t){let i=!1;const o=a=>{a.sender!==e?.webContents||i||(i=!0,s.ipcMain.removeListener(r.RENDERER_IS_READY,o))};return s.ipcMain.on(r.RENDERER_IS_READY,o),a=>{a()}}_applySizeConstraints(e,t){t.maxHeight&&t.maxWidth&&e.setMaximumSize(t.maxWidth,t.maxHeight),t.minHeight&&t.minWidth&&e.setMinimumSize(t.minWidth,t.minHeight)}_loadPage(e,t){if(MAIN_WINDOW_VITE_DEV_SERVER_URL)return e.loadURL(`${MAIN_WINDOW_VITE_DEV_SERVER_URL}/${t}.html`);e.loadFile(C.join(app.getAppPath(),"dist",`${t}.html`))}_loadWindowTemplate(e,t){this._loadPage(e,"index")}_handleCloseWindowState(e,t){const i=this.getName(e);i&&(t?this._winStates[i].instance=void 0:this._winStates[i].isHidden=!0),setTimeout(()=>{e[t?"close":"hide"]?.(),this._checkAndCloseAllWinodws()},210)}_checkAndCloseAllWinodws(){if(!this._winStates[w.MAIN].instance||this._winStates[w.MAIN].instance?.isDestroyed())return Object.values(this._winStates).forEach(t=>t?.instance?.close());if(!T.get(g.MINIMIZE_TO_TRAY)&&!this.get(w.MAIN)?.isVisible())return Object.values(this._winStates).forEach(t=>!t?.instance?.isVisible()&&t?.instance?.close())}_isHiddenWin(e){return this._winStates[e]&&this._winStates[e].isHidden}_createWinInstance(e,t){return this._isHiddenWin(e)?this._winStates[e].instance:new s.BrowserWindow({...je,icon:this._logo,...t})}focus(e){if(!e)return;const t=this.getName(e);e?.isMaximized()?(e?.restore(),u.debug(`Window ${t} restored and focused`)):u.debug(`Window ${t} focused`),e?.focus()}close(e,t=!0){if(!e)return;const i=this.getName(e);u.info(`Close window: ${i}, really: ${t}`),this._handleCloseWindowState(e,t)}toggleMax(e){e&&(e.isMaximized()?e.unmaximize():e.maximize())}getName(e){if(e){for(const[t,i]of Object.entries(this._winStates))if(i?.instance===e)return t}}get(e){if(!this._winStates[e].isHidden)return this._winStates[e].instance}onWindowCreate(e,t){this._winStates[e].onCreate.push(t)}onWindowClosed(e,t){this._winStates[e].onClosed.push(t)}}const W=Y.getInstance();let P=B();class q{static _instance;_menuTemplates=new Map;_currentMenu=void 0;constructor(){this._setupIpcListener(),this._setupLanguageChangeListener(),u.info("MenuService initialized successfully.")}_setupIpcListener(){s.ipcMain.handle(r.SHOW_CONTEXT_MENU,(e,t,i)=>new Promise(o=>this.showMenu(t,()=>o(!0),i)))}_setupLanguageChangeListener(){T.onConfigChange(e=>{e[g.LANGUAGE]&&(P=B())})}static getInstance(){return this._instance||(this._instance=new q),this._instance}register(e,t){return this._menuTemplates.set(e,t),e}showMenu(e,t,i){if(this._currentMenu)return;const o=G(this._menuTemplates.get(e));if(!o){u.warn(`Menu ${e} not found.`),t?.();return}let a=[];try{a=Array.isArray(i)?i:JSON.parse(i??"[]")}catch(l){u.error(`Failed to parse dynamicOptions for menu ${e}: ${l}`)}const c=l=>l.submenu?{...l,label:P(l?.label)??void 0,submenu:l.submenu?.map(p=>c(p))}:{...l,label:P(l?.label)??void 0},d=o.map(l=>{if(!Array.isArray(a)||!a.length)return c(l);const p=a.find(m=>m.id===l.id);if(p){const m={...l,...p};return c(m)}return l.submenu?c({...l,submenu:l.submenu?.map(m=>{const b=a.find(A=>A.id===m.id);return{...m,...b}})}):c(l)}),f=s.Menu.buildFromTemplate(d);this._currentMenu=f,f.popup({callback:()=>{this._currentMenu=void 0,t?.()}})}destroyMenu(e){this._menuTemplates.delete(e)}destroyed(){this._menuTemplates.clear(),this._currentMenu=void 0}}const x=q.getInstance();let L=B();class X{static _instance;_tray=null;_removeLanguageListener;_setupLanguageChangeListener(){this._removeLanguageListener=T.onConfigChange(e=>{e[g.LANGUAGE]&&(L=B(),this._tray&&this._updateTray())})}_updateTray(){this._tray||(this._tray=new s.Tray(oe()));const e=()=>{const t=W.get(w.MAIN);if(t&&!t?.isDestroyed()&&t?.isVisible()&&!t?.isFocused())return t.focus();if(t?.isMinimized())return t?.restore();t?.isVisible()&&t?.isFocused()||W.create(w.MAIN,ie)};this._tray.setToolTip(L("tray.tooltip")??"Diona Application"),this._tray.setContextMenu(s.Menu.buildFromTemplate([{label:L("tray.showWindow"),accelerator:"CmdOrCtrl+N",click:e},{type:"separator"},{label:L("settings.title"),click:()=>s.ipcMain.emit(`${r.OPEN_WINDOW}:${w.SETTING}`)},{role:"quit",label:L("tray.exit")}])),this._tray.removeAllListeners("click"),this._tray.on("click",e)}constructor(){this._setupLanguageChangeListener(),u.info("TrayService initialized successfully.")}static getInstance(){return this._instance||(this._instance=new X),this._instance}create(){this._tray||(this._updateTray(),s.app.on("quit",()=>{this.destroy()}))}destroy(){this._tray?.destroy(),this._tray=null,this._removeLanguageListener&&(this._removeLanguageListener(),this._removeLanguageListener=void 0)}}const J=X.getInstance();class Ye{win;views=new Map;activeId=null;skipNextNavigate=new Map;enabled=!1;constructor(e){this.win=e,this.win.on("resize",()=>this.updateActiveBounds()),this._setupIpcEvents()}_setupIpcEvents(){s.ipcMain.handle(r.TAB_CREATE,(e,t)=>this.create(t)),s.ipcMain.handle(r.TAB_LIST,()=>this.list()),s.ipcMain.handle(r.TAB_NAVIGATE,(e,{tabId:t,url:i})=>{this.navigate(t,i)}),s.ipcMain.handle(r.TAB_RELOAD,(e,t)=>{this.reload(t)}),s.ipcMain.handle(r.TAB_BACK,(e,t)=>{this.goBack(t)}),s.ipcMain.handle(r.TAB_FORWARD,(e,t)=>{this.goForward(t)}),s.ipcMain.handle(r.TAB_SWITCH,(e,t)=>{this.switch(t)}),s.ipcMain.handle(r.TAB_CLOSE,(e,t)=>{this.close(t)})}enable(){this.enabled=!0,this.updateActiveBounds(),this.activeId&&this.attach(this.activeId)}disable(){this.enabled=!1;const e=this.activeId?this.views.get(this.activeId):null;e&&this.win.removeBrowserView(e)}destroy(){this.disable(),this.views.forEach(e=>{e.webContents.destroy()}),this.views.clear(),s.ipcMain.removeHandler(r.TAB_CREATE),s.ipcMain.removeHandler(r.TAB_LIST),s.ipcMain.removeHandler(r.TAB_NAVIGATE),s.ipcMain.removeHandler(r.TAB_RELOAD),s.ipcMain.removeHandler(r.TAB_BACK),s.ipcMain.removeHandler(r.TAB_FORWARD),s.ipcMain.removeHandler(r.TAB_SWITCH),s.ipcMain.removeHandler(r.TAB_CLOSE)}list(){return Array.from(this.views.entries()).map(([e,t])=>this.info(e,t))}create(e,t=!0){const i=ce.randomUUID(),o=new s.BrowserView({webPreferences:{nodeIntegration:!1,contextIsolation:!0,sandbox:!0,preload:MAIN_WINDOW_VITE_DEV_SERVER_URL?C.join(process.cwd(),"dist-electron/preload/preload.js"):C.join(__dirname,"preload.js")}});this.views.set(i,o),this.enabled&&t&&this.attach(i);const a=e&&e.length>0?e:"about:blank";o.webContents.loadURL(a),this.bindEvents(i,o);const c=this.info(i,o);return this.win.webContents.send("tab-created",c),c}switch(e){this.views.has(e)&&(this.enabled&&this.attach(e),this.win.webContents.send("tab-switched",{tabId:e}))}close(e){const t=this.views.get(e);if(!t)return;this.activeId===e&&(this.win.removeBrowserView(t),this.activeId=null),t.webContents.destroy(),this.views.delete(e),this.win.webContents.send("tab-closed",{tabId:e});const i=this.views.keys().next().value;i&&this.switch(i)}navigate(e,t){const i=this.views.get(e);i&&(this.skipNextNavigate.set(e,!0),i.webContents.loadURL(t))}reload(e){const t=this.views.get(e);t&&t.webContents.reload()}goBack(e){const t=this.views.get(e);t&&t.webContents.canGoBack()&&t.webContents.goBack()}goForward(e){const t=this.views.get(e);t&&t.webContents.canGoForward()&&t.webContents.goForward()}attach(e){if(!this.enabled)return;const t=this.views.get(e);if(t){if(this.activeId&&this.views.get(this.activeId)){const i=this.views.get(this.activeId);this.win.removeBrowserView(i)}this.activeId=e,this.win.addBrowserView(t),this.updateActiveBounds()}}updateActiveBounds(){if(!this.enabled||!this.activeId)return;const e=this.views.get(this.activeId);if(!e)return;const[t,i]=this.win.getContentSize(),o=88,a=8,c=488,d=a,f=o+a,l=t-c-a,p=i-o-a*2;e.setBounds({x:d,y:f,width:Math.max(0,l),height:Math.max(0,p)})}bindEvents(e,t){const i=()=>this.win.webContents.send("tab-updated",this.info(e,t));t.webContents.on("did-start-loading",i),t.webContents.on("did-stop-loading",i),t.webContents.on("did-finish-load",i),t.webContents.on("page-title-updated",i),t.webContents.on("did-navigate",i),t.webContents.on("did-navigate-in-page",i),t.webContents.on("will-navigate",(o,a)=>{if(this.skipNextNavigate.get(e)){this.skipNextNavigate.set(e,!1);return}o.preventDefault(),this.create(a)}),t.webContents.setWindowOpenHandler(({url:o})=>(this.create(o),{action:"deny"}))}info(e,t){const i=t.webContents;return{id:e,url:i.getURL(),title:i.getTitle(),isLoading:i.isLoading(),canGoBack:i.canGoBack(),canGoForward:i.canGoForward()}}}const Q=n=>{if(n){J.create();return}J.destroy()},qe=n=>{const e=o=>{u.logUserOperation(`${r.SHOW_CONTEXT_MENU}:${E.CONVERSATION_ITEM}-${o}`),n.webContents.send(`${r.SHOW_CONTEXT_MENU}:${E.CONVERSATION_ITEM}`,o)};x.register(E.CONVERSATION_ITEM,[{id:D.PIN,label:"menu.conversation.pinConversation",click:()=>e(D.PIN)},{id:D.RENAME,label:"menu.conversation.renameConversation",click:()=>e(D.RENAME)},{id:D.DEL,label:"menu.conversation.delConversation",click:()=>e(D.DEL)}]);const t=o=>{u.logUserOperation(`${r.SHOW_CONTEXT_MENU}:${E.CONVERSATION_LIST}-${o}`),n.webContents.send(`${r.SHOW_CONTEXT_MENU}:${E.CONVERSATION_LIST}`,o)};x.register(E.CONVERSATION_LIST,[{id:_.NEW_CONVERSATION,label:"menu.conversation.newConversation",click:()=>t(_.NEW_CONVERSATION)},{type:"separator"},{id:_.SORT_BY,label:"menu.conversation.sortBy",submenu:[{id:_.SORT_BY_CREATE_TIME,label:"menu.conversation.sortByCreateTime",type:"radio",checked:!1,click:()=>t(_.SORT_BY_CREATE_TIME)},{id:_.SORT_BY_UPDATE_TIME,label:"menu.conversation.sortByUpdateTime",type:"radio",checked:!1,click:()=>t(_.SORT_BY_UPDATE_TIME)},{id:_.SORT_BY_NAME,label:"menu.conversation.sortByName",type:"radio",checked:!1,click:()=>t(_.SORT_BY_NAME)},{id:_.SORT_BY_MODEL,label:"menu.conversation.sortByModel",type:"radio",checked:!1,click:()=>t(_.SORT_BY_MODEL)},{type:"separator"},{id:_.SORT_ASCENDING,label:"menu.conversation.sortAscending",type:"radio",checked:!1,click:()=>t(_.SORT_ASCENDING)},{id:_.SORT_DESCENDING,label:"menu.conversation.sortDescending",type:"radio",checked:!1,click:()=>t(_.SORT_DESCENDING)}]},{id:_.BATCH_OPERATIONS,label:"menu.conversation.batchOperations",click:()=>t(_.BATCH_OPERATIONS)}]);const i=o=>{u.logUserOperation(`${r.SHOW_CONTEXT_MENU}:${E.MESSAGE_ITEM}-${o}`),n.webContents.send(`${r.SHOW_CONTEXT_MENU}:${E.MESSAGE_ITEM}`,o)};x.register(E.MESSAGE_ITEM,[{id:O.COPY,label:"menu.message.copyMessage",click:()=>i(O.COPY)},{id:O.SELECT,label:"menu.message.selectMessage",click:()=>i(O.SELECT)},{type:"separator"},{id:O.DELETE,label:"menu.message.deleteMessage",click:()=>i(O.DELETE)}])};function re(){W.onWindowCreate(w.MAIN,n=>{let e=T.get(g.MINIMIZE_TO_TRAY);T.onConfigChange(i=>{e!==i[g.MINIMIZE_TO_TRAY]&&(e=i[g.MINIMIZE_TO_TRAY],Q(e))}),Q(e),qe(n);const t=new Ye(n);t.enable(),n.on("closed",()=>{t.destroy()})}),W.create(w.MAIN,ie),s.ipcMain.on(r.START_A_DIALOGUE,async(n,e)=>{const{providerName:t,messages:i,messageId:o,selectedModel:a}=e,c=W.get(w.MAIN);if(!c)throw new Error("mainWindow not found");try{const f=await De(t)?.chat(i,a);if(!f)throw new Error("chunks or stream not found");for await(const l of f){const p={messageId:o,data:l};c.webContents.send(r.START_A_DIALOGUE+"back"+o,p)}}catch(d){const f={messageId:o,data:{isEnd:!0,isError:!0,result:d instanceof Error?d.message:String(d)}};c.webContents.send(r.START_A_DIALOGUE+"back"+o,f)}})}function Xe(){if(process.platform==="win32")return"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe";if(process.platform==="darwin")return"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";if(process.platform==="linux")return"google-chrome"}function Ze(n){return C.join(s.app.getPath("userData"),"profiles",n)}function Ke(n){return new Promise(e=>{const t=de.createServer();t.once("error",i=>e(!0)),t.once("listening",()=>{t.close(),e(!1)}),t.listen(n)})}async function Je(){try{return new Promise(n=>{const e=ue.get("http://127.0.0.1:9222/json/version",t=>{n(t.statusCode===200)});e.on("error",()=>n(!1)),e.setTimeout(1e3,()=>{e.destroy(),n(!1)})})}catch{return!1}}async function Qe(){const n=Xe(),e=Ze("default");if(h.info(`Launching Chrome with user data dir: ${e}`),await Ke(9222)){h.info("Chrome already running on port 9222, skip launching.");return}if(await Je()){h.info("Chrome already running, skip launching.");return}return new Promise((i,o)=>{he.spawn(n,["--remote-debugging-port=9222","--window-size=1920,1080","--window-position=0,0","--no-first-run",`--user-data-dir=${e}`,"--no-default-browser-check","about:blank"],{detached:!0,stdio:"ignore"}).on("error",o),setTimeout(()=>{i(0)},1e3)})}class Ve extends pe.EventEmitter{async executeScript(e,t){const o=(a,c)=>{const d=a+c;return d.length>32768?d.slice(d.length-32768):d};return await new Promise(a=>{try{const c=t?.roomType??"",d=t?.startTime??"",f=t?.endTime??"",l=t?.operation??"",p=t?.tabIndex??"",m=t?.channels??"",b=t?.startTabIndex??"",A=s.utilityProcess.fork(e,[],{env:{...process.env,ROOM_TYPE:String(c),START_DATE:String(d),END_DATE:String(f),OPERATION:String(l),TAB_INDEX:String(p),CHANNELS:typeof m=="string"?m:JSON.stringify(m),START_TAB_INDEX:String(b)},stdio:"pipe"});let I="",R="";A.stdout&&A.stdout.on("data",M=>{const N=M.toString();I=o(I,N),h.info(`stdout: ${N}`)}),A.stderr&&A.stderr.on("data",M=>{const N=M.toString();R=o(R,N),h.info(`stderr: ${N}`)}),A.on("exit",M=>{h.info(`子进程退出,退出码 ${M}`),a({success:M===0,exitCode:M,stdoutTail:I,stderrTail:R,...M===0?{}:{error:`Script exited with code ${M}`}})})}catch(c){a({success:!1,exitCode:null,stdoutTail:"",stderrTail:"",error:c?.message||"运行 Node 脚本时出错"})}})}}const H=new Map;function V(){return s.app.isPackaged?U.join(__dirname,"scripts"):U.join(process.cwd(),"electron/scripts")}function et(){const n=new Ve;s.ipcMain.handle(r.OPEN_CHANNEL,async(e,t)=>{try{await Qe();const i=V(),o=U.join(i,"open_all_channel.js");if(H.clear(),Array.isArray(t))for(let c=0;c{try{const i=t.roomList.find(l=>l.id===t.roomType),a=[["fzName","fg_trace.js"],["mtName","mt_trace.js"],["dyHotelName","dy_hotel_trace.js"],["dyHotSpringName","dy_hot_spring_trace.js"]].filter(([l])=>i?.[l]),c=V(),d=a.map(([l,p])=>{const m=U.join(c,p);if(!ee.existsSync(m))throw new Error(`Script not found for channel ${l}: ${m}`);return{channel:l,scriptPath:m}}),f=[];for(let l=0;lthis.sendToRenderer(r.UPDATE_STATUS_CHANGED,{status:"checking"})),y.autoUpdater.on("update-available",e=>this.sendToRenderer(r.UPDATE_STATUS_CHANGED,{status:"available",info:e})),y.autoUpdater.on("update-not-available",()=>this.sendToRenderer(r.UPDATE_STATUS_CHANGED,{status:"not-available"})),y.autoUpdater.on("download-progress",e=>this.sendToRenderer(r.UPDATE_STATUS_CHANGED,{status:"downloading",progress:e})),y.autoUpdater.on("update-downloaded",e=>this.sendToRenderer(r.UPDATE_STATUS_CHANGED,{status:"downloaded",info:e})),y.autoUpdater.on("error",e=>this.sendToRenderer(r.UPDATE_STATUS_CHANGED,{status:"error",error:e.message}))}sendToRenderer(e,t){s.BrowserWindow.getAllWindows().forEach(i=>{i.isDestroyed()||i.webContents.send(e,t)})}registerHandlers(){s.ipcMain.handle(r.UPDATE_CHECK,()=>s.app.isPackaged?y.autoUpdater.checkForUpdates():(this.sendToRenderer(r.UPDATE_STATUS_CHANGED,{status:"checking"}),setTimeout(()=>{this.sendToRenderer(r.UPDATE_STATUS_CHANGED,{status:"not-available"})},1500),null)),s.ipcMain.handle(r.UPDATE_DOWNLOAD,()=>s.app.isPackaged?y.autoUpdater.downloadUpdate():null),s.ipcMain.handle(r.UPDATE_INSTALL,()=>s.app.isPackaged?y.autoUpdater.quitAndInstall():null),s.ipcMain.handle(r.UPDATE_VERSION,()=>s.app.getVersion())}}const tt=Z.getInstance();tt.init();le&&s.app.quit();s.app.whenReady().then(()=>{re(),et()});s.app.on("window-all-closed",()=>{process.platform!=="darwin"&&!T.get(g.MINIMIZE_TO_TRAY)&&(h.info("app closing due to all windows being closed"),s.app.quit())});s.app.on("activate",()=>{s.BrowserWindow.getAllWindows().length===0&&re()});