diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8689597..5bb21de 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,4 +41,5 @@ jobs: SLACK_TITLE: "🚨 Build Failed" SLACK_MESSAGE: "😭 Build failed for `${{ github.repository }}` repo on main branch." SLACK_COLOR: 'danger' - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} \ No newline at end of file + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0c4ea82 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "aec"] + path = aec + url = https://github.com/samtiz/aec.git diff --git a/README.md b/README.md index e166914..e5510e2 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,6 @@ > This project is a fork of [CheatingDaddy](https://github.com/sohzm/cheating-daddy) with modifications and enhancements. Thanks to [Soham](https://x.com/soham_btw) and all the open-source contributors who made this possible! -> Currently, we're working on a full code refactor and modularization. Once that's completed, we'll jump into addressing the major issues. You can find WIP issues & changelog below this document. - πŸ€– **Fast, light & open-source**β€”Glass lives on your desktop, sees what you see, listens in real time, understands your context, and turns every moment into structured knowledge. πŸ’¬ **Proactive in meetings**β€”it surfaces action items, summaries, and answers the instant you need them. @@ -117,15 +115,17 @@ We have a list of [help wanted](https://github.com/pickle-com/glass/issues?q=is% | Status | Issue | Description | |--------|--------------------------------|---------------------------------------------------| -| 🚧 WIP | Windows Build | Make Glass buildable & runnable in Windows | | 🚧 WIP | Local LLM Support | Supporting Local LLM to power AI answers | -| 🚧 WIP | AEC Improvement | Transcription is not working occasionally | | 🚧 WIP | Firebase Data Storage Issue | Session & ask should be saved in firebase for signup users | | 🚧 WIP | Liquid Glass | Liquid Glass UI for MacOS 26 | ### Changelog - Jul 5: Now support Gemini, Intel Mac supported +- Jul 6: Full code refactoring has done. +- Jul 7: Now support Claude, LLM/STT model selection +- Jul 8: Now support Windows(beta), Improved AEC by Rust(to seperate mic/system audio), shortcut editing(beta) + ## About Pickle diff --git a/aec b/aec new file mode 160000 index 0000000..f00bb1f --- /dev/null +++ b/aec @@ -0,0 +1 @@ +Subproject commit f00bb1fb948053c752b916adfee19f90644a0b2f diff --git a/package-lock.json b/package-lock.json index 55fc266..bad6efc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pickle-glass", - "version": "0.2.1", + "version": "0.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pickle-glass", - "version": "0.2.1", + "version": "0.2.3", "hasInstallScript": true, "license": "GPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 2269777..ea125a0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,9 @@ { "name": "pickle-glass", "productName": "Glass", - "version": "0.2.2", + + "version": "0.2.3", + "description": "Cl*ely for Free", "main": "src/index.js", "scripts": { @@ -10,7 +12,7 @@ "package": "npm run build:renderer && electron-forge package", "make": "npm run build:renderer && electron-forge make", "build": "npm run build:all && electron-builder --config electron-builder.yml --publish never", - "build:win": "npm run build:all && electron-builder --win --x64 --publish never", + "build:win": "npm run build:all && electron-builder --win --x64 --publish never", "publish": "npm run build:all && electron-builder --config electron-builder.yml --publish always", "lint": "eslint --ext .ts,.tsx,.js .", "postinstall": "electron-builder install-app-deps", @@ -39,7 +41,6 @@ "better-sqlite3": "^9.4.3", "cors": "^2.8.5", "dotenv": "^17.0.0", - "electron-squirrel-startup": "^1.0.1", "electron-store": "^8.2.0", "electron-updater": "^6.6.2", @@ -74,4 +75,4 @@ "optionalDependencies": { "electron-liquid-glass": "^1.0.1" } -} \ No newline at end of file +} diff --git a/src/app/MainHeader.js b/src/app/MainHeader.js index 5212fae..7c92f7c 100644 --- a/src/app/MainHeader.js +++ b/src/app/MainHeader.js @@ -3,11 +3,12 @@ import { html, css, LitElement } from '../assets/lit-core-2.7.4.min.js'; export class MainHeader extends LitElement { static properties = { isSessionActive: { type: Boolean, state: true }, + shortcuts: { type: Object, state: true }, }; static styles = css` :host { - display: block; + display: flex; transform: translate3d(0, 0, 0); backface-visibility: hidden; transition: transform 0.2s cubic-bezier(0.23, 1, 0.32, 1), opacity 0.2s ease-out; @@ -99,7 +100,7 @@ export class MainHeader extends LitElement { } .header { - width: 100%; + width: max-content; height: 47px; padding: 2px 10px 2px 13px; background: transparent; @@ -212,16 +213,6 @@ export class MainHeader extends LitElement { } .action-button, - .settings-button { - background: transparent; - color: white; - border: none; - cursor: pointer; - display: flex; - align-items: center; - gap: 6px; - } - .action-text { padding-bottom: 1px; justify-content: center; @@ -275,9 +266,16 @@ export class MainHeader extends LitElement { .settings-button { padding: 5px; border-radius: 50%; + background: transparent; transition: background 0.15s ease; + color: white; + border: none; + cursor: pointer; + display: flex; + align-items: center; + gap: 6px; } - + .settings-button:hover { background: rgba(255, 255, 255, 0.1); } @@ -286,6 +284,7 @@ export class MainHeader extends LitElement { display: flex; align-items: center; justify-content: center; + padding: 3px; } .settings-icon svg { @@ -346,6 +345,7 @@ export class MainHeader extends LitElement { constructor() { super(); + this.shortcuts = {}; this.dragState = null; this.wasJustDragged = false; this.isVisible = true; @@ -501,6 +501,11 @@ export class MainHeader extends LitElement { this.isSessionActive = isActive; }; ipcRenderer.on('session-state-changed', this._sessionStateListener); + this._shortcutListener = (event, keybinds) => { + console.log('[MainHeader] Received updated shortcuts:', keybinds); + this.shortcuts = keybinds; + }; + ipcRenderer.on('shortcuts-updated', this._shortcutListener); } } @@ -518,6 +523,9 @@ export class MainHeader extends LitElement { if (this._sessionStateListener) { ipcRenderer.removeListener('session-state-changed', this._sessionStateListener); } + if (this._shortcutListener) { + ipcRenderer.removeListener('shortcuts-updated', this._shortcutListener); + } } } @@ -567,6 +575,29 @@ export class MainHeader extends LitElement { } + renderShortcut(accelerator) { + if (!accelerator) return html``; + + const keyMap = { + 'Cmd': '⌘', 'Command': '⌘', + 'Ctrl': 'βŒƒ', 'Control': 'βŒƒ', + 'Alt': 'βŒ₯', 'Option': 'βŒ₯', + 'Shift': '⇧', + 'Enter': '↡', + 'Backspace': '⌫', + 'Delete': '⌦', + 'Tab': 'β‡₯', + 'Escape': 'βŽ‹', + 'Up': '↑', 'Down': '↓', 'Left': '←', 'Right': 'β†’', + '\\': html``, + }; + + const keys = accelerator.split('+'); + return html`${keys.map(key => html` +
${keyMap[key] || key}
+ `)}`; + } + render() { return html`
@@ -599,14 +630,8 @@ export class MainHeader extends LitElement {
Ask
-
-
⌘
-
- - - - -
+
+ ${this.renderShortcut(this.shortcuts.nextStep)}
@@ -614,13 +639,8 @@ export class MainHeader extends LitElement {
Show/Hide
-
-
⌘
-
- - - -
+
+ ${this.renderShortcut(this.shortcuts.toggleVisibility)}
diff --git a/src/app/PickleGlassApp.js b/src/app/PickleGlassApp.js index 6cf1666..e2e8495 100644 --- a/src/app/PickleGlassApp.js +++ b/src/app/PickleGlassApp.js @@ -2,6 +2,7 @@ import { html, css, LitElement } from '../assets/lit-core-2.7.4.min.js'; import { SettingsView } from '../features/settings/SettingsView.js'; import { AssistantView } from '../features/listen/AssistantView.js'; import { AskView } from '../features/ask/AskView.js'; +import { ShortcutSettingsView } from '../features/settings/ShortCutSettingsView.js'; import '../features/listen/renderer/renderer.js'; @@ -268,6 +269,8 @@ export class PickleGlassApp extends LitElement { .onProfileChange=${profile => (this.selectedProfile = profile)} .onLanguageChange=${lang => (this.selectedLanguage = lang)} >`; + case 'shortcut-settings': + return html``; case 'history': return html``; case 'help': diff --git a/src/assets/aec.js b/src/assets/aec.js new file mode 100644 index 0000000..bbeec18 --- /dev/null +++ b/src/assets/aec.js @@ -0,0 +1,20 @@ +var createAecModule = (() => { + var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined; + return ( +async function(moduleArg = {}) { + var moduleRtn; + +var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory="";var readAsync,readBinary;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var EXITSTATUS;var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.initialized)FS.init();TTY.init();wasmExports["v"]();FS.ignorePermissions=false}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return base64Decode("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AyAAQXNxIAMoAgAiASAAIAFGIgAbNgIAIABFBEAgBCACNgIIIAEhAAwDCyACED4MBQsgAyAAQXNxIAMoAgAiASAAIAFGIgIbNgIAIAEhACACRQ0BDAQLIAMgASADKAIAIgEgACABRhs2AgAgACABRyABIQANAAsDQCACKAIEIAIQPiICDQALDAILIAMgAUF+cSADKAIAIgIgASACRiIAGzYCACAADQELIAIhAQwBCwsLC2gBA38gACgCBCICKAIAIQACQANAAkAgAgJ/IABBAnFFBEAgAEERayIBQQFyQQAgARsMAQsgAEEIcUUNASAAQXZxCyACKAIAIgEgACABRiIDGzYCACABIQAgA0UNAQwCCwsgAiAAEHQLC5QCAgJ/AX4jAEEQayIDJAACf0EAIAJFDQAaA0ACQAJAAkBBAAJ/IAFB/////wcgAiACQf////8HTxsQQyIEQX9HBEAgAyAENgIMIANBBDoACEHI6QAgBEUNARogAiAESQ0CIAEgBGohASACIARrIQIMBAsgA0EAOgALIANBADsACSADQQA6AAggA0HA8wAoAgAiBDYCDCAEQRtGDQMgA0EIagspAwAiBUL/AYNCBFENBBogAC0AAEEERwRAQfj4AEEANgIAQSUgABACQfj4ACgCAEH4+ABBADYCAEEBRg0CCyAAIAU3AgBBAQwECyAEIAJBkOsAEC8ACxAAIAAgBTcCABABAAsgAg0AC0EACyADQRBqJAALgwEBA38CQCAALQAAQQNGBEAgACgCBCICKAIAIQMgAigCBCIAKAIAIgEEQEH4+ABBADYCACABIAMQAkH4+AAoAgBB+PgAQQA2AgBBAUYNAgsgACgCBARAIAAoAggaIAMQFAsgAhAUCw8LEAAgACgCBARAIAAoAggaIAMQFAsgAhAUEAEAC04BAX8gAEEAIABBmQFNG0EBdEGwwQBqLwEAQbUyaiIAECUiAkGAAU8EQCABIABB/wAQKxogAUEAOgB/QcQADwsgASAAIAJBAWoQKxpBAAtEAQF/IwBBEGsiAiQAQQIgACABIAJBDGoQBiIABH9BwPMAIAA2AgBBfwVBAAshACACKAIMIQEgAkEQaiQAQX8gASAAGwu6AQEEfyMAIgJBgCAhAyACQRBBgCAgABtrIgQkACAEIQICQAJAIABFDQAgACECIAEiAw0AQcDzAEEc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BDoAACADLQAIIgBBBEYNASAAQQNHDQEgAygCDCICKAIAIQQCQCACKAIEIgEoAgAiAARAQfj4AEEANgIAIAAgBBACQfj4ACgCAEH4+ABBADYCAEEBRg0BCyABKAIEBEAgASgCCBogBBAUCyACEBQMAgsQACEAIAEoAgQEQCABKAIIGiAEEBQLIAIQFAwDCyAAIAMpAwg3AgALIANBMGokAA8LEAAhACADLQAIQQRGDQBB+PgAQQA2AgBBJSADQQhqEAJB+PgAKAIAQfj4AEEANgIAQQFHDQAQABoQIAALIAAQAQALlgUBBn8jAEEgayIBJAACQAJAAkAgA0UNACACQQRqIQQgA0EDdCEFIANBAWtB/////wFxQQFqIQYCQANAIAQoAgANASAEQQhqIQQgB0EBaiEHIAVBCGsiBQ0ACyAGIQcLIAMgB08EQCADIAdGDQEgAyAHayEGIAIgB0EDdGohCAJAAkADQAJAIAhBgAggBiAGQYAITxsQeSIEQX9HBEAgASAENgIEIAFBBDoAACAERQRAQcjpACEEDAgLIAhBBGohByAGQQN0IQMgBkEBa0H/////AXFBAWpBACEFA0AgBCAHKAIAIglJDQIgB0EIaiEHIAVBAWohBSAEIAlrIQQgA0EIayIDDQALIQUMAQsgAUEAOgADIAFBADsAASABQQA6AAAgAUHA8wAoAgAiAjYCBCACQRtGDQEgASEEDAYLIAUgBksNASAFIAZGBEAgBEUNBSABQQA2AhggAUEBNgIMIAFCBDcCECABQeDqADYCCCABQQhqQejqABAWAAsgCCAFQQN0aiIIKAIEIgIgBEkNAiAGIAVrIQYgCCACIARrNgIEIAggCCgCACAEajYCACABLQAAIgJBBEYNACACQQNHDQAgASgCBCIDKAIAIQQCQCADKAIEIgIoAgAiBQRAQfj4AEEANgIAIAUgBBACQfj4ACgCAEH4+ABBADYCAEEBRg0BCyACKAIEBEAgAigCCBogBBAUCyADEBQMAQsLEAAgAigCBARAIAIoAggaIAQQFAsgAxAUEAEACyAFIAZB0OoAEC8ACyABQQA2AhggAUEBNgIMIAFCBDcCECABQfjqADYCCCABQQhqQYDrABAWAAsgByADQdDqABAvAAsgAEEEOgAADAELIAAgBCkDADcCAAsgAUEgaiQAC6kCAQV/IAME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IABBEGokAEHU+ABB3PcANgIAQaz4AEGAgAQ2AgBBqPgAQeD5BDYCAEGM+ABBKjYCAEGw+ABB0OIAKAIANgIACwu/aBwAQYAIC6cHwDAAAEF0dGVtcHRlZCB0byBkaXZpZGUgYnkALSsgICAwWDB4ACVzOiVkOiAlcwAvZW1zZGsvZW1zY3JpcHRlbi9zeXN0ZW0vbGliL2xpYmN4eGFiaS9zcmMvcHJpdmF0ZV90eXBlaW5mby5jcHAAdGVybWluYXRpbmcAVGhlIFZBRCBoYXMgYmVlbiByZXBsYWNlZCBieSBhIGhhY2sgcGVuZGluZyBhIGNvbXBsZXRlIHJld3JpdGUASW4tcGxhY2UgRkZUIG5vdCBzdXBwb3J0ZWQAdGVybWluYXRlX2hhbmRsZXIgdW5leHBlY3RlZGx5IHJldHVybmVkAHJ1c3RfcGFuaWMAL1VzZXJzL2hvamlueXUvcHJvamVjdHMvZW50cnkvdHdpbi9HbGFzcy9hZWMvdGFyZ2V0L3dhc20zMi11bmtub3duLWVtc2NyaXB0ZW4vcmVsZWFzZS9idWlsZC9hZWMtcnMtc3lzLTBiYWFiOTYzMzlhZjdlMDgvb3V0L3NwZWV4ZHNwL2xpYnNwZWV4ZHNwL2tpc3NfZmZ0LmMAL1VzZXJzL2hvamlueXUvcHJvamVjdHMvZW50cnkvdHdpbi9HbGFzcy9hZWMvdGFyZ2V0L3dhc20zMi11bmtub3duLWVtc2NyaXB0ZW4vcmVsZWFzZS9idWlsZC9hZWMtcnMtc3lzLTBiYWFiOTYzMzlhZjdlMDgvb3V0L3NwZWV4ZHNwL2xpYnNwZWV4ZHNwL2tpc3NfZmZ0ci5jAGNhdGNoaW5nIGEgY2xhc3Mgd2l0aG91dCBhbiBvYmplY3Q/AEtpc3NGRlQ6IG1heCByYWRpeCBzdXBwb3J0ZWQgaXMgMTcAVGhlIGVjaG8gY2FuY2VsbGVyIHN0YXJ0ZWQgYWN0aW5nIGZ1bm55IGFuZCBnb3Qgc2xhcHBlZCAocmVzZXQpLiBJdCBzd2VhcnMgaXQgd2lsbCBiZWhhdmUgbm93LgAobnVsbCkAVW5rbm93biBzcGVleF9wcmVwcm9jZXNzX2N0bCByZXF1ZXN0OiAAd2FybmluZzogJXMKAEZhdGFsIChpbnRlcm5hbCkgZXJyb3Ig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IHNsaWNlIG9mIGxlbmd0aCByYW5nZSBlbmQgaW5kZXggc2xpY2UgaW5kZXggc3RhcnRzIGF0ICBidXQgZW5kcyBhdCAAAAADAACDBCAAkQVgAF0ToAASFyAfDCBgH+8sICsqMKArb6ZgLAKo4Cwe++AtAP4gNp7/YDb9AeE2AQohNyQN4TerDmE5LxjhOTAc4UrzHuFOQDShUh5h4VPwamFUT2/hVJ28YVUAz2FWZdGhVgDaIVcA4KFYruIhWuzk4VvQ6GFcIADuXPABf10CAAAAAgAAAAcAAABjYWxsZWQgYFJlc3VsdDo6dW53cmFwKClgIG9uIGFuIGBFcnJgIHZhbHVlTGF5b3V0RXJyb3JjYXBhY2l0eSBvdmVyZmxvd2xpYnJhcnkvYWxsb2Mvc3JjL3Jhd192ZWMvbW9kLnJzbGlicmFyeS9hbGxvYy9zcmMvc3RyaW5nLnJzbGlicmFyeS9hbGxvYy9zcmMvZmZpL2Nfc3RyLnJzbGlicmFyeS9hbGxvYy9zcmMvc2xpY2UucnPvv71saWJyYXJ5L2FsbG9jL3NyYy9zeW5jLnJzAAC8GAAA5BcAAFN0OXR5cGVfaW5mbwAAAADkGAAAABgAANwXAABOMTBfX2N4eGFiaXYxMTZfX3NoaW1fdHlwZV9pbmZvRQAAAADkGAAAMBgAAPQXAABOMTBfX2N4eGFiaXYxMTdfX2NsYXNzX3R5cGVfaW5mb0UAAADkGAAAYBgAAPQXAABOMTBfX2N4eGFiaXYxMTdfX3BiYXNlX3R5cGVfaW5mb0UAAADkGAAAkBgAAFQYAABOMTBfX2N4eGFiaXYxMTlfX3BvaW50ZXJfdHlwZV9pbmZvRQAAAAAAJBgAABYAAAAXAAAAGAAAABkAAAAaAAAAGwAAABwAAAAdAAAAAAAAAAQZAAAWAAAAHgAAABgAAAAZAAAAGgAAAB8AAAAgAAAAIQAAAOQYAAAQGQAAJBgAAE4xMF9fY3h4YWJpdjEyMF9fc2lfY2xhc3NfdHlwZV9pbmZvRQBObyBlcnJvciBpbmZvcm1hdGlvbgBJbGxlZ2FsIGJ5dGUgc2VxdWVuY2UARG9tYWluIGVycm9yAFJlc3VsdCBub3QgcmVwcmVzZW50YWJsZQBOb3QgYSB0dHkAUGVybWlzc2lvbiBkZW5pZWQAT3BlcmF0aW9uIG5vdCBwZXJtaXR0ZWQATm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeQBObyBzdWNoIHByb2Nlc3MARmlsZSBleGlzdHMAVmFsdWUgdG9vIGxhcmdlIGZvciBkYXRhIHR5cGUATm8gc3BhY2UgbGVmdCBvbiBkZXZpY2UAT3V0IG9mIG1lbW9yeQBSZXNvdXJjZSBidXN5AEludGVycnVwdGVkIHN5c3RlbSBjYWxsAFJlc291cmNlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlAEludmFsaWQgc2VlawBDcm9zcy1kZXZpY2UgbGluawBSZWFkLW9ubHkgZmlsZSBzeXN0ZW0ARGlyZWN0b3J5IG5vdCBlbXB0eQBDb25uZWN0aW9uIHJlc2V0IGJ5IHBlZXIAT3BlcmF0aW9uIHRpbWVkIG91dABDb25uZWN0aW9uIHJlZnVzZWQASG9zdCBpcyBkb3duAEhvc3QgaXMgdW5yZWFjaGFibGUAQWRkcmVzcyBpbiB1c2UAQnJva2VuIHBpcGUASS9PIGVycm9yAE5vIHN1Y2ggZGV2aWNlIG9yIGFkZHJlc3MAQmxvY2sgZGV2aWNlIHJlcXVpcmVkAE5vIHN1Y2ggZGV2aWNlAE5vdCBhIGRpcmVjdG9yeQBJcyBhIGRpcmVjdG9yeQBUZXh0IGZpbGUgYnVzeQBFeGVjIGZvcm1hdCBlcnJvcgBJbnZhbGlkIGFyZ3VtZW50AEFyZ3VtZW50IGxpc3QgdG9vIGxvbmcAU3ltYm9saWMgbGluayBsb29wAEZpbGVuYW1lIHRvbyBsb25nAFRvbyBtYW55IG9wZW4gZmlsZXMgaW4gc3lzdGVtAE5vIGZpbGUgZGVzY3JpcHRvcnMgYXZhaWxhYmxlAEJhZCBmaWxlIGRlc2NyaXB0b3IATm8gY2hpbGQgcHJvY2VzcwBCYWQgYWRkcmVzcwBGaWxlIHRvbyBsYXJnZQBUb28gbWFueSBsaW5rcwBObyBsb2NrcyBhdmFpbGFibGUAUmVzb3VyY2UgZGVhZGxvY2sgd291bGQgb2NjdXIAU3RhdGUgbm90IHJlY292ZXJhYmxlAFByZXZpb3VzIG93bmVyIGRpZWQAT3BlcmF0aW9uIGNhbmNlbGVkAEZ1bmN0aW9uIG5vdCBpbXBsZW1lbnRlZABObyBtZXNzYWdlIG9mIGRlc2lyZWQgdHlwZQBJZGVudGlmaWVyIHJlbW92ZWQARGV2aWNlIG5vdCBhIHN0cmVhbQBObyBkYXRhIGF2YWlsYWJsZQBEZXZpY2UgdGltZW91dABPdXQgb2Ygc3RyZWFtcyByZXNvdXJjZXMATGluayBoYXMgYmVlbiBzZXZlcmVkAFByb3RvY29sIGVycm9yAEJhZCBtZXNzYWdlAEZpbGUgZGVzY3JpcHRvciBpbiBiYWQgc3RhdGUATm90IGEgc29ja2V0AERlc3RpbmF0aW9uIGFkZHJlc3MgcmVxdWlyZWQATWVzc2FnZSB0b28gbGFyZ2UAUHJvdG9jb2wgd3JvbmcgdHlwZSBmb3Igc29ja2V0AFByb3RvY29sIG5vdCBhdmFpbGFibGUAUHJvdG9jb2wgbm90IHN1cHBvcnRlZABTb2NrZXQgdHlwZSBub3Qgc3VwcG9ydGVkAE5vdCBzdXBwb3J0ZWQAUHJvdG9jb2wgZmFtaWx5IG5vdCBzdXBwb3J0ZWQAQWRkcmVzcyBmYW1pbHkgbm90IHN1cHBvcnRlZCBieSBwcm90b2NvbABBZGRyZXNzIG5vdCBhdmFpbGFibGUATmV0d29yayBpcyBkb3duAE5ldHdvcmsgdW5yZWFjaGFibGUAQ29ubmVjdGlvbiByZXNldCBieSBuZXR3b3JrAENvbm5lY3Rpb24gYWJvcnRlZABObyBidWZmZXIgc3BhY2UgYXZhaWxhYmxlAFNvY2tldCBpcyBjb25uZWN0ZWQAU29ja2V0IG5vdCBjb25uZWN0ZWQAQ2Fubm90IHNlbmQgYWZ0ZXIgc29ja2V0IHNodXRkb3duAE9wZXJhdGlvbiBhbHJlYWR5IGluIHByb2dyZXNzAE9wZXJhdGlvbiBpbiBwcm9ncmVzcwBTdGFsZSBmaWxlIGhhbmRsZQBSZW1vdGUgSS9PIGVycm9yAFF1b3RhIGV4Y2VlZGVkAE5vIG1lZGl1bSBmb3VuZABXcm9uZyBtZWRpdW0gdHlwZQBNdWx0aWhvcCBhdHRlbXB0ZWQAUmVxdWlyZWQga2V5IG5vdCBhdmFpbGFibGUAS2V5IGhhcyBleHBpcmVkAEtleSBoYXMgYmVlbiByZXZva2VkAEtleSB3YXMgcmVqZWN0ZWQgYnkgc2VydmljZQAAAAClAlsA8AG1BYwFJQGDBh0DlAT/AMcDMQMLBrwBjwF/A8oEKwDaBq8AQgNOA9wBDgQVAKEGDQGUAgsCOAZkArwC/wJdA+cECwfPAssF7wXbBeECHgZFAoUAggJsA28E8QDzAxgF2QDaA0wGVAJ7AZ0DvQQAAFEAFQK7ALMDbQD/AYUELwX5BDgAZQFGAZ8AtwaoAXMCUwEAQfjCAAsMIQQAAAAAAAAAAC8CAEGYwwALBjUERwRWBABBrsMACwKgBABBwsMAC/QdRgVgBW4FYQYAAM8BAAAAAAAAAADJBukG+QYeBzkHSQdeB2xpYnJhcnkvc3RkL3NyYy9wYW5pY2tpbmcucnNyZWVudHJhbnQgaW5pdC9ydXN0Yy82YjAwYmMzODgwMTk4NjAwMTMwZTFjZjYyYjhmOGE5MzQ5NDQ4OGNjL2xpYnJhcnkvY29yZS9zcmMvY2VsbC9vbmNlLnJzY2FsbGVkIGBSZXN1bHQ6OnVud3JhcCgpYCBvbiBhbiBgRXJyYCB2YWx1ZS9ydXN0Yy82YjAwYmMzODgwMTk4NjAwMTMwZTFjZjYyYjhmOGE5MzQ5NDQ4OGNjL2xpYnJhcnkvYWxsb2Mvc3JjL3Jhd192ZWMvbW9kLnJzTnVsRXJyb3I6L3J1c3RjLzZiMDBiYzM4ODAxOTg2MDAxMzBlMWNmNjJiOGY4YTkzNDk0NDg4Y2MvbGlicmFyeS9hbGxvYy9zcmMvc2xpY2UucnN1c2Ugb2Ygc3RkOjp0aHJlYWQ6OmN1cnJlbnQoKSBpcyBub3QgcG9zc2libGUgYWZ0ZXIgdGhlIHRocmVhZCdzIGxvY2FsIGRhdGEgaGFzIGJlZW4gZGVzdHJveWVkbGlicmFyeS9zdGQvc3JjL3RocmVhZC9jdXJyZW50LnJzZmF0YWwgcnVudGltZSBlcnJvcjogCkF0dGVtcHRlZCB0byBhY2Nlc3MgdGhyZWFkLWxvY2FsIGRhdGEgd2hpbGUgYWxsb2NhdGluZyBzYWlkIGRhdGEuCkRvIG5vdCBhY2Nlc3MgZnVuY3Rpb25zIHRoYXQgYWxsb2NhdGUgaW4gdGhlIGdsb2JhbCBhbGxvY2F0b3IhClRoaXMgaXMgYSBidWcgaW4gdGhlIGdsb2JhbCBhbGxvY2F0b3IuCiwgYWJvcnRpbmcKbGlicmFyeS9zdGQvc3JjL3RocmVhZC9tb2QucnNmYWlsZWQgdG8gZ2VuZXJhdGUgdW5pcXVlIHRocmVhZCBJRDogYml0c3BhY2UgZXhoYXVzdGVkdGhyZWFkIG5hbWUgbWF5IG5vdCBjb250YWluIGludGVyaW9yIG51bGwgYnl0ZXNtYWluUlVTVF9CQUNLVFJBQ0VXb3VsZEJsb2NrAQAAAAAAAABmYWlsZWQgdG8gd3JpdGUgd2hvbGUgYnVmZmVyZW50aXR5IG5vdCBmb3VuZHBlcm1pc3Npb24gZGVuaWVkY29ubmVjdGlvbiByZWZ1c2VkY29ubmVjdGlvbiByZXNldGhvc3QgdW5yZWFjaGFibGVuZXR3b3JrIHVucmVhY2hhYmxlY29ubmVjdGlvbiBhYm9ydGVkbm90IGNvbm5lY3RlZGFkZHJlc3MgaW4gdXNlYWRkcmVzcyBub3QgYXZhaWxhYmxlbmV0d29yayBkb3duYnJva2VuIHBpcGVlbnRpdHkgYWxyZWFkeSBleGlzdHNvcGVyYXRpb24gd291bGQgYmxvY2tub3QgYSBkaXJlY3RvcnlpcyBhIGRpcmVjdG9yeWRpcmVjdG9yeSBub3QgZW1wdHlyZWFkLW9ubHkgZmlsZXN5c3RlbSBvciBzdG9yYWdlIG1lZGl1bWZpbGVzeXN0ZW0gbG9vcCBvciBpbmRpcmVjdGlvbiBsaW1pdCAoZS5nLiBzeW1saW5rIGxvb3Apc3RhbGUgbmV0d29yayBmaWxlIGhhbmRsZWludmFsaWQgaW5wdXQgcGFyYW1ldGVyaW52YWxpZCBkYXRhdGltZWQgb3V0d3JpdGUgemVyb25vIHN0b3JhZ2Ugc3BhY2VzZWVrIG9uIHVuc2Vla2FibGUgZmlsZXF1b3RhIGV4Y2VlZGVkZmlsZSB0b28gbGFyZ2VyZXNvdXJjZSBidXN5ZXhlY3V0YWJsZSBmaWxlIGJ1c3lkZWFkbG9ja2Nyb3NzLWRldmljZSBsaW5rIG9yIHJlbmFtZXRvbyBtYW55IGxpbmtzaW52YWxpZCBmaWxlbmFtZWFyZ3VtZW50IGxpc3QgdG9vIGxvbmdvcGVyYXRpb24gaW50ZXJydXB0ZWR1bnN1cHBvcnRlZHVuZXhwZWN0ZWQgZW5kIG9mIGZpbGVvdXQgb2YgbWVtb3J5aW4gcHJvZ3Jlc3NvdGhlciBlcnJvcnVuY2F0ZWdvcml6ZWQgZXJyb3JPc2NvZGVraW5kbWVzc2FnZUtpbmRFcnJvckN1c3RvbWVycm9yIChvcyBlcnJvciApbGlicmFyeS9zdGQvc3JjL2lvL21vZC5yc2EgZm9ybWF0dGluZyB0cmFpdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB3aGVuIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBkaWQgbm90YWR2YW5jaW5nIGlvIHNsaWNlcyBiZXlvbmQgdGhlaXIgbGVuZ3RoYWR2YW5jaW5nIElvU2xpY2UgYmV5b25kIGl0cyBsZW5ndGhsaWJyYXJ5L3N0ZC9zcmMvc3lzL2lvL2lvX3NsaWNlL2lvdmVjLnJzcGFuaWNrZWQgYXQgOgpmaWxlIG5hbWUgY29udGFpbmVkIGFuIHVuZXhwZWN0ZWQgTlVMIGJ5dGVzdGFjayBiYWNrdHJhY2U6Cm5vdGU6IFNvbWUgZGV0YWlscyBhcmUgb21pdHRlZCwgcnVuIHdpdGggYFJVU1RfQkFDS1RSQUNFPWZ1bGxgIGZvciBhIHZlcmJvc2UgYmFja3RyYWNlLgptZW1vcnkgYWxsb2NhdGlvbiBvZiAgYnl0ZXMgZmFpbGVkCiBieXRlcyBmYWlsZWRsaWJyYXJ5L3N0ZC9zcmMvYWxsb2MucnNmYXRhbCBydW50aW1lIGVycm9yOiBSdXN0IHBhbmljcyBtdXN0IGJlIHJldGhyb3duLCBhYm9ydGluZwpub3RlOiBydW4gd2l0aCBgUlVTVF9CQUNLVFJBQ0U9MWAgZW52aXJvbm1lbnQgdmFyaWFibGUgdG8gZGlzcGxheSBhIGJhY2t0cmFjZQo8dW5uYW1lZD4KdGhyZWFkICcnIHBhbmlja2VkIGF0IApCb3g8ZHluIEFueT5hYm9ydGluZyBkdWUgdG8gcGFuaWMgYXQgCnRocmVhZCBwYW5pY2tlZCB3aGlsZSBwcm9jZXNzaW5nIHBhbmljLiBhYm9ydGluZy4KdGhyZWFkIGNhdXNlZCBub24tdW53aW5kaW5nIHBhbmljLiBhYm9ydGluZy4KZmF0YWwgcnVudGltZSBlcnJvcjogZmFpbGVkIHRvIGluaXRpYXRlIHBhbmljLCBlcnJvciAsIGFib3J0aW5nCk5vdEZvdW5kUGVybWlzc2lvbkRlbmllZENvbm5lY3Rpb25SZWZ1c2VkQ29ubmVjdGlvblJlc2V0SG9zdFVucmVhY2hhYmxlTmV0d29ya1VucmVhY2hhYmxlQ29ubmVjdGlvbkFib3J0ZWROb3RDb25uZWN0ZWRBZGRySW5Vc2VBZGRyTm90QXZhaWxhYmxlTmV0d29ya0Rvd25Ccm9rZW5QaXBlQWxyZWFkeUV4aXN0c05vdEFEaXJlY3RvcnlJc0FEaXJlY3RvcnlEaXJlY3RvcnlOb3RFbXB0eVJlYWRPbmx5RmlsZXN5c3RlbUZpbGVzeXN0ZW1Mb29wU3RhbGVOZXR3b3JrRmlsZUhhbmRsZUludmFsaWRJbnB1dEludmFsaWREYXRhVGltZWRPdXRXcml0ZVplcm9TdG9yYWdlRnVsbE5vdFNlZWthYmxlUXVvdGFFeGNlZWRlZEZpbGVUb29MYXJnZVJlc291cmNlQnVzeUV4ZWN1dGFibGVGaWxlQnVzeURlYWRsb2NrQ3Jvc3Nlc0RldmljZXNUb29NYW55TGlua3NJbnZhbGlkRmlsZW5hbWVBcmd1bWVudExpc3RUb29Mb25nSW50ZXJydXB0ZWRVbnN1cHBvcnRlZFVuZXhwZWN0ZWRFb2ZPdXRPZk1lbW9yeUluUHJvZ3Jlc3NPdGhlclVuY2F0ZWdvcml6ZWRzdHJlcnJvcl9yIGZhaWx1cmVsaWJyYXJ5L3N0ZC9zcmMvc3lzL3BhbC91bml4L29zLnJzbGlicmFyeS9zdGQvc3JjL3N5cy9wYWwvdW5peC9zeW5jL2NvbmR2YXIucnMAAAAAbGlicmFyeS9zdGQvc3JjL3N5cy9wYWwvdW5peC9zeW5jL211dGV4LnJzZmFpbGVkIHRvIGxvY2sgbXV0ZXg6IAIAAABsaWJyYXJ5L3N0ZC9zcmMvc3lzL3N5bmMvcndsb2NrL3F1ZXVlLnJzZmF0YWwgcnVudGltZSBlcnJvcjogdHJpZWQgdG8gZHJvcCBub2RlIGluIGludHJ1c2l2ZSBsaXN0LiwgYWJvcnRpbmcKcGFyayBzdGF0ZSBjaGFuZ2VkIHVuZXhwZWN0ZWRseWxpYnJhcnkvc3RkL3NyYy9zeXMvc3luYy90aHJlYWRfcGFya2luZy9wdGhyZWFkLnJzaW5jb25zaXN0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")}function getBinarySync(file){if(ArrayBuffer.isView(file)){return file}if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return{a:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["u"];updateMemoryViews();wasmTable=wasmExports["H"];assignWasmExports(wasmExports);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod,inst))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var base64Decode=b64=>{var b1,b2,i=0,j=0,bLength=b64.length;var output=new Uint8Array((bLength*3>>2)-(b64[bLength-2]=="=")-(b64[bLength-1]=="="));for(;i>4;output[j+1]=b1<<4|b2>>2;output[j+2]=b2<<6|base64ReverseLookup[b64.charCodeAt(i+3)]}return output};var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var exceptionLast=0;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var setTempRet0=val=>__emscripten_tempret_set(val);var findMatchingCatch=args=>{var thrown=exceptionLast;if(!thrown){setTempRet0(0);return 0}var info=new ExceptionInfo(thrown);info.set_adjusted_ptr(thrown);var thrownType=info.get_type();if(!thrownType){setTempRet0(0);return thrown}for(var caughtType of args){if(caughtType===0||caughtType===thrownType){break}var adjusted_ptr_addr=info.ptr+16;if(___cxa_can_catch(caughtType,thrownType,adjusted_ptr_addr)){setTempRet0(caughtType);return thrown}}setTempRet0(thrownType);return thrown};var ___cxa_find_matching_catch_2=()=>findMatchingCatch([]);var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var ___resumeException=ptr=>{if(!exceptionLast){exceptionLast=ptr}throw exceptionLast};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);function ___syscall_getcwd(buf,size){try{if(size===0)return-28;var cwd=FS.cwd();var cwdLengthInBytes=lengthBytesUTF8(cwd)+1;if(sizeabort("");var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.language||"C").replace("-","_")+".UTF-8";var env={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:lang,_:getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;var envp=0;for(var string of getEnvStrings()){var ptr=environ_buf+bufSize;HEAPU32[__environ+envp>>2]=ptr;bufSize+=stringToUTF8(string,ptr,Infinity)+1;envp+=4}return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;for(var string of strings){bufSize+=lengthBytesUTF8(string)+1}HEAPU32[penviron_buf_size>>2]=bufSize;return 0};var runtimeKeepaliveCounter=0;var keepRuntimeAlive=()=>noExitRuntime||runtimeKeepaliveCounter>0;var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){Module["onExit"]?.(code);ABORT=true}quit_(code,new ExitStatus(code))};var exitJS=(status,implicit)=>{EXITSTATUS=status;_proc_exit(status)};var _exit=exitJS;var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.slice(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.slice(0,-1)}return root+dir},basename:path=>path&&path.match(/([^\/]+|\/)\/*$/)[1],join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>view=>crypto.getRandomValues(view);var randomFill=view=>{(randomFill=initRandomFill())(view)};var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).slice(1);to=PATH_FS.resolve(to).slice(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var FS_stdin_getChar_buffer=[];var intArrayFromString=(stringy,dontAddNull,length)=>{var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array};var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else{}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output?.length>0){err(UTF8ArrayToString(tty.output));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16895,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.atime=node.mtime=node.ctime=Date.now();if(parent){parent.contents[name]=node;parent.atime=parent.mtime=parent.ctime=node.atime}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.atime);attr.mtime=new Date(node.mtime);attr.ctime=new Date(node.ctime);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){for(const key of["mode","atime","mtime","ctime"]){if(attr[key]!=null){node[key]=attr[key]}}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw MEMFS.doesNotExistError},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){if(FS.isDir(old_node.mode)){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}FS.hashRemoveNode(new_node)}delete old_node.parent.contents[old_node.name];new_dir.contents[new_name]=old_node;old_node.name=new_name;new_dir.ctime=new_dir.mtime=old_node.parent.ctime=old_node.parent.mtime=Date.now()},unlink(parent,name){delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},readdir(node){return[".","..",...Object.keys(node.contents)]},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var arrayBuffer=await readAsync(url);return new Uint8Array(arrayBuffer)};var FS_createDataFile=(...args)=>FS.createDataFile(...args);var getUniqueRunDependency=id=>id;var preloadPlugins=[];var FS_handledByPreloadPlugin=(byteArray,fullname,finish,onerror)=>{if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach(plugin=>{if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}});return handled};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}onload?.();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,()=>{onerror?.();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url).then(processData,onerror)}else{processData(url)}};var FS_modeStringToFlags=str=>{var flagModes={r:0,"r+":2,w:512|64|1,"w+":512|64|2,a:1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,filesystems:null,syncFSRequests:0,readFiles:{},ErrnoError:class{name="ErrnoError";constructor(errno){this.errno=errno}},FSStream:class{shared={};get object(){return this.node}set object(val){this.node=val}get isRead(){return(this.flags&2097155)!==1}get isWrite(){return(this.flags&2097155)!==0}get isAppend(){return this.flags&1024}get flags(){return this.shared.flags}set flags(val){this.shared.flags=val}get position(){return this.shared.position}set position(val){this.shared.position=val}},FSNode:class{node_ops={};stream_ops={};readMode=292|73;writeMode=146;mounted=null;constructor(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.rdev=rdev;this.atime=this.mtime=this.ctime=Date.now()}get read(){return(this.mode&this.readMode)===this.readMode}set read(val){val?this.mode|=this.readMode:this.mode&=~this.readMode}get write(){return(this.mode&this.writeMode)===this.writeMode}set write(val){val?this.mode|=this.writeMode:this.mode&=~this.writeMode}get isFolder(){return FS.isDir(this.mode)}get isDevice(){return FS.isChrdev(this.mode)}},lookupPath(path,opts={}){if(!path){throw new FS.ErrnoError(44)}opts.follow_mount??=true;if(!PATH.isAbs(path)){path=FS.cwd()+"/"+path}linkloop:for(var nlinks=0;nlinks<40;nlinks++){var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){if(!FS.isDir(dir.mode)){return 54}try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&(512|64)){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},checkOpExists(op,err){if(!op){throw new FS.ErrnoError(err)}return op},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},dupStream(origStream,fd=-1){var stream=FS.createStream(origStream,fd);stream.stream_ops?.dup?.(stream);return stream},doSetAttr(stream,node,attr){var setattr=stream?.stream_ops.setattr;var arg=setattr?stream:node;setattr??=node.node_ops.setattr;FS.checkOpExists(setattr,63);setattr(arg,attr)},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type,opts,mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name){throw new FS.ErrnoError(28)}if(name==="."||name===".."){throw new FS.ErrnoError(20)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},statfs(path){return FS.statfsNode(FS.lookupPath(path,{follow:true}).node)},statfsStream(stream){return FS.statfsNode(stream.node)},statfsNode(node){var rtn={bsize:4096,frsize:4096,blocks:1e6,bfree:5e5,bavail:5e5,files:FS.nextInode,ffree:FS.nextInode-1,fsid:42,flags:2,namelen:255};if(node.node_ops.statfs){Object.assign(rtn,node.node_ops.statfs(node.mount.opts.root))}return rtn},create(path,mode=438){mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode=511){mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var dir of dirs){if(!dir)continue;if(d||PATH.isAbs(path))d+="/";d+=dir;try{FS.mkdir(d,mode)}catch(e){if(e.errno!=20)throw e}}},mkdev(path,mode,dev){if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink(oldpath,newpath){if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name);old_node.parent=new_dir}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var readdir=FS.checkOpExists(node.node_ops.readdir,54);return readdir(node)},unlink(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return link.node_ops.readlink(link)},stat(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;var getattr=FS.checkOpExists(node.node_ops.getattr,63);return getattr(node)},fstat(fd){var stream=FS.getStreamChecked(fd);var node=stream.node;var getattr=stream.stream_ops.getattr;var arg=getattr?stream:node;getattr??=node.node_ops.getattr;FS.checkOpExists(getattr,63);return getattr(arg)},lstat(path){return FS.stat(path,true)},doChmod(stream,node,mode,dontFollow){FS.doSetAttr(stream,node,{mode:mode&4095|node.mode&~4095,ctime:Date.now(),dontFollow})},chmod(path,mode,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChmod(null,node,mode,dontFollow)},lchmod(path,mode){FS.chmod(path,mode,true)},fchmod(fd,mode){var stream=FS.getStreamChecked(fd);FS.doChmod(stream,stream.node,mode,false)},doChown(stream,node,dontFollow){FS.doSetAttr(stream,node,{timestamp:Date.now(),dontFollow})},chown(path,uid,gid,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChown(null,node,dontFollow)},lchown(path,uid,gid){FS.chown(path,uid,gid,true)},fchown(fd,uid,gid){var stream=FS.getStreamChecked(fd);FS.doChown(stream,stream.node,false)},doTruncate(stream,node,len){if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}FS.doSetAttr(stream,node,{size:len,timestamp:Date.now()})},truncate(path,len){if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}FS.doTruncate(null,node,len)},ftruncate(fd,len){var stream=FS.getStreamChecked(fd);if(len<0||(stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.doTruncate(stream,stream.node,len)},utime(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var setattr=FS.checkOpExists(node.node_ops.setattr,63);setattr(node,{atime,mtime})},open(path,flags,mode=438){if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS_modeStringToFlags(flags):flags;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;var isDirPath;if(typeof path=="object"){node=path}else{isDirPath=path.endsWith("/");var lookup=FS.lookupPath(path,{follow:!(flags&131072),noent_okay:true});node=lookup.node;path=lookup.path}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else if(isDirPath){throw new FS.ErrnoError(31)}else{node=FS.mknod(path,mode|511,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node,path:FS.getPath(node),flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(created){FS.chmod(node,mode&511)}if(Module["logReadFiles"]&&!(flags&1)){if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close(stream){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed(stream){return stream.fd===null},llseek(stream,offset,whence){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},mmap(stream,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}if(!length){throw new FS.ErrnoError(28)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync(stream,buffer,offset,length,mmapFlags){if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){buf=UTF8ArrayToString(buf)}FS.close(stream);return buf},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){data=new Uint8Array(intArrayFromString(data,true))}if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length,llseek:()=>0});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomFill(randomBuffer);randomLeft=randomBuffer.byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16895,73);node.stream_ops={llseek:MEMFS.stream_ops.llseek};node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path},id:fd+1};ret.parent=ret;return ret},readdir(){return Array.from(FS.streams.entries()).filter(([k,v])=>v).map(([k,v])=>k.toString())}};return node}},{},"/proc/self/fd")},createStandardStreams(input,output,error){if(input){FS.createDevice("/dev","stdin",input)}else{FS.symlink("/dev/tty","/dev/stdin")}if(output){FS.createDevice("/dev","stdout",null,output)}else{FS.symlink("/dev/tty","/dev/stdout")}if(error){FS.createDevice("/dev","stderr",null,error)}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},staticInit(){FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={MEMFS}},init(input,output,error){FS.initialized=true;input??=Module["stdin"];output??=Module["stdout"];error??=Module["stderr"];FS.createStandardStreams(input,output,error)},quit(){FS.initialized=false;for(var stream of FS.streams){if(stream){FS.close(stream)}}},findObject(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath(parent,path,canRead,canWrite){parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){if(e.errno!=20)throw e}parent=current}return current},createFile(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile(parent,name,data,canRead,canWrite,canOwn){var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]}setDataGetter(getter){this.getter=getter}cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true}get length(){if(!this.lengthKnown){this.cacheLength()}return this._length}get chunkSize(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(key=>{var fn=node.stream_ops[key];stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}});function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return dir+"/"+path},writeStat(buf,stat){HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAP32[buf+12>>2]=stat.uid;HEAP32[buf+16>>2]=stat.gid;HEAP32[buf+20>>2]=stat.rdev;HEAP64[buf+24>>3]=BigInt(stat.size);HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();HEAP64[buf+40>>3]=BigInt(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3*1e3;HEAP64[buf+56>>3]=BigInt(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3*1e3;HEAP64[buf+72>>3]=BigInt(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3*1e3;HEAP64[buf+88>>3]=BigInt(stat.ino);return 0},writeStatFs(buf,stats){HEAP32[buf+4>>2]=stats.bsize;HEAP32[buf+40>>2]=stats.bsize;HEAP32[buf+8>>2]=stats.blocks;HEAP32[buf+12>>2]=stats.bfree;HEAP32[buf+16>>2]=stats.bavail;HEAP32[buf+20>>2]=stats.files;HEAP32[buf+24>>2]=stats.ffree;HEAP32[buf+28>>2]=stats.fsid;HEAP32[buf+44>>2]=stats.flags;HEAP32[buf+36>>2]=stats.namelen},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream},varargs:undefined,getStr(ptr){var ret=UTF8ToString(ptr);return ret}};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>numINT53_MAX?NaN:Number(num);function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);HEAP64[newOffset>>3]=BigInt(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var wasmTableMirror=[];var wasmTable;var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};for(var base64ReverseLookup=new Uint8Array(123),i=25;i>=0;--i){base64ReverseLookup[48+i]=52+i;base64ReverseLookup[65+i]=i;base64ReverseLookup[97+i]=26+i}base64ReverseLookup[43]=62;base64ReverseLookup[47]=63;FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();MEMFS.doesNotExistError=new FS.ErrnoError(44);MEMFS.doesNotExistError.stack="";{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["preloadPlugins"])preloadPlugins=Module["preloadPlugins"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}Module["ccall"]=ccall;Module["cwrap"]=cwrap;var _AecNew,_AecCancelEcho,_AecDestroy,_malloc,_free,_setThrew,__emscripten_tempret_set,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,___cxa_can_catch;function assignWasmExports(wasmExports){Module["_AecNew"]=_AecNew=wasmExports["w"];Module["_AecCancelEcho"]=_AecCancelEcho=wasmExports["x"];Module["_AecDestroy"]=_AecDestroy=wasmExports["y"];Module["_malloc"]=_malloc=wasmExports["z"];Module["_free"]=_free=wasmExports["A"];_setThrew=wasmExports["B"];__emscripten_tempret_set=wasmExports["C"];__emscripten_stack_restore=wasmExports["D"];__emscripten_stack_alloc=wasmExports["E"];_emscripten_stack_get_current=wasmExports["F"];___cxa_can_catch=wasmExports["G"]}var wasmImports={a:___cxa_find_matching_catch_2,q:___cxa_throw,b:___resumeException,p:___syscall_getcwd,r:__abort_js,t:_emscripten_resize_heap,n:_environ_get,o:_environ_sizes_get,k:_exit,s:_fd_close,l:_fd_seek,g:_fd_write,i:invoke_ii,f:invoke_iiii,m:invoke_iiiiii,c:invoke_vi,d:invoke_vii,e:invoke_viii,j:invoke_viiii,h:invoke_viiiii};var wasmExports=await createWasm();function invoke_vi(index,a1){var sp=stackSave();try{getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viii(index,a1,a2,a3){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_vii(index,a1,a2){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viiii(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iiii(index,a1,a2,a3){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_ii(index,a1){var sp=stackSave();try{return getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iiiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})} + + + return moduleRtn; +} +); +})(); +if (typeof exports === 'object' && typeof module === 'object') { + module.exports = createAecModule; + // This default export looks redundant, but it allows TS to import this + // commonjs style module. + module.exports.default = createAecModule; +} else if (typeof define === 'function' && define['amd']) + define([], () => createAecModule); diff --git a/src/common/ai/providers/gemini.js b/src/common/ai/providers/gemini.js index c3c4743..31f7e33 100644 --- a/src/common/ai/providers/gemini.js +++ b/src/common/ai/providers/gemini.js @@ -1,5 +1,5 @@ -const { GoogleGenerativeAI } = require('@google/generative-ai'); -const { GoogleGenAI } = require('@google/genai'); +const { GoogleGenerativeAI } = require("@google/generative-ai") +const { GoogleGenAI } = require("@google/genai") /** * Creates a Gemini STT session @@ -9,322 +9,294 @@ const { GoogleGenAI } = require('@google/genai'); * @param {object} [opts.callbacks] - Event callbacks * @returns {Promise} STT session */ -async function createSTT({ apiKey, language = 'en-US', callbacks = {}, ...config }) { - const liveClient = new GoogleGenAI({ vertexai: false, apiKey }); +async function createSTT({ apiKey, language = "en-US", callbacks = {}, ...config }) { + const liveClient = new GoogleGenAI({ vertexai: false, apiKey }) // Language code BCP-47 conversion - const lang = language.includes('-') ? language : `${language}-US`; + const lang = language.includes("-") ? language : `${language}-US` const session = await liveClient.live.connect({ + model: 'gemini-live-2.5-flash-preview', - callbacks, + callbacks: { + ...callbacks, + onMessage: (msg) => { + if (!msg || typeof msg !== 'object') return; + msg.provider = 'gemini'; + callbacks.onmessage?.(msg); + } + }, + config: { inputAudioTranscription: {}, speechConfig: { languageCode: lang }, }, - }); + }) return { - sendRealtimeInput: async payload => session.sendRealtimeInput(payload), + sendRealtimeInput: async (payload) => session.sendRealtimeInput(payload), close: async () => session.close(), - }; + } } /** - * Creates a Gemini LLM instance - * @param {object} opts - Configuration options - * @param {string} opts.apiKey - Gemini API key - * @param {string} [opts.model='gemini-2.5-flash'] - Model name - * @param {number} [opts.temperature=0.7] - Temperature - * @param {number} [opts.maxTokens=8192] - Max tokens - * @returns {object} LLM instance + * Creates a Gemini LLM instance with proper text response handling */ -function createLLM({ apiKey, model = 'gemini-2.5-flash', temperature = 0.7, maxTokens = 8192, ...config }) { - const client = new GoogleGenerativeAI(apiKey); - +function createLLM({ apiKey, model = "gemini-2.5-flash", temperature = 0.7, maxTokens = 8192, ...config }) { + const client = new GoogleGenerativeAI(apiKey) + return { generateContent: async (parts) => { - const geminiModel = client.getGenerativeModel({ model: model }); - - let systemPrompt = ''; - let userContent = []; - + const geminiModel = client.getGenerativeModel({ + model: model, + generationConfig: { + temperature, + maxOutputTokens: maxTokens, + // Ensure we get text responses, not JSON + responseMimeType: "text/plain", + }, + }) + + const systemPrompt = "" + const userContent = [] + for (const part of parts) { - if (typeof part === 'string') { - if (systemPrompt === '' && part.includes('You are')) { - systemPrompt = part; - } else { - userContent.push(part); - } + if (typeof part === "string") { + // Don't automatically assume strings starting with "You are" are system prompts + // Check if it's explicitly marked as a system instruction + userContent.push(part) } else if (part.inlineData) { - // Convert base64 image data to Gemini format userContent.push({ inlineData: { mimeType: part.inlineData.mimeType, - data: part.inlineData.data - } - }); + data: part.inlineData.data, + }, + }) } } - - // Prepare content array - const content = []; - - // Add system instruction if present - if (systemPrompt) { - // For Gemini, we'll prepend system prompt to user content - content.push(systemPrompt + '\n\n' + userContent[0]); - content.push(...userContent.slice(1)); - } else { - content.push(...userContent); - } - + try { - const result = await geminiModel.generateContent(content); - const response = await result.response; - + const result = await geminiModel.generateContent(userContent) + const response = await result.response + + // Return plain text, not wrapped in JSON structure return { response: { - text: () => response.text() - } - }; + text: () => response.text(), + }, + } } catch (error) { - console.error('Gemini API error:', error); - throw error; + console.error("Gemini API error:", error) + throw error } }, - - // For compatibility with chat-style interfaces + chat: async (messages) => { - // Extract system instruction if present - let systemInstruction = ''; - const history = []; - let lastMessage; + // Filter out any system prompts that might be causing JSON responses + let systemInstruction = "" + const history = [] + let lastMessage messages.forEach((msg, index) => { - if (msg.role === 'system') { - systemInstruction = msg.content; - return; + if (msg.role === "system") { + // Clean system instruction - avoid JSON formatting requests + systemInstruction = msg.content + .replace(/respond in json/gi, "") + .replace(/format.*json/gi, "") + .replace(/return.*json/gi, "") + + // Add explicit instruction for natural text + if (!systemInstruction.includes("respond naturally")) { + systemInstruction += "\n\nRespond naturally in plain text, not in JSON or structured format." + } + return } - - // Gemini's history format - const role = msg.role === 'user' ? 'user' : 'model'; + + const role = msg.role === "user" ? "user" : "model" if (index === messages.length - 1) { - lastMessage = msg; + lastMessage = msg } else { - history.push({ role, parts: [{ text: msg.content }] }); + history.push({ role, parts: [{ text: msg.content }] }) } - }); - - const geminiModel = client.getGenerativeModel({ + }) + + const geminiModel = client.getGenerativeModel({ model: model, - systemInstruction: systemInstruction - }); - - const chat = geminiModel.startChat({ - history: history, + systemInstruction: + systemInstruction || + "Respond naturally in plain text format. Do not use JSON or structured responses unless specifically requested.", generationConfig: { temperature: temperature, maxOutputTokens: maxTokens, - } - }); - - // Get the last user message content - let content = lastMessage.content; - - // Handle multimodal content for the last message + // Force plain text responses + responseMimeType: "text/plain", + }, + }) + + const chat = geminiModel.startChat({ + history: history, + }) + + let content = lastMessage.content + + // Handle multimodal content if (Array.isArray(content)) { - const geminiContent = []; + const geminiContent = [] for (const part of content) { - if (typeof part === 'string') { - geminiContent.push(part); - } else if (part.type === 'text') { - geminiContent.push(part.text); - } else if (part.type === 'image_url' && part.image_url) { - // Convert base64 image to Gemini format - const base64Data = part.image_url.url.split(',')[1]; + if (typeof part === "string") { + geminiContent.push(part) + } else if (part.type === "text") { + geminiContent.push(part.text) + } else if (part.type === "image_url" && part.image_url) { + const base64Data = part.image_url.url.split(",")[1] geminiContent.push({ inlineData: { - mimeType: 'image/png', - data: base64Data - } - }); + mimeType: "image/png", + data: base64Data, + }, + }) } } - content = geminiContent; + content = geminiContent } - - const result = await chat.sendMessage(content); - const response = await result.response; + + const result = await chat.sendMessage(content) + const response = await result.response + + // Return plain text content return { content: response.text(), - raw: result - }; - } - }; + raw: result, + } + }, + } } /** - * Creates a Gemini streaming LLM instance - * @param {object} opts - Configuration options - * @param {string} opts.apiKey - Gemini API key - * @param {string} [opts.model='gemini-2.5-flash'] - Model name - * @param {number} [opts.temperature=0.7] - Temperature - * @param {number} [opts.maxTokens=8192] - Max tokens - * @returns {object} Streaming LLM instance + * Creates a Gemini streaming LLM instance with text response fix */ -function createStreamingLLM({ apiKey, model = 'gemini-2.5-flash', temperature = 0.7, maxTokens = 8192, ...config }) { - const client = new GoogleGenerativeAI(apiKey); - +function createStreamingLLM({ apiKey, model = "gemini-2.5-flash", temperature = 0.7, maxTokens = 8192, ...config }) { + const client = new GoogleGenerativeAI(apiKey) + return { streamChat: async (messages) => { - console.log('[Gemini Provider] Starting streaming request'); - - // Extract system instruction if present - let systemInstruction = ''; - const nonSystemMessages = []; - + console.log("[Gemini Provider] Starting streaming request") + + let systemInstruction = "" + const nonSystemMessages = [] + for (const msg of messages) { - if (msg.role === 'system') { - systemInstruction = msg.content; + if (msg.role === "system") { + // Clean and modify system instruction + systemInstruction = msg.content + .replace(/respond in json/gi, "") + .replace(/format.*json/gi, "") + .replace(/return.*json/gi, "") + + if (!systemInstruction.includes("respond naturally")) { + systemInstruction += "\n\nRespond naturally in plain text, not in JSON or structured format." + } } else { - nonSystemMessages.push(msg); + nonSystemMessages.push(msg) } } - - const geminiModel = client.getGenerativeModel({ + + const geminiModel = client.getGenerativeModel({ model: model, - systemInstruction: systemInstruction || undefined - }); - - const chat = geminiModel.startChat({ - history: [], + systemInstruction: + systemInstruction || + "Respond naturally in plain text format. Do not use JSON or structured responses unless specifically requested.", generationConfig: { temperature, maxOutputTokens: maxTokens || 8192, - } - }); - - // Create a ReadableStream to handle Gemini's streaming + // Force plain text responses + responseMimeType: "text/plain", + }, + }) + const stream = new ReadableStream({ async start(controller) { try { - console.log('[Gemini Provider] Processing messages:', nonSystemMessages.length, 'messages (excluding system)'); - - // Get the last user message - const lastMessage = nonSystemMessages[nonSystemMessages.length - 1]; - let lastUserMessage = lastMessage.content; - - // Handle case where content might be an array (multimodal) - if (Array.isArray(lastUserMessage)) { - // Extract text content from array - const textParts = lastUserMessage.filter(part => - typeof part === 'string' || (part && part.type === 'text') - ); - lastUserMessage = textParts.map(part => - typeof part === 'string' ? part : part.text - ).join(' '); - } - - console.log('[Gemini Provider] Sending message to Gemini:', - typeof lastUserMessage === 'string' ? lastUserMessage.substring(0, 100) + '...' : 'multimodal content'); - - // Prepare the message content for Gemini - let geminiContent = []; - - // Handle multimodal content properly + const lastMessage = nonSystemMessages[nonSystemMessages.length - 1] + let geminiContent = [] + if (Array.isArray(lastMessage.content)) { for (const part of lastMessage.content) { - if (typeof part === 'string') { - geminiContent.push(part); - } else if (part.type === 'text') { - geminiContent.push(part.text); - } else if (part.type === 'image_url' && part.image_url) { - // Convert base64 image to Gemini format - const base64Data = part.image_url.url.split(',')[1]; + if (typeof part === "string") { + geminiContent.push(part) + } else if (part.type === "text") { + geminiContent.push(part.text) + } else if (part.type === "image_url" && part.image_url) { + const base64Data = part.image_url.url.split(",")[1] geminiContent.push({ inlineData: { - mimeType: 'image/png', - data: base64Data - } - }); + mimeType: "image/png", + data: base64Data, + }, + }) } } } else { - geminiContent = [lastUserMessage]; + geminiContent = [lastMessage.content] } - - console.log('[Gemini Provider] Prepared Gemini content:', - geminiContent.length, 'parts'); - - // Stream the response - let chunkCount = 0; - let totalContent = ''; - - const contentParts = geminiContent.map(part => { - if (typeof part === 'string') { - return { text: part }; + + const contentParts = geminiContent.map((part) => { + if (typeof part === "string") { + return { text: part } } else if (part.inlineData) { - return { inlineData: part.inlineData }; + return { inlineData: part.inlineData } } - return part; - }); + return part + }) const result = await geminiModel.generateContentStream({ - contents: [{ - role: 'user', - parts: contentParts - }], - generationConfig: { - temperature, - maxOutputTokens: maxTokens || 8192, - } - }); - + contents: [ + { + role: "user", + parts: contentParts, + }, + ], + }) + for await (const chunk of result.stream) { - chunkCount++; - const chunkText = chunk.text() || ''; - totalContent += chunkText; - - // Format as SSE data + const chunkText = chunk.text() || "" + + // Format as SSE data - this should now be plain text const data = JSON.stringify({ - choices: [{ - delta: { - content: chunkText - } - }] - }); - controller.enqueue(new TextEncoder().encode(`data: ${data}\n\n`)); + choices: [ + { + delta: { + content: chunkText, + }, + }, + ], + }) + controller.enqueue(new TextEncoder().encode(`data: ${data}\n\n`)) } - - console.log(`[Gemini Provider] Streamed ${chunkCount} chunks, total length: ${totalContent.length} chars`); - - // Send the final done message - controller.enqueue(new TextEncoder().encode('data: [DONE]\n\n')); - controller.close(); - console.log('[Gemini Provider] Streaming completed successfully'); + + controller.enqueue(new TextEncoder().encode("data: [DONE]\n\n")) + controller.close() } catch (error) { - console.error('[Gemini Provider] Streaming error:', error); - controller.error(error); + console.error("[Gemini Provider] Streaming error:", error) + controller.error(error) } - } - }); - - // Create a Response object with the stream + }, + }) + return new Response(stream, { headers: { - 'Content-Type': 'text/event-stream', - 'Cache-Control': 'no-cache', - 'Connection': 'keep-alive' - } - }); - } - }; + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache", + Connection: "keep-alive", + }, + }) + }, + } } module.exports = { createSTT, createLLM, - createStreamingLLM -}; + createStreamingLLM, +} diff --git a/src/common/ai/providers/openai.js b/src/common/ai/providers/openai.js index a27c547..79b1ef3 100644 --- a/src/common/ai/providers/openai.js +++ b/src/common/ai/providers/openai.js @@ -48,11 +48,11 @@ async function createSTT({ apiKey, language = 'en', callbacks = {}, usePortkey = turn_detection: { type: 'server_vad', threshold: 0.5, - prefix_padding_ms: 50, - silence_duration_ms: 25, + prefix_padding_ms: 200, + silence_duration_ms: 100, }, input_audio_noise_reduction: { - type: 'near_field' + type: 'far_field' } } }; @@ -72,6 +72,7 @@ async function createSTT({ apiKey, language = 'en', callbacks = {}, usePortkey = close: () => { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: 'session.close' })); + ws.onmessage = ws.onerror = () => {}; // ν•Έλ“€λŸ¬ 제거 ws.close(1000, 'Client initiated close.'); } } @@ -79,10 +80,17 @@ async function createSTT({ apiKey, language = 'en', callbacks = {}, usePortkey = }; ws.onmessage = (event) => { - const message = JSON.parse(event.data); - if (callbacks && callbacks.onmessage) { - callbacks.onmessage(message); - } + // ── μ’…λ£ŒΒ·ν•˜νŠΈλΉ„νŠΈ νŒ¨ν‚· 필터링 ────────────────────────────── + if (!event.data || event.data === 'null' || event.data === '[DONE]') return; + + let msg; + try { msg = JSON.parse(event.data); } + catch { return; } // JSON νŒŒμ‹± μ‹€νŒ¨ λ¬΄μ‹œ + + if (!msg || typeof msg !== 'object') return; + + msg.provider = 'openai'; // ← 항상 λͺ…μ‹œ + callbacks.onmessage?.(msg); }; ws.onerror = (error) => { diff --git a/src/common/config/schema.js b/src/common/config/schema.js index 19e0d8c..00b58f7 100644 --- a/src/common/config/schema.js +++ b/src/common/config/schema.js @@ -6,7 +6,8 @@ const LATEST_SCHEMA = { { name: 'email', type: 'TEXT NOT NULL' }, { name: 'created_at', type: 'INTEGER' }, { name: 'api_key', type: 'TEXT' }, - { name: 'provider', type: 'TEXT DEFAULT \'openai\'' } + { name: 'provider', type: 'TEXT DEFAULT \'openai\'' }, + { name: 'auto_update_enabled', type: 'INTEGER DEFAULT 1' } ] }, sessions: { diff --git a/src/common/services/authService.js b/src/common/services/authService.js index a664ba1..fd4b9de 100644 --- a/src/common/services/authService.js +++ b/src/common/services/authService.js @@ -37,56 +37,64 @@ class AuthService { this.currentUserMode = 'local'; // 'local' or 'firebase' this.currentUser = null; this.isInitialized = false; + this.initializationPromise = null; } initialize() { - if (this.isInitialized) return; + if (this.isInitialized) return this.initializationPromise; - const auth = getFirebaseAuth(); - onAuthStateChanged(auth, async (user) => { - const previousUser = this.currentUser; + this.initializationPromise = new Promise((resolve) => { + const auth = getFirebaseAuth(); + onAuthStateChanged(auth, async (user) => { + const previousUser = this.currentUser; - if (user) { - // User signed IN - console.log(`[AuthService] Firebase user signed in:`, user.uid); - this.currentUser = user; - this.currentUserId = user.uid; - this.currentUserMode = 'firebase'; + if (user) { + // User signed IN + console.log(`[AuthService] Firebase user signed in:`, user.uid); + this.currentUser = user; + this.currentUserId = user.uid; + this.currentUserMode = 'firebase'; - // Start background task to fetch and save virtual key - (async () => { - try { - const idToken = await user.getIdToken(true); - const virtualKey = await getVirtualKeyByEmail(user.email, idToken); + // Start background task to fetch and save virtual key + (async () => { + try { + const idToken = await user.getIdToken(true); + const virtualKey = await getVirtualKeyByEmail(user.email, idToken); - if (global.modelStateService) { - global.modelStateService.setFirebaseVirtualKey(virtualKey); + if (global.modelStateService) { + global.modelStateService.setFirebaseVirtualKey(virtualKey); + } + console.log(`[AuthService] BG: Virtual key for ${user.email} has been processed.`); + + } catch (error) { + console.error('[AuthService] BG: Failed to fetch or save virtual key:', error); } - console.log(`[AuthService] BG: Virtual key for ${user.email} has been processed.`); + })(); - } catch (error) { - console.error('[AuthService] BG: Failed to fetch or save virtual key:', error); - } - })(); - - } else { - // User signed OUT - console.log(`[AuthService] No Firebase user.`); - if (previousUser) { - console.log(`[AuthService] Clearing API key for logged-out user: ${previousUser.uid}`); - if (global.modelStateService) { - global.modelStateService.setFirebaseVirtualKey(null); + } else { + // User signed OUT + console.log(`[AuthService] No Firebase user.`); + if (previousUser) { + console.log(`[AuthService] Clearing API key for logged-out user: ${previousUser.uid}`); + if (global.modelStateService) { + global.modelStateService.setFirebaseVirtualKey(null); + } } + this.currentUser = null; + this.currentUserId = 'default_user'; + this.currentUserMode = 'local'; } - this.currentUser = null; - this.currentUserId = 'default_user'; - this.currentUserMode = 'local'; - } - this.broadcastUserState(); + this.broadcastUserState(); + + if (!this.isInitialized) { + this.isInitialized = true; + console.log('[AuthService] Initialized and resolved initialization promise.'); + resolve(); + } + }); }); - this.isInitialized = true; - console.log('[AuthService] Initialized and attached to Firebase Auth state.'); + return this.initializationPromise; } async signInWithCustomToken(token) { diff --git a/src/common/services/modelStateService.js b/src/common/services/modelStateService.js index 33de127..7218ce7 100644 --- a/src/common/services/modelStateService.js +++ b/src/common/services/modelStateService.js @@ -67,6 +67,11 @@ class ModelStateService { }; this.state = this.store.get(`users.${userId}`, defaultState); console.log(`[ModelStateService] State loaded for user: ${userId}`); + for (const p of Object.keys(PROVIDERS)) { + if (!(p in this.state.apiKeys)) { + this.state.apiKeys[p] = null; + } + } this._autoSelectAvailableModels(); this._saveState(); this._logCurrentSelection(); diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index 32441b7..ff85e16 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -11,7 +11,13 @@ const authService = require('../common/services/authService'); const systemSettingsRepository = require('../common/repositories/systemSettings'); const userRepository = require('../common/repositories/user'); const fetch = require('node-fetch'); - +const Store = require('electron-store'); +const shortCutStore = new Store({ + name: 'user-preferences', + defaults: { + customKeybinds: {} + } +}); /* ────────────────[ GLASS BYPASS ]─────────────── */ let liquidGlass; @@ -51,6 +57,7 @@ let settingsHideTimer = null; let selectedCaptureSourceId = null; +// let shortcutEditorWindow = null; let layoutManager = null; function updateLayout() { if (layoutManager) { @@ -60,16 +67,16 @@ function updateLayout() { let movementManager = null; -let storedProvider = 'openai'; const featureWindows = ['listen','ask','settings']; +// const featureWindows = ['listen','ask','settings','shortcut-settings']; function isAllowed(name) { if (name === 'header') return true; return featureWindows.includes(name) && currentHeaderState === 'main'; } -function createFeatureWindows(header) { - if (windowPool.has('listen')) return; +function createFeatureWindows(header, namesToCreate) { + // if (windowPool.has('listen')) return; const commonChildOptions = { parent: header, @@ -84,106 +91,207 @@ function createFeatureWindows(header) { webPreferences: { nodeIntegration: true, contextIsolation: false }, }; - // listen - const listen = new BrowserWindow({ - ...commonChildOptions, width:400,minWidth:400,maxWidth:400, - maxHeight:700, - }); - listen.setContentProtection(isContentProtectionOn); - listen.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - if (process.platform === 'darwin') { - listen.setWindowButtonVisibility(false); - } - const listenLoadOptions = { query: { view: 'listen' } }; - if (!shouldUseLiquidGlass) { - listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); - } - else { - listenLoadOptions.query.glass = 'true'; - listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); - listen.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(listen.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); - if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); - // liquidGlass.unstable_setScrim(viewId, 1); - // liquidGlass.unstable_setSubdued(viewId, 1); + const createFeatureWindow = (name) => { + if (windowPool.has(name)) return; + + switch (name) { + case 'listen': { + const listen = new BrowserWindow({ + ...commonChildOptions, width:400,minWidth:400,maxWidth:400, + maxHeight:700, + }); + listen.setContentProtection(isContentProtectionOn); + listen.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); + if (process.platform === 'darwin') { + listen.setWindowButtonVisibility(false); + } + const listenLoadOptions = { query: { view: 'listen' } }; + if (!shouldUseLiquidGlass) { + listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); + } + else { + listenLoadOptions.query.glass = 'true'; + listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); + listen.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(listen.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } + windowPool.set('listen', listen); + break; } - }); - } + // ask + case 'ask': { + const ask = new BrowserWindow({ ...commonChildOptions, width:600 }); + ask.setContentProtection(isContentProtectionOn); + ask.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); + if (process.platform === 'darwin') { + ask.setWindowButtonVisibility(false); + } + const askLoadOptions = { query: { view: 'ask' } }; + if (!shouldUseLiquidGlass) { + ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); + } + else { + askLoadOptions.query.glass = 'true'; + ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); + ask.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(ask.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } - windowPool.set('listen', listen); - - // ask - const ask = new BrowserWindow({ ...commonChildOptions, width:600 }); - ask.setContentProtection(isContentProtectionOn); - ask.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - if (process.platform === 'darwin') { - ask.setWindowButtonVisibility(false); - } - const askLoadOptions = { query: { view: 'ask' } }; - if (!shouldUseLiquidGlass) { - ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); - } - else { - askLoadOptions.query.glass = 'true'; - ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); - ask.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(ask.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); - if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); - // liquidGlass.unstable_setScrim(viewId, 1); - // liquidGlass.unstable_setSubdued(viewId, 1); + ask.on('blur',()=>ask.webContents.send('window-blur')); + + // Open DevTools in development + if (!app.isPackaged) { + ask.webContents.openDevTools({ mode: 'detach' }); + } + windowPool.set('ask', ask); + break; } - }); - } - ask.on('blur',()=>ask.webContents.send('window-blur')); - - // Open DevTools in development - if (!app.isPackaged) { - ask.webContents.openDevTools({ mode: 'detach' }); - } - windowPool.set('ask', ask); - - // settings - const settings = new BrowserWindow({ ...commonChildOptions, width:240, maxHeight:400, parent:undefined }); - settings.setContentProtection(isContentProtectionOn); - settings.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); - if (process.platform === 'darwin') { - settings.setWindowButtonVisibility(false); - } - const settingsLoadOptions = { query: { view: 'settings' } }; - if (!shouldUseLiquidGlass) { - settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) - .catch(console.error); - } - else { - settingsLoadOptions.query.glass = 'true'; - settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) - .catch(console.error); - settings.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(settings.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); - if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); - // liquidGlass.unstable_setScrim(viewId, 1); - // liquidGlass.unstable_setSubdued(viewId, 1); + // settings + case 'settings': { + const settings = new BrowserWindow({ ...commonChildOptions, width:240, maxHeight:400, parent:undefined }); + settings.setContentProtection(isContentProtectionOn); + settings.setVisibleOnAllWorkspaces(true,{visibleOnFullScreen:true}); + if (process.platform === 'darwin') { + settings.setWindowButtonVisibility(false); + } + const settingsLoadOptions = { query: { view: 'settings' } }; + if (!shouldUseLiquidGlass) { + settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) + .catch(console.error); + } + else { + settingsLoadOptions.query.glass = 'true'; + settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) + .catch(console.error); + settings.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(settings.getNativeWindowHandle(), { + cornerRadius: 12, + tintColor: '#FF00001A', // Red tint + opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + // liquidGlass.unstable_setScrim(viewId, 1); + // liquidGlass.unstable_setSubdued(viewId, 1); + } + }); + } + windowPool.set('settings', settings); + break; } - }); + + case 'shortcut-settings': { + const shortcutEditor = new BrowserWindow({ + ...commonChildOptions, + width: 420, + height: 720, + modal: false, + parent: undefined, + alwaysOnTop: true, + titleBarOverlay: false, + }); + + if (process.platform === 'darwin') { + shortcutEditor.setAlwaysOnTop(true, 'screen-saver'); + } else { + shortcutEditor.setAlwaysOnTop(true); + } + + /* ──────────[ β‘  λ‹€λ₯Έ μ°½ 클릭 차단 ]────────── */ + const disableClicks = () => { + for (const [name, win] of windowPool) { + if (win !== shortcutEditor && !win.isDestroyed()) { + win.setIgnoreMouseEvents(true, { forward: true }); + } + } + }; + const restoreClicks = () => { + for (const [, win] of windowPool) { + if (!win.isDestroyed()) win.setIgnoreMouseEvents(false); + } + }; + + const header = windowPool.get('header'); + if (header && !header.isDestroyed()) { + const { x, y, width } = header.getBounds(); + shortcutEditor.setBounds({ x, y, width }); + } + + shortcutEditor.once('ready-to-show', () => { + disableClicks(); + shortcutEditor.show(); + }); + + const loadOptions = { query: { view: 'shortcut-settings' } }; + if (!shouldUseLiquidGlass) { + shortcutEditor.loadFile(path.join(__dirname, '../app/content.html'), loadOptions); + } else { + loadOptions.query.glass = 'true'; + shortcutEditor.loadFile(path.join(__dirname, '../app/content.html'), loadOptions); + shortcutEditor.webContents.once('did-finish-load', () => { + const viewId = liquidGlass.addView(shortcutEditor.getNativeWindowHandle(), { + cornerRadius: 12, tintColor: '#FF00001A', opaque: false, + }); + if (viewId !== -1) { + liquidGlass.unstable_setVariant(viewId, 2); + } + }); + } + + shortcutEditor.on('closed', () => { + restoreClicks(); + windowPool.delete('shortcut-settings'); + console.log('[Shortcuts] Re-enabled after editing.'); + loadAndRegisterShortcuts(movementManager); + }); + + shortcutEditor.webContents.once('dom-ready', async () => { + const savedKeybinds = shortCutStore.get('customKeybinds', {}); + const defaultKeybinds = getDefaultKeybinds(); + const keybinds = { ...defaultKeybinds, ...savedKeybinds }; + shortcutEditor.webContents.send('load-shortcuts', keybinds); + }); + + if (!app.isPackaged) { + shortcutEditor.webContents.openDevTools({ mode: 'detach' }); + } + windowPool.set('shortcut-settings', shortcutEditor); + break; + } + } + }; + + if (Array.isArray(namesToCreate)) { + namesToCreate.forEach(name => createFeatureWindow(name)); + } else if (typeof namesToCreate === 'string') { + createFeatureWindow(namesToCreate); + } else { + createFeatureWindow('listen'); + createFeatureWindow('ask'); + createFeatureWindow('settings'); } - windowPool.set('settings', settings); } function destroyFeatureWindows() { @@ -199,6 +307,7 @@ function destroyFeatureWindows() { } + function getCurrentDisplay(window) { if (!window || window.isDestroyed()) return screen.getPrimaryDisplay(); @@ -354,7 +463,7 @@ function createWindows() { setupIpcHandlers(movementManager); if (currentHeaderState === 'main') { - createFeatureWindows(header); + createFeatureWindows(header, ['listen', 'ask', 'settings', 'shortcut-settings']); } header.setContentProtection(isContentProtectionOn); @@ -385,10 +494,6 @@ function createWindows() { header.on('resize', updateLayout); - // header.webContents.once('dom-ready', () => { - // loadAndRegisterShortcuts(); - // }); - ipcMain.handle('toggle-all-windows-visibility', () => toggleAllWindowsVisibility(movementManager)); ipcMain.handle('toggle-feature', async (event, featureName) => { @@ -584,37 +689,32 @@ function createWindows() { } }); - // setupIpcHandlers(); - return windowPool; } function loadAndRegisterShortcuts(movementManager) { + if (windowPool.has('shortcut-settings')) { + console.log('[Shortcuts] Editing in progress, skipping registration.'); + return; + } + const defaultKeybinds = getDefaultKeybinds(); - const header = windowPool.get('header'); + const savedKeybinds = shortCutStore.get('customKeybinds', {}); + const keybinds = { ...defaultKeybinds, ...savedKeybinds }; + const sendToRenderer = (channel, ...args) => { windowPool.forEach(win => { - try { - if (win && !win.isDestroyed()) { + if (win && !win.isDestroyed()) { + try { win.webContents.send(channel, ...args); + } catch (e) { + // 창이 이미 λ‹«ν˜”μ„ 수 μžˆμœΌλ―€λ‘œ 였λ₯˜λ₯Ό λ¬΄μ‹œν•©λ‹ˆλ‹€. } - } catch (e) {} + } }); }; - - if (!header) { - return updateGlobalShortcuts(defaultKeybinds, undefined, sendToRenderer, movementManager); - } - - header.webContents - .executeJavaScript(`(() => localStorage.getItem('customKeybinds'))()`) - .then(saved => (saved ? JSON.parse(saved) : {})) - .then(savedKeybinds => { - const keybinds = { ...defaultKeybinds, ...savedKeybinds }; - updateGlobalShortcuts(keybinds, header, sendToRenderer, movementManager); - }) - .catch(() => updateGlobalShortcuts(defaultKeybinds, header, sendToRenderer, movementManager)); + updateGlobalShortcuts(keybinds, windowPool.get('header'), sendToRenderer, movementManager); } @@ -768,6 +868,7 @@ function setupIpcHandlers(movementManager) { } else { // 'apikey' | 'permission' destroyFeatureWindows(); } + loadAndRegisterShortcuts(movementManager); for (const [name, win] of windowPool) { if (!isAllowed(name) && !win.isDestroyed()) { @@ -777,36 +878,69 @@ function setupIpcHandlers(movementManager) { win.show(); } } - - const header = windowPool.get('header'); - if (header && !header.isDestroyed()) { - header.webContents - .executeJavaScript(`(() => localStorage.getItem('customKeybinds'))()`) - .then(saved => { - const defaultKeybinds = getDefaultKeybinds(); - const savedKeybinds = saved ? JSON.parse(saved) : {}; - const keybinds = { ...defaultKeybinds, ...savedKeybinds }; - - const sendToRenderer = (channel, ...args) => { - windowPool.forEach(win => { - try { - if (win && !win.isDestroyed()) { - win.webContents.send(channel, ...args); - } - } catch (e) {} - }); - }; - - updateGlobalShortcuts(keybinds, header, sendToRenderer, movementManager); - }) - .catch(console.error); - } }); ipcMain.on('update-keybinds', (event, newKeybinds) => { updateGlobalShortcuts(newKeybinds); }); + ipcMain.handle('get-current-shortcuts', () => { + const defaultKeybinds = getDefaultKeybinds(); + const savedKeybinds = shortCutStore.get('customKeybinds', {}); + return { ...defaultKeybinds, ...savedKeybinds }; + }); + + ipcMain.handle('open-shortcut-editor', () => { + const header = windowPool.get('header'); + if (!header) return; + + // νŽΈμ§‘κΈ° μ—΄κΈ° μ „ λͺ¨λ“  단좕킀 λΉ„ν™œμ„±ν™” + globalShortcut.unregisterAll(); + console.log('[Shortcuts] Disabled for editing.'); + + createFeatureWindows(header, 'shortcut-settings'); + }); + + ipcMain.handle('get-default-shortcuts', () => { + shortCutStore.set('customKeybinds', {}); + return getDefaultKeybinds(); + }); + + ipcMain.handle('save-shortcuts', async (event, newKeybinds) => { + try { + const defaultKeybinds = getDefaultKeybinds(); + const customKeybinds = {}; + for (const key in newKeybinds) { + if (newKeybinds[key] && newKeybinds[key] !== defaultKeybinds[key]) { + customKeybinds[key] = newKeybinds[key]; + } + } + + shortCutStore.set('customKeybinds', customKeybinds); + console.log('[Shortcuts] Custom keybinds saved to store:', customKeybinds); + + const editor = windowPool.get('shortcut-settings'); + if (editor && !editor.isDestroyed()) { + editor.close(); + } else { + loadAndRegisterShortcuts(movementManager); + } + + return { success: true }; + } catch (error) { + console.error("Failed to save shortcuts:", error); + loadAndRegisterShortcuts(movementManager); + return { success: false, error: error.message }; + } + }); + + ipcMain.on('close-shortcut-editor', () => { + const editor = windowPool.get('shortcut-settings'); + if (editor && !editor.isDestroyed()) { + editor.close(); + } + }); + ipcMain.handle('open-login-page', () => { const webUrl = process.env.pickleglass_WEB_URL || 'http://localhost:3000'; const personalizeUrl = `${webUrl}/personalize?desktop=true`; @@ -971,15 +1105,6 @@ function setupIpcHandlers(movementManager) { console.log('[WindowManager] Received request to log out.'); await authService.signOut(); - //////// before_modelStateService //////// - // await setApiKey(null); - - // windowPool.forEach(win => { - // if (win && !win.isDestroyed()) { - // win.webContents.send('api-key-removed'); - // } - // }); - //////// before_modelStateService //////// }); ipcMain.handle('check-system-permissions', async () => { @@ -1114,101 +1239,6 @@ function setupIpcHandlers(movementManager) { } -//////// before_modelStateService //////// -// async function setApiKey(apiKey, provider = 'openai') { -// console.log('[WindowManager] Persisting API key and provider to DB'); - -// try { -// await userRepository.saveApiKey(apiKey, authService.getCurrentUserId(), provider); -// console.log('[WindowManager] API key and provider saved to SQLite'); - -// // Notify authService that the key status may have changed -// await authService.updateApiKeyStatus(); - -// } catch (err) { -// console.error('[WindowManager] Failed to save API key to SQLite:', err); -// } - -// windowPool.forEach(win => { -// if (win && !win.isDestroyed()) { -// const js = apiKey ? ` -// localStorage.setItem('openai_api_key', ${JSON.stringify(apiKey)}); -// localStorage.setItem('ai_provider', ${JSON.stringify(provider)}); -// ` : ` -// localStorage.removeItem('openai_api_key'); -// localStorage.removeItem('ai_provider'); -// `; -// win.webContents.executeJavaScript(js).catch(() => {}); -// } -// }); -// } - - -// async function getStoredApiKey() { -// const userId = authService.getCurrentUserId(); -// if (!userId) return null; -// const user = await userRepository.getById(userId); -// return user?.api_key || null; -// } - -// async function getStoredProvider() { -// const userId = authService.getCurrentUserId(); -// if (!userId) return 'openai'; -// const user = await userRepository.getById(userId); -// return user?.provider || 'openai'; -// } - -// function setupApiKeyIPC() { -// const { ipcMain } = require('electron'); - -// // Both handlers now do the same thing: fetch the key from the source of truth. -// ipcMain.handle('get-stored-api-key', getStoredApiKey); - -// ipcMain.handle('api-key-validated', async (event, data) => { -// console.log('[WindowManager] API key validation completed, saving...'); - -// // Support both old format (string) and new format (object) -// const apiKey = typeof data === 'string' ? data : data.apiKey; -// const provider = typeof data === 'string' ? 'openai' : (data.provider || 'openai'); - -// await setApiKey(apiKey, provider); - -// windowPool.forEach((win, name) => { -// if (win && !win.isDestroyed()) { -// win.webContents.send('api-key-validated', { apiKey, provider }); -// } -// }); - -// return { success: true }; -// }); - -// ipcMain.handle('remove-api-key', async () => { -// console.log('[WindowManager] API key removal requested'); -// await setApiKey(null); - -// windowPool.forEach((win, name) => { -// if (win && !win.isDestroyed()) { -// win.webContents.send('api-key-removed'); -// } -// }); - -// const settingsWindow = windowPool.get('settings'); -// if (settingsWindow && settingsWindow.isVisible()) { -// settingsWindow.hide(); -// console.log('[WindowManager] Settings window hidden after clearing API key.'); -// } - -// return { success: true }; -// }); - -// ipcMain.handle('get-ai-provider', getStoredProvider); - -// console.log('[WindowManager] API key related IPC handlers registered (SQLite-backed)'); -// } -//////// before_modelStateService //////// - - - //////// after_modelStateService //////// async function getStoredApiKey() { @@ -1227,15 +1257,15 @@ async function getStoredProvider() { } /** - * λ Œλ”λŸ¬μ—μ„œ μš”μ²­ν•œ νƒ€μž…('llm' λ˜λŠ” 'stt')에 λŒ€ν•œ λͺ¨λΈ 정보λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. - * @param {IpcMainInvokeEvent} event - μΌλ ‰νŠΈλ‘  IPC 이벀트 객체 - * @param {{type: 'llm' | 'stt'}} { type } - μš”μ²­ν•  λͺ¨λΈ νƒ€μž… + * + * @param {IpcMainInvokeEvent} event + * @param {{type: 'llm' | 'stt'}} */ async function getCurrentModelInfo(event, { type }) { if (global.modelStateService && (type === 'llm' || type === 'stt')) { return global.modelStateService.getCurrentModelInfo(type); } - return null; // μ„œλΉ„μŠ€κ°€ μ—†κ±°λ‚˜ μœ νš¨ν•˜μ§€ μ•Šμ€ νƒ€μž…μΌ 경우 null λ°˜ν™˜ + return null; } function setupApiKeyIPC() { @@ -1279,33 +1309,26 @@ function getDefaultKeybinds() { } function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementManager) { - // console.log('Updating global shortcuts with:', keybinds); - - // Unregister all existing shortcuts globalShortcut.unregisterAll(); - let toggleVisibilityDebounceTimer = null; - + if (sendToRenderer) { + sendToRenderer('shortcuts-updated', keybinds); + console.log('[Shortcuts] Broadcasted updated shortcuts to all windows.'); + } + + // ✨ ν•˜λ“œμ½”λ”©λœ 단좕킀 등둝을 μœ„ν•΄ λ³€μˆ˜ μœ μ§€ const isMac = process.platform === 'darwin'; const modifier = isMac ? 'Cmd' : 'Ctrl'; + const header = windowPool.get('header'); + const state = header?.currentHeaderState || currentHeaderState; - if (keybinds.toggleVisibility) { - try { - globalShortcut.register(keybinds.toggleVisibility, () => toggleAllWindowsVisibility(movementManager)); - console.log(`Registered toggleVisibility: ${keybinds.toggleVisibility}`); - } catch (error) { - console.error(`Failed to register toggleVisibility (${keybinds.toggleVisibility}):`, error); - } - } - + // ✨ κΈ°λŠ₯ 1: μ‚¬μš©μžκ°€ μ„€μ •ν•  수 μ—†λŠ” 'λͺ¨λ‹ˆν„° 이동' 단좕킀 (κΈ°μ‘΄ 둜직 μœ μ§€) const displays = screen.getAllDisplays(); if (displays.length > 1) { displays.forEach((display, index) => { const key = `${modifier}+Shift+${index + 1}`; try { - globalShortcut.register(key, () => { - movementManager.moveToDisplay(display.id); - }); + globalShortcut.register(key, () => movementManager.moveToDisplay(display.id)); console.log(`Registered display switch shortcut: ${key} -> Display ${index + 1}`); } catch (error) { console.error(`Failed to register display switch ${key}:`, error); @@ -1313,171 +1336,122 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan }); } - if (currentHeaderState === 'apikey') { + // API ν‚€ μž…λ ₯ μƒνƒœμ—μ„œλŠ” ν•„μˆ˜ 단좕킀(toggleVisibility) μ™Έμ—λŠ” 아무것도 λ“±λ‘ν•˜μ§€ μ•ŠμŒ + if (state === 'apikey') { + if (keybinds.toggleVisibility) { + try { + globalShortcut.register(keybinds.toggleVisibility, () => toggleAllWindowsVisibility(movementManager)); + } catch (error) { + console.error(`Failed to register toggleVisibility (${keybinds.toggleVisibility}):`, error); + } + } console.log('ApiKeyHeader is active, skipping conditional shortcuts'); return; } - const directions = [ - { key: `${modifier}+Left`, direction: 'left' }, - { key: `${modifier}+Right`, direction: 'right' }, - { key: `${modifier}+Up`, direction: 'up' }, - { key: `${modifier}+Down`, direction: 'down' }, - ]; - - directions.forEach(({ key, direction }) => { - try { - globalShortcut.register(key, () => { - const header = windowPool.get('header'); - if (header && header.isVisible()) { - movementManager.moveStep(direction); - } - }); - // console.log(`Registered global shortcut: ${key} -> ${direction}`); - } catch (error) { - console.error(`Failed to register ${key}:`, error); - } - }); - + // ✨ κΈ°λŠ₯ 2: μ‚¬μš©μžκ°€ μ„€μ •ν•  수 μ—†λŠ” 'ν™”λ©΄ κ°€μž₯자리 이동' 단좕킀 (κΈ°μ‘΄ 둜직 μœ μ§€) const edgeDirections = [ { key: `${modifier}+Shift+Left`, direction: 'left' }, { key: `${modifier}+Shift+Right`, direction: 'right' }, - { key: `${modifier}+Shift+Up`, direction: 'up' }, - { key: `${modifier}+Shift+Down`, direction: 'down' }, + // { key: `${modifier}+Shift+Up`, direction: 'up' }, + // { key: `${modifier}+Shift+Down`, direction: 'down' }, ]; - edgeDirections.forEach(({ key, direction }) => { try { globalShortcut.register(key, () => { - const header = windowPool.get('header'); - if (header && header.isVisible()) { - movementManager.moveToEdge(direction); - } + if (header && header.isVisible()) movementManager.moveToEdge(direction); }); - console.log(`Registered global shortcut: ${key} -> edge ${direction}`); } catch (error) { - console.error(`Failed to register ${key}:`, error); + console.error(`Failed to register edge move for ${key}:`, error); } }); - if (keybinds.toggleClickThrough) { + + // ✨ κΈ°λŠ₯ 3: μ‚¬μš©μžκ°€ μ„€μ • κ°€λŠ₯ν•œ λͺ¨λ“  단좕킀λ₯Ό λ™μ μœΌλ‘œ 등둝 (μƒˆλ‘œμš΄ 방식 적용) + for (const action in keybinds) { + const accelerator = keybinds[action]; + if (!accelerator) continue; + try { - globalShortcut.register(keybinds.toggleClickThrough, () => { - mouseEventsIgnored = !mouseEventsIgnored; - if (mouseEventsIgnored) { - mainWindow.setIgnoreMouseEvents(true, { forward: true }); - console.log('Mouse events ignored'); - } else { - mainWindow.setIgnoreMouseEvents(false); - console.log('Mouse events enabled'); - } - mainWindow.webContents.send('click-through-toggled', mouseEventsIgnored); - }); - // console.log(`Registered toggleClickThrough: ${keybinds.toggleClickThrough}`); - } catch (error) { - console.error(`Failed to register toggleClickThrough (${keybinds.toggleClickThrough}):`, error); - } - } - - if (keybinds.nextStep) { - try { - globalShortcut.register(keybinds.nextStep, () => { - console.log('⌘/Ctrl+Enter Ask shortcut triggered'); - - const askWindow = windowPool.get('ask'); - if (!askWindow || askWindow.isDestroyed()) { - console.error('Ask window not found or destroyed'); - return; - } - - if (askWindow.isVisible()) { - askWindow.webContents.send('ask-global-send'); - } else { - try { - askWindow.show(); - - const header = windowPool.get('header'); - if (header) { - const currentHeaderPosition = header.getBounds(); + let callback; + switch(action) { + case 'toggleVisibility': + callback = () => toggleAllWindowsVisibility(movementManager); + break; + case 'nextStep': + callback = () => { + const askWindow = windowPool.get('ask'); + if (!askWindow || askWindow.isDestroyed()) return; + if (askWindow.isVisible()) { + askWindow.webContents.send('ask-global-send'); + } else { + askWindow.show(); updateLayout(); - header.setPosition(currentHeaderPosition.x, currentHeaderPosition.y, false); + askWindow.webContents.send('window-show-animation'); } - - askWindow.webContents.send('window-show-animation'); - } catch (e) { - console.error('Error showing Ask window:', e); - } - } - }); - // console.log(`Registered Ask shortcut (nextStep): ${keybinds.nextStep}`); - } catch (error) { - console.error(`Failed to register Ask shortcut (${keybinds.nextStep}):`, error); - } - } - - if (keybinds.manualScreenshot) { - try { - globalShortcut.register(keybinds.manualScreenshot, () => { - console.log('Manual screenshot shortcut triggered'); - mainWindow.webContents.executeJavaScript(` - if (window.captureManualScreenshot) { - window.captureManualScreenshot(); - } else { - console.log('Manual screenshot function not available'); - } - `); - }); - // console.log(`Registered manualScreenshot: ${keybinds.manualScreenshot}`); - } catch (error) { - console.error(`Failed to register manualScreenshot (${keybinds.manualScreenshot}):`, error); - } - } - - if (keybinds.previousResponse) { - try { - globalShortcut.register(keybinds.previousResponse, () => { - console.log('Previous response shortcut triggered'); - sendToRenderer('navigate-previous-response'); - }); - // console.log(`Registered previousResponse: ${keybinds.previousResponse}`); - } catch (error) { - console.error(`Failed to register previousResponse (${keybinds.previousResponse}):`, error); - } - } - - if (keybinds.nextResponse) { - try { - globalShortcut.register(keybinds.nextResponse, () => { - console.log('Next response shortcut triggered'); - sendToRenderer('navigate-next-response'); - }); - // console.log(`Registered nextResponse: ${keybinds.nextResponse}`); - } catch (error) { - console.error(`Failed to register nextResponse (${keybinds.nextResponse}):`, error); - } - } - - if (keybinds.scrollUp) { - try { - globalShortcut.register(keybinds.scrollUp, () => { - console.log('Scroll up shortcut triggered'); - sendToRenderer('scroll-response-up'); - }); - // console.log(`Registered scrollUp: ${keybinds.scrollUp}`); - } catch (error) { - console.error(`Failed to register scrollUp (${keybinds.scrollUp}):`, error); - } - } - - if (keybinds.scrollDown) { - try { - globalShortcut.register(keybinds.scrollDown, () => { - console.log('Scroll down shortcut triggered'); - sendToRenderer('scroll-response-down'); - }); - // console.log(`Registered scrollDown: ${keybinds.scrollDown}`); - } catch (error) { - console.error(`Failed to register scrollDown (${keybinds.scrollDown}):`, error); + }; + break; + case 'scrollUp': + callback = () => { + // 'ask' 창을 λͺ…μ‹œμ μœΌλ‘œ κ°€μ Έμ˜΅λ‹ˆλ‹€. + const askWindow = windowPool.get('ask'); + // 'ask' 창이 μ‘΄μž¬ν•˜κ³ , νŒŒκ΄΄λ˜μ§€ μ•Šμ•˜μœΌλ©°, λ³΄μ΄λŠ” κ²½μš°μ—λ§Œ 이벀트λ₯Ό μ „μ†‘ν•©λ‹ˆλ‹€. + if (askWindow && !askWindow.isDestroyed() && askWindow.isVisible()) { + askWindow.webContents.send('scroll-response-up'); + } + }; + break; + case 'scrollDown': + callback = () => { + // 'ask' 창을 λͺ…μ‹œμ μœΌλ‘œ κ°€μ Έμ˜΅λ‹ˆλ‹€. + const askWindow = windowPool.get('ask'); + // 'ask' 창이 μ‘΄μž¬ν•˜κ³ , νŒŒκ΄΄λ˜μ§€ μ•Šμ•˜μœΌλ©°, λ³΄μ΄λŠ” κ²½μš°μ—λ§Œ 이벀트λ₯Ό μ „μ†‘ν•©λ‹ˆλ‹€. + if (askWindow && !askWindow.isDestroyed() && askWindow.isVisible()) { + askWindow.webContents.send('scroll-response-down'); + } + }; + break; + case 'moveUp': + callback = () => { if (header && header.isVisible()) movementManager.moveStep('up'); }; + break; + case 'moveDown': + callback = () => { if (header && header.isVisible()) movementManager.moveStep('down'); }; + break; + case 'moveLeft': + callback = () => { if (header && header.isVisible()) movementManager.moveStep('left'); }; + break; + case 'moveRight': + callback = () => { if (header && header.isVisible()) movementManager.moveStep('right'); }; + break; + case 'toggleClickThrough': + callback = () => { + mouseEventsIgnored = !mouseEventsIgnored; + if(mainWindow && !mainWindow.isDestroyed()){ + mainWindow.setIgnoreMouseEvents(mouseEventsIgnored, { forward: true }); + mainWindow.webContents.send('click-through-toggled', mouseEventsIgnored); + } + }; + break; + case 'manualScreenshot': + callback = () => { + if(mainWindow && !mainWindow.isDestroyed()) { + mainWindow.webContents.executeJavaScript('window.captureManualScreenshot && window.captureManualScreenshot();'); + } + }; + break; + case 'previousResponse': + callback = () => sendToRenderer('navigate-previous-response'); + break; + case 'nextResponse': + callback = () => sendToRenderer('navigate-next-response'); + break; + } + + if (callback) { + globalShortcut.register(accelerator, callback); + } + } catch(e) { + console.error(`Failed to register shortcut for "${action}" (${accelerator}):`, e.message); } } } diff --git a/src/features/ask/AskView.js b/src/features/ask/AskView.js index 33cb43c..ee0c153 100644 --- a/src/features/ask/AskView.js +++ b/src/features/ask/AskView.js @@ -658,6 +658,8 @@ export class AskView extends LitElement { this.handleDocumentClick = this.handleDocumentClick.bind(this); this.handleWindowBlur = this.handleWindowBlur.bind(this); + this.handleScroll = this.handleScroll.bind(this); + this.loadLibraries(); // --- Resize helpers --- @@ -863,6 +865,9 @@ export class AskView extends LitElement { ipcRenderer.on('ask-response-chunk', this.handleStreamChunk); ipcRenderer.on('ask-response-stream-end', this.handleStreamEnd); + + ipcRenderer.on('scroll-response-up', () => this.handleScroll('up')); + ipcRenderer.on('scroll-response-down', () => this.handleScroll('down')); console.log('βœ… AskView: IPC 이벀트 λ¦¬μŠ€λ„ˆ 등둝 μ™„λ£Œ'); } } @@ -901,9 +906,24 @@ export class AskView extends LitElement { ipcRenderer.removeListener('ask-response-chunk', this.handleStreamChunk); ipcRenderer.removeListener('ask-response-stream-end', this.handleStreamEnd); + + ipcRenderer.removeListener('scroll-response-up', () => this.handleScroll('up')); + ipcRenderer.removeListener('scroll-response-down', () => this.handleScroll('down')); console.log('βœ… AskView: IPC 이벀트 λ¦¬μŠ€λ„ˆ 제거 μ™„λ£Œ'); } } + + handleScroll(direction) { + const scrollableElement = this.shadowRoot.querySelector('#responseContainer'); + if (scrollableElement) { + const scrollAmount = 100; // ν•œ λ²ˆμ— μŠ€ν¬λ‘€ν•  μ–‘ (px) + if (direction === 'up') { + scrollableElement.scrollTop -= scrollAmount; + } else { + scrollableElement.scrollTop += scrollAmount; + } + } + } // --- 슀트리밍 처리 ν•Έλ“€λŸ¬ --- handleStreamChunk(event, { token }) { diff --git a/src/features/listen/listenService.js b/src/features/listen/listenService.js index 3b89aa2..4218745 100644 --- a/src/features/listen/listenService.js +++ b/src/features/listen/listenService.js @@ -1,4 +1,4 @@ -const { BrowserWindow } = require('electron'); +const { BrowserWindow, app } = require('electron'); const SttService = require('./stt/sttService'); const SummaryService = require('./summary/summaryService'); const authService = require('../../common/services/authService'); @@ -117,8 +117,27 @@ class ListenService { throw new Error('Failed to initialize database session'); } - // Initialize STT sessions - await this.sttService.initializeSttSessions(language); + /* ---------- STT Initialization Retry Logic ---------- */ + const MAX_RETRY = 10; + const RETRY_DELAY_MS = 300; // 0.3 seconds + + let sttReady = false; + for (let attempt = 1; attempt <= MAX_RETRY; attempt++) { + try { + await this.sttService.initializeSttSessions(language); + sttReady = true; + break; // Exit on success + } catch (err) { + console.warn( + `[ListenService] STT init attempt ${attempt} failed: ${err.message}` + ); + if (attempt < MAX_RETRY) { + await new Promise(r => setTimeout(r, RETRY_DELAY_MS)); + } + } + } + if (!sttReady) throw new Error('STT init failed after retries'); + /* ------------------------------------------- */ console.log('βœ… Listen service initialized successfully.'); @@ -213,9 +232,9 @@ class ListenService { try { await this.sendAudioContent(data, mimeType); return { success: true }; - } catch (error) { - console.error('Error sending user audio:', error); - return { success: false, error: error.message }; + } catch (e) { + console.error('Error sending user audio:', e); + return { success: false, error: e.message }; } }); @@ -237,9 +256,13 @@ class ListenService { if (process.platform !== 'darwin') { return { success: false, error: 'macOS audio capture only available on macOS' }; } + if (this.sttService.isMacOSAudioRunning?.()) { + return { success: false, error: 'already_running' }; + } + try { const success = await this.startMacOSAudioCapture(); - return { success }; + return { success, error: null }; } catch (error) { console.error('Error starting macOS audio capture:', error); return { success: false, error: error.message }; @@ -274,4 +297,4 @@ class ListenService { } } -module.exports = ListenService; \ No newline at end of file +module.exports = ListenService; \ No newline at end of file diff --git a/src/features/listen/renderer/listenCapture.js b/src/features/listen/renderer/listenCapture.js index 1c27f75..1607d0b 100644 --- a/src/features/listen/renderer/listenCapture.js +++ b/src/features/listen/renderer/listenCapture.js @@ -1,5 +1,30 @@ const { ipcRenderer } = require('electron'); +const createAecModule = require('../../../assets/aec.js'); +let aecModPromise = null; // ν•œ 번만 λ‘œλ“œ +let aecMod = null; +let aecPtr = 0; // Rust Aec* 1개만 μž¬μ‚¬μš© + +/** WASM λͺ¨λ“ˆ κ°€μ Έμ˜€κ³  1회 μ΄ˆκΈ°ν™” */ +async function getAec () { + if (aecModPromise) return aecModPromise; // μΊμ‹œ + + aecModPromise = createAecModule().then((M) => { + aecMod = M; + // C 심볼 β†’ JS 래퍼 바인딩 (λ”± 1번) + M.newPtr = M.cwrap('AecNew', 'number', + ['number','number','number','number']); + M.cancel = M.cwrap('AecCancelEcho', null, + ['number','number','number','number','number']); + M.destroy = M.cwrap('AecDestroy', null, ['number']); + return M; + }); + + return aecModPromise; +} + +// λ°”λ‘œ λ‘œλ“œ-μ‹€νŒ¨ 둜그λ₯Ό 보기 μœ„ν•΄ +getAec().catch(console.error); // --------------------------- // Constants & Globals // --------------------------- @@ -80,128 +105,49 @@ function arrayBufferToBase64(buffer) { return btoa(binary); } -// --------------------------- -// Complete SimpleAEC implementation (exact from renderer.js) -// --------------------------- -class SimpleAEC { - constructor() { - this.adaptiveFilter = new Float32Array(1024); - this.mu = 0.2; - this.echoDelay = 100; - this.sampleRate = 24000; - this.delaySamples = Math.floor((this.echoDelay / 1000) * this.sampleRate); - - this.echoGain = 0.5; - this.noiseFloor = 0.01; - - // πŸ”§ Adaptive-gain parameters (User-tuned, very aggressive) - this.targetErr = 0.002; - this.adaptRate = 0.1; - - console.log('🎯 AEC initialized (hyper-aggressive)'); - } - - process(micData, systemData) { - if (!systemData || systemData.length === 0) { - return micData; - } - - for (let i = 0; i < systemData.length; i++) { - if (systemData[i] > 0.98) systemData[i] = 0.98; - else if (systemData[i] < -0.98) systemData[i] = -0.98; - - systemData[i] = Math.tanh(systemData[i] * 4); - } - - let sum2 = 0; - for (let i = 0; i < systemData.length; i++) sum2 += systemData[i] * systemData[i]; - const rms = Math.sqrt(sum2 / systemData.length); - const targetRms = 0.08; // πŸ”§ κΈ°μ€€ RMS (κΈ°μ‘΄ 0.1) - const scale = targetRms / (rms + 1e-6); // 1e-6: 0-division λ°©μ§€ - - const output = new Float32Array(micData.length); - - const optimalDelay = this.findOptimalDelay(micData, systemData); - - for (let i = 0; i < micData.length; i++) { - let echoEstimate = 0; - - for (let d = -500; d <= 500; d += 100) { - const delayIndex = i - optimalDelay - d; - if (delayIndex >= 0 && delayIndex < systemData.length) { - const weight = Math.exp(-Math.abs(d) / 1000); - echoEstimate += systemData[delayIndex] * scale * this.echoGain * weight; - } - } - - output[i] = micData[i] - echoEstimate * 0.9; - - if (Math.abs(output[i]) < this.noiseFloor) { - output[i] *= 0.5; - } - - if (this.isSimilarToSystem(output[i], systemData, i, optimalDelay)) { - output[i] *= 0.25; - } - - output[i] = Math.max(-1, Math.min(1, output[i])); - } - - - let errSum = 0; - for (let i = 0; i < output.length; i++) errSum += output[i] * output[i]; - const errRms = Math.sqrt(errSum / output.length); - - const err = errRms - this.targetErr; - this.echoGain += this.adaptRate * err; // λΉ„λ‘€ μ œμ–΄ - this.echoGain = Math.max(0, Math.min(1, this.echoGain)); - - return output; - } - - findOptimalDelay(micData, systemData) { - let maxCorr = 0; - let optimalDelay = this.delaySamples; - - for (let delay = 0; delay < 5000 && delay < systemData.length; delay += 200) { - let corr = 0; - let count = 0; - - for (let i = 0; i < Math.min(500, micData.length); i++) { - if (i + delay < systemData.length) { - corr += micData[i] * systemData[i + delay]; - count++; - } - } - - if (count > 0) { - corr = Math.abs(corr / count); - if (corr > maxCorr) { - maxCorr = corr; - optimalDelay = delay; - } - } - } - - return optimalDelay; - } - - isSimilarToSystem(sample, systemData, index, delay) { - const windowSize = 50; - let similarity = 0; - - for (let i = -windowSize; i <= windowSize; i++) { - const sysIndex = index - delay + i; - if (sysIndex >= 0 && sysIndex < systemData.length) { - similarity += Math.abs(sample - systemData[sysIndex]); - } - } - - return similarity / (2 * windowSize + 1) < 0.15; - } +/* ───────────────────────── JS β†”οΈŽ WASM 헬퍼 ───────────────────────── */ +function int16PtrFromFloat32(mod, f32) { + const len = f32.length; + const bytes = len * 2; + const ptr = mod._malloc(bytes); + // HEAP16이 μ—†μœΌλ©΄ HEAPU8.buffer둜 직접 λž˜ν•‘ + const heapBuf = (mod.HEAP16 ? mod.HEAP16.buffer : mod.HEAPU8.buffer); + const i16 = new Int16Array(heapBuf, ptr, len); + for (let i = 0; i < len; ++i) { + const s = Math.max(-1, Math.min(1, f32[i])); + i16[i] = s < 0 ? s * 0x8000 : s * 0x7fff; + } + return { ptr, view: i16 }; +} + +function float32FromInt16View(i16) { + const out = new Float32Array(i16.length); + for (let i = 0; i < i16.length; ++i) out[i] = i16[i] / 32768; + return out; +} + +/* ν•„μš”ν•˜λ‹€λ©΄ μ’…λ£Œ μ‹œ */ +function disposeAec () { + getAec().then(mod => { if (aecPtr) mod.destroy(aecPtr); }); +} + +function runAecSync (micF32, sysF32) { + if (!aecMod || !aecPtr || !aecMod.HEAPU8) return micF32; // 아직 λͺ¨λ“ˆ μ•ˆ 뜸 β†’ 패슀 + + const len = micF32.length; + const mic = int16PtrFromFloat32(aecMod, micF32); + const echo = int16PtrFromFloat32(aecMod, sysF32); + const out = aecMod._malloc(len * 2); + + aecMod.cancel(aecPtr, mic.ptr, echo.ptr, out, len); + + const heapBuf = (aecMod.HEAP16 ? aecMod.HEAP16.buffer : aecMod.HEAPU8.buffer); + const outF32 = float32FromInt16View(new Int16Array(heapBuf, out, len)); + + aecMod._free(mic.ptr); aecMod._free(echo.ptr); aecMod._free(out); + return outF32; } -let aecProcessor = new SimpleAEC(); // System audio data handler ipcRenderer.on('system-audio-data', (event, { data }) => { @@ -214,8 +160,6 @@ ipcRenderer.on('system-audio-data', (event, { data }) => { if (systemAudioBuffer.length > MAX_SYSTEM_BUFFER_SIZE) { systemAudioBuffer = systemAudioBuffer.slice(-MAX_SYSTEM_BUFFER_SIZE); } - - console.log('πŸ“₯ Received system audio for AEC reference'); }); // --------------------------- @@ -305,39 +249,47 @@ setInterval(() => { // --------------------------- // Audio processing functions (exact from renderer.js) // --------------------------- -function setupMicProcessing(micStream) { +async function setupMicProcessing(micStream) { + /* ── WASM λ¨Όμ € λ‘œλ“œ ───────────────────────── */ + const mod = await getAec(); + if (!aecPtr) aecPtr = mod.newPtr(160, 1600, 24000, 1); + + const micAudioContext = new AudioContext({ sampleRate: SAMPLE_RATE }); + await micAudioContext.resume(); const micSource = micAudioContext.createMediaStreamSource(micStream); const micProcessor = micAudioContext.createScriptProcessor(BUFFER_SIZE, 1, 1); let audioBuffer = []; const samplesPerChunk = SAMPLE_RATE * AUDIO_CHUNK_DURATION; - micProcessor.onaudioprocess = async e => { + micProcessor.onaudioprocess = (e) => { const inputData = e.inputBuffer.getChannelData(0); audioBuffer.push(...inputData); + console.log('🎀 micProcessor.onaudioprocess'); + // samplesPerChunk(=2400) 만큼 λͺ¨μ΄λ©΄ 전솑 while (audioBuffer.length >= samplesPerChunk) { let chunk = audioBuffer.splice(0, samplesPerChunk); - let processedChunk = new Float32Array(chunk); + let processedChunk = new Float32Array(chunk); // κΈ°λ³Έκ°’ - // Check for system audio and apply AEC only if voice is active - if (aecProcessor && systemAudioBuffer.length > 0) { - const latestSystemAudio = systemAudioBuffer[systemAudioBuffer.length - 1]; - const systemFloat32 = base64ToFloat32Array(latestSystemAudio.data); + // ───────────────── WASM AEC ───────────────── + if (systemAudioBuffer.length > 0) { + const latest = systemAudioBuffer[systemAudioBuffer.length - 1]; + const sysF32 = base64ToFloat32Array(latest.data); - // Apply AEC only when system audio has active speech - if (isVoiceActive(systemFloat32)) { - processedChunk = aecProcessor.process(new Float32Array(chunk), systemFloat32); - console.log('πŸ”Š Applied AEC because system audio is active'); - } + // **μŒμ„± ꡬ간일 λ•Œλ§Œ 런** + processedChunk = runAecSync(new Float32Array(chunk), sysF32); + console.log('πŸ”Š Applied WASM-AEC (speex)'); + } else { + console.log('πŸ”Š No system audio for AEC reference'); } - const pcmData16 = convertFloat32ToInt16(processedChunk); - const base64Data = arrayBufferToBase64(pcmData16.buffer); + const pcm16 = convertFloat32ToInt16(processedChunk); + const b64 = arrayBufferToBase64(pcm16.buffer); - await ipcRenderer.invoke('send-audio-content', { - data: base64Data, + ipcRenderer.invoke('send-audio-content', { + data: b64, mimeType: 'audio/pcm;rate=24000', }); } @@ -520,7 +472,19 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu // Start macOS audio capture const audioResult = await ipcRenderer.invoke('start-macos-audio'); if (!audioResult.success) { - throw new Error('Failed to start macOS audio capture: ' + audioResult.error); + console.warn('[listenCapture] macOS audio start failed:', audioResult.error); + + // 이미 μ‹€ν–‰ 쀑 β†’ stop ν›„ μž¬μ‹œλ„ + if (audioResult.error === 'already_running') { + await ipcRenderer.invoke('stop-macos-audio'); + await new Promise(r => setTimeout(r, 500)); + const retry = await ipcRenderer.invoke('start-macos-audio'); + if (!retry.success) { + throw new Error('Retry failed: ' + retry.error); + } + } else { + throw new Error('Failed to start macOS audio capture: ' + audioResult.error); + } } // Initialize screen capture in main process @@ -543,7 +507,7 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu }); console.log('macOS microphone capture started'); - const { context, processor } = setupMicProcessing(micMediaStream); + const { context, processor } = await setupMicProcessing(micMediaStream); audioContext = context; audioProcessor = processor; } catch (micErr) { @@ -616,7 +580,7 @@ async function startCapture(screenshotIntervalSeconds = 5, imageQuality = 'mediu video: false, }); console.log('Windows microphone capture started'); - const { context, processor } = setupMicProcessing(micMediaStream); + const { context, processor } = await setupMicProcessing(micMediaStream); audioContext = context; audioProcessor = processor; } catch (micErr) { @@ -719,6 +683,9 @@ function stopCapture() { // Exports & global registration // --------------------------- module.exports = { + getAec, // μƒˆλ‘œ λ§Œλ“  μ΄ˆκΈ°ν™” ν•¨μˆ˜ + runAecSync, // sync 버전 + disposeAec, // ν•„μš”μ‹œ Rust 객체 파괴 startCapture, stopCapture, captureManualScreenshot, diff --git a/src/features/listen/stt/sttService.js b/src/features/listen/stt/sttService.js index e11d579..187f76e 100644 --- a/src/features/listen/stt/sttService.js +++ b/src/features/listen/stt/sttService.js @@ -12,11 +12,6 @@ class SttService { this.myCurrentUtterance = ''; this.theirCurrentUtterance = ''; - this.myLastPartialText = ''; - this.theirLastPartialText = ''; - this.myInactivityTimer = null; - this.theirInactivityTimer = null; - // Turn-completion debouncing this.myCompletionBuffer = ''; this.theirCompletionBuffer = ''; @@ -38,33 +33,6 @@ class SttService { this.onStatusUpdate = onStatusUpdate; } - // async getApiKey() { - // const storedKey = await getStoredApiKey(); - // if (storedKey) { - // console.log('[SttService] Using stored API key'); - // return storedKey; - // } - - // const envKey = process.env.OPENAI_API_KEY; - // if (envKey) { - // console.log('[SttService] Using environment API key'); - // return envKey; - // } - - // console.error('[SttService] No API key found in storage or environment'); - // return null; - // } - - // async getAiProvider() { - // try { - // const { ipcRenderer } = require('electron'); - // const provider = await ipcRenderer.invoke('get-ai-provider'); - // return provider || 'openai'; - // } catch (error) { - // return getStoredProvider ? getStoredProvider() : 'openai'; - // } - // } - sendToRenderer(channel, data) { BrowserWindow.getAllWindows().forEach(win => { if (!win.isDestroyed()) { @@ -74,10 +42,9 @@ class SttService { } flushMyCompletion() { - if (!this.modelInfo || !this.myCompletionBuffer.trim()) return; + const finalText = (this.myCompletionBuffer + this.myCurrentUtterance).trim(); + if (!this.modelInfo || !finalText) return; - const finalText = this.myCompletionBuffer.trim(); - // Notify completion callback if (this.onTranscriptionComplete) { this.onTranscriptionComplete('Me', finalText); @@ -102,9 +69,8 @@ class SttService { } flushTheirCompletion() { - if (!this.modelInfo || !this.theirCompletionBuffer.trim()) return; - - const finalText = this.theirCompletionBuffer.trim(); + const finalText = (this.theirCompletionBuffer + this.theirCurrentUtterance).trim(); + if (!this.modelInfo || !finalText) return; // Notify completion callback if (this.onTranscriptionComplete) { @@ -130,39 +96,29 @@ class SttService { } debounceMyCompletion(text) { - // μƒλŒ€λ°©μ΄ λ§ν•˜κ³  있던 경우, ν™”μžκ°€ λ³€κ²½λ˜μ—ˆμœΌλ―€λ‘œ μ¦‰μ‹œ μƒλŒ€λ°©μ˜ 말풍선을 μ™„μ„±ν•©λ‹ˆλ‹€. - if (this.theirCompletionTimer) { - clearTimeout(this.theirCompletionTimer); - this.flushTheirCompletion(); + if (this.modelInfo?.provider === 'gemini') { + this.myCompletionBuffer += text; + } else { + this.myCompletionBuffer += (this.myCompletionBuffer ? ' ' : '') + text; } - this.myCompletionBuffer += (this.myCompletionBuffer ? ' ' : '') + text; - if (this.myCompletionTimer) clearTimeout(this.myCompletionTimer); this.myCompletionTimer = setTimeout(() => this.flushMyCompletion(), COMPLETION_DEBOUNCE_MS); } debounceTheirCompletion(text) { - // λ‚΄κ°€ λ§ν•˜κ³  있던 경우, ν™”μžκ°€ λ³€κ²½λ˜μ—ˆμœΌλ―€λ‘œ μ¦‰μ‹œ λ‚΄ 말풍선을 μ™„μ„±ν•©λ‹ˆλ‹€. - if (this.myCompletionTimer) { - clearTimeout(this.myCompletionTimer); - this.flushMyCompletion(); + if (this.modelInfo?.provider === 'gemini') { + this.theirCompletionBuffer += text; + } else { + this.theirCompletionBuffer += (this.theirCompletionBuffer ? ' ' : '') + text; } - this.theirCompletionBuffer += (this.theirCompletionBuffer ? ' ' : '') + text; - if (this.theirCompletionTimer) clearTimeout(this.theirCompletionTimer); this.theirCompletionTimer = setTimeout(() => this.flushTheirCompletion(), COMPLETION_DEBOUNCE_MS); } async initializeSttSessions(language = 'en') { const effectiveLanguage = process.env.OPENAI_TRANSCRIBE_LANG || language || 'en'; - - // const API_KEY = await this.getApiKey(); - // if (!API_KEY) { - // throw new Error('No API key available'); - // } - // const provider = await this.getAiProvider(); const modelInfo = await getCurrentModelInfo(null, { type: 'stt' }); if (!modelInfo || !modelInfo.apiKey) { @@ -171,10 +127,6 @@ class SttService { this.modelInfo = modelInfo; console.log(`[SttService] Initializing STT for ${modelInfo.provider} using model ${modelInfo.model}`); - - // const isGemini = modelInfo.provider === 'gemini'; - // console.log(`[SttService] Initializing STT for provider: ${modelInfo.provider}`); - const handleMyMessage = message => { if (!this.modelInfo) { console.log('[SttService] Ignoring message - session already closed'); @@ -182,13 +134,35 @@ class SttService { } if (this.modelInfo.provider === 'gemini') { - const text = message.serverContent?.inputTranscription?.text || ''; - if (text && text.trim()) { - const finalUtteranceText = text.trim().replace(//g, '').trim(); - if (finalUtteranceText && finalUtteranceText !== '.') { - this.debounceMyCompletion(finalUtteranceText); - } + if (!message.serverContent?.modelTurn) { + console.log('[Gemini STT - Me]', JSON.stringify(message, null, 2)); } + + if (message.serverContent?.turnComplete) { + if (this.myCompletionTimer) { + clearTimeout(this.myCompletionTimer); + this.flushMyCompletion(); + } + return; + } + + const transcription = message.serverContent?.inputTranscription; + if (!transcription || !transcription.text) return; + + const textChunk = transcription.text; + if (!textChunk.trim() || textChunk.trim() === '') { + return; // 1. Ignore whitespace-only chunks or noise + } + + this.debounceMyCompletion(textChunk); + + this.sendToRenderer('stt-update', { + speaker: 'Me', + text: this.myCompletionBuffer, + isPartial: true, + isFinal: false, + timestamp: Date.now(), + }); } else { const type = message.type; const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || ''; @@ -222,19 +196,43 @@ class SttService { }; const handleTheirMessage = message => { + if (!message || typeof message !== 'object') return; + if (!this.modelInfo) { console.log('[SttService] Ignoring message - session already closed'); return; } if (this.modelInfo.provider === 'gemini') { - const text = message.serverContent?.inputTranscription?.text || ''; - if (text && text.trim()) { - const finalUtteranceText = text.trim().replace(//g, '').trim(); - if (finalUtteranceText && finalUtteranceText !== '.') { - this.debounceTheirCompletion(finalUtteranceText); - } + if (!message.serverContent?.modelTurn) { + console.log('[Gemini STT - Them]', JSON.stringify(message, null, 2)); } + + if (message.serverContent?.turnComplete) { + if (this.theirCompletionTimer) { + clearTimeout(this.theirCompletionTimer); + this.flushTheirCompletion(); + } + return; + } + + const transcription = message.serverContent?.inputTranscription; + if (!transcription || !transcription.text) return; + + const textChunk = transcription.text; + if (!textChunk.trim() || textChunk.trim() === '') { + return; // 1. Ignore whitespace-only chunks or noise + } + + this.debounceTheirCompletion(textChunk); + + this.sendToRenderer('stt-update', { + speaker: 'Them', + text: this.theirCompletionBuffer, + isPartial: true, + isFinal: false, + timestamp: Date.now(), + }); } else { const type = message.type; const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || ''; @@ -494,14 +492,6 @@ class SttService { this.stopMacOSAudioCapture(); // Clear timers - if (this.myInactivityTimer) { - clearTimeout(this.myInactivityTimer); - this.myInactivityTimer = null; - } - if (this.theirInactivityTimer) { - clearTimeout(this.theirInactivityTimer); - this.theirInactivityTimer = null; - } if (this.myCompletionTimer) { clearTimeout(this.myCompletionTimer); this.myCompletionTimer = null; @@ -527,8 +517,6 @@ class SttService { // Reset state this.myCurrentUtterance = ''; this.theirCurrentUtterance = ''; - this.myLastPartialText = ''; - this.theirLastPartialText = ''; this.myCompletionBuffer = ''; this.theirCompletionBuffer = ''; this.modelInfo = null; diff --git a/src/features/settings/SettingsView.js b/src/features/settings/SettingsView.js index d78703c..bd99937 100644 --- a/src/features/settings/SettingsView.js +++ b/src/features/settings/SettingsView.js @@ -437,22 +437,10 @@ export class SettingsView extends LitElement { } `; - //////// before_modelStateService //////// - // static properties = { - // firebaseUser: { type: Object, state: true }, - // apiKey: { type: String, state: true }, - // isLoading: { type: Boolean, state: true }, - // isContentProtectionOn: { type: Boolean, state: true }, - // settings: { type: Object, state: true }, - // presets: { type: Array, state: true }, - // selectedPreset: { type: Object, state: true }, - // showPresets: { type: Boolean, state: true }, - // saving: { type: Boolean, state: true }, - // }; - //////// before_modelStateService //////// //////// after_modelStateService //////// static properties = { + shortcuts: { type: Object, state: true }, firebaseUser: { type: Object, state: true }, isLoading: { type: Boolean, state: true }, isContentProtectionOn: { type: Boolean, state: true }, @@ -468,25 +456,15 @@ export class SettingsView extends LitElement { presets: { type: Array, state: true }, selectedPreset: { type: Object, state: true }, showPresets: { type: Boolean, state: true }, + autoUpdateEnabled: { type: Boolean, state: true }, + autoUpdateLoading: { type: Boolean, state: true }, }; //////// after_modelStateService //////// constructor() { super(); - //////// before_modelStateService //////// - // this.firebaseUser = null; - // this.apiKey = null; - // this.isLoading = false; - // this.isContentProtectionOn = true; - // this.settings = null; - // this.presets = []; - // this.selectedPreset = null; - // this.showPresets = false; - // this.saving = false; - // this.loadInitialData(); - //////// before_modelStateService //////// - //////// after_modelStateService //////// + this.shortcuts = {}; this.firebaseUser = null; this.apiKeys = { openai: '', gemini: '', anthropic: '' }; this.providerConfig = {}; @@ -503,51 +481,47 @@ export class SettingsView extends LitElement { this.selectedPreset = null; this.showPresets = false; this.handleUsePicklesKey = this.handleUsePicklesKey.bind(this) + this.autoUpdateEnabled = true; + this.autoUpdateLoading = true; this.loadInitialData(); //////// after_modelStateService //////// } + async loadAutoUpdateSetting() { + if (!window.require) return; + const { ipcRenderer } = window.require('electron'); + this.autoUpdateLoading = true; + try { + const enabled = await ipcRenderer.invoke('settings:get-auto-update'); + this.autoUpdateEnabled = enabled; + console.log('Auto-update setting loaded:', enabled); + } catch (e) { + console.error('Error loading auto-update setting:', e); + this.autoUpdateEnabled = true; // fallback + } + this.autoUpdateLoading = false; + this.requestUpdate(); + } - //////// before_modelStateService //////// - // async loadInitialData() { - // if (!window.require) return; - - // try { - // this.isLoading = true; - // const { ipcRenderer } = window.require('electron'); - - // // Load all data in parallel - // const [settings, presets, apiKey, contentProtection, userState] = await Promise.all([ - // ipcRenderer.invoke('settings:getSettings'), - // ipcRenderer.invoke('settings:getPresets'), - // ipcRenderer.invoke('get-stored-api-key'), - // ipcRenderer.invoke('get-content-protection-status'), - // ipcRenderer.invoke('get-current-user') - // ]); - - // this.settings = settings; - // this.presets = presets || []; - // this.apiKey = apiKey; - // this.isContentProtectionOn = contentProtection; - - // // Set first user preset as selected - // if (this.presets.length > 0) { - // const firstUserPreset = this.presets.find(p => p.is_default === 0); - // if (firstUserPreset) { - // this.selectedPreset = firstUserPreset; - // } - // } - - // if (userState && userState.isLoggedIn) { - // this.firebaseUser = userState.user; - // } - // } catch (error) { - // console.error('Error loading initial data:', error); - // } finally { - // this.isLoading = false; - // } - // } - //////// before_modelStateService //////// + async handleToggleAutoUpdate() { + if (!window.require || this.autoUpdateLoading) return; + const { ipcRenderer } = window.require('electron'); + this.autoUpdateLoading = true; + this.requestUpdate(); + try { + const newValue = !this.autoUpdateEnabled; + const result = await ipcRenderer.invoke('settings:set-auto-update', newValue); + if (result && result.success) { + this.autoUpdateEnabled = newValue; + } else { + console.error('Failed to update auto-update setting'); + } + } catch (e) { + console.error('Error toggling auto-update:', e); + } + this.autoUpdateLoading = false; + this.requestUpdate(); + } //////// after_modelStateService //////// async loadInitialData() { @@ -555,7 +529,7 @@ export class SettingsView extends LitElement { this.isLoading = true; const { ipcRenderer } = window.require('electron'); try { - const [userState, config, storedKeys, availableLlm, availableStt, selectedModels, presets, contentProtection] = await Promise.all([ + const [userState, config, storedKeys, availableLlm, availableStt, selectedModels, presets, contentProtection, shortcuts] = await Promise.all([ ipcRenderer.invoke('get-current-user'), ipcRenderer.invoke('model:get-provider-config'), // Provider μ„€μ • λ‘œλ“œ ipcRenderer.invoke('model:get-all-keys'), @@ -563,7 +537,8 @@ export class SettingsView extends LitElement { ipcRenderer.invoke('model:get-available-models', { type: 'stt' }), ipcRenderer.invoke('model:get-selected-models'), ipcRenderer.invoke('settings:getPresets'), - ipcRenderer.invoke('get-content-protection-status') + ipcRenderer.invoke('get-content-protection-status'), + ipcRenderer.invoke('get-current-shortcuts') ]); if (userState && userState.isLoggedIn) this.firebaseUser = userState; @@ -575,6 +550,7 @@ export class SettingsView extends LitElement { this.selectedStt = selectedModels.stt; this.presets = presets || []; this.isContentProtectionOn = contentProtection; + this.shortcuts = shortcuts || {}; if (this.presets.length > 0) { const firstUserPreset = this.presets.find(p => p.is_default === 0); if (firstUserPreset) this.selectedPreset = firstUserPreset; @@ -668,12 +644,20 @@ export class SettingsView extends LitElement { } //////// after_modelStateService //////// + openShortcutEditor() { + if (window.require) { + const { ipcRenderer } = window.require('electron'); + ipcRenderer.invoke('open-shortcut-editor'); + } + } + connectedCallback() { super.connectedCallback(); this.setupEventListeners(); this.setupIpcListeners(); this.setupWindowResize(); + this.loadAutoUpdateSetting(); } disconnectedCallback() { @@ -705,6 +689,7 @@ export class SettingsView extends LitElement { } else { this.firebaseUser = null; } + this.loadAutoUpdateSetting(); this.requestUpdate(); }; @@ -732,10 +717,15 @@ export class SettingsView extends LitElement { console.error('[SettingsView] Failed to refresh presets:', error); } }; + this._shortcutListener = (event, keybinds) => { + console.log('[SettingsView] Received updated shortcuts:', keybinds); + this.shortcuts = keybinds; + }; ipcRenderer.on('user-state-changed', this._userStateListener); ipcRenderer.on('settings-updated', this._settingsUpdatedListener); ipcRenderer.on('presets-updated', this._presetsUpdatedListener); + ipcRenderer.on('shortcuts-updated', this._shortcutListener); } cleanupIpcListeners() { @@ -752,6 +742,9 @@ export class SettingsView extends LitElement { if (this._presetsUpdatedListener) { ipcRenderer.removeListener('presets-updated', this._presetsUpdatedListener); } + if (this._shortcutListener) { + ipcRenderer.removeListener('shortcuts-updated', this._shortcutListener); + } } setupWindowResize() { @@ -797,14 +790,41 @@ export class SettingsView extends LitElement { } } + // getMainShortcuts() { + // return [ + // { name: 'Show / Hide', key: '\\' }, + // { name: 'Ask Anything', key: '↡' }, + // { name: 'Scroll AI Response', key: '↕' } + // ]; + // } getMainShortcuts() { return [ - { name: 'Show / Hide', key: '\\' }, - { name: 'Ask Anything', key: '↡' }, - { name: 'Scroll AI Response', key: '↕' } + { name: 'Show / Hide', accelerator: this.shortcuts.toggleVisibility }, + { name: 'Ask Anything', accelerator: this.shortcuts.nextStep }, + { name: 'Scroll Up Response', accelerator: this.shortcuts.scrollUp }, + { name: 'Scroll Down Response', accelerator: this.shortcuts.scrollDown }, ]; } + renderShortcutKeys(accelerator) { + if (!accelerator) return html`N/A`; + + const keyMap = { + 'Cmd': '⌘', 'Command': '⌘', 'Ctrl': 'βŒƒ', 'Alt': 'βŒ₯', 'Shift': '⇧', 'Enter': '↡', + 'Up': '↑', 'Down': '↓', 'Left': '←', 'Right': 'β†’' + }; + + // scrollDown/scrollUp의 특수 처리 + if (accelerator.includes('↕')) { + const keys = accelerator.replace('↕','').split('+'); + keys.push('↕'); + return html`${keys.map(key => html`${keyMap[key] || key}`)}`; + } + + const keys = accelerator.split('+'); + return html`${keys.map(key => html`${keyMap[key] || key}`)}`; + } + togglePresets() { this.showPresets = !this.showPresets; } @@ -1131,14 +1151,20 @@ export class SettingsView extends LitElement { ${apiKeyManagementHTML} ${modelSelectionHTML} + +
+ +
+
${this.getMainShortcuts().map(shortcut => html`
${shortcut.name}
- ⌘ - ${shortcut.key} + ${this.renderShortcutKeys(shortcut.accelerator)}
`)} @@ -1177,6 +1203,9 @@ export class SettingsView extends LitElement { +
+

Edit Shortcuts

+ +
+ ${Object.keys(this.shortcuts).map(key=>html` +
+
+ ${this.formatShortcutName(key)} + + + + + + this.startCapture(key)} + @keydown=${e=>this.handleKeydown(e,key)} + @blur=${()=>this.stopCapture()} + /> +
+ + ${this.feedback[key] ? html` + ` : html`` + } +
+ `)} +
+ +
+ + + +
+
+ `; + } + } + +customElements.define('shortcut-settings-view', ShortcutSettingsView); \ No newline at end of file diff --git a/src/features/settings/repositories/index.js b/src/features/settings/repositories/index.js index 508ebe5..973a149 100644 --- a/src/features/settings/repositories/index.js +++ b/src/features/settings/repositories/index.js @@ -18,4 +18,6 @@ module.exports = { createPreset: (...args) => getRepository().createPreset(...args), updatePreset: (...args) => getRepository().updatePreset(...args), deletePreset: (...args) => getRepository().deletePreset(...args), + getAutoUpdate: (...args) => getRepository().getAutoUpdate(...args), + setAutoUpdate: (...args) => getRepository().setAutoUpdate(...args), }; \ No newline at end of file diff --git a/src/features/settings/repositories/sqlite.repository.js b/src/features/settings/repositories/sqlite.repository.js index 6611346..86769d9 100644 --- a/src/features/settings/repositories/sqlite.repository.js +++ b/src/features/settings/repositories/sqlite.repository.js @@ -90,10 +90,57 @@ function deletePreset(id, uid) { } } +function getAutoUpdate(uid) { + const db = sqliteClient.getDb(); + const targetUid = uid; + + try { + const row = db.prepare('SELECT auto_update_enabled FROM users WHERE uid = ?').get(targetUid); + + if (row) { + console.log('SQLite: Auto update setting found:', row.auto_update_enabled); + return row.auto_update_enabled !== 0; + } else { + // User doesn't exist, create them with default settings + const now = Math.floor(Date.now() / 1000); + const stmt = db.prepare( + 'INSERT OR REPLACE INTO users (uid, display_name, email, created_at, auto_update_enabled) VALUES (?, ?, ?, ?, ?)'); + stmt.run(targetUid, 'User', 'user@example.com', now, 1); + return true; // default to enabled + } + } catch (error) { + console.error('SQLite: Error getting auto_update_enabled setting:', error); + return true; // fallback to enabled + } +} + +function setAutoUpdate(uid, isEnabled) { + const db = sqliteClient.getDb(); + const targetUid = uid || sqliteClient.defaultUserId; + + try { + const result = db.prepare('UPDATE users SET auto_update_enabled = ? WHERE uid = ?').run(isEnabled ? 1 : 0, targetUid); + + // If no rows were updated, the user might not exist, so create them + if (result.changes === 0) { + const now = Math.floor(Date.now() / 1000); + const stmt = db.prepare('INSERT OR REPLACE INTO users (uid, display_name, email, created_at, auto_update_enabled) VALUES (?, ?, ?, ?, ?)'); + stmt.run(targetUid, 'User', 'user@example.com', now, isEnabled ? 1 : 0); + } + + return { success: true }; + } catch (error) { + console.error('SQLite: Error setting auto-update:', error); + throw error; + } +} + module.exports = { getPresets, getPresetTemplates, createPreset, updatePreset, - deletePreset + deletePreset, + getAutoUpdate, + setAutoUpdate }; \ No newline at end of file diff --git a/src/features/settings/settingsService.js b/src/features/settings/settingsService.js index 6360f36..76b0d1a 100644 --- a/src/features/settings/settingsService.js +++ b/src/features/settings/settingsService.js @@ -383,6 +383,29 @@ async function updateContentProtection(enabled) { } } +async function getAutoUpdateSetting() { + try { + const uid = authService.getCurrentUserId(); + // This can be awaited if the repository returns a promise. + // Assuming it's synchronous for now based on original structure. + return settingsRepository.getAutoUpdate(uid); + } catch (error) { + console.error('[SettingsService] Error getting auto update setting:', error); + return true; // Fallback to enabled + } +} + +async function setAutoUpdateSetting(isEnabled) { + try { + const uid = authService.getCurrentUserId(); + await settingsRepository.setAutoUpdate(uid, isEnabled); + return { success: true }; + } catch (error) { + console.error('[SettingsService] Error setting auto update setting:', error); + return { success: false, error: error.message }; + } +} + function initialize() { // cleanup windowNotificationManager.cleanup(); @@ -428,6 +451,15 @@ function initialize() { ipcMain.handle('settings:updateContentProtection', async (event, enabled) => { return await updateContentProtection(enabled); }); + + ipcMain.handle('settings:get-auto-update', async () => { + return await getAutoUpdateSetting(); + }); + + ipcMain.handle('settings:set-auto-update', async (event, isEnabled) => { + console.log('[SettingsService] Setting auto update setting:', isEnabled); + return await setAutoUpdateSetting(isEnabled); + }); console.log('[SettingsService] Initialized and ready.'); } @@ -459,4 +491,5 @@ module.exports = { saveApiKey, removeApiKey, updateContentProtection, + getAutoUpdateSetting, }; \ No newline at end of file diff --git a/src/index.js b/src/index.js index 9194356..6015c26 100644 --- a/src/index.js +++ b/src/index.js @@ -26,6 +26,7 @@ const askService = require('./features/ask/askService'); const settingsService = require('./features/settings/settingsService'); const sessionRepository = require('./common/repositories/session'); const ModelStateService = require('./common/services/modelStateService'); +const sqliteClient = require('./common/services/sqliteClient'); const eventBridge = new EventEmitter(); let WEB_PORT = 3000; @@ -189,10 +190,12 @@ app.whenReady().then(async () => { // Clean up zombie sessions from previous runs first sessionRepository.endAllActiveSessions(); - authService.initialize(); + await authService.initialize(); + //////// after_modelStateService //////// modelStateService.initialize(); //////// after_modelStateService //////// + listenService.setupIpcHandlers(); askService.initialize(); settingsService.initialize(); @@ -213,6 +216,7 @@ app.whenReady().then(async () => { ); } + // initAutoUpdater should be called after auth is initialized initAutoUpdater(); // Process any pending deep link after everything is initialized @@ -649,8 +653,13 @@ async function startWebStack() { } // Auto-update initialization -function initAutoUpdater() { +async function initAutoUpdater() { try { + const autoUpdateEnabled = await settingsService.getAutoUpdateSetting(); + if (!autoUpdateEnabled) { + console.log('[AutoUpdater] Skipped because auto-updates are disabled in settings'); + return; + } // Skip auto-updater in development mode if (!app.isPackaged) { console.log('[AutoUpdater] Skipped in development (app is not packaged)');