dsh-ssh-manage 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +7 -7
- package/README.md +7 -7
- package/assets/LICENSE.addon-search +19 -0
- package/assets/addon-search.js +2 -0
- package/client.js +362 -11
- package/index.js +1 -0
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -45,7 +45,7 @@ No more jumping between a terminal and DSH, and no need to remember where each h
|
|
|
45
45
|
|
|
46
46
|
- Click "Connect" to open a real PTY shell, not a one-command-at-a-time console.
|
|
47
47
|
- Multiple hosts stay as tabs: switching to another DSH session and coming back re-attaches to the existing shell and replays roughly the last 256 KB of output; only closing the tab ends the session.
|
|
48
|
-
- xterm.js 6.0.0 rendering with 256 colors, cursor, scrollback, selection copy, paste and
|
|
48
|
+
- xterm.js 6.0.0 rendering with 256 colors, cursor, scrollback, selection copy, paste, resize, in-terminal search, font-size controls and a right-click copy/paste menu.
|
|
49
49
|
- Terminal theme follows the DSH light/dark theme; the session bar has quick actions for address, password status, test, files, details, clear and close.
|
|
50
50
|
- Output is streamed over a same-origin HTTP/SSE connection; input, resize and close use same-origin HTTP POST. A tested WebSocket channel is kept as a fallback.
|
|
51
51
|
- Clear status and a "Reconnect" button when the backend is unavailable — no silent hang.
|
|
@@ -96,16 +96,16 @@ Creating a host requires alias, hostname and password. The password is not writt
|
|
|
96
96
|
|
|
97
97
|
### From npm (recommended)
|
|
98
98
|
|
|
99
|
-
npm package: [`dsh-ssh-manage`](https://www.npmjs.com/package/dsh-ssh-manage) (current version `0.3.
|
|
99
|
+
npm package: [`dsh-ssh-manage`](https://www.npmjs.com/package/dsh-ssh-manage) (current version `0.3.1`).
|
|
100
100
|
|
|
101
101
|
```text
|
|
102
|
-
plugin_manager action=install_bundle target=dsh-ssh-manage@0.3.
|
|
102
|
+
plugin_manager action=install_bundle target=dsh-ssh-manage@0.3.1
|
|
103
103
|
```
|
|
104
104
|
|
|
105
105
|
Or with the DSH CLI:
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
|
-
dsh plugin add dsh-ssh-manage@0.3.
|
|
108
|
+
dsh plugin add dsh-ssh-manage@0.3.1
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
After installation, refresh the Web page; the sidebar shows an "SSH Hosts" entry with id `dsh-ssh-manage`.
|
|
@@ -137,7 +137,7 @@ and make sure the package is resolvable by the profile (for example `link:` to t
|
|
|
137
137
|
|
|
138
138
|
| | Requirement |
|
|
139
139
|
| --- | --- |
|
|
140
|
-
| **DSH** | **`>=0.2.1-rc.3 <0.3.
|
|
140
|
+
| **DSH** | **`>=0.2.1-rc.3 <0.3.1`** (validated on DSH Desktop `0.2.1-rc.3`) |
|
|
141
141
|
| **Node.js** | `>=20` (follows the DSH runtime) |
|
|
142
142
|
| **Platform** | Validated on macOS; the test suite only uses Node built-ins and runs cross-platform |
|
|
143
143
|
| **Network** | Reachable SSH port (22 by default, or the configured port) |
|
|
@@ -211,7 +211,7 @@ npm test
|
|
|
211
211
|
| `node scripts/test-sse.mjs` | HTTP/SSE PTY end-to-end against a real ssh2 mock server + 401 auth |
|
|
212
212
|
| `npm test` | All of the above |
|
|
213
213
|
|
|
214
|
-
The terminal uses vendored xterm.js 6.0.0 (MIT, see `assets/LICENSE.xterm`)
|
|
214
|
+
The terminal uses vendored xterm.js 6.0.0 (MIT, see `assets/LICENSE.xterm`), @xterm/addon-fit 0.11.0 (MIT, see `assets/LICENSE.addon-fit`) and @xterm/addon-search 0.16.0 (MIT, see `assets/LICENSE.addon-search`).
|
|
215
215
|
|
|
216
216
|
## Known limitations
|
|
217
217
|
|
|
@@ -221,7 +221,7 @@ The terminal uses vendored xterm.js 6.0.0 (MIT, see `assets/LICENSE.xterm`) and
|
|
|
221
221
|
- **Config editing scope**: the editor only changes `Host`, `HostName`, `User`, `Port` and plugin metadata; maintain other SSH directives in `~/.ssh/config`.
|
|
222
222
|
- **Batch commands** run one command; they are not an interactive terminal. Per-host output is capped at 1 MB and marked `truncated` when exceeded.
|
|
223
223
|
- **File size**: SFTP files are capped at 10 MB.
|
|
224
|
-
- **xterm assets**: the first terminal open loads about 500 KB of xterm.js from the same origin (no CDN).
|
|
224
|
+
- **xterm assets**: the first terminal open loads about 500 KB of xterm.js basics; the search addon loads on demand, about 556 KiB total from the same origin (no CDN).
|
|
225
225
|
|
|
226
226
|
## Contributing
|
|
227
227
|
|
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
|
|
46
46
|
- 点「连接」打开真正的 PTY shell,不是一条命令一条命令地执行。
|
|
47
47
|
- 多台主机以标签页常驻:切换到其它 DSH 会话再回来,终端会重新附着到原来的 shell,并回放最近约 256 KB 输出;关闭标签、Host 退出,或 30 分钟无输出/输入/心跳才会结束会话。
|
|
48
|
-
- xterm.js 6.0.0 渲染,支持 256 色、光标、滚动回看、选中复制、粘贴、窗口 resize
|
|
48
|
+
- xterm.js 6.0.0 渲染,支持 256 色、光标、滚动回看、选中复制、粘贴、窗口 resize、终端内搜索、字号调整和右键复制/粘贴菜单。
|
|
49
49
|
- 终端主题跟随 DSH 明暗主题;会话顶部有地址、密码状态、测试连接、文件、详情、清屏、关闭等快捷操作。
|
|
50
50
|
- 输出走同源 HTTP/SSE 长连接,输入 / 尺寸 / 关闭走同源 HTTP POST;插件同时保留经过测试的 WebSocket 备用通道。
|
|
51
51
|
- 断线或后端未加载时显示明确的状态与「重新连接」,不会静默卡死。
|
|
@@ -98,16 +98,16 @@
|
|
|
98
98
|
|
|
99
99
|
### 从 npm 安装(推荐)
|
|
100
100
|
|
|
101
|
-
npm 包:[`dsh-ssh-manage`](https://www.npmjs.com/package/dsh-ssh-manage)(当前版本 `0.3.
|
|
101
|
+
npm 包:[`dsh-ssh-manage`](https://www.npmjs.com/package/dsh-ssh-manage)(当前版本 `0.3.1`)。
|
|
102
102
|
|
|
103
103
|
```text
|
|
104
|
-
plugin_manager action=install_bundle target=dsh-ssh-manage@0.3.
|
|
104
|
+
plugin_manager action=install_bundle target=dsh-ssh-manage@0.3.1
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
或使用 DSH CLI:
|
|
108
108
|
|
|
109
109
|
```bash
|
|
110
|
-
dsh plugin add dsh-ssh-manage@0.3.
|
|
110
|
+
dsh plugin add dsh-ssh-manage@0.3.1
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
安装后刷新 Web 页面,左侧栏会出现「SSH 主机」入口,入口 id 为 `dsh-ssh-manage`。
|
|
@@ -139,7 +139,7 @@ plugin_manager action=install_bundle target=<仓库绝对路径>/dsh-ssh-manage
|
|
|
139
139
|
|
|
140
140
|
| | 要求 |
|
|
141
141
|
| --- | --- |
|
|
142
|
-
| **DSH** | **`>=0.2.1-rc.3 <0.3.
|
|
142
|
+
| **DSH** | **`>=0.2.1-rc.3 <0.3.1`**(实机验证版本:DSH Desktop `0.2.1-rc.3`) |
|
|
143
143
|
| **Node.js** | `>=20`(跟随 DSH 内置运行时) |
|
|
144
144
|
| **平台** | 实机验证 macOS;测试套件只依赖 Node 内置模块,可跨平台运行 |
|
|
145
145
|
| **网络** | 需要能访问目标 SSH 主机的 22 端口(或配置的端口) |
|
|
@@ -214,7 +214,7 @@ npm test
|
|
|
214
214
|
| `node scripts/test-sse.mjs` | 真实 ssh2 mock 服务器上的 HTTP/SSE PTY 端到端 + 401 鉴权 |
|
|
215
215
|
| `npm test` | 以上全部 |
|
|
216
216
|
|
|
217
|
-
终端组件使用随插件分发的 xterm.js 6.0.0(MIT,见 `assets/LICENSE.xterm`)与 @xterm/addon-
|
|
217
|
+
终端组件使用随插件分发的 xterm.js 6.0.0(MIT,见 `assets/LICENSE.xterm`)、@xterm/addon-fit 0.11.0(MIT,见 `assets/LICENSE.addon-fit`)与 @xterm/addon-search 0.16.0(MIT,见 `assets/LICENSE.addon-search`)。
|
|
218
218
|
|
|
219
219
|
## 已知限制
|
|
220
220
|
|
|
@@ -224,7 +224,7 @@ npm test
|
|
|
224
224
|
- **配置编辑范围**:编辑器只修改 `Host`、`HostName`、`User`、`Port` 与插件元数据;其它 SSH 指令请在 `~/.ssh/config` 中维护。
|
|
225
225
|
- **批量命令**:一次执行一条命令,不等同于交互式终端;单台输出上限 1 MB,超出会标记 `truncated`。
|
|
226
226
|
- **文件大小**:SFTP 单文件上限 10 MB。
|
|
227
|
-
- **xterm 资源**:首次打开会加载约 500 KB 的 xterm.js
|
|
227
|
+
- **xterm 资源**:首次打开会加载约 500 KB 的 xterm.js 基础资源;搜索组件按需加载,总计约 556 KiB(本地同源,不访问 CDN)。
|
|
228
228
|
|
|
229
229
|
## 参与贡献
|
|
230
230
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2017, The xterm.js authors (https://github.com/xtermjs/xterm.js)
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SearchAddon=t():e.SearchAddon=t()}(globalThis,(()=>(()=>{"use strict";var e={864:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DecorationManager=void 0;const i=s(540);class r extends i.Disposable{constructor(e){super(),this._terminal=e,this._highlightDecorations=[],this._highlightedLines=new Set,this._register((0,i.toDisposable)((()=>this.clearHighlightDecorations())))}createHighlightDecorations(e,t){this.clearHighlightDecorations();for(const s of e){const e=this._createResultDecorations(s,t,!1);if(e)for(const t of e)this._storeDecoration(t,s)}}createActiveDecoration(e,t){const s=this._createResultDecorations(e,t,!0);if(s)return{decorations:s,match:e,dispose(){(0,i.dispose)(s)}}}clearHighlightDecorations(){(0,i.dispose)(this._highlightDecorations),this._highlightDecorations=[],this._highlightedLines.clear()}_storeDecoration(e,t){this._highlightedLines.add(e.marker.line),this._highlightDecorations.push({decoration:e,match:t,dispose(){e.dispose()}})}_applyStyles(e,t,s){e.classList.contains("xterm-find-result-decoration")||(e.classList.add("xterm-find-result-decoration"),t&&(e.style.outline=`1px solid ${t}`)),s&&e.classList.add("xterm-find-active-result-decoration")}_createResultDecorations(e,t,s){const r=[];let n=e.col,o=e.size,a=-this._terminal.buffer.active.baseY-this._terminal.buffer.active.cursorY+e.row;for(;o>0;){const e=Math.min(this._terminal.cols-n,o);r.push([a,n,e]),n=0,o-=e,a++}const l=[];for(const e of r){const r=this._terminal.registerMarker(e[0]),n=this._terminal.registerDecoration({marker:r,x:e[1],width:e[2],backgroundColor:s?t.activeMatchBackground:t.matchBackground,overviewRulerOptions:this._highlightedLines.has(r.line)?void 0:{color:s?t.activeMatchColorOverviewRuler:t.matchOverviewRuler,position:"center"}});if(n){const e=[];e.push(r),e.push(n.onRender((e=>this._applyStyles(e,s?t.activeMatchBorder:t.matchBorder,!1)))),e.push(n.onDispose((()=>(0,i.dispose)(e)))),l.push(n)}}return 0===l.length?void 0:l}}t.DecorationManager=r},615:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SearchEngine=void 0,t.SearchEngine=class{constructor(e,t){this._terminal=e,this._lineCache=t}find(e,t,s,i){if(!e||0===e.length)return void this._terminal.clearSelection();if(s>this._terminal.cols)throw new Error(`Invalid col: ${s} to search in terminal of ${this._terminal.cols} cols`);this._lineCache.initLinesCache();const r={startRow:t,startCol:s};let n=this._findInLine(e,r,i);if(!n)for(let s=t+1;s<this._terminal.buffer.active.baseY+this._terminal.rows&&(r.startRow=s,r.startCol=0,n=this._findInLine(e,r,i),!n);s++);return n}findNextWithSelection(e,t,s){if(!e||0===e.length)return void this._terminal.clearSelection();const i=this._terminal.getSelectionPosition();this._terminal.clearSelection();let r=0,n=0;i&&(s===e?(r=i.end.x,n=i.end.y):(r=i.start.x,n=i.start.y)),this._lineCache.initLinesCache();const o={startRow:n,startCol:r};let a=this._findInLine(e,o,t);if(!a)for(let s=n+1;s<this._terminal.buffer.active.baseY+this._terminal.rows&&(o.startRow=s,o.startCol=0,a=this._findInLine(e,o,t),!a);s++);if(!a&&0!==n)for(let s=0;s<n&&(o.startRow=s,o.startCol=0,a=this._findInLine(e,o,t),!a);s++);return!a&&i&&(o.startRow=i.start.y,o.startCol=0,a=this._findInLine(e,o,t)),a}findPreviousWithSelection(e,t,s){if(!e||0===e.length)return void this._terminal.clearSelection();const i=this._terminal.getSelectionPosition();this._terminal.clearSelection();let r=this._terminal.buffer.active.baseY+this._terminal.rows-1,n=this._terminal.cols;const o=!0;this._lineCache.initLinesCache();const a={startRow:r,startCol:n};let l;if(i&&(a.startRow=r=i.start.y,a.startCol=n=i.start.x,s!==e&&(l=this._findInLine(e,a,t,!1),l||(a.startRow=r=i.end.y,a.startCol=n=i.end.x))),l||(l=this._findInLine(e,a,t,o)),!l){a.startCol=Math.max(a.startCol,this._terminal.cols);for(let s=r-1;s>=0&&(a.startRow=s,l=this._findInLine(e,a,t,o),!l);s--);}if(!l&&r!==this._terminal.buffer.active.baseY+this._terminal.rows-1)for(let s=this._terminal.buffer.active.baseY+this._terminal.rows-1;s>=r&&(a.startRow=s,l=this._findInLine(e,a,t,o),!l);s--);return l}_isWholeWord(e,t,s){return(0===e||" ~!@#$%^&*()+`-=[]{}|\\;:\"',./<>?".includes(t[e-1]))&&(e+s.length===t.length||" ~!@#$%^&*()+`-=[]{}|\\;:\"',./<>?".includes(t[e+s.length]))}_findInLine(e,t,s={},i=!1){const r=t.startRow,n=t.startCol,o=this._terminal.buffer.active.getLine(r);if(o?.isWrapped)return i?void(t.startCol+=this._terminal.cols):(t.startRow--,t.startCol+=this._terminal.cols,this._findInLine(e,t,s));let a=this._lineCache.getLineFromCache(r);a||(a=this._lineCache.translateBufferLineToStringWithWrap(r,!0),this._lineCache.setLineInCache(r,a));const[l,h]=a,c=this._bufferColsToStringOffset(r,n);let u=e,d=l;s.regex||(u=s.caseSensitive?e:e.toLowerCase(),d=s.caseSensitive?l:l.toLowerCase());let f=-1;if(s.regex){const t=RegExp(u,s.caseSensitive?"g":"gi");let r;if(i)for(;r=t.exec(d.slice(0,c));)f=t.lastIndex-r[0].length,e=r[0],t.lastIndex-=e.length-1;else r=t.exec(d.slice(c)),r&&r[0].length>0&&(f=c+(t.lastIndex-r[0].length),e=r[0])}else i?c-u.length>=0&&(f=d.lastIndexOf(u,c-u.length)):f=d.indexOf(u,c);if(f>=0){if(s.wholeWord&&!this._isWholeWord(f,d,e))return;let t=0;for(;t<h.length-1&&f>=h[t+1];)t++;let i=t;for(;i<h.length-1&&f+e.length>=h[i+1];)i++;const n=f-h[t],o=f+e.length-h[i],a=this._stringLengthToBufferSize(r+t,n);return{term:e,col:a,row:r+t,size:this._stringLengthToBufferSize(r+i,o)-a+this._terminal.cols*(i-t)}}}_stringLengthToBufferSize(e,t){const s=this._terminal.buffer.active.getLine(e);if(!s)return 0;for(let e=0;e<t;e++){const i=s.getCell(e);if(!i)break;const r=i.getChars();r.length>1&&(t-=r.length-1);const n=s.getCell(e+1);n&&0===n.getWidth()&&t++}return t}_bufferColsToStringOffset(e,t){let s=e,i=0,r=this._terminal.buffer.active.getLine(s);for(;t>0&&r;){for(let e=0;e<t&&e<this._terminal.cols;e++){const t=r.getCell(e);if(!t)break;t.getWidth()&&(i+=0===t.getCode()?1:t.getChars().length)}if(s++,r=this._terminal.buffer.active.getLine(s),r&&!r.isWrapped)break;t-=this._terminal.cols}return i}}},149:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SearchLineCache=void 0;const i=s(540),r=s(940);class n extends i.Disposable{constructor(e){super(),this._terminal=e,this._linesCacheTimeout=this._register(new i.MutableDisposable),this._linesCacheDisposables=this._register(new i.MutableDisposable),this._register((0,i.toDisposable)((()=>this._destroyLinesCache())))}initLinesCache(){this._linesCache||(this._linesCache=new Array(this._terminal.buffer.active.length),this._linesCacheDisposables.value=(0,i.combinedDisposable)(this._terminal.onLineFeed((()=>this._destroyLinesCache())),this._terminal.onCursorMove((()=>this._destroyLinesCache())),this._terminal.onResize((()=>this._destroyLinesCache())))),this._linesCacheTimeout.value=(0,r.disposableTimeout)((()=>this._destroyLinesCache()),15e3)}_destroyLinesCache(){this._linesCache=void 0,this._linesCacheDisposables.clear(),this._linesCacheTimeout.clear()}getLineFromCache(e){return this._linesCache?.[e]}setLineInCache(e,t){this._linesCache&&(this._linesCache[e]=t)}translateBufferLineToStringWithWrap(e,t){const s=[],i=[0];let r=this._terminal.buffer.active.getLine(e);for(;r;){const n=this._terminal.buffer.active.getLine(e+1),o=!!n&&n.isWrapped;let a=r.translateToString(!o&&t);if(o&&n){const e=r.getCell(r.length-1);e&&0===e.getCode()&&1===e.getWidth()&&2===n.getCell(0)?.getWidth()&&(a=a.slice(0,-1))}if(s.push(a),!o)break;i.push(i[i.length-1]+a.length),e++,r=n}return[s.join(""),i]}}t.SearchLineCache=n},438:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResultTracker=void 0;const i=s(276),r=s(540);class n extends r.Disposable{constructor(){super(...arguments),this._searchResults=[],this._onDidChangeResults=this._register(new i.Emitter)}get onDidChangeResults(){return this._onDidChangeResults.event}get searchResults(){return this._searchResults}get selectedDecoration(){return this._selectedDecoration}set selectedDecoration(e){this._selectedDecoration=e}updateResults(e,t){this._searchResults=e.slice(0,t)}clearResults(){this._searchResults=[]}clearSelectedDecoration(){this._selectedDecoration&&(this._selectedDecoration.dispose(),this._selectedDecoration=void 0)}findResultIndex(e){for(let t=0;t<this._searchResults.length;t++){const s=this._searchResults[t];if(s.row===e.row&&s.col===e.col&&s.size===e.size)return t}return-1}fireResultsChanged(e){if(!e)return;let t=-1;this._selectedDecoration&&(t=this.findResultIndex(this._selectedDecoration.match)),this._onDidChangeResults.fire({resultIndex:t,resultCount:this._searchResults.length})}reset(){this.clearSelectedDecoration(),this.clearResults()}}t.SearchResultTracker=n},772:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SearchState=void 0,t.SearchState=class{get cachedSearchTerm(){return this._cachedSearchTerm}set cachedSearchTerm(e){this._cachedSearchTerm=e}get lastSearchOptions(){return this._lastSearchOptions}set lastSearchOptions(e){this._lastSearchOptions=e}isValidSearchTerm(e){return!!(e&&e.length>0)}didOptionsChange(e){return!this._lastSearchOptions||!!e&&(this._lastSearchOptions.caseSensitive!==e.caseSensitive||this._lastSearchOptions.regex!==e.regex||this._lastSearchOptions.wholeWord!==e.wholeWord)}shouldUpdateHighlighting(e,t){return!!t?.decorations&&(void 0===this._cachedSearchTerm||e!==this._cachedSearchTerm||this.didOptionsChange(t))}clearCachedTerm(){this._cachedSearchTerm=void 0}reset(){this._cachedSearchTerm=void 0,this._lastSearchOptions=void 0}}},732:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Permutation=t.CallbackIterable=t.ArrayQueue=t.booleanComparator=t.numberComparator=t.CompareResult=void 0,t.tail=function(e,t=0){return e[e.length-(1+t)]},t.tail2=function(e){if(0===e.length)throw new Error("Invalid tail call");return[e.slice(0,e.length-1),e[e.length-1]]},t.equals=function(e,t,s=(e,t)=>e===t){if(e===t)return!0;if(!e||!t)return!1;if(e.length!==t.length)return!1;for(let i=0,r=e.length;i<r;i++)if(!s(e[i],t[i]))return!1;return!0},t.removeFastWithoutKeepingOrder=function(e,t){const s=e.length-1;t<s&&(e[t]=e[s]),e.pop()},t.binarySearch=function(e,t,s){return n(e.length,(i=>s(e[i],t)))},t.binarySearch2=n,t.quickSelect=function e(t,s,i){if((t|=0)>=s.length)throw new TypeError("invalid index");const r=s[Math.floor(s.length*Math.random())],n=[],o=[],a=[];for(const e of s){const t=i(e,r);t<0?n.push(e):t>0?o.push(e):a.push(e)}return t<n.length?e(t,n,i):t<n.length+a.length?a[0]:e(t-(n.length+a.length),o,i)},t.groupBy=function(e,t){const s=[];let i;for(const r of e.slice(0).sort(t))i&&0===t(i[0],r)?i.push(r):(i=[r],s.push(i));return s},t.groupAdjacentBy=function*(e,t){let s,i;for(const r of e)void 0!==i&&t(i,r)?s.push(r):(s&&(yield s),s=[r]),i=r;s&&(yield s)},t.forEachAdjacent=function(e,t){for(let s=0;s<=e.length;s++)t(0===s?void 0:e[s-1],s===e.length?void 0:e[s])},t.forEachWithNeighbors=function(e,t){for(let s=0;s<e.length;s++)t(0===s?void 0:e[s-1],e[s],s+1===e.length?void 0:e[s+1])},t.sortedDiff=o,t.delta=function(e,t,s){const i=o(e,t,s),r=[],n=[];for(const t of i)r.push(...e.slice(t.start,t.start+t.deleteCount)),n.push(...t.toInsert);return{removed:r,added:n}},t.top=function(e,t,s){if(0===s)return[];const i=e.slice(0,s).sort(t);return a(e,t,i,s,e.length),i},t.topAsync=function(e,t,s,r,n){return 0===s?Promise.resolve([]):new Promise(((o,l)=>{(async()=>{const o=e.length,l=e.slice(0,s).sort(t);for(let h=s,c=Math.min(s+r,o);h<o;h=c,c=Math.min(c+r,o)){if(h>s&&await new Promise((e=>setTimeout(e))),n&&n.isCancellationRequested)throw new i.CancellationError;a(e,t,l,h,c)}return l})().then(o,l)}))},t.coalesce=function(e){return e.filter((e=>!!e))},t.coalesceInPlace=function(e){let t=0;for(let s=0;s<e.length;s++)e[s]&&(e[t]=e[s],t+=1);e.length=t},t.move=function(e,t,s){e.splice(s,0,e.splice(t,1)[0])},t.isFalsyOrEmpty=function(e){return!Array.isArray(e)||0===e.length},t.isNonEmptyArray=function(e){return Array.isArray(e)&&e.length>0},t.distinct=function(e,t=e=>e){const s=new Set;return e.filter((e=>{const i=t(e);return!s.has(i)&&(s.add(i),!0)}))},t.uniqueFilter=function(e){const t=new Set;return s=>{const i=e(s);return!t.has(i)&&(t.add(i),!0)}},t.firstOrDefault=function(e,t){return e.length>0?e[0]:t},t.lastOrDefault=function(e,t){return e.length>0?e[e.length-1]:t},t.commonPrefixLength=function(e,t,s=(e,t)=>e===t){let i=0;for(let r=0,n=Math.min(e.length,t.length);r<n&&s(e[r],t[r]);r++)i++;return i},t.range=function(e,t){let s="number"==typeof t?e:0;"number"==typeof t?s=e:(s=0,t=e);const i=[];if(s<=t)for(let e=s;e<t;e++)i.push(e);else for(let e=s;e>t;e--)i.push(e);return i},t.index=function(e,t,s){return e.reduce(((e,i)=>(e[t(i)]=s?s(i):i,e)),Object.create(null))},t.insert=function(e,t){return e.push(t),()=>l(e,t)},t.remove=l,t.arrayInsert=function(e,t,s){const i=e.slice(0,t),r=e.slice(t);return i.concat(s,r)},t.shuffle=function(e,t){let s;if("number"==typeof t){let e=t;s=()=>{const t=179426549*Math.sin(e++);return t-Math.floor(t)}}else s=Math.random;for(let t=e.length-1;t>0;t-=1){const i=Math.floor(s()*(t+1)),r=e[t];e[t]=e[i],e[i]=r}},t.pushToStart=function(e,t){const s=e.indexOf(t);s>-1&&(e.splice(s,1),e.unshift(t))},t.pushToEnd=function(e,t){const s=e.indexOf(t);s>-1&&(e.splice(s,1),e.push(t))},t.pushMany=function(e,t){for(const s of t)e.push(s)},t.mapArrayOrNot=function(e,t){return Array.isArray(e)?e.map(t):t(e)},t.asArray=function(e){return Array.isArray(e)?e:[e]},t.getRandomElement=function(e){return e[Math.floor(Math.random()*e.length)]},t.insertInto=h,t.splice=function(e,t,s,i){const r=c(e,t);let n=e.splice(r,s);return void 0===n&&(n=[]),h(e,r,i),n},t.compareBy=function(e,t){return(s,i)=>t(e(s),e(i))},t.tieBreakComparators=function(...e){return(t,s)=>{for(const i of e){const e=i(t,s);if(!u.isNeitherLessOrGreaterThan(e))return e}return u.neitherLessOrGreaterThan}},t.reverseOrder=function(e){return(t,s)=>-e(t,s)};const i=s(577),r=s(411);function n(e,t){let s=0,i=e-1;for(;s<=i;){const e=(s+i)/2|0,r=t(e);if(r<0)s=e+1;else{if(!(r>0))return e;i=e-1}}return-(s+1)}function o(e,t,s){const i=[];function r(e,t,s){if(0===t&&0===s.length)return;const r=i[i.length-1];r&&r.start+r.deleteCount===e?(r.deleteCount+=t,r.toInsert.push(...s)):i.push({start:e,deleteCount:t,toInsert:s})}let n=0,o=0;for(;;){if(n===e.length){r(n,0,t.slice(o));break}if(o===t.length){r(n,e.length-n,[]);break}const i=e[n],a=t[o],l=s(i,a);0===l?(n+=1,o+=1):l<0?(r(n,1,[]),n+=1):l>0&&(r(n,0,[a]),o+=1)}return i}function a(e,t,s,i,n){for(const o=s.length;i<n;i++){const n=e[i];if(t(n,s[o-1])<0){s.pop();const e=(0,r.findFirstIdxMonotonousOrArrLen)(s,(e=>t(n,e)<0));s.splice(e,0,n)}}}function l(e,t){const s=e.indexOf(t);if(s>-1)return e.splice(s,1),t}function h(e,t,s){const i=c(e,t),r=e.length,n=s.length;e.length=r+n;for(let t=r-1;t>=i;t--)e[t+n]=e[t];for(let t=0;t<n;t++)e[t+i]=s[t]}function c(e,t){return t<0?Math.max(t+e.length,0):Math.min(t,e.length)}var u;!function(e){e.isLessThan=function(e){return e<0},e.isLessThanOrEqual=function(e){return e<=0},e.isGreaterThan=function(e){return e>0},e.isNeitherLessOrGreaterThan=function(e){return 0===e},e.greaterThan=1,e.lessThan=-1,e.neitherLessOrGreaterThan=0}(u||(t.CompareResult=u={})),t.numberComparator=(e,t)=>e-t,t.booleanComparator=(e,s)=>(0,t.numberComparator)(e?1:0,s?1:0),t.ArrayQueue=class{constructor(e){this.items=e,this.firstIdx=0,this.lastIdx=this.items.length-1}get length(){return this.lastIdx-this.firstIdx+1}takeWhile(e){let t=this.firstIdx;for(;t<this.items.length&&e(this.items[t]);)t++;const s=t===this.firstIdx?null:this.items.slice(this.firstIdx,t);return this.firstIdx=t,s}takeFromEndWhile(e){let t=this.lastIdx;for(;t>=0&&e(this.items[t]);)t--;const s=t===this.lastIdx?null:this.items.slice(t+1,this.lastIdx+1);return this.lastIdx=t,s}peek(){if(0!==this.length)return this.items[this.firstIdx]}peekLast(){if(0!==this.length)return this.items[this.lastIdx]}dequeue(){const e=this.items[this.firstIdx];return this.firstIdx++,e}removeLast(){const e=this.items[this.lastIdx];return this.lastIdx--,e}takeCount(e){const t=this.items.slice(this.firstIdx,this.firstIdx+e);return this.firstIdx+=e,t}};class d{static{this.empty=new d((e=>{}))}constructor(e){this.iterate=e}forEach(e){this.iterate((t=>(e(t),!0)))}toArray(){const e=[];return this.iterate((t=>(e.push(t),!0))),e}filter(e){return new d((t=>this.iterate((s=>!e(s)||t(s)))))}map(e){return new d((t=>this.iterate((s=>t(e(s))))))}some(e){let t=!1;return this.iterate((s=>(t=e(s),!t))),t}findFirst(e){let t;return this.iterate((s=>!e(s)||(t=s,!1))),t}findLast(e){let t;return this.iterate((s=>(e(s)&&(t=s),!0))),t}findLastMaxBy(e){let t,s=!0;return this.iterate((i=>((s||u.isGreaterThan(e(i,t)))&&(s=!1,t=i),!0))),t}}t.CallbackIterable=d;class f{constructor(e){this._indexMap=e}static createSortPermutation(e,t){const s=Array.from(e.keys()).sort(((s,i)=>t(e[s],e[i])));return new f(s)}apply(e){return e.map(((t,s)=>e[this._indexMap[s]]))}inverse(){const e=this._indexMap.slice();for(let t=0;t<this._indexMap.length;t++)e[this._indexMap[t]]=t;return new f(e)}}t.Permutation=f},411:(e,t)=>{function s(e,t,s=e.length-1){for(let i=s;i>=0;i--)if(t(e[i]))return i;return-1}function i(e,t,s=0,i=e.length){let r=s,n=i;for(;r<n;){const s=Math.floor((r+n)/2);t(e[s])?r=s+1:n=s}return r-1}function r(e,t,s=0,i=e.length){let r=s,n=i;for(;r<n;){const s=Math.floor((r+n)/2);t(e[s])?n=s:r=s+1}return r}Object.defineProperty(t,"__esModule",{value:!0}),t.MonotonousArray=void 0,t.findLast=function(e,t){const i=s(e,t);if(-1!==i)return e[i]},t.findLastIdx=s,t.findLastMonotonous=function(e,t){const s=i(e,t);return-1===s?void 0:e[s]},t.findLastIdxMonotonous=i,t.findFirstMonotonous=function(e,t){const s=r(e,t);return s===e.length?void 0:e[s]},t.findFirstIdxMonotonousOrArrLen=r,t.findFirstIdxMonotonous=function(e,t,s=0,i=e.length){const n=r(e,t,s,i);return n===e.length?-1:n},t.findFirstMax=o,t.findLastMax=function(e,t){if(0===e.length)return;let s=e[0];for(let i=1;i<e.length;i++){const r=e[i];t(r,s)>=0&&(s=r)}return s},t.findFirstMin=function(e,t){return o(e,((e,s)=>-t(e,s)))},t.findMaxIdx=function(e,t){if(0===e.length)return-1;let s=0;for(let i=1;i<e.length;i++)t(e[i],e[s])>0&&(s=i);return s},t.mapFindFirst=function(e,t){for(const s of e){const e=t(s);if(void 0!==e)return e}};class n{static{this.assertInvariants=!1}constructor(e){this._array=e,this._findLastMonotonousLastIdx=0}findLastMonotonous(e){if(n.assertInvariants){if(this._prevFindLastPredicate)for(const t of this._array)if(this._prevFindLastPredicate(t)&&!e(t))throw new Error("MonotonousArray: current predicate must be weaker than (or equal to) the previous predicate.");this._prevFindLastPredicate=e}const t=i(this._array,e,this._findLastMonotonousLastIdx);return this._findLastMonotonousLastIdx=t+1,-1===t?void 0:this._array[t]}}function o(e,t){if(0===e.length)return;let s=e[0];for(let i=1;i<e.length;i++){const r=e[i];t(r,s)>0&&(s=r)}return s}t.MonotonousArray=n},940:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.AsyncIterableSource=t.CancelableAsyncIterableObject=t.AsyncIterableObject=t.LazyStatefulPromise=t.StatefulPromise=t.Promises=t.DeferredPromise=t.IntervalCounter=t.TaskSequentializer=t.GlobalIdleValue=t.AbstractIdleValue=t._runWhenIdle=t.runWhenGlobalIdle=t.ThrottledWorker=t.RunOnceWorker=t.ProcessTimeRunOnceScheduler=t.RunOnceScheduler=t.IntervalTimer=t.TimeoutTimer=t.LimitedQueue=t.Queue=t.Limiter=t.AutoOpenBarrier=t.Barrier=t.ThrottledDelayer=t.Delayer=t.SequencerByKey=t.Sequencer=t.Throttler=void 0,t.isThenable=c,t.createCancelablePromise=u,t.raceCancellation=function(e,t,s){return new Promise(((i,r)=>{const n=t.onCancellationRequested((()=>{n.dispose(),i(s)}));e.then(i,r).finally((()=>n.dispose()))}))},t.raceCancellationError=function(e,t){return new Promise(((s,i)=>{const n=t.onCancellationRequested((()=>{n.dispose(),i(new r.CancellationError)}));e.then(s,i).finally((()=>n.dispose()))}))},t.raceCancellablePromises=async function(e){let t=-1;const s=e.map(((e,s)=>e.then((e=>(t=s,e)))));try{return await Promise.race(s)}finally{e.forEach(((e,s)=>{s!==t&&e.cancel()}))}},t.raceTimeout=function(e,t,s){let i;const r=setTimeout((()=>{i?.(void 0),s?.()}),t);return Promise.race([e.finally((()=>clearTimeout(r))),new Promise((e=>i=e))])},t.asPromise=function(e){return new Promise(((t,s)=>{const i=e();c(i)?i.then(t,s):t(i)}))},t.promiseWithResolvers=d,t.timeout=m,t.disposableTimeout=function(e,t=0,s){const i=setTimeout((()=>{e(),s&&r.dispose()}),t),r=(0,o.toDisposable)((()=>{clearTimeout(i),s?.deleteAndLeak(r)}));return s?.add(r),r},t.sequence=function(e){const t=[];let s=0;const i=e.length;return Promise.resolve(null).then((function r(n){null!=n&&t.push(n);const o=s<i?e[s++]():null;return o?o.then(r):Promise.resolve(t)}))},t.first=function(e,t=e=>!!e,s=null){let i=0;const r=e.length,n=()=>{if(i>=r)return Promise.resolve(s);const o=e[i++];return Promise.resolve(o()).then((e=>t(e)?Promise.resolve(e):n()))};return n()},t.firstParallel=function(e,t=e=>!!e,s=null){if(0===e.length)return Promise.resolve(s);let i=e.length;const r=()=>{i=-1;for(const t of e)t.cancel?.()};return new Promise(((n,o)=>{for(const a of e)a.then((e=>{--i>=0&&t(e)?(r(),n(e)):0===i&&n(s)})).catch((e=>{--i>=0&&(r(),o(e))}))}))},t.retry=async function(e,t,s){let i;for(let r=0;r<s;r++)try{return await e()}catch(e){i=e,await m(t)}throw i},t.createCancelableAsyncIterable=function(e){const t=new i.CancellationTokenSource,s=e(t.token);return new T(t,(async e=>{const i=t.token.onCancellationRequested((()=>{i.dispose(),t.dispose(),e.reject(new r.CancellationError)}));try{for await(const i of s){if(t.token.isCancellationRequested)return;e.emitOne(i)}i.dispose(),t.dispose()}catch(s){i.dispose(),t.dispose(),e.reject(s)}}))};const i=s(473),r=s(577),n=s(276),o=s(540),a=s(973),l=s(329),h=s(764);function c(e){return!!e&&"function"==typeof e.then}function u(e){const t=new i.CancellationTokenSource,s=e(t.token),n=new Promise(((e,i)=>{const n=t.token.onCancellationRequested((()=>{n.dispose(),i(new r.CancellationError)}));Promise.resolve(s).then((s=>{n.dispose(),t.dispose(),e(s)}),(e=>{n.dispose(),t.dispose(),i(e)}))}));return new class{cancel(){t.cancel(),t.dispose()}then(e,t){return n.then(e,t)}catch(e){return this.then(void 0,e)}finally(e){return n.finally(e)}}}function d(){let e,t;return{promise:new Promise(((s,i)=>{e=s,t=i})),resolve:e,reject:t}}class f{constructor(){this.isDisposed=!1,this.activePromise=null,this.queuedPromise=null,this.queuedPromiseFactory=null}queue(e){if(this.isDisposed)return Promise.reject(new Error("Throttler is disposed"));if(this.activePromise){if(this.queuedPromiseFactory=e,!this.queuedPromise){const e=()=>{if(this.queuedPromise=null,this.isDisposed)return;const e=this.queue(this.queuedPromiseFactory);return this.queuedPromiseFactory=null,e};this.queuedPromise=new Promise((t=>{this.activePromise.then(e,e).then(t)}))}return new Promise(((e,t)=>{this.queuedPromise.then(e,t)}))}return this.activePromise=e(),new Promise(((e,t)=>{this.activePromise.then((t=>{this.activePromise=null,e(t)}),(e=>{this.activePromise=null,t(e)}))}))}dispose(){this.isDisposed=!0}}t.Throttler=f,t.Sequencer=class{constructor(){this.current=Promise.resolve(null)}queue(e){return this.current=this.current.then((()=>e()),(()=>e()))}},t.SequencerByKey=class{constructor(){this.promiseMap=new Map}queue(e,t){const s=(this.promiseMap.get(e)??Promise.resolve()).catch((()=>{})).then(t).finally((()=>{this.promiseMap.get(e)===s&&this.promiseMap.delete(e)}));return this.promiseMap.set(e,s),s}};class p{constructor(e){this.defaultDelay=e,this.deferred=null,this.completionPromise=null,this.doResolve=null,this.doReject=null,this.task=null}trigger(e,t=this.defaultDelay){this.task=e,this.cancelTimeout(),this.completionPromise||(this.completionPromise=new Promise(((e,t)=>{this.doResolve=e,this.doReject=t})).then((()=>{if(this.completionPromise=null,this.doResolve=null,this.task){const e=this.task;return this.task=null,e()}})));const s=()=>{this.deferred=null,this.doResolve?.(null)};return this.deferred=t===l.MicrotaskDelay?(e=>{let t=!0;return queueMicrotask((()=>{t&&(t=!1,e())})),{isTriggered:()=>t,dispose:()=>{t=!1}}})(s):((e,t)=>{let s=!0;const i=setTimeout((()=>{s=!1,t()}),e);return{isTriggered:()=>s,dispose:()=>{clearTimeout(i),s=!1}}})(t,s),this.completionPromise}isTriggered(){return!!this.deferred?.isTriggered()}cancel(){this.cancelTimeout(),this.completionPromise&&(this.doReject?.(new r.CancellationError),this.completionPromise=null)}cancelTimeout(){this.deferred?.dispose(),this.deferred=null}dispose(){this.cancel()}}t.Delayer=p,t.ThrottledDelayer=class{constructor(e){this.delayer=new p(e),this.throttler=new f}trigger(e,t){return this.delayer.trigger((()=>this.throttler.queue(e)),t)}isTriggered(){return this.delayer.isTriggered()}cancel(){this.delayer.cancel()}dispose(){this.delayer.dispose(),this.throttler.dispose()}};class _{constructor(){this._isOpen=!1,this._promise=new Promise(((e,t)=>{this._completePromise=e}))}isOpen(){return this._isOpen}open(){this._isOpen=!0,this._completePromise(!0)}wait(){return this._promise}}function m(e,t){return t?new Promise(((s,i)=>{const n=setTimeout((()=>{o.dispose(),s()}),e),o=t.onCancellationRequested((()=>{clearTimeout(n),o.dispose(),i(new r.CancellationError)}))})):u((t=>m(e,t)))}t.Barrier=_,t.AutoOpenBarrier=class extends _{constructor(e){super(),this._timeout=setTimeout((()=>this.open()),e)}open(){clearTimeout(this._timeout),super.open()}};class g{constructor(e){this._size=0,this._isDisposed=!1,this.maxDegreeOfParalellism=e,this.outstandingPromises=[],this.runningPromises=0,this._onDrained=new n.Emitter}whenIdle(){return this.size>0?n.Event.toPromise(this.onDrained):Promise.resolve()}get onDrained(){return this._onDrained.event}get size(){return this._size}queue(e){if(this._isDisposed)throw new Error("Object has been disposed");return this._size++,new Promise(((t,s)=>{this.outstandingPromises.push({factory:e,c:t,e:s}),this.consume()}))}consume(){for(;this.outstandingPromises.length&&this.runningPromises<this.maxDegreeOfParalellism;){const e=this.outstandingPromises.shift();this.runningPromises++;const t=e.factory();t.then(e.c,e.e),t.then((()=>this.consumed()),(()=>this.consumed()))}}consumed(){this._isDisposed||(this.runningPromises--,0==--this._size&&this._onDrained.fire(),this.outstandingPromises.length>0&&this.consume())}clear(){if(this._isDisposed)throw new Error("Object has been disposed");this.outstandingPromises.length=0,this._size=this.runningPromises}dispose(){this._isDisposed=!0,this.outstandingPromises.length=0,this._size=0,this._onDrained.dispose()}}t.Limiter=g,t.Queue=class extends g{constructor(){super(1)}},t.LimitedQueue=class{constructor(){this.sequentializer=new w,this.tasks=0}queue(e){return this.sequentializer.isRunning()?this.sequentializer.queue((()=>this.sequentializer.run(this.tasks++,e()))):this.sequentializer.run(this.tasks++,e())}},t.TimeoutTimer=class{constructor(e,t){this._isDisposed=!1,this._token=-1,"function"==typeof e&&"number"==typeof t&&this.setIfNotSet(e,t)}dispose(){this.cancel(),this._isDisposed=!0}cancel(){-1!==this._token&&(clearTimeout(this._token),this._token=-1)}cancelAndSet(e,t){if(this._isDisposed)throw new r.BugIndicatingError("Calling 'cancelAndSet' on a disposed TimeoutTimer");this.cancel(),this._token=setTimeout((()=>{this._token=-1,e()}),t)}setIfNotSet(e,t){if(this._isDisposed)throw new r.BugIndicatingError("Calling 'setIfNotSet' on a disposed TimeoutTimer");-1===this._token&&(this._token=setTimeout((()=>{this._token=-1,e()}),t))}},t.IntervalTimer=class{constructor(){this.disposable=void 0,this.isDisposed=!1}cancel(){this.disposable?.dispose(),this.disposable=void 0}cancelAndSet(e,t,s=globalThis){if(this.isDisposed)throw new r.BugIndicatingError("Calling 'cancelAndSet' on a disposed IntervalTimer");this.cancel();const i=s.setInterval((()=>{e()}),t);this.disposable=(0,o.toDisposable)((()=>{s.clearInterval(i),this.disposable=void 0}))}dispose(){this.cancel(),this.isDisposed=!0}};class v{constructor(e,t){this.timeoutToken=-1,this.runner=e,this.timeout=t,this.timeoutHandler=this.onTimeout.bind(this)}dispose(){this.cancel(),this.runner=null}cancel(){this.isScheduled()&&(clearTimeout(this.timeoutToken),this.timeoutToken=-1)}schedule(e=this.timeout){this.cancel(),this.timeoutToken=setTimeout(this.timeoutHandler,e)}get delay(){return this.timeout}set delay(e){this.timeout=e}isScheduled(){return-1!==this.timeoutToken}flush(){this.isScheduled()&&(this.cancel(),this.doRun())}onTimeout(){this.timeoutToken=-1,this.runner&&this.doRun()}doRun(){this.runner?.()}}t.RunOnceScheduler=v,t.ProcessTimeRunOnceScheduler=class{constructor(e,t){t%1e3!=0&&console.warn(`ProcessTimeRunOnceScheduler resolution is 1s, ${t}ms is not a multiple of 1000ms.`),this.runner=e,this.timeout=t,this.counter=0,this.intervalToken=-1,this.intervalHandler=this.onInterval.bind(this)}dispose(){this.cancel(),this.runner=null}cancel(){this.isScheduled()&&(clearInterval(this.intervalToken),this.intervalToken=-1)}schedule(e=this.timeout){e%1e3!=0&&console.warn(`ProcessTimeRunOnceScheduler resolution is 1s, ${e}ms is not a multiple of 1000ms.`),this.cancel(),this.counter=Math.ceil(e/1e3),this.intervalToken=setInterval(this.intervalHandler,1e3)}isScheduled(){return-1!==this.intervalToken}onInterval(){this.counter--,this.counter>0||(clearInterval(this.intervalToken),this.intervalToken=-1,this.runner?.())}},t.RunOnceWorker=class extends v{constructor(e,t){super(e,t),this.units=[]}work(e){this.units.push(e),this.isScheduled()||this.schedule()}doRun(){const e=this.units;this.units=[],this.runner?.(e)}dispose(){this.units=[],super.dispose()}};class b extends o.Disposable{constructor(e,t){super(),this.options=e,this.handler=t,this.pendingWork=[],this.throttler=this._register(new o.MutableDisposable),this.disposed=!1}get pending(){return this.pendingWork.length}work(e){if(this.disposed)return!1;if("number"==typeof this.options.maxBufferedWork)if(this.throttler.value){if(this.pending+e.length>this.options.maxBufferedWork)return!1}else if(this.pending+e.length-this.options.maxWorkChunkSize>this.options.maxBufferedWork)return!1;for(const t of e)this.pendingWork.push(t);return this.throttler.value||this.doWork(),!0}doWork(){this.handler(this.pendingWork.splice(0,this.options.maxWorkChunkSize)),this.pendingWork.length>0&&(this.throttler.value=new v((()=>{this.throttler.clear(),this.doWork()}),this.options.throttleDelay),this.throttler.value.schedule())}dispose(){super.dispose(),this.disposed=!0}}t.ThrottledWorker=b,"function"!=typeof globalThis.requestIdleCallback||"function"!=typeof globalThis.cancelIdleCallback?t._runWhenIdle=(e,t)=>{(0,a.setTimeout0)((()=>{if(s)return;const e=Date.now()+15,i={didTimeout:!0,timeRemaining:()=>Math.max(0,e-Date.now())};t(Object.freeze(i))}));let s=!1;return{dispose(){s||(s=!0)}}}:t._runWhenIdle=(e,t,s)=>{const i=e.requestIdleCallback(t,"number"==typeof s?{timeout:s}:void 0);let r=!1;return{dispose(){r||(r=!0,e.cancelIdleCallback(i))}}},t.runWhenGlobalIdle=e=>(0,t._runWhenIdle)(globalThis,e);class y{constructor(e,s){this._didRun=!1,this._executor=()=>{try{this._value=s()}catch(e){this._error=e}finally{this._didRun=!0}},this._handle=(0,t._runWhenIdle)(e,(()=>this._executor()))}dispose(){this._handle.dispose()}get value(){if(this._didRun||(this._handle.dispose(),this._executor()),this._error)throw this._error;return this._value}get isInitialized(){return this._didRun}}t.AbstractIdleValue=y,t.GlobalIdleValue=class extends y{constructor(e){super(globalThis,e)}};class w{isRunning(e){return"number"==typeof e?this._running?.taskId===e:!!this._running}get running(){return this._running?.promise}cancelRunning(){this._running?.cancel()}run(e,t,s){return this._running={taskId:e,cancel:()=>s?.(),promise:t},t.then((()=>this.doneRunning(e)),(()=>this.doneRunning(e))),t}doneRunning(e){this._running&&e===this._running.taskId&&(this._running=void 0,this.runQueued())}runQueued(){if(this._queued){const e=this._queued;this._queued=void 0,e.run().then(e.promiseResolve,e.promiseReject)}}queue(e){if(this._queued)this._queued.run=e;else{const{promise:t,resolve:s,reject:i}=d();this._queued={run:e,promise:t,promiseResolve:s,promiseReject:i}}return this._queued.promise}hasQueued(){return!!this._queued}async join(){return this._queued?.promise??this._running?.promise}}var D,S,E;t.TaskSequentializer=w,t.IntervalCounter=class{constructor(e,t=()=>Date.now()){this.interval=e,this.nowFn=t,this.lastIncrementTime=0,this.value=0}increment(){const e=this.nowFn();return e-this.lastIncrementTime>this.interval&&(this.lastIncrementTime=e,this.value=0),this.value++,this.value}},function(e){e[e.Resolved=0]="Resolved",e[e.Rejected=1]="Rejected"}(D||(D={}));class k{get isRejected(){return this.outcome?.outcome===D.Rejected}get isResolved(){return this.outcome?.outcome===D.Resolved}get isSettled(){return!!this.outcome}get value(){return this.outcome?.outcome===D.Resolved?this.outcome?.value:void 0}constructor(){this.p=new Promise(((e,t)=>{this.completeCallback=e,this.errorCallback=t}))}complete(e){return new Promise((t=>{this.completeCallback(e),this.outcome={outcome:D.Resolved,value:e},t()}))}error(e){return new Promise((t=>{this.errorCallback(e),this.outcome={outcome:D.Rejected,value:e},t()}))}cancel(){return this.error(new r.CancellationError)}}t.DeferredPromise=k,function(e){e.settled=async function(e){let t;const s=await Promise.all(e.map((e=>e.then((e=>e),(e=>{t||(t=e)})))));if(void 0!==t)throw t;return s},e.withAsyncBody=function(e){return new Promise((async(t,s)=>{try{await e(t,s)}catch(e){s(e)}}))}}(S||(t.Promises=S={}));class C{get value(){return this._value}get error(){return this._error}get isResolved(){return this._isResolved}constructor(e){this._value=void 0,this._error=void 0,this._isResolved=!1,this.promise=e.then((e=>(this._value=e,this._isResolved=!0,e)),(e=>{throw this._error=e,this._isResolved=!0,e}))}requireValue(){if(!this._isResolved)throw new r.BugIndicatingError("Promise is not resolved yet");if(this._error)throw this._error;return this._value}}t.StatefulPromise=C,t.LazyStatefulPromise=class{constructor(e){this._compute=e,this._promise=new h.Lazy((()=>new C(this._compute())))}requireValue(){return this._promise.value.requireValue()}getPromise(){return this._promise.value.promise}get currentValue(){return this._promise.rawValue?.value}},function(e){e[e.Initial=0]="Initial",e[e.DoneOK=1]="DoneOK",e[e.DoneError=2]="DoneError"}(E||(E={}));class L{static fromArray(e){return new L((t=>{t.emitMany(e)}))}static fromPromise(e){return new L((async t=>{t.emitMany(await e)}))}static fromPromises(e){return new L((async t=>{await Promise.all(e.map((async e=>t.emitOne(await e))))}))}static merge(e){return new L((async t=>{await Promise.all(e.map((async e=>{for await(const s of e)t.emitOne(s)})))}))}static{this.EMPTY=L.fromArray([])}constructor(e,t){this._state=E.Initial,this._results=[],this._error=null,this._onReturn=t,this._onStateChanged=new n.Emitter,queueMicrotask((async()=>{const t={emitOne:e=>this.emitOne(e),emitMany:e=>this.emitMany(e),reject:e=>this.reject(e)};try{await Promise.resolve(e(t)),this.resolve()}catch(e){this.reject(e)}finally{t.emitOne=void 0,t.emitMany=void 0,t.reject=void 0}}))}[Symbol.asyncIterator](){let e=0;return{next:async()=>{for(;;){if(this._state===E.DoneError)throw this._error;if(e<this._results.length)return{done:!1,value:this._results[e++]};if(this._state===E.DoneOK)return{done:!0,value:void 0};await n.Event.toPromise(this._onStateChanged.event)}},return:async()=>(this._onReturn?.(),{done:!0,value:void 0})}}static map(e,t){return new L((async s=>{for await(const i of e)s.emitOne(t(i))}))}map(e){return L.map(this,e)}static filter(e,t){return new L((async s=>{for await(const i of e)t(i)&&s.emitOne(i)}))}filter(e){return L.filter(this,e)}static coalesce(e){return L.filter(e,(e=>!!e))}coalesce(){return L.coalesce(this)}static async toPromise(e){const t=[];for await(const s of e)t.push(s);return t}toPromise(){return L.toPromise(this)}emitOne(e){this._state===E.Initial&&(this._results.push(e),this._onStateChanged.fire())}emitMany(e){this._state===E.Initial&&(this._results=this._results.concat(e),this._onStateChanged.fire())}resolve(){this._state===E.Initial&&(this._state=E.DoneOK,this._onStateChanged.fire())}reject(e){this._state===E.Initial&&(this._state=E.DoneError,this._error=e,this._onStateChanged.fire())}}t.AsyncIterableObject=L;class T extends L{constructor(e,t){super(t),this._source=e}cancel(){this._source.cancel()}}t.CancelableAsyncIterableObject=T,t.AsyncIterableSource=class{constructor(e){let t,s;this._deferred=new k,this._asyncIterable=new L((e=>{if(!t)return s&&e.emitMany(s),this._errorFn=t=>e.reject(t),this._emitFn=t=>e.emitOne(t),this._deferred.p;e.reject(t)}),e),this._emitFn=e=>{s||(s=[]),s.push(e)},this._errorFn=e=>{t||(t=e)}}get asyncIterable(){return this._asyncIterable}resolve(){this._deferred.complete()}reject(e){this._errorFn(e),this._deferred.complete()}emitOne(e){this._emitFn(e)}}},473:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CancellationTokenSource=t.CancellationToken=void 0,t.cancelOnDispose=function(e){const t=new a;return e.add({dispose(){t.cancel()}}),t.token};const i=s(276),r=Object.freeze((function(e,t){const s=setTimeout(e.bind(t),0);return{dispose(){clearTimeout(s)}}}));var n;!function(e){e.isCancellationToken=function(t){return t===e.None||t===e.Cancelled||t instanceof o||!(!t||"object"!=typeof t)&&"boolean"==typeof t.isCancellationRequested&&"function"==typeof t.onCancellationRequested},e.None=Object.freeze({isCancellationRequested:!1,onCancellationRequested:i.Event.None}),e.Cancelled=Object.freeze({isCancellationRequested:!0,onCancellationRequested:r})}(n||(t.CancellationToken=n={}));class o{constructor(){this._isCancelled=!1,this._emitter=null}cancel(){this._isCancelled||(this._isCancelled=!0,this._emitter&&(this._emitter.fire(void 0),this.dispose()))}get isCancellationRequested(){return this._isCancelled}get onCancellationRequested(){return this._isCancelled?r:(this._emitter||(this._emitter=new i.Emitter),this._emitter.event)}dispose(){this._emitter&&(this._emitter.dispose(),this._emitter=null)}}class a{constructor(e){this._token=void 0,this._parentListener=void 0,this._parentListener=e&&e.onCancellationRequested(this.cancel,this)}get token(){return this._token||(this._token=new o),this._token}cancel(){this._token?this._token instanceof o&&this._token.cancel():this._token=n.Cancelled}dispose(e=!1){e&&this.cancel(),this._parentListener?.dispose(),this._token?this._token instanceof o&&this._token.dispose():this._token=n.None}}t.CancellationTokenSource=a},33:(e,t)=>{var s;Object.defineProperty(t,"__esModule",{value:!0}),t.SetWithKey=void 0,t.groupBy=function(e,t){const s=Object.create(null);for(const i of e){const e=t(i);let r=s[e];r||(r=s[e]=[]),r.push(i)}return s},t.diffSets=function(e,t){const s=[],i=[];for(const i of e)t.has(i)||s.push(i);for(const s of t)e.has(s)||i.push(s);return{removed:s,added:i}},t.diffMaps=function(e,t){const s=[],i=[];for(const[i,r]of e)t.has(i)||s.push(r);for(const[s,r]of t)e.has(s)||i.push(r);return{removed:s,added:i}},t.intersection=function(e,t){const s=new Set;for(const i of t)e.has(i)&&s.add(i);return s};class i{static{s=Symbol.toStringTag}constructor(e,t){this.toKey=t,this._map=new Map,this[s]="SetWithKey";for(const t of e)this.add(t)}get size(){return this._map.size}add(e){const t=this.toKey(e);return this._map.set(t,e),this}delete(e){return this._map.delete(this.toKey(e))}has(e){return this._map.has(this.toKey(e))}*entries(){for(const e of this._map.values())yield[e,e]}keys(){return this.values()}*values(){for(const e of this._map.values())yield e}clear(){this._map.clear()}forEach(e,t){this._map.forEach((s=>e.call(t,s,s,this)))}[Symbol.iterator](){return this.values()}}t.SetWithKey=i},577:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.BugIndicatingError=t.ErrorNoTelemetry=t.ExpectedError=t.NotSupportedError=t.NotImplementedError=t.ReadonlyError=t.CancellationError=t.errorHandler=t.ErrorHandler=void 0,t.setUnexpectedErrorHandler=function(e){t.errorHandler.setUnexpectedErrorHandler(e)},t.isSigPipeError=function(e){if(!e||"object"!=typeof e)return!1;const t=e;return"EPIPE"===t.code&&"WRITE"===t.syscall?.toUpperCase()},t.onUnexpectedError=function(e){r(e)||t.errorHandler.onUnexpectedError(e)},t.onUnexpectedExternalError=function(e){r(e)||t.errorHandler.onUnexpectedExternalError(e)},t.transformErrorForSerialization=function(e){if(e instanceof Error){const{name:t,message:s}=e;return{$isError:!0,name:t,message:s,stack:e.stacktrace||e.stack,noTelemetry:c.isErrorNoTelemetry(e)}}return e},t.transformErrorFromSerialization=function(e){let t;return e.noTelemetry?t=new c:(t=new Error,t.name=e.name),t.message=e.message,t.stack=e.stack,t},t.isCancellationError=r,t.canceled=function(){const e=new Error(i);return e.name=e.message,e},t.illegalArgument=function(e){return e?new Error(`Illegal argument: ${e}`):new Error("Illegal argument")},t.illegalState=function(e){return e?new Error(`Illegal state: ${e}`):new Error("Illegal state")},t.getErrorMessage=function(e){return e?e.message?e.message:e.stack?e.stack.split("\n")[0]:String(e):"Error"};class s{constructor(){this.listeners=[],this.unexpectedErrorHandler=function(e){setTimeout((()=>{if(e.stack){if(c.isErrorNoTelemetry(e))throw new c(e.message+"\n\n"+e.stack);throw new Error(e.message+"\n\n"+e.stack)}throw e}),0)}}addListener(e){return this.listeners.push(e),()=>{this._removeListener(e)}}emit(e){this.listeners.forEach((t=>{t(e)}))}_removeListener(e){this.listeners.splice(this.listeners.indexOf(e),1)}setUnexpectedErrorHandler(e){this.unexpectedErrorHandler=e}getUnexpectedErrorHandler(){return this.unexpectedErrorHandler}onUnexpectedError(e){this.unexpectedErrorHandler(e),this.emit(e)}onUnexpectedExternalError(e){this.unexpectedErrorHandler(e)}}t.ErrorHandler=s,t.errorHandler=new s;const i="Canceled";function r(e){return e instanceof n||e instanceof Error&&e.name===i&&e.message===i}class n extends Error{constructor(){super(i),this.name=this.message}}t.CancellationError=n;class o extends TypeError{constructor(e){super(e?`${e} is read-only and cannot be changed`:"Cannot change read-only property")}}t.ReadonlyError=o;class a extends Error{constructor(e){super("NotImplemented"),e&&(this.message=e)}}t.NotImplementedError=a;class l extends Error{constructor(e){super("NotSupported"),e&&(this.message=e)}}t.NotSupportedError=l;class h extends Error{constructor(){super(...arguments),this.isExpected=!0}}t.ExpectedError=h;class c extends Error{constructor(e){super(e),this.name="CodeExpectedError"}static fromError(e){if(e instanceof c)return e;const t=new c;return t.message=e.message,t.stack=e.stack,t}static isErrorNoTelemetry(e){return"CodeExpectedError"===e.name}}t.ErrorNoTelemetry=c;class u extends Error{constructor(e){super(e||"An unexpected bug occurred."),Object.setPrototypeOf(this,u.prototype)}}t.BugIndicatingError=u},276:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ValueWithChangeEvent=t.Relay=t.EventBufferer=t.DynamicListEventMultiplexer=t.EventMultiplexer=t.MicrotaskEmitter=t.DebounceEmitter=t.PauseableEmitter=t.AsyncEmitter=t.createEventDeliveryQueue=t.Emitter=t.ListenerRefusalError=t.ListenerLeakError=t.EventProfiling=t.Event=void 0,t.setGlobalLeakWarningThreshold=function(e){const t=c;return c=e,{dispose(){c=t}}};const i=s(577),r=s(355),n=s(540),o=s(711),a=s(79);var l;!function(e){function t(e){return(t,s=null,i)=>{let r,n=!1;return r=e((e=>{if(!n)return r?r.dispose():n=!0,t.call(s,e)}),null,i),n&&r.dispose(),r}}function s(e,t,s){return r(((s,i=null,r)=>e((e=>s.call(i,t(e))),null,r)),s)}function i(e,t,s){return r(((s,i=null,r)=>e((e=>t(e)&&s.call(i,e)),null,r)),s)}function r(e,t){let s;const i=new g({onWillAddFirstListener(){s=e(i.fire,i)},onDidRemoveLastListener(){s?.dispose()}});return t?.add(i),i.event}function o(e,t,s=100,i=!1,r=!1,n,o){let a,l,h,c,u=0;const d=new g({leakWarningThreshold:n,onWillAddFirstListener(){a=e((e=>{u++,l=t(l,e),i&&!h&&(d.fire(l),l=void 0),c=()=>{const e=l;l=void 0,h=void 0,(!i||u>1)&&d.fire(e),u=0},"number"==typeof s?(clearTimeout(h),h=setTimeout(c,s)):void 0===h&&(h=0,queueMicrotask(c))}))},onWillRemoveListener(){r&&u>0&&c?.()},onDidRemoveLastListener(){c=void 0,a.dispose()}});return o?.add(d),d.event}e.None=()=>n.Disposable.None,e.defer=function(e,t){return o(e,(()=>{}),0,void 0,!0,void 0,t)},e.once=t,e.map=s,e.forEach=function(e,t,s){return r(((s,i=null,r)=>e((e=>{t(e),s.call(i,e)}),null,r)),s)},e.filter=i,e.signal=function(e){return e},e.any=function(...e){return(t,s=null,i)=>{return r=(0,n.combinedDisposable)(...e.map((e=>e((e=>t.call(s,e)))))),(o=i)instanceof Array?o.push(r):o&&o.add(r),r;var r,o}},e.reduce=function(e,t,i,r){let n=i;return s(e,(e=>(n=t(n,e),n)),r)},e.debounce=o,e.accumulate=function(t,s=0,i){return e.debounce(t,((e,t)=>e?(e.push(t),e):[t]),s,void 0,!0,void 0,i)},e.latch=function(e,t=(e,t)=>e===t,s){let r,n=!0;return i(e,(e=>{const s=n||!t(e,r);return n=!1,r=e,s}),s)},e.split=function(t,s,i){return[e.filter(t,s,i),e.filter(t,(e=>!s(e)),i)]},e.buffer=function(e,t=!1,s=[],i){let r=s.slice(),n=e((e=>{r?r.push(e):a.fire(e)}));i&&i.add(n);const o=()=>{r?.forEach((e=>a.fire(e))),r=null},a=new g({onWillAddFirstListener(){n||(n=e((e=>a.fire(e))),i&&i.add(n))},onDidAddFirstListener(){r&&(t?setTimeout(o):o())},onDidRemoveLastListener(){n&&n.dispose(),n=null}});return i&&i.add(a),a.event},e.chain=function(e,t){return(s,i,r)=>{const n=t(new l);return e((function(e){const t=n.evaluate(e);t!==a&&s.call(i,t)}),void 0,r)}};const a=Symbol("HaltChainable");class l{constructor(){this.steps=[]}map(e){return this.steps.push(e),this}forEach(e){return this.steps.push((t=>(e(t),t))),this}filter(e){return this.steps.push((t=>e(t)?t:a)),this}reduce(e,t){let s=t;return this.steps.push((t=>(s=e(s,t),s))),this}latch(e=(e,t)=>e===t){let t,s=!0;return this.steps.push((i=>{const r=s||!e(i,t);return s=!1,t=i,r?i:a})),this}evaluate(e){for(const t of this.steps)if((e=t(e))===a)break;return e}}e.fromNodeEventEmitter=function(e,t,s=e=>e){const i=(...e)=>r.fire(s(...e)),r=new g({onWillAddFirstListener:()=>e.on(t,i),onDidRemoveLastListener:()=>e.removeListener(t,i)});return r.event},e.fromDOMEventEmitter=function(e,t,s=e=>e){const i=(...e)=>r.fire(s(...e)),r=new g({onWillAddFirstListener:()=>e.addEventListener(t,i),onDidRemoveLastListener:()=>e.removeEventListener(t,i)});return r.event},e.toPromise=function(e){return new Promise((s=>t(e)(s)))},e.fromPromise=function(e){const t=new g;return e.then((e=>{t.fire(e)}),(()=>{t.fire(void 0)})).finally((()=>{t.dispose()})),t.event},e.forward=function(e,t){return e((e=>t.fire(e)))},e.runAndSubscribe=function(e,t,s){return t(s),e((e=>t(e)))};class h{constructor(e,t){this._observable=e,this._counter=0,this._hasChanged=!1;const s={onWillAddFirstListener:()=>{e.addObserver(this)},onDidRemoveLastListener:()=>{e.removeObserver(this)}};this.emitter=new g(s),t&&t.add(this.emitter)}beginUpdate(e){this._counter++}handlePossibleChange(e){}handleChange(e,t){this._hasChanged=!0}endUpdate(e){this._counter--,0===this._counter&&(this._observable.reportChanges(),this._hasChanged&&(this._hasChanged=!1,this.emitter.fire(this._observable.get())))}}e.fromObservable=function(e,t){return new h(e,t).emitter.event},e.fromObservableLight=function(e){return(t,s,i)=>{let r=0,o=!1;const a={beginUpdate(){r++},endUpdate(){r--,0===r&&(e.reportChanges(),o&&(o=!1,t.call(s)))},handlePossibleChange(){},handleChange(){o=!0}};e.addObserver(a),e.reportChanges();const l={dispose(){e.removeObserver(a)}};return i instanceof n.DisposableStore?i.add(l):Array.isArray(i)&&i.push(l),l}}}(l||(t.Event=l={}));class h{static{this.all=new Set}static{this._idPool=0}constructor(e){this.listenerCount=0,this.invocationCount=0,this.elapsedOverall=0,this.durations=[],this.name=`${e}_${h._idPool++}`,h.all.add(this)}start(e){this._stopWatch=new a.StopWatch,this.listenerCount=e}stop(){if(this._stopWatch){const e=this._stopWatch.elapsed();this.durations.push(e),this.elapsedOverall+=e,this.invocationCount+=1,this._stopWatch=void 0}}}t.EventProfiling=h;let c=-1;class u{static{this._idPool=1}constructor(e,t,s=(u._idPool++).toString(16).padStart(3,"0")){this._errorHandler=e,this.threshold=t,this.name=s,this._warnCountdown=0}dispose(){this._stacks?.clear()}check(e,t){const s=this.threshold;if(s<=0||t<s)return;this._stacks||(this._stacks=new Map);const i=this._stacks.get(e.value)||0;if(this._stacks.set(e.value,i+1),this._warnCountdown-=1,this._warnCountdown<=0){this._warnCountdown=.5*s;const[e,i]=this.getMostFrequentStack(),r=`[${this.name}] potential listener LEAK detected, having ${t} listeners already. MOST frequent listener (${i}):`;console.warn(r),console.warn(e);const n=new f(r,e);this._errorHandler(n)}return()=>{const t=this._stacks.get(e.value)||0;this._stacks.set(e.value,t-1)}}getMostFrequentStack(){if(!this._stacks)return;let e,t=0;for(const[s,i]of this._stacks)(!e||t<i)&&(e=[s,i],t=i);return e}}class d{static create(){const e=new Error;return new d(e.stack??"")}constructor(e){this.value=e}print(){console.warn(this.value.split("\n").slice(2).join("\n"))}}class f extends Error{constructor(e,t){super(e),this.name="ListenerLeakError",this.stack=t}}t.ListenerLeakError=f;class p extends Error{constructor(e,t){super(e),this.name="ListenerRefusalError",this.stack=t}}t.ListenerRefusalError=p;let _=0;class m{constructor(e){this.value=e,this.id=_++}}class g{constructor(e){this._size=0,this._options=e,this._leakageMon=c>0||this._options?.leakWarningThreshold?new u(e?.onListenerError??i.onUnexpectedError,this._options?.leakWarningThreshold??c):void 0,this._perfMon=this._options?._profName?new h(this._options._profName):void 0,this._deliveryQueue=this._options?.deliveryQueue}dispose(){this._disposed||(this._disposed=!0,this._deliveryQueue?.current===this&&this._deliveryQueue.reset(),this._listeners&&(this._listeners=void 0,this._size=0),this._options?.onDidRemoveLastListener?.(),this._leakageMon?.dispose())}get event(){return this._event??=(e,t,s)=>{if(this._leakageMon&&this._size>this._leakageMon.threshold**2){const e=`[${this._leakageMon.name}] REFUSES to accept new listeners because it exceeded its threshold by far (${this._size} vs ${this._leakageMon.threshold})`;console.warn(e);const t=this._leakageMon.getMostFrequentStack()??["UNKNOWN stack",-1],s=new p(`${e}. HINT: Stack shows most frequent listener (${t[1]}-times)`,t[0]);return(this._options?.onListenerError||i.onUnexpectedError)(s),n.Disposable.None}if(this._disposed)return n.Disposable.None;t&&(e=e.bind(t));const r=new m(e);let o;this._leakageMon&&this._size>=Math.ceil(.2*this._leakageMon.threshold)&&(r.stack=d.create(),o=this._leakageMon.check(r.stack,this._size+1)),this._listeners?this._listeners instanceof m?(this._deliveryQueue??=new v,this._listeners=[this._listeners,r]):this._listeners.push(r):(this._options?.onWillAddFirstListener?.(this),this._listeners=r,this._options?.onDidAddFirstListener?.(this)),this._size++;const a=(0,n.toDisposable)((()=>{o?.(),this._removeListener(r)}));return s instanceof n.DisposableStore?s.add(a):Array.isArray(s)&&s.push(a),a},this._event}_removeListener(e){if(this._options?.onWillRemoveListener?.(this),!this._listeners)return;if(1===this._size)return this._listeners=void 0,this._options?.onDidRemoveLastListener?.(this),void(this._size=0);const t=this._listeners,s=t.indexOf(e);if(-1===s)throw console.log("disposed?",this._disposed),console.log("size?",this._size),console.log("arr?",JSON.stringify(this._listeners)),new Error("Attempted to dispose unknown listener");this._size--,t[s]=void 0;const i=this._deliveryQueue.current===this;if(2*this._size<=t.length){let e=0;for(let s=0;s<t.length;s++)t[s]?t[e++]=t[s]:i&&(this._deliveryQueue.end--,e<this._deliveryQueue.i&&this._deliveryQueue.i--);t.length=e}}_deliver(e,t){if(!e)return;const s=this._options?.onListenerError||i.onUnexpectedError;if(s)try{e.value(t)}catch(e){s(e)}else e.value(t)}_deliverQueue(e){const t=e.current._listeners;for(;e.i<e.end;)this._deliver(t[e.i++],e.value);e.reset()}fire(e){if(this._deliveryQueue?.current&&(this._deliverQueue(this._deliveryQueue),this._perfMon?.stop()),this._perfMon?.start(this._size),this._listeners)if(this._listeners instanceof m)this._deliver(this._listeners,e);else{const t=this._deliveryQueue;t.enqueue(this,e,this._listeners.length),this._deliverQueue(t)}this._perfMon?.stop()}hasListeners(){return this._size>0}}t.Emitter=g,t.createEventDeliveryQueue=()=>new v;class v{constructor(){this.i=-1,this.end=0}enqueue(e,t,s){this.i=0,this.end=s,this.current=e,this.value=t}reset(){this.i=this.end,this.current=void 0,this.value=void 0}}t.AsyncEmitter=class extends g{async fireAsync(e,t,s){if(this._listeners)for(this._asyncDeliveryQueue||(this._asyncDeliveryQueue=new o.LinkedList),((e,t)=>{if(e instanceof m)t(e);else for(let s=0;s<e.length;s++){const i=e[s];i&&t(i)}})(this._listeners,(t=>this._asyncDeliveryQueue.push([t.value,e])));this._asyncDeliveryQueue.size>0&&!t.isCancellationRequested;){const[e,r]=this._asyncDeliveryQueue.shift(),n=[],o={...r,token:t,waitUntil:t=>{if(Object.isFrozen(n))throw new Error("waitUntil can NOT be called asynchronous");s&&(t=s(t,e)),n.push(t)}};try{e(o)}catch(e){(0,i.onUnexpectedError)(e);continue}Object.freeze(n),await Promise.allSettled(n).then((e=>{for(const t of e)"rejected"===t.status&&(0,i.onUnexpectedError)(t.reason)}))}}};class b extends g{get isPaused(){return 0!==this._isPaused}constructor(e){super(e),this._isPaused=0,this._eventQueue=new o.LinkedList,this._mergeFn=e?.merge}pause(){this._isPaused++}resume(){if(0!==this._isPaused&&0==--this._isPaused)if(this._mergeFn){if(this._eventQueue.size>0){const e=Array.from(this._eventQueue);this._eventQueue.clear(),super.fire(this._mergeFn(e))}}else for(;!this._isPaused&&0!==this._eventQueue.size;)super.fire(this._eventQueue.shift())}fire(e){this._size&&(0!==this._isPaused?this._eventQueue.push(e):super.fire(e))}}t.PauseableEmitter=b,t.DebounceEmitter=class extends b{constructor(e){super(e),this._delay=e.delay??100}fire(e){this._handle||(this.pause(),this._handle=setTimeout((()=>{this._handle=void 0,this.resume()}),this._delay)),super.fire(e)}},t.MicrotaskEmitter=class extends g{constructor(e){super(e),this._queuedEvents=[],this._mergeFn=e?.merge}fire(e){this.hasListeners()&&(this._queuedEvents.push(e),1===this._queuedEvents.length&&queueMicrotask((()=>{this._mergeFn?super.fire(this._mergeFn(this._queuedEvents)):this._queuedEvents.forEach((e=>super.fire(e))),this._queuedEvents=[]})))}};class y{constructor(){this.hasListeners=!1,this.events=[],this.emitter=new g({onWillAddFirstListener:()=>this.onFirstListenerAdd(),onDidRemoveLastListener:()=>this.onLastListenerRemove()})}get event(){return this.emitter.event}add(e){const t={event:e,listener:null};return this.events.push(t),this.hasListeners&&this.hook(t),(0,n.toDisposable)((0,r.createSingleCallFunction)((()=>{this.hasListeners&&this.unhook(t);const e=this.events.indexOf(t);this.events.splice(e,1)})))}onFirstListenerAdd(){this.hasListeners=!0,this.events.forEach((e=>this.hook(e)))}onLastListenerRemove(){this.hasListeners=!1,this.events.forEach((e=>this.unhook(e)))}hook(e){e.listener=e.event((e=>this.emitter.fire(e)))}unhook(e){e.listener?.dispose(),e.listener=null}dispose(){this.emitter.dispose();for(const e of this.events)e.listener?.dispose();this.events=[]}}t.EventMultiplexer=y,t.DynamicListEventMultiplexer=class{constructor(e,t,s,i){this._store=new n.DisposableStore;const r=this._store.add(new y),o=this._store.add(new n.DisposableMap);function a(e){o.set(e,r.add(i(e)))}for(const t of e)a(t);this._store.add(t((e=>{a(e)}))),this._store.add(s((e=>{o.deleteAndDispose(e)}))),this.event=r.event}dispose(){this._store.dispose()}},t.EventBufferer=class{constructor(){this.data=[]}wrapEvent(e,t,s){return(i,r,n)=>e((e=>{const n=this.data[this.data.length-1];if(!t)return void(n?n.buffers.push((()=>i.call(r,e))):i.call(r,e));const o=n;o?(o.items??=[],o.items.push(e),0===o.buffers.length&&n.buffers.push((()=>{o.reducedResult??=s?o.items.reduce(t,s):o.items.reduce(t),i.call(r,o.reducedResult)}))):i.call(r,t(s,e))}),void 0,n)}bufferEvents(e){const t={buffers:new Array};this.data.push(t);const s=e();return this.data.pop(),t.buffers.forEach((e=>e())),s}},t.Relay=class{constructor(){this.listening=!1,this.inputEvent=l.None,this.inputEventListener=n.Disposable.None,this.emitter=new g({onDidAddFirstListener:()=>{this.listening=!0,this.inputEventListener=this.inputEvent(this.emitter.fire,this.emitter)},onDidRemoveLastListener:()=>{this.listening=!1,this.inputEventListener.dispose()}}),this.event=this.emitter.event}set input(e){this.inputEvent=e,this.listening&&(this.inputEventListener.dispose(),this.inputEventListener=e(this.emitter.fire,this.emitter))}dispose(){this.inputEventListener.dispose(),this.emitter.dispose()}},t.ValueWithChangeEvent=class{static const(e){return new w(e)}constructor(e){this._value=e,this._onDidChange=new g,this.onDidChange=this._onDidChange.event}get value(){return this._value}set value(e){e!==this._value&&(this._value=e,this._onDidChange.fire(void 0))}};class w{constructor(e){this.value=e,this.onDidChange=l.None}}},355:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createSingleCallFunction=function(e,t){const s=this;let i,r=!1;return function(){if(r)return i;if(r=!0,t)try{i=e.apply(s,arguments)}finally{t()}else i=e.apply(s,arguments);return i}}},956:(e,t)=>{var s;Object.defineProperty(t,"__esModule",{value:!0}),t.Iterable=void 0,function(e){function t(e){return e&&"object"==typeof e&&"function"==typeof e[Symbol.iterator]}e.is=t;const s=Object.freeze([]);function*i(e){yield e}e.empty=function(){return s},e.single=i,e.wrap=function(e){return t(e)?e:i(e)},e.from=function(e){return e||s},e.reverse=function*(e){for(let t=e.length-1;t>=0;t--)yield e[t]},e.isEmpty=function(e){return!e||!0===e[Symbol.iterator]().next().done},e.first=function(e){return e[Symbol.iterator]().next().value},e.some=function(e,t){let s=0;for(const i of e)if(t(i,s++))return!0;return!1},e.find=function(e,t){for(const s of e)if(t(s))return s},e.filter=function*(e,t){for(const s of e)t(s)&&(yield s)},e.map=function*(e,t){let s=0;for(const i of e)yield t(i,s++)},e.flatMap=function*(e,t){let s=0;for(const i of e)yield*t(i,s++)},e.concat=function*(...e){for(const t of e)yield*t},e.reduce=function(e,t,s){let i=s;for(const s of e)i=t(i,s);return i},e.slice=function*(e,t,s=e.length){for(t<0&&(t+=e.length),s<0?s+=e.length:s>e.length&&(s=e.length);t<s;t++)yield e[t]},e.consume=function(t,s=Number.POSITIVE_INFINITY){const i=[];if(0===s)return[i,t];const r=t[Symbol.iterator]();for(let t=0;t<s;t++){const t=r.next();if(t.done)return[i,e.empty()];i.push(t.value)}return[i,{[Symbol.iterator]:()=>r}]},e.asyncToArray=async function(e){const t=[];for await(const s of e)t.push(s);return Promise.resolve(t)}}(s||(t.Iterable=s={}))},764:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Lazy=void 0,t.Lazy=class{constructor(e){this.executor=e,this._didRun=!1}get hasValue(){return this._didRun}get value(){if(!this._didRun)try{this._value=this.executor()}catch(e){this._error=e}finally{this._didRun=!0}if(this._error)throw this._error;return this._value}get rawValue(){return this._value}}},540:(e,t,s)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DisposableMap=t.ImmortalReference=t.AsyncReferenceCollection=t.ReferenceCollection=t.SafeDisposable=t.RefCountedDisposable=t.MandatoryMutableDisposable=t.MutableDisposable=t.Disposable=t.DisposableStore=t.DisposableTracker=void 0,t.setDisposableTracker=function(e){l=e},t.trackDisposable=c,t.markAsDisposed=u,t.markAsSingleton=function(e){return l?.markAsSingleton(e),e},t.isDisposable=f,t.dispose=p,t.disposeIfDisposable=function(e){for(const t of e)f(t)&&t.dispose();return[]},t.combinedDisposable=function(...e){const t=_((()=>p(e)));return function(e,t){if(l)for(const s of e)l.setParent(s,t)}(e,t),t},t.toDisposable=_,t.disposeOnReturn=function(e){const t=new m;try{e(t)}finally{t.dispose()}};const i=s(732),r=s(33),n=s(714),o=s(355),a=s(956);let l=null;class h{constructor(){this.livingDisposables=new Map}static{this.idx=0}getDisposableData(e){let t=this.livingDisposables.get(e);return t||(t={parent:null,source:null,isSingleton:!1,value:e,idx:h.idx++},this.livingDisposables.set(e,t)),t}trackDisposable(e){const t=this.getDisposableData(e);t.source||(t.source=(new Error).stack)}setParent(e,t){this.getDisposableData(e).parent=t}markAsDisposed(e){this.livingDisposables.delete(e)}markAsSingleton(e){this.getDisposableData(e).isSingleton=!0}getRootParent(e,t){const s=t.get(e);if(s)return s;const i=e.parent?this.getRootParent(this.getDisposableData(e.parent),t):e;return t.set(e,i),i}getTrackedDisposables(){const e=new Map;return[...this.livingDisposables.entries()].filter((([,t])=>null!==t.source&&!this.getRootParent(t,e).isSingleton)).flatMap((([e])=>e))}computeLeakingDisposables(e=10,t){let s;if(t)s=t;else{const e=new Map,t=[...this.livingDisposables.values()].filter((t=>null!==t.source&&!this.getRootParent(t,e).isSingleton));if(0===t.length)return;const i=new Set(t.map((e=>e.value)));if(s=t.filter((e=>!(e.parent&&i.has(e.parent)))),0===s.length)throw new Error("There are cyclic diposable chains!")}if(!s)return;function o(e){const t=e.source.split("\n").map((e=>e.trim().replace("at ",""))).filter((e=>""!==e));return function(e,t){for(;e.length>0&&t.some((t=>"string"==typeof t?t===e[0]:e[0].match(t)));)e.shift()}(t,["Error",/^trackDisposable \(.*\)$/,/^DisposableTracker.trackDisposable \(.*\)$/]),t.reverse()}const a=new n.SetMap;for(const e of s){const t=o(e);for(let s=0;s<=t.length;s++)a.add(t.slice(0,s).join("\n"),e)}s.sort((0,i.compareBy)((e=>e.idx),i.numberComparator));let l="",h=0;for(const t of s.slice(0,e)){h++;const e=o(t),i=[];for(let t=0;t<e.length;t++){let n=e[t];n=`(shared with ${a.get(e.slice(0,t+1).join("\n")).size}/${s.length} leaks) at ${n}`;const l=a.get(e.slice(0,t).join("\n")),h=(0,r.groupBy)([...l].map((e=>o(e)[t])),(e=>e));delete h[e[t]];for(const[e,t]of Object.entries(h))i.unshift(` - stacktraces of ${t.length} other leaks continue with ${e}`);i.unshift(n)}l+=`\n\n\n==================== Leaking disposable ${h}/${s.length}: ${t.value.constructor.name} ====================\n${i.join("\n")}\n============================================================\n\n`}return s.length>e&&(l+=`\n\n\n... and ${s.length-e} more leaking disposables\n\n`),{leaks:s,details:l}}}function c(e){return l?.trackDisposable(e),e}function u(e){l?.markAsDisposed(e)}function d(e,t){l?.setParent(e,t)}function f(e){return"object"==typeof e&&null!==e&&"function"==typeof e.dispose&&0===e.dispose.length}function p(e){if(a.Iterable.is(e)){const t=[];for(const s of e)if(s)try{s.dispose()}catch(e){t.push(e)}if(1===t.length)throw t[0];if(t.length>1)throw new AggregateError(t,"Encountered errors while disposing of store");return Array.isArray(e)?[]:e}if(e)return e.dispose(),e}function _(e){const t=c({dispose:(0,o.createSingleCallFunction)((()=>{u(t),e()}))});return t}t.DisposableTracker=h;class m{static{this.DISABLE_DISPOSED_WARNING=!1}constructor(){this._toDispose=new Set,this._isDisposed=!1,c(this)}dispose(){this._isDisposed||(u(this),this._isDisposed=!0,this.clear())}get isDisposed(){return this._isDisposed}clear(){if(0!==this._toDispose.size)try{p(this._toDispose)}finally{this._toDispose.clear()}}add(e){if(!e)return e;if(e===this)throw new Error("Cannot register a disposable on itself!");return d(e,this),this._isDisposed?m.DISABLE_DISPOSED_WARNING||console.warn(new Error("Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!").stack):this._toDispose.add(e),e}delete(e){if(e){if(e===this)throw new Error("Cannot dispose a disposable on itself!");this._toDispose.delete(e),e.dispose()}}deleteAndLeak(e){e&&this._toDispose.has(e)&&(this._toDispose.delete(e),d(e,null))}}t.DisposableStore=m;class g{static{this.None=Object.freeze({dispose(){}})}constructor(){this._store=new m,c(this),d(this._store,this)}dispose(){u(this),this._store.dispose()}_register(e){if(e===this)throw new Error("Cannot register a disposable on itself!");return this._store.add(e)}}t.Disposable=g;class v{constructor(){this._isDisposed=!1,c(this)}get value(){return this._isDisposed?void 0:this._value}set value(e){this._isDisposed||e===this._value||(this._value?.dispose(),e&&d(e,this),this._value=e)}clear(){this.value=void 0}dispose(){this._isDisposed=!0,u(this),this._value?.dispose(),this._value=void 0}clearAndLeak(){const e=this._value;return this._value=void 0,e&&d(e,null),e}}t.MutableDisposable=v,t.MandatoryMutableDisposable=class{constructor(e){this._disposable=new v,this._isDisposed=!1,this._disposable.value=e}get value(){return this._disposable.value}set value(e){this._isDisposed||e===this._disposable.value||(this._disposable.value=e)}dispose(){this._isDisposed=!0,this._disposable.dispose()}},t.RefCountedDisposable=class{constructor(e){this._disposable=e,this._counter=1}acquire(){return this._counter++,this}release(){return 0==--this._counter&&this._disposable.dispose(),this}},t.SafeDisposable=class{constructor(){this.dispose=()=>{},this.unset=()=>{},this.isset=()=>!1,c(this)}set(e){let t=e;return this.unset=()=>t=void 0,this.isset=()=>void 0!==t,this.dispose=()=>{t&&(t(),t=void 0,u(this))},this}},t.ReferenceCollection=class{constructor(){this.references=new Map}acquire(e,...t){let s=this.references.get(e);s||(s={counter:0,object:this.createReferencedObject(e,...t)},this.references.set(e,s));const{object:i}=s,r=(0,o.createSingleCallFunction)((()=>{0==--s.counter&&(this.destroyReferencedObject(e,s.object),this.references.delete(e))}));return s.counter++,{object:i,dispose:r}}},t.AsyncReferenceCollection=class{constructor(e){this.referenceCollection=e}async acquire(e,...t){const s=this.referenceCollection.acquire(e,...t);try{return{object:await s.object,dispose:()=>s.dispose()}}catch(e){throw s.dispose(),e}}},t.ImmortalReference=class{constructor(e){this.object=e}dispose(){}};class b{constructor(){this._store=new Map,this._isDisposed=!1,c(this)}dispose(){u(this),this._isDisposed=!0,this.clearAndDisposeAll()}clearAndDisposeAll(){if(this._store.size)try{p(this._store.values())}finally{this._store.clear()}}has(e){return this._store.has(e)}get size(){return this._store.size}get(e){return this._store.get(e)}set(e,t,s=!1){this._isDisposed&&console.warn(new Error("Trying to add a disposable to a DisposableMap that has already been disposed of. The added object will be leaked!").stack),s||this._store.get(e)?.dispose(),this._store.set(e,t)}deleteAndDispose(e){this._store.get(e)?.dispose(),this._store.delete(e)}deleteAndLeak(e){const t=this._store.get(e);return this._store.delete(e),t}keys(){return this._store.keys()}values(){return this._store.values()}[Symbol.iterator](){return this._store[Symbol.iterator]()}}t.DisposableMap=b},711:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.LinkedList=void 0;class s{static{this.Undefined=new s(void 0)}constructor(e){this.element=e,this.next=s.Undefined,this.prev=s.Undefined}}class i{constructor(){this._first=s.Undefined,this._last=s.Undefined,this._size=0}get size(){return this._size}isEmpty(){return this._first===s.Undefined}clear(){let e=this._first;for(;e!==s.Undefined;){const t=e.next;e.prev=s.Undefined,e.next=s.Undefined,e=t}this._first=s.Undefined,this._last=s.Undefined,this._size=0}unshift(e){return this._insert(e,!1)}push(e){return this._insert(e,!0)}_insert(e,t){const i=new s(e);if(this._first===s.Undefined)this._first=i,this._last=i;else if(t){const e=this._last;this._last=i,i.prev=e,e.next=i}else{const e=this._first;this._first=i,i.next=e,e.prev=i}this._size+=1;let r=!1;return()=>{r||(r=!0,this._remove(i))}}shift(){if(this._first!==s.Undefined){const e=this._first.element;return this._remove(this._first),e}}pop(){if(this._last!==s.Undefined){const e=this._last.element;return this._remove(this._last),e}}_remove(e){if(e.prev!==s.Undefined&&e.next!==s.Undefined){const t=e.prev;t.next=e.next,e.next.prev=t}else e.prev===s.Undefined&&e.next===s.Undefined?(this._first=s.Undefined,this._last=s.Undefined):e.next===s.Undefined?(this._last=this._last.prev,this._last.next=s.Undefined):e.prev===s.Undefined&&(this._first=this._first.next,this._first.prev=s.Undefined);this._size-=1}*[Symbol.iterator](){let e=this._first;for(;e!==s.Undefined;)yield e.element,e=e.next}}t.LinkedList=i},714:(e,t)=>{var s;Object.defineProperty(t,"__esModule",{value:!0}),t.SetMap=t.BidirectionalMap=t.CounterSet=t.Touch=void 0,t.getOrSet=function(e,t,s){let i=e.get(t);return void 0===i&&(i=s,e.set(t,i)),i},t.mapToString=function(e){const t=[];return e.forEach(((e,s)=>{t.push(`${s} => ${e}`)})),`Map(${e.size}) {${t.join(", ")}}`},t.setToString=function(e){const t=[];return e.forEach((e=>{t.push(e)})),`Set(${e.size}) {${t.join(", ")}}`},t.mapsStrictEqualIgnoreOrder=function(e,t){if(e===t)return!0;if(e.size!==t.size)return!1;for(const[s,i]of e)if(!t.has(s)||t.get(s)!==i)return!1;for(const[s]of t)if(!e.has(s))return!1;return!0},function(e){e[e.None=0]="None",e[e.AsOld=1]="AsOld",e[e.AsNew=2]="AsNew"}(s||(t.Touch=s={})),t.CounterSet=class{constructor(){this.map=new Map}add(e){return this.map.set(e,(this.map.get(e)||0)+1),this}delete(e){let t=this.map.get(e)||0;return 0!==t&&(t--,0===t?this.map.delete(e):this.map.set(e,t),!0)}has(e){return this.map.has(e)}},t.BidirectionalMap=class{constructor(e){if(this._m1=new Map,this._m2=new Map,e)for(const[t,s]of e)this.set(t,s)}clear(){this._m1.clear(),this._m2.clear()}set(e,t){this._m1.set(e,t),this._m2.set(t,e)}get(e){return this._m1.get(e)}getKey(e){return this._m2.get(e)}delete(e){const t=this._m1.get(e);return void 0!==t&&(this._m1.delete(e),this._m2.delete(t),!0)}forEach(e,t){this._m1.forEach(((s,i)=>{e.call(t,s,i,this)}))}keys(){return this._m1.keys()}values(){return this._m1.values()}},t.SetMap=class{constructor(){this.map=new Map}add(e,t){let s=this.map.get(e);s||(s=new Set,this.map.set(e,s)),s.add(t)}delete(e,t){const s=this.map.get(e);s&&(s.delete(t),0===s.size&&this.map.delete(e))}forEach(e,t){const s=this.map.get(e);s&&s.forEach(t)}get(e){return this.map.get(e)||new Set}}},973:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isAndroid=t.isEdge=t.isSafari=t.isFirefox=t.isChrome=t.OS=t.OperatingSystem=t.setTimeout0=t.setTimeout0IsFaster=t.translationsConfigFile=t.platformLocale=t.locale=t.Language=t.language=t.userAgent=t.platform=t.isCI=t.isMobile=t.isIOS=t.webWorkerOrigin=t.isWebWorker=t.isWeb=t.isElectron=t.isNative=t.isLinuxSnap=t.isLinux=t.isMacintosh=t.isWindows=t.Platform=t.LANGUAGE_DEFAULT=void 0,t.PlatformToString=function(e){switch(e){case w.Web:return"Web";case w.Mac:return"Mac";case w.Linux:return"Linux";case w.Windows:return"Windows"}},t.isLittleEndian=function(){if(!C){C=!0;const e=new Uint8Array(2);e[0]=1,e[1]=2;const t=new Uint16Array(e.buffer);k=513===t[0]}return k},t.isBigSurOrNewer=function(e){return parseFloat(e)>=20},t.LANGUAGE_DEFAULT="en";let s,i,r,n=!1,o=!1,a=!1,l=!1,h=!1,c=!1,u=!1,d=!1,f=!1,p=!1,_=t.LANGUAGE_DEFAULT,m=t.LANGUAGE_DEFAULT;const g=globalThis;let v;void 0!==g.vscode&&void 0!==g.vscode.process?v=g.vscode.process:"undefined"!=typeof process&&"string"==typeof process?.versions?.node&&(v=process);const b="string"==typeof v?.versions?.electron,y=b&&"renderer"===v?.type;if("object"==typeof v){n="win32"===v.platform,o="darwin"===v.platform,a="linux"===v.platform,l=a&&!!v.env.SNAP&&!!v.env.SNAP_REVISION,u=b,f=!!v.env.CI||!!v.env.BUILD_ARTIFACTSTAGINGDIRECTORY,s=t.LANGUAGE_DEFAULT,_=t.LANGUAGE_DEFAULT;const e=v.env.VSCODE_NLS_CONFIG;if(e)try{const r=JSON.parse(e);s=r.userLocale,m=r.osLocale,_=r.resolvedLanguage||t.LANGUAGE_DEFAULT,i=r.languagePack?.translationsConfigFile}catch(e){}h=!0}else"object"!=typeof navigator||y?console.error("Unable to resolve platform."):(r=navigator.userAgent,n=r.indexOf("Windows")>=0,o=r.indexOf("Macintosh")>=0,d=(r.indexOf("Macintosh")>=0||r.indexOf("iPad")>=0||r.indexOf("iPhone")>=0)&&!!navigator.maxTouchPoints&&navigator.maxTouchPoints>0,a=r.indexOf("Linux")>=0,p=r?.indexOf("Mobi")>=0,c=!0,_=globalThis._VSCODE_NLS_LANGUAGE||t.LANGUAGE_DEFAULT,s=navigator.language.toLowerCase(),m=s);var w;!function(e){e[e.Web=0]="Web",e[e.Mac=1]="Mac",e[e.Linux=2]="Linux",e[e.Windows=3]="Windows"}(w||(t.Platform=w={}));let D=w.Web;var S,E;o?D=w.Mac:n?D=w.Windows:a&&(D=w.Linux),t.isWindows=n,t.isMacintosh=o,t.isLinux=a,t.isLinuxSnap=l,t.isNative=h,t.isElectron=u,t.isWeb=c,t.isWebWorker=c&&"function"==typeof g.importScripts,t.webWorkerOrigin=t.isWebWorker?g.origin:void 0,t.isIOS=d,t.isMobile=p,t.isCI=f,t.platform=D,t.userAgent=r,t.language=_,function(e){e.value=function(){return t.language},e.isDefaultVariant=function(){return 2===t.language.length?"en"===t.language:t.language.length>=3&&"e"===t.language[0]&&"n"===t.language[1]&&"-"===t.language[2]},e.isDefault=function(){return"en"===t.language}}(S||(t.Language=S={})),t.locale=s,t.platformLocale=m,t.translationsConfigFile=i,t.setTimeout0IsFaster="function"==typeof g.postMessage&&!g.importScripts,t.setTimeout0=(()=>{if(t.setTimeout0IsFaster){const e=[];g.addEventListener("message",(t=>{if(t.data&&t.data.vscodeScheduleAsyncWork)for(let s=0,i=e.length;s<i;s++){const i=e[s];if(i.id===t.data.vscodeScheduleAsyncWork)return e.splice(s,1),void i.callback()}}));let t=0;return s=>{const i=++t;e.push({id:i,callback:s}),g.postMessage({vscodeScheduleAsyncWork:i},"*")}}return e=>setTimeout(e)})(),function(e){e[e.Windows=1]="Windows",e[e.Macintosh=2]="Macintosh",e[e.Linux=3]="Linux"}(E||(t.OperatingSystem=E={})),t.OS=o||d?E.Macintosh:n?E.Windows:E.Linux;let k=!0,C=!1;t.isChrome=!!(t.userAgent&&t.userAgent.indexOf("Chrome")>=0),t.isFirefox=!!(t.userAgent&&t.userAgent.indexOf("Firefox")>=0),t.isSafari=!!(!t.isChrome&&t.userAgent&&t.userAgent.indexOf("Safari")>=0),t.isEdge=!!(t.userAgent&&t.userAgent.indexOf("Edg/")>=0),t.isAndroid=!!(t.userAgent&&t.userAgent.indexOf("Android")>=0)},79:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.StopWatch=void 0;const s=globalThis.performance&&"function"==typeof globalThis.performance.now;class i{static create(e){return new i(e)}constructor(e){this._now=s&&!1===e?Date.now:globalThis.performance.now.bind(globalThis.performance),this._startTime=this._now(),this._stopTime=-1}stop(){this._stopTime=this._now()}reset(){this._startTime=this._now(),this._stopTime=-1}elapsed(){return-1!==this._stopTime?this._stopTime-this._startTime:this._now()-this._startTime}}t.StopWatch=i},329:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.MicrotaskDelay=void 0,t.MicrotaskDelay=Symbol("MicrotaskDelay")}},t={};function s(i){var r=t[i];if(void 0!==r)return r.exports;var n=t[i]={exports:{}};return e[i](n,n.exports,s),n.exports}var i={};return(()=>{var e=i;Object.defineProperty(e,"__esModule",{value:!0}),e.SearchAddon=void 0;const t=s(540),r=s(940),n=s(149),o=s(772),a=s(615),l=s(864),h=s(438);class c extends t.Disposable{get onDidChangeResults(){return this._resultTracker.onDidChangeResults}constructor(e){super(),this._highlightTimeout=this._register(new t.MutableDisposable),this._lineCache=this._register(new t.MutableDisposable),this._state=new o.SearchState,this._resultTracker=this._register(new h.SearchResultTracker),this._highlightLimit=e?.highlightLimit??1e3}activate(e){this._terminal=e,this._lineCache.value=new n.SearchLineCache(e),this._engine=new a.SearchEngine(e,this._lineCache.value),this._decorationManager=new l.DecorationManager(e),this._register(this._terminal.onWriteParsed((()=>this._updateMatches()))),this._register(this._terminal.onResize((()=>this._updateMatches()))),this._register((0,t.toDisposable)((()=>this.clearDecorations())))}_updateMatches(){this._highlightTimeout.clear(),this._state.cachedSearchTerm&&this._state.lastSearchOptions?.decorations&&(this._highlightTimeout.value=(0,r.disposableTimeout)((()=>{const e=this._state.cachedSearchTerm;this._state.clearCachedTerm(),this.findPrevious(e,{...this._state.lastSearchOptions,incremental:!0},{noScroll:!0})}),200))}clearDecorations(e){this._resultTracker.clearSelectedDecoration(),this._decorationManager?.clearHighlightDecorations(),this._resultTracker.clearResults(),e||this._state.clearCachedTerm()}clearActiveDecoration(){this._resultTracker.clearSelectedDecoration()}findNext(e,t,s){if(!this._terminal||!this._engine)throw new Error("Cannot use addon until it has been loaded");this._state.lastSearchOptions=t,this._state.shouldUpdateHighlighting(e,t)&&this._highlightAllMatches(e,t);const i=this._findNextAndSelect(e,t,s);return this._fireResults(t),this._state.cachedSearchTerm=e,i}_highlightAllMatches(e,t){if(!this._terminal||!this._engine||!this._decorationManager)throw new Error("Cannot use addon until it has been loaded");if(!this._state.isValidSearchTerm(e))return void this.clearDecorations();this.clearDecorations(!0);const s=[];let i,r=this._engine.find(e,0,0,t);for(;r&&(i?.row!==r.row||i?.col!==r.col)&&!(s.length>=this._highlightLimit);)i=r,s.push(i),r=this._engine.find(e,i.col+i.term.length>=this._terminal.cols?i.row+1:i.row,i.col+i.term.length>=this._terminal.cols?0:i.col+1,t);this._resultTracker.updateResults(s,this._highlightLimit),t.decorations&&this._decorationManager.createHighlightDecorations(s,t.decorations)}_findNextAndSelect(e,t,s){if(!this._terminal||!this._engine)return!1;if(!this._state.isValidSearchTerm(e))return this._terminal.clearSelection(),this.clearDecorations(),!1;const i=this._engine.findNextWithSelection(e,t,this._state.cachedSearchTerm);return this._selectResult(i,t?.decorations,s?.noScroll)}findPrevious(e,t,s){if(!this._terminal||!this._engine)throw new Error("Cannot use addon until it has been loaded");this._state.lastSearchOptions=t,this._state.shouldUpdateHighlighting(e,t)&&this._highlightAllMatches(e,t);const i=this._findPreviousAndSelect(e,t,s);return this._fireResults(t),this._state.cachedSearchTerm=e,i}_fireResults(e){this._resultTracker.fireResultsChanged(!!e?.decorations)}_findPreviousAndSelect(e,t,s){if(!this._terminal||!this._engine)return!1;if(!this._state.isValidSearchTerm(e))return this._terminal.clearSelection(),this.clearDecorations(),!1;const i=this._engine.findPreviousWithSelection(e,t,this._state.cachedSearchTerm);return this._selectResult(i,t?.decorations,s?.noScroll)}_selectResult(e,t,s){if(!this._terminal||!this._decorationManager)return!1;if(this._resultTracker.clearSelectedDecoration(),!e)return this._terminal.clearSelection(),!1;if(this._terminal.select(e.col,e.row,e.size),t){const s=this._decorationManager.createActiveDecoration(e,t);s&&(this._resultTracker.selectedDecoration=s)}if(!s&&(e.row>=this._terminal.buffer.active.viewportY+this._terminal.rows||e.row<this._terminal.buffer.active.viewportY)){let t=e.row-this._terminal.buffer.active.viewportY;t-=Math.floor(this._terminal.rows/2),this._terminal.scrollLines(t)}return!0}}e.SearchAddon=c})(),i})()));
|
|
2
|
+
//# sourceMappingURL=addon-search.js.map
|
package/client.js
CHANGED
|
@@ -161,6 +161,21 @@ window.__ModuleLoader__.load({
|
|
|
161
161
|
'terminal.openDetails': ['打开主机详情', 'Open details'],
|
|
162
162
|
'terminal.assetsError': ['终端组件加载失败:{message}。如果刚更新插件,请重启 DSH 后重试。', 'Could not load the terminal component: {message}. If the plugin was just updated, restart DSH and retry.'],
|
|
163
163
|
'terminal.resyncFailed': ['终端输出曾中断,已尝试重新同步;如仍异常请重连。', 'Terminal output was interrupted; attempted a resync. Reconnect if problems persist.'],
|
|
164
|
+
'terminal.search': ['搜索终端', 'Search terminal'],
|
|
165
|
+
'terminal.searchNext': ['下一个', 'Next match'],
|
|
166
|
+
'terminal.searchPrevious': ['上一个', 'Previous match'],
|
|
167
|
+
'terminal.searchCase': ['区分大小写', 'Match case'],
|
|
168
|
+
'terminal.searchClose': ['关闭搜索', 'Close search'],
|
|
169
|
+
'terminal.fontSmaller': ['缩小字号', 'Smaller terminal font'],
|
|
170
|
+
'terminal.fontLarger': ['放大字号', 'Larger terminal font'],
|
|
171
|
+
'terminal.menu.copy': ['复制', 'Copy'],
|
|
172
|
+
'terminal.menu.paste': ['粘贴', 'Paste'],
|
|
173
|
+
'terminal.menu.selectAll': ['全选', 'Select all'],
|
|
174
|
+
'terminal.menu.clear': ['清屏', 'Clear'],
|
|
175
|
+
'terminal.menu.title': ['终端菜单', 'Terminal menu'],
|
|
176
|
+
'terminal.searchUnavailable': ['终端搜索加载失败,请重启 DSH 后重试。', 'Terminal search failed to load; restart DSH and retry.'],
|
|
177
|
+
'terminal.copyFailed': ['复制失败,请检查浏览器剪贴板权限。', 'Copy failed; check browser clipboard permissions.'],
|
|
178
|
+
'terminal.pasteFailed': ['粘贴失败,请检查浏览器剪贴板权限。', 'Paste failed; check browser clipboard permissions.'],
|
|
164
179
|
'terminal.backendHint': ['无法连接到插件后端。如果刚更新插件,请重启 DSH 后重试。', 'Cannot reach the plugin backend. If the plugin was just updated, restart DSH and retry.'],
|
|
165
180
|
'terminal.passwordMissing': ['该主机还没有保存密码,请先打开「主机详情」设置服务器密码。', 'No password stored for this host. Open Details and set the server password first.'],
|
|
166
181
|
'drawer.exit': ['退出码 {code}', 'exit {code}'],
|
|
@@ -1152,6 +1167,25 @@ window.__ModuleLoader__.load({
|
|
|
1152
1167
|
}
|
|
1153
1168
|
}
|
|
1154
1169
|
|
|
1170
|
+
const TERMINAL_FONT_KEY = 'dsh-ssh-manage:terminal-font-size'
|
|
1171
|
+
const TERMINAL_FONT_MIN = 10
|
|
1172
|
+
const TERMINAL_FONT_MAX = 20
|
|
1173
|
+
|
|
1174
|
+
function clampTerminalFontSize(value) {
|
|
1175
|
+
const numeric = Number(value)
|
|
1176
|
+
if (!Number.isFinite(numeric)) return 13
|
|
1177
|
+
return Math.min(TERMINAL_FONT_MAX, Math.max(TERMINAL_FONT_MIN, Math.round(numeric)))
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
function readTerminalFontSize() {
|
|
1181
|
+
try {
|
|
1182
|
+
const stored = window.localStorage.getItem(TERMINAL_FONT_KEY)
|
|
1183
|
+
return stored === null ? 13 : clampTerminalFontSize(stored)
|
|
1184
|
+
} catch {
|
|
1185
|
+
return 13
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1155
1189
|
function App({ ctx }) {
|
|
1156
1190
|
const t = useT(ctx)
|
|
1157
1191
|
const localeId = useLocaleId(ctx)
|
|
@@ -1187,6 +1221,7 @@ window.__ModuleLoader__.load({
|
|
|
1187
1221
|
)
|
|
1188
1222
|
const [activeSessionId, setActiveSessionId] = React.useState(() => persistentPanelState.activeSessionId)
|
|
1189
1223
|
const [treeWidth, setTreeWidth] = React.useState(readTreeWidth)
|
|
1224
|
+
const [terminalFontSize, setTerminalFontSize] = React.useState(readTerminalFontSize)
|
|
1190
1225
|
const [clearSignals, setClearSignals] = React.useState({})
|
|
1191
1226
|
const [sessionStates, setSessionStates] = React.useState({})
|
|
1192
1227
|
const toastTimer = React.useRef(null)
|
|
@@ -1226,6 +1261,12 @@ window.__ModuleLoader__.load({
|
|
|
1226
1261
|
} catch {}
|
|
1227
1262
|
}, [treeWidth])
|
|
1228
1263
|
|
|
1264
|
+
React.useEffect(() => {
|
|
1265
|
+
try {
|
|
1266
|
+
window.localStorage.setItem(TERMINAL_FONT_KEY, String(terminalFontSize))
|
|
1267
|
+
} catch {}
|
|
1268
|
+
}, [terminalFontSize])
|
|
1269
|
+
|
|
1229
1270
|
React.useEffect(() => {
|
|
1230
1271
|
for (const session of sessions) ptyActiveIds.add(session.id)
|
|
1231
1272
|
}, [sessions])
|
|
@@ -1717,6 +1758,8 @@ window.__ModuleLoader__.load({
|
|
|
1717
1758
|
groupsCloseGuard,
|
|
1718
1759
|
treeWidth,
|
|
1719
1760
|
setTreeWidth,
|
|
1761
|
+
terminalFontSize,
|
|
1762
|
+
setTerminalFontSize,
|
|
1720
1763
|
sessions,
|
|
1721
1764
|
activeSessionId,
|
|
1722
1765
|
sessionStates,
|
|
@@ -2833,6 +2876,24 @@ window.__ModuleLoader__.load({
|
|
|
2833
2876
|
},
|
|
2834
2877
|
h(IconServer, { size: 15 }),
|
|
2835
2878
|
),
|
|
2879
|
+
h(
|
|
2880
|
+
IconButton,
|
|
2881
|
+
{
|
|
2882
|
+
title: t('terminal.fontSmaller'),
|
|
2883
|
+
disabled: model.terminalFontSize <= TERMINAL_FONT_MIN,
|
|
2884
|
+
onClick: () => model.setTerminalFontSize((value) => Math.max(TERMINAL_FONT_MIN, value - 1)),
|
|
2885
|
+
},
|
|
2886
|
+
h('span', { className: 'ssh-fontGlyph' }, 'A−'),
|
|
2887
|
+
),
|
|
2888
|
+
h(
|
|
2889
|
+
IconButton,
|
|
2890
|
+
{
|
|
2891
|
+
title: t('terminal.fontLarger'),
|
|
2892
|
+
disabled: model.terminalFontSize >= TERMINAL_FONT_MAX,
|
|
2893
|
+
onClick: () => model.setTerminalFontSize((value) => Math.min(TERMINAL_FONT_MAX, value + 1)),
|
|
2894
|
+
},
|
|
2895
|
+
h('span', { className: 'ssh-fontGlyph' }, 'A+'),
|
|
2896
|
+
),
|
|
2836
2897
|
h(
|
|
2837
2898
|
IconButton,
|
|
2838
2899
|
{
|
|
@@ -2869,6 +2930,7 @@ window.__ModuleLoader__.load({
|
|
|
2869
2930
|
model,
|
|
2870
2931
|
host,
|
|
2871
2932
|
sessionId: session.id,
|
|
2933
|
+
fontSize: model.terminalFontSize,
|
|
2872
2934
|
clearSignal: clearSignals[session.id] ?? 0,
|
|
2873
2935
|
active: isVisible && session.id === activeSession.id,
|
|
2874
2936
|
})
|
|
@@ -2969,6 +3031,14 @@ window.__ModuleLoader__.load({
|
|
|
2969
3031
|
css: 'dsh-ssh-manage-xterm-css',
|
|
2970
3032
|
script: 'dsh-ssh-manage-xterm-script',
|
|
2971
3033
|
fit: 'dsh-ssh-manage-xterm-fit',
|
|
3034
|
+
search: 'dsh-ssh-manage-xterm-search',
|
|
3035
|
+
}
|
|
3036
|
+
|
|
3037
|
+
function terminalAssetReady(id) {
|
|
3038
|
+
if (id === TERMINAL_ASSET_IDS.script) return Boolean(window.Terminal)
|
|
3039
|
+
if (id === TERMINAL_ASSET_IDS.fit) return Boolean(window.FitAddon && window.FitAddon.FitAddon)
|
|
3040
|
+
if (id === TERMINAL_ASSET_IDS.search) return Boolean(window.SearchAddon && window.SearchAddon.SearchAddon)
|
|
3041
|
+
return false
|
|
2972
3042
|
}
|
|
2973
3043
|
let terminalAssetsPromise = null
|
|
2974
3044
|
|
|
@@ -2976,10 +3046,7 @@ window.__ModuleLoader__.load({
|
|
|
2976
3046
|
return new Promise((resolve, reject) => {
|
|
2977
3047
|
const existing = document.getElementById(id)
|
|
2978
3048
|
if (existing) {
|
|
2979
|
-
const ready =
|
|
2980
|
-
id === TERMINAL_ASSET_IDS.script
|
|
2981
|
-
? Boolean(window.Terminal)
|
|
2982
|
-
: Boolean(window.FitAddon && window.FitAddon.FitAddon)
|
|
3049
|
+
const ready = terminalAssetReady(id)
|
|
2983
3050
|
if (ready) {
|
|
2984
3051
|
resolve()
|
|
2985
3052
|
return
|
|
@@ -3003,8 +3070,12 @@ window.__ModuleLoader__.load({
|
|
|
3003
3070
|
}
|
|
3004
3071
|
|
|
3005
3072
|
function loadTerminalAssets() {
|
|
3006
|
-
if (window.Terminal && window.FitAddon && window.FitAddon.FitAddon) {
|
|
3007
|
-
return Promise.resolve({
|
|
3073
|
+
if (window.Terminal && window.FitAddon && window.FitAddon.FitAddon && window.SearchAddon?.SearchAddon) {
|
|
3074
|
+
return Promise.resolve({
|
|
3075
|
+
Terminal: window.Terminal,
|
|
3076
|
+
FitAddon: window.FitAddon.FitAddon,
|
|
3077
|
+
SearchAddon: window.SearchAddon.SearchAddon,
|
|
3078
|
+
})
|
|
3008
3079
|
}
|
|
3009
3080
|
if (terminalAssetsPromise) return terminalAssetsPromise
|
|
3010
3081
|
if (!document.getElementById(TERMINAL_ASSET_IDS.css)) {
|
|
@@ -3016,9 +3087,17 @@ window.__ModuleLoader__.load({
|
|
|
3016
3087
|
}
|
|
3017
3088
|
terminalAssetsPromise = loadScriptAsset(TERMINAL_ASSET_IDS.script, '/dsh-ssh-manage/assets/xterm.js')
|
|
3018
3089
|
.then(() => loadScriptAsset(TERMINAL_ASSET_IDS.fit, '/dsh-ssh-manage/assets/addon-fit.js'))
|
|
3090
|
+
// Search is optional: a missing/blocked addon must not break the terminal.
|
|
3091
|
+
.then(() => loadScriptAsset(TERMINAL_ASSET_IDS.search, '/dsh-ssh-manage/assets/addon-search.js').catch(() => null))
|
|
3019
3092
|
.then(() => {
|
|
3020
|
-
if (!window.Terminal || !window.FitAddon || !window.FitAddon.FitAddon)
|
|
3021
|
-
|
|
3093
|
+
if (!window.Terminal || !window.FitAddon || !window.FitAddon.FitAddon) {
|
|
3094
|
+
throw new Error('Terminal assets did not initialize')
|
|
3095
|
+
}
|
|
3096
|
+
return {
|
|
3097
|
+
Terminal: window.Terminal,
|
|
3098
|
+
FitAddon: window.FitAddon.FitAddon,
|
|
3099
|
+
SearchAddon: window.SearchAddon?.SearchAddon ?? null,
|
|
3100
|
+
}
|
|
3022
3101
|
})
|
|
3023
3102
|
.catch((error) => {
|
|
3024
3103
|
terminalAssetsPromise = null
|
|
@@ -3315,6 +3394,29 @@ window.__ModuleLoader__.load({
|
|
|
3315
3394
|
void ptyPost(PTY_CLEAR_ROUTE, { id }, 15_000).catch(() => {})
|
|
3316
3395
|
}
|
|
3317
3396
|
|
|
3397
|
+
async function copyTextToClipboard(text) {
|
|
3398
|
+
if (!text) return false
|
|
3399
|
+
try {
|
|
3400
|
+
if (navigator.clipboard?.writeText) {
|
|
3401
|
+
await navigator.clipboard.writeText(text)
|
|
3402
|
+
return true
|
|
3403
|
+
}
|
|
3404
|
+
} catch {}
|
|
3405
|
+
try {
|
|
3406
|
+
const textarea = document.createElement('textarea')
|
|
3407
|
+
textarea.value = text
|
|
3408
|
+
textarea.style.position = 'fixed'
|
|
3409
|
+
textarea.style.opacity = '0'
|
|
3410
|
+
document.body.appendChild(textarea)
|
|
3411
|
+
textarea.select()
|
|
3412
|
+
const copied = document.execCommand('copy')
|
|
3413
|
+
textarea.remove()
|
|
3414
|
+
return copied
|
|
3415
|
+
} catch {
|
|
3416
|
+
return false
|
|
3417
|
+
}
|
|
3418
|
+
}
|
|
3419
|
+
|
|
3318
3420
|
function decodeBase64(text) {
|
|
3319
3421
|
const binary = atob(String(text ?? ''))
|
|
3320
3422
|
const bytes = new Uint8Array(binary.length)
|
|
@@ -3322,15 +3424,25 @@ window.__ModuleLoader__.load({
|
|
|
3322
3424
|
return bytes
|
|
3323
3425
|
}
|
|
3324
3426
|
|
|
3325
|
-
function TerminalPane({ model, host, sessionId, active, clearSignal }) {
|
|
3427
|
+
function TerminalPane({ model, host, sessionId, active, clearSignal, fontSize }) {
|
|
3326
3428
|
const { t } = model
|
|
3327
3429
|
const hostRef = React.useRef(host)
|
|
3328
3430
|
hostRef.current = host
|
|
3329
3431
|
const containerRef = React.useRef(null)
|
|
3330
3432
|
const termRef = React.useRef(null)
|
|
3331
3433
|
const fitRef = React.useRef(null)
|
|
3434
|
+
const searchAddonRef = React.useRef(null)
|
|
3435
|
+
const searchInputRef = React.useRef(null)
|
|
3436
|
+
const menuRef = React.useRef(null)
|
|
3437
|
+
const fontSizeRef = React.useRef(fontSize)
|
|
3438
|
+
fontSizeRef.current = fontSize
|
|
3332
3439
|
const activeRef = React.useRef(active === true)
|
|
3333
3440
|
const [status, setStatus] = React.useState('loading')
|
|
3441
|
+
const [searchOpen, setSearchOpen] = React.useState(false)
|
|
3442
|
+
const searchOpenRef = React.useRef(false)
|
|
3443
|
+
const [searchText, setSearchText] = React.useState('')
|
|
3444
|
+
const [searchCase, setSearchCase] = React.useState(false)
|
|
3445
|
+
const [menu, setMenu] = React.useState(null)
|
|
3334
3446
|
const [message, setMessage] = React.useState('')
|
|
3335
3447
|
const [retryToken, setRetryToken] = React.useState(0)
|
|
3336
3448
|
const clearRequested = React.useRef(false)
|
|
@@ -3370,6 +3482,131 @@ window.__ModuleLoader__.load({
|
|
|
3370
3482
|
} catch {}
|
|
3371
3483
|
}, [clearSignal])
|
|
3372
3484
|
|
|
3485
|
+
React.useEffect(() => {
|
|
3486
|
+
const term = termRef.current
|
|
3487
|
+
if (!term) return
|
|
3488
|
+
try {
|
|
3489
|
+
if (term.options.fontSize !== fontSize) {
|
|
3490
|
+
term.options.fontSize = fontSize
|
|
3491
|
+
fitRef.current?.fit()
|
|
3492
|
+
}
|
|
3493
|
+
} catch {}
|
|
3494
|
+
}, [fontSize])
|
|
3495
|
+
|
|
3496
|
+
const openSearch = () => {
|
|
3497
|
+
if (!searchAddonRef.current) {
|
|
3498
|
+
try { model.notify?.(t('terminal.searchUnavailable'), 'error') } catch {}
|
|
3499
|
+
return
|
|
3500
|
+
}
|
|
3501
|
+
searchOpenRef.current = true
|
|
3502
|
+
setSearchOpen(true)
|
|
3503
|
+
requestAnimationFrame(() => searchInputRef.current?.focus())
|
|
3504
|
+
}
|
|
3505
|
+
|
|
3506
|
+
const closeSearch = () => {
|
|
3507
|
+
searchOpenRef.current = false
|
|
3508
|
+
setSearchOpen(false)
|
|
3509
|
+
try { searchAddonRef.current?.clearDecorations?.() } catch {}
|
|
3510
|
+
try { termRef.current?.focus() } catch {}
|
|
3511
|
+
}
|
|
3512
|
+
|
|
3513
|
+
const findInTerminal = (direction, caseSensitive = searchCase) => {
|
|
3514
|
+
const addon = searchAddonRef.current
|
|
3515
|
+
const text = searchText.trim()
|
|
3516
|
+
if (!addon) return
|
|
3517
|
+
try {
|
|
3518
|
+
if (text === '') addon.clearDecorations?.()
|
|
3519
|
+
else if (direction < 0) addon.findPrevious(text, { caseSensitive })
|
|
3520
|
+
else addon.findNext(text, { caseSensitive })
|
|
3521
|
+
} catch {}
|
|
3522
|
+
}
|
|
3523
|
+
|
|
3524
|
+
const updateSearchText = (value) => {
|
|
3525
|
+
setSearchText(value)
|
|
3526
|
+
const addon = searchAddonRef.current
|
|
3527
|
+
if (!addon) return
|
|
3528
|
+
try {
|
|
3529
|
+
if (value.trim() === '') addon.clearDecorations?.()
|
|
3530
|
+
else addon.findNext(value.trim(), { caseSensitive: searchCase })
|
|
3531
|
+
} catch {}
|
|
3532
|
+
}
|
|
3533
|
+
|
|
3534
|
+
const terminalMenuAction = (action) => {
|
|
3535
|
+
const term = termRef.current
|
|
3536
|
+
setMenu(null)
|
|
3537
|
+
if (!term) return
|
|
3538
|
+
const refocus = () => {
|
|
3539
|
+
requestAnimationFrame(() => {
|
|
3540
|
+
try { termRef.current?.focus() } catch {}
|
|
3541
|
+
})
|
|
3542
|
+
}
|
|
3543
|
+
if (action === 'selectAll') {
|
|
3544
|
+
try { term.selectAll() } catch {}
|
|
3545
|
+
refocus()
|
|
3546
|
+
return
|
|
3547
|
+
}
|
|
3548
|
+
if (action === 'clear') {
|
|
3549
|
+
// Route through App so clearRequested/clearEpoch and the host buffer
|
|
3550
|
+
// stay in sync with the session-bar clear button.
|
|
3551
|
+
if (typeof model.clearSession === 'function') model.clearSession(sessionId)
|
|
3552
|
+
else clearPtySession(sessionId)
|
|
3553
|
+
try { term.clear(); term.write('\x1b[H\x1b[2J') } catch {}
|
|
3554
|
+
refocus()
|
|
3555
|
+
return
|
|
3556
|
+
}
|
|
3557
|
+
if (action === 'copy') {
|
|
3558
|
+
const text = term.getSelection()
|
|
3559
|
+
void copyTextToClipboard(text).then((ok) => {
|
|
3560
|
+
if (!ok) {
|
|
3561
|
+
try { model.notify?.(t('terminal.copyFailed'), 'error') } catch {}
|
|
3562
|
+
}
|
|
3563
|
+
refocus()
|
|
3564
|
+
})
|
|
3565
|
+
return
|
|
3566
|
+
}
|
|
3567
|
+
if (action === 'paste') {
|
|
3568
|
+
if (!navigator.clipboard?.readText) {
|
|
3569
|
+
try { model.notify?.(t('terminal.pasteFailed'), 'error') } catch {}
|
|
3570
|
+
refocus()
|
|
3571
|
+
return
|
|
3572
|
+
}
|
|
3573
|
+
navigator.clipboard.readText().then((text) => {
|
|
3574
|
+
if (text) {
|
|
3575
|
+
try { term.paste(text) } catch {}
|
|
3576
|
+
}
|
|
3577
|
+
refocus()
|
|
3578
|
+
}).catch(() => {
|
|
3579
|
+
try { model.notify?.(t('terminal.pasteFailed'), 'error') } catch {}
|
|
3580
|
+
refocus()
|
|
3581
|
+
})
|
|
3582
|
+
}
|
|
3583
|
+
}
|
|
3584
|
+
|
|
3585
|
+
React.useEffect(() => {
|
|
3586
|
+
if (!menu) return undefined
|
|
3587
|
+
const close = () => setMenu(null)
|
|
3588
|
+
const onKey = (event) => {
|
|
3589
|
+
if (event.key !== 'Escape') return
|
|
3590
|
+
event.preventDefault()
|
|
3591
|
+
event.stopPropagation()
|
|
3592
|
+
setMenu(null)
|
|
3593
|
+
try { termRef.current?.focus() } catch {}
|
|
3594
|
+
}
|
|
3595
|
+
const onDown = (event) => {
|
|
3596
|
+
if (menuRef.current && menuRef.current.contains(event.target)) return
|
|
3597
|
+
setMenu(null)
|
|
3598
|
+
}
|
|
3599
|
+
document.addEventListener('mousedown', onDown)
|
|
3600
|
+
document.addEventListener('keydown', onKey, true)
|
|
3601
|
+
requestAnimationFrame(() => {
|
|
3602
|
+
menuRef.current?.querySelector('button')?.focus()
|
|
3603
|
+
})
|
|
3604
|
+
return () => {
|
|
3605
|
+
document.removeEventListener('mousedown', onDown)
|
|
3606
|
+
document.removeEventListener('keydown', onKey, true)
|
|
3607
|
+
}
|
|
3608
|
+
}, [menu])
|
|
3609
|
+
|
|
3373
3610
|
React.useEffect(() => {
|
|
3374
3611
|
const container = containerRef.current
|
|
3375
3612
|
if (!container) return undefined
|
|
@@ -3434,7 +3671,7 @@ window.__ModuleLoader__.load({
|
|
|
3434
3671
|
term = new Terminal({
|
|
3435
3672
|
cursorBlink: true,
|
|
3436
3673
|
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',
|
|
3437
|
-
fontSize: 13,
|
|
3674
|
+
fontSize: fontSizeRef.current ?? 13,
|
|
3438
3675
|
lineHeight: 1.2,
|
|
3439
3676
|
scrollback: 5000,
|
|
3440
3677
|
allowProposedApi: true,
|
|
@@ -3444,9 +3681,39 @@ window.__ModuleLoader__.load({
|
|
|
3444
3681
|
})
|
|
3445
3682
|
fit = new FitAddon()
|
|
3446
3683
|
term.loadAddon(fit)
|
|
3684
|
+
if (assets.SearchAddon) {
|
|
3685
|
+
const searchAddon = new assets.SearchAddon()
|
|
3686
|
+
term.loadAddon(searchAddon)
|
|
3687
|
+
searchAddonRef.current = searchAddon
|
|
3688
|
+
}
|
|
3447
3689
|
term.open(container)
|
|
3448
3690
|
termRef.current = term
|
|
3449
3691
|
fitRef.current = fit
|
|
3692
|
+
term.attachCustomKeyEventHandler((event) => {
|
|
3693
|
+
if (event.type !== 'keydown') return true
|
|
3694
|
+
const meta = event.metaKey || event.ctrlKey
|
|
3695
|
+
if (meta && event.key.toLowerCase() === 'f') {
|
|
3696
|
+
event.preventDefault()
|
|
3697
|
+
openSearch()
|
|
3698
|
+
return false
|
|
3699
|
+
}
|
|
3700
|
+
if (meta && (event.key === '=' || event.key === '+')) {
|
|
3701
|
+
event.preventDefault()
|
|
3702
|
+
model.setTerminalFontSize((value) => Math.min(TERMINAL_FONT_MAX, value + 1))
|
|
3703
|
+
return false
|
|
3704
|
+
}
|
|
3705
|
+
if (meta && (event.key === '-' || event.key === '_')) {
|
|
3706
|
+
event.preventDefault()
|
|
3707
|
+
model.setTerminalFontSize((value) => Math.max(TERMINAL_FONT_MIN, value - 1))
|
|
3708
|
+
return false
|
|
3709
|
+
}
|
|
3710
|
+
if (event.key === 'Escape' && searchOpenRef.current) {
|
|
3711
|
+
event.preventDefault()
|
|
3712
|
+
closeSearch()
|
|
3713
|
+
return false
|
|
3714
|
+
}
|
|
3715
|
+
return true
|
|
3716
|
+
})
|
|
3450
3717
|
try { fit.fit() } catch {}
|
|
3451
3718
|
themeUnsub = subscribeTerminalTheme(() => {
|
|
3452
3719
|
if (removed || !term) return
|
|
@@ -3691,6 +3958,7 @@ window.__ModuleLoader__.load({
|
|
|
3691
3958
|
}
|
|
3692
3959
|
termRef.current = null
|
|
3693
3960
|
fitRef.current = null
|
|
3961
|
+
searchAddonRef.current = null
|
|
3694
3962
|
}
|
|
3695
3963
|
}, [sessionId, retryToken])
|
|
3696
3964
|
|
|
@@ -3698,8 +3966,81 @@ window.__ModuleLoader__.load({
|
|
|
3698
3966
|
const showOverlay = status !== 'ready'
|
|
3699
3967
|
return h(
|
|
3700
3968
|
'div',
|
|
3701
|
-
{
|
|
3969
|
+
{
|
|
3970
|
+
className: 'ssh-terminalPane',
|
|
3971
|
+
onContextMenu: (event) => {
|
|
3972
|
+
if (!termRef.current || status !== 'ready') return
|
|
3973
|
+
if (event.target?.closest?.('.ssh-terminalSearch')) return
|
|
3974
|
+
event.preventDefault()
|
|
3975
|
+
const rect = event.currentTarget.getBoundingClientRect()
|
|
3976
|
+
setMenu({
|
|
3977
|
+
x: Math.max(0, Math.min(event.clientX - rect.left, rect.width - 170)),
|
|
3978
|
+
y: Math.max(0, Math.min(event.clientY - rect.top, rect.height - 150)),
|
|
3979
|
+
})
|
|
3980
|
+
},
|
|
3981
|
+
onMouseDown: () => setMenu(null),
|
|
3982
|
+
},
|
|
3702
3983
|
h('div', { className: 'ssh-terminalHost', ref: containerRef }),
|
|
3984
|
+
searchOpen
|
|
3985
|
+
? h(
|
|
3986
|
+
'div',
|
|
3987
|
+
{
|
|
3988
|
+
className: 'ssh-terminalSearch',
|
|
3989
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
3990
|
+
},
|
|
3991
|
+
h(IconSearch, { size: 13 }),
|
|
3992
|
+
h('input', {
|
|
3993
|
+
ref: searchInputRef,
|
|
3994
|
+
className: 'ssh-terminalSearchInput',
|
|
3995
|
+
value: searchText,
|
|
3996
|
+
placeholder: t('terminal.search'),
|
|
3997
|
+
'aria-label': t('terminal.search'),
|
|
3998
|
+
onChange: (event) => updateSearchText(event.target.value),
|
|
3999
|
+
onKeyDown: (event) => {
|
|
4000
|
+
event.stopPropagation()
|
|
4001
|
+
if (event.key === 'Escape') closeSearch()
|
|
4002
|
+
else if (event.key === 'Enter') findInTerminal(event.shiftKey ? -1 : 1)
|
|
4003
|
+
},
|
|
4004
|
+
}),
|
|
4005
|
+
h('button', {
|
|
4006
|
+
type: 'button',
|
|
4007
|
+
className: cx('ssh-terminalSearchBtn', searchCase && 'on'),
|
|
4008
|
+
title: t('terminal.searchCase'),
|
|
4009
|
+
'aria-pressed': searchCase,
|
|
4010
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
4011
|
+
onClick: () => {
|
|
4012
|
+
const next = !searchCase
|
|
4013
|
+
setSearchCase(next)
|
|
4014
|
+
if (searchText.trim()) findInTerminal(1, next)
|
|
4015
|
+
},
|
|
4016
|
+
}, 'Aa'),
|
|
4017
|
+
h('button', { type: 'button', className: 'ssh-terminalSearchBtn', title: t('terminal.searchPrevious'), 'aria-label': t('terminal.searchPrevious'), onMouseDown: (event) => event.preventDefault(), onClick: () => findInTerminal(-1) }, h(IconChevronLeft, { size: 12 })),
|
|
4018
|
+
h('button', { type: 'button', className: 'ssh-terminalSearchBtn', title: t('terminal.searchNext'), 'aria-label': t('terminal.searchNext'), onMouseDown: (event) => event.preventDefault(), onClick: () => findInTerminal(1) }, h(IconChevronRight, { size: 12 })),
|
|
4019
|
+
h('button', { type: 'button', className: 'ssh-terminalSearchBtn', title: t('terminal.searchClose'), 'aria-label': t('terminal.searchClose'), onClick: closeSearch }, h(IconClose, { size: 12 })),
|
|
4020
|
+
)
|
|
4021
|
+
: null,
|
|
4022
|
+
menu
|
|
4023
|
+
? h(
|
|
4024
|
+
'div',
|
|
4025
|
+
{
|
|
4026
|
+
ref: menuRef,
|
|
4027
|
+
className: 'ssh-terminalMenu',
|
|
4028
|
+
role: 'menu',
|
|
4029
|
+
'aria-label': t('terminal.menu.title'),
|
|
4030
|
+
style: { left: menu.x, top: menu.y },
|
|
4031
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
4032
|
+
},
|
|
4033
|
+
['copy', 'paste', 'selectAll', 'clear'].map((action) =>
|
|
4034
|
+
h('button', {
|
|
4035
|
+
key: action,
|
|
4036
|
+
type: 'button',
|
|
4037
|
+
role: 'menuitem',
|
|
4038
|
+
className: 'ssh-terminalMenuItem',
|
|
4039
|
+
onClick: () => terminalMenuAction(action),
|
|
4040
|
+
}, t(`terminal.menu.${action}`)),
|
|
4041
|
+
),
|
|
4042
|
+
)
|
|
4043
|
+
: null,
|
|
3703
4044
|
showOverlay
|
|
3704
4045
|
? h(
|
|
3705
4046
|
'div',
|
|
@@ -4949,6 +5290,16 @@ body.ssh-col-resizing,body.ssh-col-resizing *{cursor:col-resize!important;user-s
|
|
|
4949
5290
|
.ssh-terminalOverlayActions{display:flex;gap:8px;flex-wrap:wrap;justify-content:center}
|
|
4950
5291
|
.ssh-sessionLayer{flex:1;min-height:0;display:flex;flex-direction:column;background:var(--ssh-bg)}
|
|
4951
5292
|
.ssh-sessionState{width:6px;height:6px;border-radius:50%;background:var(--ssh-dim);flex:0 0 auto}
|
|
5293
|
+
.ssh-fontGlyph{font-size:10.5px;font-weight:600;letter-spacing:-.4px}
|
|
5294
|
+
.ssh-terminalSearch{position:absolute;top:8px;right:18px;z-index:5;max-width:calc(100% - 24px);display:flex;align-items:center;gap:5px;padding:5px 7px;border:.5px solid var(--ssh-border-strong);border-radius:10px;background:var(--ssh-layer-1);box-shadow:var(--ssh-shadow);color:var(--ssh-text-3)}
|
|
5295
|
+
.ssh-terminalSearchInput{width:min(180px,42vw);max-width:100%;height:24px;padding:0 7px;border:.5px solid var(--ssh-border);border-radius:6px;background:var(--ssh-bg);color:var(--ssh-text);font:inherit;font-size:12px;outline:none}
|
|
5296
|
+
.ssh-terminalSearchInput:focus{border-color:var(--ssh-brand)}
|
|
5297
|
+
.ssh-terminalSearchBtn{appearance:none;display:inline-flex;align-items:center;justify-content:center;height:24px;min-width:24px;padding:0 5px;border:0;border-radius:6px;background:transparent;color:var(--ssh-text-2);font:inherit;font-size:11px;cursor:pointer}
|
|
5298
|
+
.ssh-terminalSearchBtn:hover{background:var(--ssh-hover);color:var(--ssh-text)}
|
|
5299
|
+
.ssh-terminalSearchBtn.on{background:color-mix(in srgb,var(--ssh-brand) 15%,transparent);color:var(--ssh-brand)}
|
|
5300
|
+
.ssh-terminalMenu{position:absolute;z-index:7;min-width:150px;padding:4px;border:.5px solid var(--ssh-border-strong);border-radius:9px;background:var(--ssh-layer-1);box-shadow:var(--ssh-shadow)}
|
|
5301
|
+
.ssh-terminalMenuItem{appearance:none;display:flex;align-items:center;width:100%;height:28px;padding:0 9px;border:0;border-radius:6px;background:transparent;color:var(--ssh-text-2);font:inherit;font-size:12px;text-align:left;cursor:pointer}
|
|
5302
|
+
.ssh-terminalMenuItem:hover{background:var(--ssh-hover);color:var(--ssh-text)}
|
|
4952
5303
|
.ssh-sessionState.loading,.ssh-sessionState.connecting{background:var(--ssh-warn)}
|
|
4953
5304
|
.ssh-sessionState.ready{background:var(--ssh-success)}
|
|
4954
5305
|
.ssh-sessionState.error,.ssh-sessionState.closed{background:var(--ssh-danger)}
|
package/index.js
CHANGED
|
@@ -28,6 +28,7 @@ const ASSETS = [
|
|
|
28
28
|
{ path: '/dsh-ssh-manage/assets/xterm.js', file: 'xterm.js', contentType: 'text/javascript; charset=utf-8' },
|
|
29
29
|
{ path: '/dsh-ssh-manage/assets/xterm.css', file: 'xterm.css', contentType: 'text/css; charset=utf-8' },
|
|
30
30
|
{ path: '/dsh-ssh-manage/assets/addon-fit.js', file: 'addon-fit.js', contentType: 'text/javascript; charset=utf-8' },
|
|
31
|
+
{ path: '/dsh-ssh-manage/assets/addon-search.js', file: 'addon-search.js', contentType: 'text/javascript; charset=utf-8' },
|
|
31
32
|
]
|
|
32
33
|
const MAX_BODY_BYTES = 16 * 1024 * 1024
|
|
33
34
|
const ACTIONS = ['overview', 'list_hosts', 'save_host', 'delete_host', 'set_metadata', 'save_password', 'delete_password', 'test_connection', 'inspect_host', 'exec', 'batch_exec', 'sftp_list', 'sftp_upload', 'sftp_download']
|